Skip to content

Commit b4ba546

Browse files
TheBlueMattandozw
authored andcommitted
Avoid storing a full FinalOnionHopData in OnionPayload::Invoice
We only use it to check the amount when processing MPP parts, but store the full object (including new payment metadata) in it. Because we now store the amount in the parent structure, there is no need for it at all in the `OnionPayload`. Sadly, for serialization compatibility, we need it to continue to exist, at least temporarily, but we can avoid populating the new fields in that case.
1 parent 04381b6 commit b4ba546

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,11 @@ enum OnionPayload {
162162
/// Contains a total_msat (which may differ from value if this is a Multi-Path Payment) and a
163163
/// payment_secret which prevents path-probing attacks and can associate different HTLCs which
164164
/// are part of the same payment.
165-
Invoice(msgs::FinalOnionHopData),
165+
Invoice {
166+
/// This is only here for backwards-compatibility in serialization, in the future it can be
167+
/// removed, breaking clients running 0.0.104 and earlier.
168+
_legacy_hop_data: msgs::FinalOnionHopData,
169+
},
166170
/// Contains the payer-provided preimage.
167171
Spontaneous(PaymentPreimage),
168172
}
@@ -3092,11 +3096,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
30923096
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
30933097
routing, incoming_shared_secret, payment_hash, amt_to_forward, .. },
30943098
prev_funding_outpoint } => {
3095-
let (cltv_expiry, total_msat, onion_payload, phantom_shared_secret) = match routing {
3096-
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } =>
3097-
(incoming_cltv_expiry, payment_data.total_msat, OnionPayload::Invoice(payment_data), phantom_shared_secret),
3099+
let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing {
3100+
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } => {
3101+
let _legacy_hop_data = msgs::FinalOnionHopData {
3102+
payment_secret: payment_data.payment_secret,
3103+
total_msat: payment_data.total_msat
3104+
};
3105+
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data), phantom_shared_secret)
3106+
},
30983107
PendingHTLCRouting::ReceiveKeysend { payment_preimage, incoming_cltv_expiry } =>
3099-
(incoming_cltv_expiry, amt_to_forward, OnionPayload::Spontaneous(payment_preimage), None),
3108+
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage), None, None),
31003109
_ => {
31013110
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
31023111
}
@@ -3111,7 +3120,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31113120
},
31123121
value: amt_to_forward,
31133122
timer_ticks: 0,
3114-
total_msat,
3123+
total_msat: if let Some(data) = &payment_data { data.total_msat } else { amt_to_forward },
31153124
cltv_expiry,
31163125
onion_payload,
31173126
};
@@ -3135,7 +3144,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31353144
}
31363145

