Skip to content

Commit 25a2066

Browse files
committed
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 4bb74e3 commit 25a2066

File tree

1 file changed

+31
-25
lines changed

1 file changed

+31
-25
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,11 @@ enum OnionPayload {
449449
/// Contains a total_msat (which may differ from value if this is a Multi-Path Payment) and a
450450
/// payment_secret which prevents path-probing attacks and can associate different HTLCs which
451451
/// are part of the same payment.
452-
Invoice(msgs::FinalOnionHopData),
452+
Invoice {
453+
/// This is only here for backwards-compatibility in serialization, in the future it can be
454+
/// removed, breaking clients running 0.0.104 and earlier.
455+
_legacy_hop_data: msgs::FinalOnionHopData,
456+
},
453457
/// Contains the payer-provided preimage.
454458
Spontaneous(PaymentPreimage),
455459
}
@@ -3173,11 +3177,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31733177
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
31743178
routing, incoming_shared_secret, payment_hash, amt_to_forward, .. },
31753179
prev_funding_outpoint } => {
3176-
let (cltv_expiry, total_msat, onion_payload) = match routing {
3177-
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } =>
3178-
(incoming_cltv_expiry, payment_data.total_msat, OnionPayload::Invoice(payment_data)),
3180+
let (cltv_expiry, onion_payload, payment_data) = match routing {
3181+
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } => {
3182+
let _legacy_hop_data = msgs::FinalOnionHopData {
3183+
payment_secret: payment_data.payment_secret,
3184+
total_msat: payment_data.total_msat
3185+
};
3186+
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data))
3187+
},
31793188
PendingHTLCRouting::ReceiveKeysend { payment_preimage, incoming_cltv_expiry } =>
3180-
(incoming_cltv_expiry, amt_to_forward, OnionPayload::Spontaneous(payment_preimage)),
3189+
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage), None),
31813190
_ => {
31823191
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
31833192
}
@@ -3190,7 +3199,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31903199
incoming_packet_shared_secret: incoming_shared_secret,
31913200
},
31923201
value: amt_to_forward,
3193-
total_msat,
3202+
total_msat: if let Some(data) = &payment_data { data.total_msat } else { amt_to_forward },
31943203
cltv_expiry,
31953204
onion_payload,
31963205
};
@@ -3213,7 +3222,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32133222
}
32143223

32153224
macro_rules! check_total_value {
3216-
($payment_data_total_msat: expr, $payment_secret: expr, $payment_preimage: expr) => {{
3225+
($payment_data: expr, $payment_preimage: expr) => {{
32173226
let mut payment_received_generated = false;
32183227
let htlcs = channel_state.claimable_htlcs.entry(payment_hash)
32193228
.or_insert(Vec::new());
@@ -3228,7 +3237,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32283237
for htlc in htlcs.iter() {
32293238
total_value += htlc.value;
32303239
match &htlc.onion_payload {
3231-
OnionPayload::Invoice(_) => {
3240+
OnionPayload::Invoice { .. } => {
32323241
if htlc.total_msat != claimable_htlc.total_msat {
32333242
log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
32343243
log_bytes!(payment_hash.0), claimable_htlc.total_msat, htlc.total_msat);
@@ -3250,7 +3259,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32503259
payment_hash,
32513260
purpose: events::PaymentPurpose::InvoicePayment {
32523261
payment_preimage: $payment_preimage,
3253-
payment_secret: $payment_secret,
3262+
payment_secret: $payment_data.payment_secret,
32543263
},
32553264
amt: total_value,
32563265
});
@@ -3275,17 +3284,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32753284
match payment_secrets.entry(payment_hash) {
32763285
hash_map::Entry::Vacant(_) => {
32773286
match claimable_htlc.onion_payload {
3278-
OnionPayload::Invoice(ref payment_data) => {
3287+
OnionPayload::Invoice { .. } => {
3288+
let payment_data = payment_data.unwrap();
32793289
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) {
32803290
Ok(payment_preimage) => payment_preimage,
32813291
Err(()) => {
32823292
fail_htlc!(claimable_htlc);
32833293
continue
32843294
}
32853295
};
3286-
let payment_data_total_msat = payment_data.total_msat;
3287-
let payment_secret = payment_data.payment_secret.clone();
3288-
check_total_value!(payment_data_total_msat, payment_secret, payment_preimage);
3296+
check_total_value!(payment_data, payment_preimage);
32893297
},
32903298
OnionPayload::Spontaneous(preimage) => {
32913299
match channel_state.claimable_htlcs.entry(payment_hash) {
@@ -3306,14 +3314,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
33063314
}
33073315
},
33083316
hash_map::Entry::Occupied(inbound_payment) => {
3309-
let payment_data =
3310-
if let OnionPayload::Invoice(ref data) = claimable_htlc.onion_payload {
3311-
data.clone()
3312-
} else {
3313-
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));
3314-
fail_htlc!(claimable_htlc);
3315-
continue
3316-
};
3317+
if payment_data.is_none() {
3318+
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));
3319+
fail_htlc!(claimable_htlc);
3320+
continue
3321+
};
3322+
let payment_data = payment_data.unwrap();
33173323
if inbound_payment.get().payment_secret != payment_data.payment_secret {
33183324
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", log_bytes!(payment_hash.0));
33193325
fail_htlc!(claimable_htlc);
@@ -3322,7 +3328,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
33223328
log_bytes!(payment_hash.0), payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap());
33233329
fail_htlc!(claimable_htlc);
33243330
} else {
3325-
let payment_received_generated = check_total_value!(payment_data.total_msat, payment_data.payment_secret, inbound_payment.get().payment_preimage);
3331+
let payment_received_generated = check_total_value!(payment_data, inbound_payment.get().payment_preimage);
33263332
if payment_received_generated {
33273333
inbound_payment.remove_entry();
33283334
}
@@ -5922,11 +5928,11 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
59225928
impl Writeable for ClaimableHTLC {
59235929
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
59245930
let payment_data = match &self.onion_payload {
5925-
OnionPayload::Invoice(data) => Some(data.clone()),
5931+
OnionPayload::Invoice { _legacy_hop_data } => Some(_legacy_hop_data),
59265932
_ => None,
59275933
};
59285934
let keysend_preimage = match self.onion_payload {
5929-
OnionPayload::Invoice(_) => None,
5935+
OnionPayload::Invoice { .. } => None,
59305936
OnionPayload::Spontaneous(preimage) => Some(preimage.clone()),
59315937
};
59325938
write_tlv_fields!(writer, {
@@ -5974,7 +5980,7 @@ impl Readable for ClaimableHTLC {
59745980
if total_msat.is_none() {
59755981
total_msat = Some(payment_data.as_ref().unwrap().total_msat);
59765982
}
5977-
OnionPayload::Invoice(payment_data.unwrap())
5983+
OnionPayload::Invoice { _legacy_hop_data: payment_data.unwrap() }
59785984
},
59795985
};
59805986
Ok(Self {

0 commit comments

Comments
 (0)