@@ -23,7 +23,7 @@ use bitcoin::constants::ChainHash;
23
23
use bitcoin::key::constants::SECRET_KEY_SIZE;
24
24
use bitcoin::network::Network;
25
25
26
- use bitcoin::hashes::Hash;
26
+ use bitcoin::hashes::{ Hash, HashEngine, HmacEngine} ;
27
27
use bitcoin::hashes::hmac::Hmac;
28
28
use bitcoin::hashes::sha256::Hash as Sha256;
29
29
use bitcoin::hash_types::{BlockHash, Txid};
@@ -369,6 +369,7 @@ pub(crate) struct HTLCPreviousHopData {
369
369
counterparty_node_id: Option<PublicKey>,
370
370
}
371
371
372
+ #[derive(PartialEq, Eq)]
372
373
enum OnionPayload {
373
374
/// Indicates this incoming onion payload is for the purpose of paying an invoice.
374
375
Invoice {
@@ -381,6 +382,7 @@ enum OnionPayload {
381
382
}
382
383
383
384
/// HTLCs that are to us and can be failed/claimed by the user
385
+ #[derive(PartialEq, Eq)]
384
386
struct ClaimableHTLC {
385
387
prev_hop: HTLCPreviousHopData,
386
388
cltv_expiry: u32,
@@ -412,6 +414,23 @@ impl From<&ClaimableHTLC> for events::ClaimedHTLC {
412
414
}
413
415
}
414
416
417
+ impl PartialOrd for ClaimableHTLC {
418
+ fn partial_cmp(&self, other: &ClaimableHTLC) -> Option<cmp::Ordering> {
419
+ Some(self.cmp(other))
420
+ }
421
+ }
422
+ impl Ord for ClaimableHTLC {
423
+ fn cmp(&self, other: &ClaimableHTLC) -> cmp::Ordering {
424
+ let res = (self.prev_hop.channel_id, self.prev_hop.htlc_id).cmp(
425
+ &(other.prev_hop.channel_id, other.prev_hop.htlc_id)
426
+ );
427
+ if res.is_eq() {
428
+ debug_assert!(self == other, "ClaimableHTLCs from the same source should be identical");
429
+ }
430
+ res
431
+ }
432
+ }
433
+
415
434
/// A trait defining behavior for creating and verifing the HMAC for authenticating a given data.
416
435
pub trait Verification {
417
436
/// Constructs an HMAC to include in [`OffersContext`] for the data along with the given
@@ -492,6 +511,22 @@ impl Verification for PaymentId {
492
511
}
493
512
}
494
513
514
+ impl PaymentId {
515
+ fn for_inbound_from_htlcs<I: Iterator<Item=(ChannelId, u64)>>(key: &[u8; 32], htlcs: I) -> PaymentId {
516
+ let mut prev_pair = None;
517
+ let mut hasher = HmacEngine::new(key);
518
+ for (channel_id, htlc_id) in htlcs {
519
+ hasher.input(&channel_id.0);
520
+ hasher.input(&htlc_id.to_le_bytes());
521
+ if let Some(prev) = prev_pair {
522
+ debug_assert!(prev < (channel_id, htlc_id), "HTLCs should be sorted");
523
+ }
524
+ prev_pair = Some((channel_id, htlc_id));
525
+ }
526
+ PaymentId(Hmac::<Sha256>::from_engine(hasher).to_byte_array())
527
+ }
528
+ }
529
+
495
530
impl Writeable for PaymentId {
496
531
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
497
532
self.0.write(w)
@@ -765,6 +800,7 @@ struct ClaimingPayment {
765
800
htlcs: Vec<events::ClaimedHTLC>,
766
801
sender_intended_value: Option<u64>,
767
802
onion_fields: Option<RecipientOnionFields>,
803
+ payment_id: Option<PaymentId>,
768
804
}
769
805
impl_writeable_tlv_based!(ClaimingPayment, {
770
806
(0, amount_msat, required),
@@ -773,6 +809,7 @@ impl_writeable_tlv_based!(ClaimingPayment, {
773
809
(5, htlcs, optional_vec),
774
810
(7, sender_intended_value, option),
775
811
(9, onion_fields, option),
812
+ (11, payment_id, option),
776
813
});
777
814
778
815
struct ClaimablePayment {
@@ -781,6 +818,15 @@ struct ClaimablePayment {
781
818
htlcs: Vec<ClaimableHTLC>,
782
819
}
783
820
821
+ impl ClaimablePayment {
822
+ fn inbound_payment_id(&self, secret: &[u8; 32]) -> PaymentId {
823
+ PaymentId::for_inbound_from_htlcs(
824
+ secret,
825
+ self.htlcs.iter().map(|htlc| (htlc.prev_hop.channel_id, htlc.prev_hop.htlc_id))
826
+ )
827
+ }
828
+ }
829
+
784
830
/// Represent the channel funding transaction type.
785
831
enum FundingType {
786
832
/// This variant is useful when we want LDK to validate the funding transaction and
@@ -5773,10 +5819,9 @@ where
5773
5819
} else {
5774
5820
claimable_payment.onion_fields = Some(onion_fields);
5775
5821
}
5776
- let ref mut htlcs = &mut claimable_payment.htlcs;
5777
5822
let mut total_value = claimable_htlc.sender_intended_value;
5778
5823
let mut earliest_expiry = claimable_htlc.cltv_expiry;
5779
- for htlc in htlcs.iter() {
5824
+ for htlc in claimable_payment. htlcs.iter() {
5780
5825
total_value += htlc.sender_intended_value;
5781
5826
earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
5782
5827
if htlc.total_msat != claimable_htlc.total_msat {
@@ -5798,13 +5843,18 @@ where
5798
5843
#[allow(unused_assignments)] {
5799
5844
committed_to_claimable = true;
5800
5845
}
5801
- htlcs.push(claimable_htlc);
5802
- let amount_msat = htlcs.iter().map(|htlc| htlc.value).sum();
5803
- htlcs.iter_mut().for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5804
- let counterparty_skimmed_fee_msat = htlcs.iter()
5846
+ claimable_payment.htlcs.push(claimable_htlc);
5847
+ let amount_msat =
5848
+ claimable_payment.htlcs.iter().map(|htlc| htlc.value).sum();
5849
+ claimable_payment.htlcs.iter_mut()
5850
+ .for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5851
+ let counterparty_skimmed_fee_msat = claimable_payment.htlcs.iter()
5805
5852
.map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
5806
5853
debug_assert!(total_value.saturating_sub(amount_msat) <=
5807
5854
counterparty_skimmed_fee_msat);
5855
+ claimable_payment.htlcs.sort();
5856
+ let payment_id =
5857
+ claimable_payment.inbound_payment_id(&self.inbound_payment_id_secret);
5808
5858
new_events.push_back((events::Event::PaymentClaimable {
5809
5859
receiver_node_id: Some(receiver_node_id),
5810
5860
payment_hash,
@@ -5815,13 +5865,14 @@ where
5815
5865
via_user_channel_id: Some(prev_user_channel_id),
5816
5866
claim_deadline: Some(earliest_expiry - HTLC_FAIL_BACK_BUFFER),
5817
5867
onion_fields: claimable_payment.onion_fields.clone(),
5868
+ payment_id: Some(payment_id),
5818
5869
}, None));
5819
5870
payment_claimable_generated = true;
5820
5871
} else {
5821
5872
// Nothing to do - we haven't reached the total
5822
5873
// payment value yet, wait until we receive more
5823
5874
// MPP parts.
5824
- htlcs.push(claimable_htlc);
5875
+ claimable_payment. htlcs.push(claimable_htlc);
5825
5876
#[allow(unused_assignments)] {
5826
5877
committed_to_claimable = true;
5827
5878
}
@@ -6618,6 +6669,7 @@ where
6618
6669
}
6619
6670
}
6620
6671
6672
+ let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6621
6673
let claiming_payment = claimable_payments.pending_claiming_payments
6622
6674
.entry(payment_hash)
6623
6675
.and_modify(|_| {
@@ -6635,6 +6687,7 @@ where
6635
6687
htlcs,
6636
6688
sender_intended_value,
6637
6689
onion_fields: payment.onion_fields,
6690
+ payment_id: Some(payment_id),
6638
6691
}
6639
6692
});
6640
6693
@@ -7152,6 +7205,7 @@ where
7152
7205
htlcs,
7153
7206
sender_intended_value: sender_intended_total_msat,
7154
7207
onion_fields,
7208
+ payment_id,
7155
7209
}) = payment {
7156
7210
self.pending_events.lock().unwrap().push_back((events::Event::PaymentClaimed {
7157
7211
payment_hash,
@@ -7161,6 +7215,7 @@ where
7161
7215
htlcs,
7162
7216
sender_intended_total_msat,
7163
7217
onion_fields,
7218
+ payment_id,
7164
7219
}, None));
7165
7220
}
7166
7221
},
@@ -12910,6 +12965,7 @@ where
12910
12965
previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &bounded_fee_estimator, &args.logger);
12911
12966
}
12912
12967
}
12968
+ let payment_id = payment.inbound_payment_id(&inbound_payment_id_secret.unwrap());
12913
12969
pending_events_read.push_back((events::Event::PaymentClaimed {
12914
12970
receiver_node_id,
12915
12971
payment_hash,
@@ -12918,6 +12974,7 @@ where
12918
12974
htlcs: payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(),
12919
12975
sender_intended_total_msat: payment.htlcs.first().map(|htlc| htlc.total_msat),
12920
12976
onion_fields: payment.onion_fields,
12977
+ payment_id: Some(payment_id),
12921
12978
}, None));
12922
12979
}
12923
12980
}
0 commit comments