@@ -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};
@@ -366,6 +366,7 @@ pub(crate) struct HTLCPreviousHopData {
366
366
counterparty_node_id: Option<PublicKey>,
367
367
}
368
368
369
+ #[derive(PartialEq, Eq)]
369
370
enum OnionPayload {
370
371
/// Indicates this incoming onion payload is for the purpose of paying an invoice.
371
372
Invoice {
@@ -378,6 +379,7 @@ enum OnionPayload {
378
379
}
379
380
380
381
/// HTLCs that are to us and can be failed/claimed by the user
382
+ #[derive(PartialEq, Eq)]
381
383
struct ClaimableHTLC {
382
384
prev_hop: HTLCPreviousHopData,
383
385
cltv_expiry: u32,
@@ -409,6 +411,23 @@ impl From<&ClaimableHTLC> for events::ClaimedHTLC {
409
411
}
410
412
}
411
413
414
+ impl PartialOrd for ClaimableHTLC {
415
+ fn partial_cmp(&self, other: &ClaimableHTLC) -> Option<cmp::Ordering> {
416
+ Some(self.cmp(other))
417
+ }
418
+ }
419
+ impl Ord for ClaimableHTLC {
420
+ fn cmp(&self, other: &ClaimableHTLC) -> cmp::Ordering {
421
+ let res = (self.prev_hop.channel_id, self.prev_hop.htlc_id).cmp(
422
+ &(other.prev_hop.channel_id, other.prev_hop.htlc_id)
423
+ );
424
+ if res.is_eq() {
425
+ debug_assert!(self == other, "ClaimableHTLCs from the same source should be identical");
426
+ }
427
+ res
428
+ }
429
+ }
430
+
412
431
/// A trait defining behavior for creating and verifing the HMAC for authenticating a given data.
413
432
pub trait Verification {
414
433
/// Constructs an HMAC to include in [`OffersContext`] for the data along with the given
@@ -471,6 +490,22 @@ impl Verification for PaymentId {
471
490
}
472
491
}
473
492
493
+ impl PaymentId {
494
+ fn for_inbound_from_htlcs<I: Iterator<Item=(ChannelId, u64)>>(key: &[u8; 32], htlcs: I) -> PaymentId {
495
+ let mut prev_pair = None;
496
+ let mut hasher = HmacEngine::new(key);
497
+ for (channel_id, htlc_id) in htlcs {
498
+ hasher.input(&channel_id.0);
499
+ hasher.input(&htlc_id.to_le_bytes());
500
+ if let Some(prev) = prev_pair {
501
+ debug_assert!(prev < (channel_id, htlc_id), "HTLCs should be sorted");
502
+ }
503
+ prev_pair = Some((channel_id, htlc_id));
504
+ }
505
+ PaymentId(Hmac::<Sha256>::from_engine(hasher).to_byte_array())
506
+ }
507
+ }
508
+
474
509
impl Writeable for PaymentId {
475
510
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
476
511
self.0.write(w)
@@ -744,6 +779,7 @@ struct ClaimingPayment {
744
779
htlcs: Vec<events::ClaimedHTLC>,
745
780
sender_intended_value: Option<u64>,
746
781
onion_fields: Option<RecipientOnionFields>,
782
+ payment_id: Option<PaymentId>,
747
783
}
748
784
impl_writeable_tlv_based!(ClaimingPayment, {
749
785
(0, amount_msat, required),
@@ -752,6 +788,7 @@ impl_writeable_tlv_based!(ClaimingPayment, {
752
788
(5, htlcs, optional_vec),
753
789
(7, sender_intended_value, option),
754
790
(9, onion_fields, option),
791
+ (11, payment_id, option),
755
792
});
756
793
757
794
struct ClaimablePayment {
@@ -760,6 +797,15 @@ struct ClaimablePayment {
760
797
htlcs: Vec<ClaimableHTLC>,
761
798
}
762
799
800
+ impl ClaimablePayment {
801
+ fn inbound_payment_id(&self, secret: &[u8; 32]) -> PaymentId {
802
+ PaymentId::for_inbound_from_htlcs(
803
+ secret,
804
+ self.htlcs.iter().map(|htlc| (htlc.prev_hop.channel_id, htlc.prev_hop.htlc_id))
805
+ )
806
+ }
807
+ }
808
+
763
809
/// Represent the channel funding transaction type.
764
810
enum FundingType {
765
811
/// This variant is useful when we want LDK to validate the funding transaction and
@@ -5627,10 +5673,9 @@ where
5627
5673
} else {
5628
5674
claimable_payment.onion_fields = Some(onion_fields);
5629
5675
}
5630
- let ref mut htlcs = &mut claimable_payment.htlcs;
5631
5676
let mut total_value = claimable_htlc.sender_intended_value;
5632
5677
let mut earliest_expiry = claimable_htlc.cltv_expiry;
5633
- for htlc in htlcs.iter() {
5678
+ for htlc in claimable_payment. htlcs.iter() {
5634
5679
total_value += htlc.sender_intended_value;
5635
5680
earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
5636
5681
if htlc.total_msat != claimable_htlc.total_msat {
@@ -5652,13 +5697,18 @@ where
5652
5697
#[allow(unused_assignments)] {
5653
5698
committed_to_claimable = true;
5654
5699
}
5655
- htlcs.push(claimable_htlc);
5656
- let amount_msat = htlcs.iter().map(|htlc| htlc.value).sum();
5657
- htlcs.iter_mut().for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5658
- let counterparty_skimmed_fee_msat = htlcs.iter()
5700
+ claimable_payment.htlcs.push(claimable_htlc);
5701
+ let amount_msat =
5702
+ claimable_payment.htlcs.iter().map(|htlc| htlc.value).sum();
5703
+ claimable_payment.htlcs.iter_mut()
5704
+ .for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5705
+ let counterparty_skimmed_fee_msat = claimable_payment.htlcs.iter()
5659
5706
.map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
5660
5707
debug_assert!(total_value.saturating_sub(amount_msat) <=
5661
5708
counterparty_skimmed_fee_msat);
5709
+ claimable_payment.htlcs.sort();
5710
+ let payment_id =
5711
+ claimable_payment.inbound_payment_id(&self.inbound_payment_id_secret);
5662
5712
new_events.push_back((events::Event::PaymentClaimable {
5663
5713
receiver_node_id: Some(receiver_node_id),
5664
5714
payment_hash,
@@ -5669,13 +5719,14 @@ where
5669
5719
via_user_channel_id: Some(prev_user_channel_id),
5670
5720
claim_deadline: Some(earliest_expiry - HTLC_FAIL_BACK_BUFFER),
5671
5721
onion_fields: claimable_payment.onion_fields.clone(),
5722
+ payment_id: Some(payment_id),
5672
5723
}, None));
5673
5724
payment_claimable_generated = true;
5674
5725
} else {
5675
5726
// Nothing to do - we haven't reached the total
5676
5727
// payment value yet, wait until we receive more
5677
5728
// MPP parts.
5678
- htlcs.push(claimable_htlc);
5729
+ claimable_payment. htlcs.push(claimable_htlc);
5679
5730
#[allow(unused_assignments)] {
5680
5731
committed_to_claimable = true;
5681
5732
}
@@ -6472,6 +6523,7 @@ where
6472
6523
}
6473
6524
}
6474
6525
6526
+ let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6475
6527
let claiming_payment = claimable_payments.pending_claiming_payments
6476
6528
.entry(payment_hash)
6477
6529
.and_modify(|_| {
@@ -6489,6 +6541,7 @@ where
6489
6541
htlcs,
6490
6542
sender_intended_value,
6491
6543
onion_fields: payment.onion_fields,
6544
+ payment_id: Some(payment_id),
6492
6545
}
6493
6546
});
6494
6547
@@ -7006,6 +7059,7 @@ where
7006
7059
htlcs,
7007
7060
sender_intended_value: sender_intended_total_msat,
7008
7061
onion_fields,
7062
+ payment_id,
7009
7063
}) = payment {
7010
7064
self.pending_events.lock().unwrap().push_back((events::Event::PaymentClaimed {
7011
7065
payment_hash,
@@ -7015,6 +7069,7 @@ where
7015
7069
htlcs,
7016
7070
sender_intended_total_msat,
7017
7071
onion_fields,
7072
+ payment_id,
7018
7073
}, None));
7019
7074
}
7020
7075
},
@@ -12740,6 +12795,7 @@ where
12740
12795
previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &bounded_fee_estimator, &args.logger);
12741
12796
}
12742
12797
}
12798
+ let payment_id = payment.inbound_payment_id(&inbound_payment_id_secret.unwrap());
12743
12799
pending_events_read.push_back((events::Event::PaymentClaimed {
12744
12800
receiver_node_id,
12745
12801
payment_hash,
@@ -12748,6 +12804,7 @@ where
12748
12804
htlcs: payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(),
12749
12805
sender_intended_total_msat: payment.htlcs.first().map(|htlc| htlc.total_msat),
12750
12806
onion_fields: payment.onion_fields,
12807
+ payment_id: Some(payment_id),
12751
12808
}, None));
12752
12809
}
12753
12810
}
0 commit comments