Skip to content

Commit 5e14518

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 299a2ef commit 5e14518

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
}
@@ -3169,11 +3173,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31693173
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
31703174
routing, incoming_shared_secret, payment_hash, amt_to_forward, .. },
31713175
prev_funding_outpoint } => {
3172-
let (cltv_expiry, total_msat, onion_payload) = match routing {
3173-
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } =>
3174-
(incoming_cltv_expiry, payment_data.total_msat, OnionPayload::Invoice(payment_data)),
3176+
let (cltv_expiry, onion_payload, payment_data) = match routing {
3177+
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } => {
3178+
let _legacy_hop_data = msgs::FinalOnionHopData {
3179+
payment_secret: payment_data.payment_secret,
3180+
total_msat: payment_data.total_msat
3181+
};
3182+
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data))
3183+
},
31753184
PendingHTLCRouting::ReceiveKeysend { payment_preimage, incoming_cltv_expiry } =>
3176-
(incoming_cltv_expiry, amt_to_forward, OnionPayload::Spontaneous(payment_preimage)),
3185+
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage), None),
31773186
_ => {
31783187
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
31793188
}
@@ -3186,7 +3195,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31863195
incoming_packet_shared_secret: incoming_shared_secret,
31873196
},
31883197
value: amt_to_forward,
3189-
total_msat,
3198+
total_msat: if let Some(data) = &payment_data { data.total_msat } else { amt_to_forward },
31903199
cltv_expiry,
31913200
onion_payload,
31923201
};
@@ -3209,7 +3218,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32093218
}
32103219

32113220
macro_rules! check_total_value {
3212-
($payment_data_total_msat: expr, $payment_secret: expr, $payment_preimage: expr) => {{
3221+
($payment_data: expr, $payment_preimage: expr) => {{
32133222
let mut payment_received_generated = false;
32143223
let htlcs = channel_state.claimable_htlcs.entry(payment_hash)
32153224
.or_insert(Vec::new());
@@ -3224,7 +3233,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32243233
for htlc in htlcs.iter() {
32253234
total_value += htlc.value;
32263235
match &htlc.onion_payload {
3227-
OnionPayload::Invoice(_) => {
3236+
OnionPayload::Invoice { .. } => {
32283237
if htlc.total_msat != claimable_htlc.total_msat {
32293238
log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
32303239
log_bytes!(payment_hash.0), claimable_htlc.total_msat, htlc.total_msat);
@@ -3246,7 +3255,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32463255
payment_hash,
32473256
purpose: events::PaymentPurpose::InvoicePayment {
32483257
payment_preimage: $payment_preimage,
3249-
payment_secret: $payment_secret,
3258+
payment_secret: $payment_data.payment_secret,
32503259
},
32513260
amt: total_value,
32523261
});
@@ -3271,17 +3280,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
32713280
match payment_secrets.entry(payment_hash) {
32723281
hash_map::Entry::Vacant(_) => {
32733282
match claimable_htlc.onion_payload {
3274-
OnionPayload::Invoice(ref payment_data) => {
3283+
OnionPayload::Invoice { .. } => {
3284+
let payment_data = payment_data.unwrap();
32753285
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) {
32763286
Ok(payment_preimage) => payment_preimage,
32773287
Err(()) => {
32783288
fail_htlc!(claimable_htlc);
32793289
continue
32803290
}
32813291
};
3282-
let payment_data_total_msat = payment_data.total_msat;
3283-
let payment_secret = payment_data.payment_secret.clone();
3284-
check_total_value!(payment_data_total_msat, payment_secret, payment_preimage);
3292+
check_total_value!(payment_data, payment_preimage);
32853293
},
32863294
OnionPayload::Spontaneous(preimage) => {
32873295
match channel_state.claimable_htlcs.entry(payment_hash) {
@@ -3302,14 +3310,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
33023310
}
33033311
},
33043312
hash_map::Entry::Occupied(inbound_payment) => {
3305-
let payment_data =
3306-
if let OnionPayload::Invoice(ref data) = claimable_htlc.onion_payload {
3307-
data.clone()
3308-
} else {
3309-
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));
3310-
fail_htlc!(claimable_htlc);
3311-
continue
3312-
};
3313+
if payment_data.is_none() {
3314+
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));
3315+
fail_htlc!(claimable_htlc);
3316+
continue
3317+
};
3318+
let payment_data = payment_data.unwrap();
33133319
if inbound_payment.get().payment_secret != payment_data.payment_secret {
33143320
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", log_bytes!(payment_hash.0));
33153321
fail_htlc!(claimable_htlc);
@@ -3318,7 +3324,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
33183324
log_bytes!(payment_hash.0), payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap());
33193325
fail_htlc!(claimable_htlc);
33203326
} else {
3321-
let payment_received_generated = check_total_value!(payment_data.total_msat, payment_data.payment_secret, inbound_payment.get().payment_preimage);
3327+
let payment_received_generated = check_total_value!(payment_data, inbound_payment.get().payment_preimage);
33223328
if payment_received_generated {
33233329
inbound_payment.remove_entry();
33243330
}
@@ -5918,11 +5924,11 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
59185924
impl Writeable for ClaimableHTLC {
59195925
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
59205926
let payment_data = match &self.onion_payload {
5921-
OnionPayload::Invoice(data) => Some(data.clone()),
5927+
OnionPayload::Invoice { _legacy_hop_data } => Some(_legacy_hop_data),
59225928
_ => None,
59235929
};
59245930
let keysend_preimage = match self.onion_payload {
5925-
OnionPayload::Invoice(_) => None,
5931+
OnionPayload::Invoice { .. } => None,
59265932
OnionPayload::Spontaneous(preimage) => Some(preimage.clone()),
59275933
};
59285934
write_tlv_fields!(writer, {
@@ -5970,7 +5976,7 @@ impl Readable for ClaimableHTLC {
59705976
if total_msat.is_none() {
59715977
total_msat = Some(payment_data.as_ref().unwrap().total_msat);
59725978
}
5973-
OnionPayload::Invoice(payment_data.unwrap())
5979+
OnionPayload::Invoice { _legacy_hop_data: payment_data.unwrap() }
59745980
},
59755981
};
59765982
Ok(Self {

0 commit comments

Comments
 (0)