31373146
macro_rules! check_total_value {
3138-
($payment_data_total_msat: expr, $payment_secret: expr, $payment_preimage: expr) => {{
3147+
($payment_data: expr, $payment_preimage: expr) => {{
31393148
let mut payment_received_generated = false;
31403149
let htlcs = channel_state.claimable_htlcs.entry(payment_hash)
31413150
.or_insert(Vec::new());
@@ -3150,7 +3159,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31503159
for htlc in htlcs.iter() {
31513160
total_value += htlc.value;
31523161
match &htlc.onion_payload {
3153-
OnionPayload::Invoice(_) => {
3162+
OnionPayload::Invoice { .. } => {
31543163
if htlc.total_msat != claimable_htlc.total_msat {
31553164
log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
31563165
log_bytes!(payment_hash.0), claimable_htlc.total_msat, htlc.total_msat);
@@ -3169,7 +3178,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31693178
payment_hash,
31703179
purpose: events::PaymentPurpose::InvoicePayment {
31713180
payment_preimage: $payment_preimage,
3172-
payment_secret: $payment_secret,
3181+
payment_secret: $payment_data.payment_secret,
31733182
},
31743183
amt: total_value,
31753184
});
@@ -3194,16 +3203,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31943203
match payment_secrets.entry(payment_hash) {
31953204
hash_map::Entry::Vacant(_) => {
31963205
match claimable_htlc.onion_payload {
3197-
OnionPayload::Invoice(ref payment_data) => {
3206+
OnionPayload::Invoice { .. } => {
3207+
let payment_data = payment_data.unwrap();
31983208
let payment_preimage = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) {
31993209
Ok(payment_preimage) => payment_preimage,
32003210
Err(()) => {
32013211
fail_htlc!(claimable_htlc);
32023212
continue
32033213
}
32043214
};
3205-
let payment_secret = payment_data.payment_secret.clone();
3206-
check_total_value!(payment_data.total_msat, payment_secret, payment_preimage);
3215+
check_total_value!(payment_data, payment_preimage);
32073216
},
32083217
OnionPayload::Spontaneous(preimage) => {
32093218
match channel_state.claimable_htlcs.entry(payment_hash) {
@@ -3224,14 +3233,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32243233
}
32253234
},
32263235
hash_map::Entry::Occupied(inbound_payment) => {
3227-
let payment_data =
3228-
if let OnionPayload::Invoice(ref data) = claimable_htlc.onion_payload {
3229-
data.clone()
3230-
} else {
3231-
log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", log_bytes!(payment_hash.0));
3232-
fail_htlc!(claimable_htlc);
3233-
continue
3234-
};
3236+
if payment_data.is_none() {
3237+
log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", log_bytes!(payment_hash.0));
3238+
fail_htlc!(claimable_htlc);
3239+
continue
3240+
};
3241+
let payment_data = payment_data.unwrap();
32353242
if inbound_payment.get().payment_secret != payment_data.payment_secret {
32363243
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", log_bytes!(payment_hash.0));
32373244
fail_htlc!(claimable_htlc);
@@ -3240,7 +3247,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32403247
log_bytes!(payment_hash.0), payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap());
32413248
fail_htlc!(claimable_htlc);
32423249
} else {
3243-
let payment_received_generated = check_total_value!(payment_data.total_msat, payment_data.payment_secret, inbound_payment.get().payment_preimage);
3250+
let payment_received_generated = check_total_value!(payment_data, inbound_payment.get().payment_preimage);
32443251
if payment_received_generated {
32453252
inbound_payment.remove_entry();
32463253
}
@@ -3459,7 +3466,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
34593466
debug_assert!(false);
34603467
return false;
34613468
}
3462-
if let OnionPayload::Invoice(ref final_hop_data) = htlcs[0].onion_payload {
3469+
if let OnionPayload::Invoice { _legacy_hop_data: ref final_hop_data } = htlcs[0].onion_payload {
34633470
// Check if we've received all the parts we need for an MPP (the value of the parts adds to total_msat).
34643471
// In this case we're not going to handle any timeouts of the parts here.
34653472
if final_hop_data.total_msat == htlcs.iter().fold(0, |total, htlc| total + htlc.value) {
@@ -6061,11 +6068,11 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
60616068
impl Writeable for ClaimableHTLC {
60626069
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
60636070
let payment_data = match &self.onion_payload {
6064-
OnionPayload::Invoice(data) => Some(data.clone()),
6071+
OnionPayload::Invoice { _legacy_hop_data } => Some(_legacy_hop_data),
60656072
_ => None,
60666073
};
60676074
let keysend_preimage = match self.onion_payload {
6068-
OnionPayload::Invoice(_) => None,
6075+
OnionPayload::Invoice { .. } => None,
60696076
OnionPayload::Spontaneous(preimage) => Some(preimage.clone()),
60706077
};
60716078
write_tlv_fields!(writer, {
@@ -6113,7 +6120,7 @@ impl Readable for ClaimableHTLC {
61136120
if total_msat.is_none() {
61146121
total_msat = Some(payment_data.as_ref().unwrap().total_msat);
61156122
}
6116-
OnionPayload::Invoice(payment_data.unwrap())
6123+
OnionPayload::Invoice { _legacy_hop_data: payment_data.unwrap() }
61176124
},
61186125
};
61196126
Ok(Self {

0 commit comments

Comments
 (0)