@@ -23,7 +23,7 @@ use bitcoin::constants::ChainHash;
2323use bitcoin::key::constants::SECRET_KEY_SIZE;
2424use bitcoin::network::Network;
2525
26- use bitcoin::hashes::Hash;
26+ use bitcoin::hashes::{ Hash, HashEngine, HmacEngine} ;
2727use bitcoin::hashes::hmac::Hmac;
2828use bitcoin::hashes::sha256::Hash as Sha256;
2929use bitcoin::hash_types::{BlockHash, Txid};
@@ -368,6 +368,7 @@ pub(crate) struct HTLCPreviousHopData {
368368 counterparty_node_id: Option<PublicKey>,
369369}
370370
371+ #[derive(PartialEq, Eq)]
371372enum OnionPayload {
372373 /// Indicates this incoming onion payload is for the purpose of paying an invoice.
373374 Invoice {
@@ -380,6 +381,7 @@ enum OnionPayload {
380381}
381382
382383/// HTLCs that are to us and can be failed/claimed by the user
384+ #[derive(PartialEq, Eq)]
383385struct ClaimableHTLC {
384386 prev_hop: HTLCPreviousHopData,
385387 cltv_expiry: u32,
@@ -411,6 +413,23 @@ impl From<&ClaimableHTLC> for events::ClaimedHTLC {
411413 }
412414}
413415
416+ impl PartialOrd for ClaimableHTLC {
417+ fn partial_cmp(&self, other: &ClaimableHTLC) -> Option<cmp::Ordering> {
418+ Some(self.cmp(other))
419+ }
420+ }
421+ impl Ord for ClaimableHTLC {
422+ fn cmp(&self, other: &ClaimableHTLC) -> cmp::Ordering {
423+ let res = (self.prev_hop.channel_id, self.prev_hop.htlc_id).cmp(
424+ &(other.prev_hop.channel_id, other.prev_hop.htlc_id)
425+ );
426+ if res.is_eq() {
427+ debug_assert!(self == other, "ClaimableHTLCs from the same source should be identical");
428+ }
429+ res
430+ }
431+ }
432+
414433/// A trait defining behavior for creating and verifing the HMAC for authenticating a given data.
415434pub trait Verification {
416435 /// Constructs an HMAC to include in [`OffersContext`] for the data along with the given
@@ -491,6 +510,22 @@ impl Verification for PaymentId {
491510 }
492511}
493512
513+ impl PaymentId {
514+ fn for_inbound_from_htlcs<I: Iterator<Item=(ChannelId, u64)>>(key: &[u8; 32], htlcs: I) -> PaymentId {
515+ let mut prev_pair = None;
516+ let mut hasher = HmacEngine::new(key);
517+ for (channel_id, htlc_id) in htlcs {
518+ hasher.input(&channel_id.0);
519+ hasher.input(&htlc_id.to_le_bytes());
520+ if let Some(prev) = prev_pair {
521+ debug_assert!(prev < (channel_id, htlc_id), "HTLCs should be sorted");
522+ }
523+ prev_pair = Some((channel_id, htlc_id));
524+ }
525+ PaymentId(Hmac::<Sha256>::from_engine(hasher).to_byte_array())
526+ }
527+ }
528+
494529impl Writeable for PaymentId {
495530 fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
496531 self.0.write(w)
@@ -764,6 +799,7 @@ struct ClaimingPayment {
764799 htlcs: Vec<events::ClaimedHTLC>,
765800 sender_intended_value: Option<u64>,
766801 onion_fields: Option<RecipientOnionFields>,
802+ payment_id: Option<PaymentId>,
767803}
768804impl_writeable_tlv_based!(ClaimingPayment, {
769805 (0, amount_msat, required),
@@ -772,6 +808,7 @@ impl_writeable_tlv_based!(ClaimingPayment, {
772808 (5, htlcs, optional_vec),
773809 (7, sender_intended_value, option),
774810 (9, onion_fields, option),
811+ (11, payment_id, option),
775812});
776813
777814struct ClaimablePayment {
@@ -780,6 +817,15 @@ struct ClaimablePayment {
780817 htlcs: Vec<ClaimableHTLC>,
781818}
782819
820+ impl ClaimablePayment {
821+ fn inbound_payment_id(&self, secret: &[u8; 32]) -> PaymentId {
822+ PaymentId::for_inbound_from_htlcs(
823+ secret,
824+ self.htlcs.iter().map(|htlc| (htlc.prev_hop.channel_id, htlc.prev_hop.htlc_id))
825+ )
826+ }
827+ }
828+
783829/// Represent the channel funding transaction type.
784830enum FundingType {
785831 /// This variant is useful when we want LDK to validate the funding transaction and
@@ -5749,10 +5795,9 @@ where
57495795 } else {
57505796 claimable_payment.onion_fields = Some(onion_fields);
57515797 }
5752- let ref mut htlcs = &mut claimable_payment.htlcs;
57535798 let mut total_value = claimable_htlc.sender_intended_value;
57545799 let mut earliest_expiry = claimable_htlc.cltv_expiry;
5755- for htlc in htlcs.iter() {
5800+ for htlc in claimable_payment. htlcs.iter() {
57565801 total_value += htlc.sender_intended_value;
57575802 earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
57585803 if htlc.total_msat != claimable_htlc.total_msat {
@@ -5774,13 +5819,18 @@ where
57745819 #[allow(unused_assignments)] {
57755820 committed_to_claimable = true;
57765821 }
5777- htlcs.push(claimable_htlc);
5778- let amount_msat = htlcs.iter().map(|htlc| htlc.value).sum();
5779- htlcs.iter_mut().for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5780- let counterparty_skimmed_fee_msat = htlcs.iter()
5822+ claimable_payment.htlcs.push(claimable_htlc);
5823+ let amount_msat =
5824+ claimable_payment.htlcs.iter().map(|htlc| htlc.value).sum();
5825+ claimable_payment.htlcs.iter_mut()
5826+ .for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5827+ let counterparty_skimmed_fee_msat = claimable_payment.htlcs.iter()
57815828 .map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
57825829 debug_assert!(total_value.saturating_sub(amount_msat) <=
57835830 counterparty_skimmed_fee_msat);
5831+ claimable_payment.htlcs.sort();
5832+ let payment_id =
5833+ claimable_payment.inbound_payment_id(&self.inbound_payment_id_secret);
57845834 new_events.push_back((events::Event::PaymentClaimable {
57855835 receiver_node_id: Some(receiver_node_id),
57865836 payment_hash,
@@ -5791,13 +5841,14 @@ where
57915841 via_user_channel_id: Some(prev_user_channel_id),
57925842 claim_deadline: Some(earliest_expiry - HTLC_FAIL_BACK_BUFFER),
57935843 onion_fields: claimable_payment.onion_fields.clone(),
5844+ payment_id: Some(payment_id),
57945845 }, None));
57955846 payment_claimable_generated = true;
57965847 } else {
57975848 // Nothing to do - we haven't reached the total
57985849 // payment value yet, wait until we receive more
57995850 // MPP parts.
5800- htlcs.push(claimable_htlc);
5851+ claimable_payment. htlcs.push(claimable_htlc);
58015852 #[allow(unused_assignments)] {
58025853 committed_to_claimable = true;
58035854 }
@@ -6594,6 +6645,7 @@ where
65946645 }
65956646 }
65966647
6648+ let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
65976649 let claiming_payment = claimable_payments.pending_claiming_payments
65986650 .entry(payment_hash)
65996651 .and_modify(|_| {
@@ -6611,6 +6663,7 @@ where
66116663 htlcs,
66126664 sender_intended_value,
66136665 onion_fields: payment.onion_fields,
6666+ payment_id: Some(payment_id),
66146667 }
66156668 });
66166669
@@ -7128,6 +7181,7 @@ where
71287181 htlcs,
71297182 sender_intended_value: sender_intended_total_msat,
71307183 onion_fields,
7184+ payment_id,
71317185 }) = payment {
71327186 self.pending_events.lock().unwrap().push_back((events::Event::PaymentClaimed {
71337187 payment_hash,
@@ -7137,6 +7191,7 @@ where
71377191 htlcs,
71387192 sender_intended_total_msat,
71397193 onion_fields,
7194+ payment_id,
71407195 }, None));
71417196 }
71427197 },
@@ -12863,6 +12918,7 @@ where
1286312918 previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &bounded_fee_estimator, &args.logger);
1286412919 }
1286512920 }
12921+ let payment_id = payment.inbound_payment_id(&inbound_payment_id_secret.unwrap());
1286612922 pending_events_read.push_back((events::Event::PaymentClaimed {
1286712923 receiver_node_id,
1286812924 payment_hash,
@@ -12871,6 +12927,7 @@ where
1287112927 htlcs: payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(),
1287212928 sender_intended_total_msat: payment.htlcs.first().map(|htlc| htlc.total_msat),
1287312929 onion_fields: payment.onion_fields,
12930+ payment_id: Some(payment_id),
1287412931 }, None));
1287512932 }
1287612933 }
0 commit comments