@@ -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 user-provided identifier in [`ChannelManager::send_payment`] used to uniquely identify
413
432
/// a payment and ensure idempotency in LDK.
414
433
///
@@ -435,6 +454,20 @@ impl PaymentId {
435
454
) -> Result<(), ()> {
436
455
signer::verify_payment_id(*self, hmac, nonce, expanded_key)
437
456
}
457
+
458
+ fn for_inbound_from_htlcs<I: Iterator<Item=(ChannelId, u64)>>(key: &[u8; 32], htlcs: I) -> PaymentId {
459
+ let mut prev_pair = None;
460
+ let mut hasher = HmacEngine::new(key);
461
+ for (channel_id, htlc_id) in htlcs {
462
+ hasher.input(&channel_id.0);
463
+ hasher.input(&htlc_id.to_le_bytes());
464
+ if let Some(prev) = prev_pair {
465
+ debug_assert!(prev < (channel_id, htlc_id), "HTLCs should be sorted");
466
+ }
467
+ prev_pair = Some((channel_id, htlc_id));
468
+ }
469
+ PaymentId(Hmac::<Sha256>::from_engine(hasher).to_byte_array())
470
+ }
438
471
}
439
472
440
473
impl Writeable for PaymentId {
@@ -710,6 +743,7 @@ struct ClaimingPayment {
710
743
htlcs: Vec<events::ClaimedHTLC>,
711
744
sender_intended_value: Option<u64>,
712
745
onion_fields: Option<RecipientOnionFields>,
746
+ payment_id: Option<PaymentId>,
713
747
}
714
748
impl_writeable_tlv_based!(ClaimingPayment, {
715
749
(0, amount_msat, required),
@@ -718,6 +752,7 @@ impl_writeable_tlv_based!(ClaimingPayment, {
718
752
(5, htlcs, optional_vec),
719
753
(7, sender_intended_value, option),
720
754
(9, onion_fields, option),
755
+ (11, payment_id, option),
721
756
});
722
757
723
758
struct ClaimablePayment {
@@ -726,6 +761,15 @@ struct ClaimablePayment {
726
761
htlcs: Vec<ClaimableHTLC>,
727
762
}
728
763
764
+ impl ClaimablePayment {
765
+ fn inbound_payment_id(&self, secret: &[u8; 32]) -> PaymentId {
766
+ PaymentId::for_inbound_from_htlcs(
767
+ secret,
768
+ self.htlcs.iter().map(|htlc| (htlc.prev_hop.channel_id, htlc.prev_hop.htlc_id))
769
+ )
770
+ }
771
+ }
772
+
729
773
/// Represent the channel funding transaction type.
730
774
enum FundingType {
731
775
/// This variant is useful when we want LDK to validate the funding transaction and
@@ -5593,10 +5637,9 @@ where
5593
5637
} else {
5594
5638
claimable_payment.onion_fields = Some(onion_fields);
5595
5639
}
5596
- let ref mut htlcs = &mut claimable_payment.htlcs;
5597
5640
let mut total_value = claimable_htlc.sender_intended_value;
5598
5641
let mut earliest_expiry = claimable_htlc.cltv_expiry;
5599
- for htlc in htlcs.iter() {
5642
+ for htlc in claimable_payment. htlcs.iter() {
5600
5643
total_value += htlc.sender_intended_value;
5601
5644
earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
5602
5645
if htlc.total_msat != claimable_htlc.total_msat {
@@ -5618,13 +5661,18 @@ where
5618
5661
#[allow(unused_assignments)] {
5619
5662
committed_to_claimable = true;
5620
5663
}
5621
- htlcs.push(claimable_htlc);
5622
- let amount_msat = htlcs.iter().map(|htlc| htlc.value).sum();
5623
- htlcs.iter_mut().for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5624
- let counterparty_skimmed_fee_msat = htlcs.iter()
5664
+ claimable_payment.htlcs.push(claimable_htlc);
5665
+ let amount_msat =
5666
+ claimable_payment.htlcs.iter().map(|htlc| htlc.value).sum();
5667
+ claimable_payment.htlcs.iter_mut()
5668
+ .for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5669
+ let counterparty_skimmed_fee_msat = claimable_payment.htlcs.iter()
5625
5670
.map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
5626
5671
debug_assert!(total_value.saturating_sub(amount_msat) <=
5627
5672
counterparty_skimmed_fee_msat);
5673
+ claimable_payment.htlcs.sort();
5674
+ let payment_id =
5675
+ claimable_payment.inbound_payment_id(&self.inbound_payment_id_secret);
5628
5676
new_events.push_back((events::Event::PaymentClaimable {
5629
5677
receiver_node_id: Some(receiver_node_id),
5630
5678
payment_hash,
@@ -5635,13 +5683,14 @@ where
5635
5683
via_user_channel_id: Some(prev_user_channel_id),
5636
5684
claim_deadline: Some(earliest_expiry - HTLC_FAIL_BACK_BUFFER),
5637
5685
onion_fields: claimable_payment.onion_fields.clone(),
5686
+ payment_id: Some(payment_id),
5638
5687
}, None));
5639
5688
payment_claimable_generated = true;
5640
5689
} else {
5641
5690
// Nothing to do - we haven't reached the total
5642
5691
// payment value yet, wait until we receive more
5643
5692
// MPP parts.
5644
- htlcs.push(claimable_htlc);
5693
+ claimable_payment. htlcs.push(claimable_htlc);
5645
5694
#[allow(unused_assignments)] {
5646
5695
committed_to_claimable = true;
5647
5696
}
@@ -6438,6 +6487,7 @@ where
6438
6487
}
6439
6488
}
6440
6489
6490
+ let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6441
6491
let claiming_payment = claimable_payments.pending_claiming_payments
6442
6492
.entry(payment_hash)
6443
6493
.and_modify(|_| {
@@ -6455,6 +6505,7 @@ where
6455
6505
htlcs,
6456
6506
sender_intended_value,
6457
6507
onion_fields: payment.onion_fields,
6508
+ payment_id: Some(payment_id),
6458
6509
}
6459
6510
});
6460
6511
@@ -6972,6 +7023,7 @@ where
6972
7023
htlcs,
6973
7024
sender_intended_value: sender_intended_total_msat,
6974
7025
onion_fields,
7026
+ payment_id,
6975
7027
}) = payment {
6976
7028
self.pending_events.lock().unwrap().push_back((events::Event::PaymentClaimed {
6977
7029
payment_hash,
@@ -6981,6 +7033,7 @@ where
6981
7033
htlcs,
6982
7034
sender_intended_total_msat,
6983
7035
onion_fields,
7036
+ payment_id,
6984
7037
}, None));
6985
7038
}
6986
7039
},
@@ -12646,6 +12699,7 @@ where
12646
12699
previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &bounded_fee_estimator, &args.logger);
12647
12700
}
12648
12701
}
12702
+ let payment_id = payment.inbound_payment_id(&inbound_payment_id_secret.unwrap());
12649
12703
pending_events_read.push_back((events::Event::PaymentClaimed {
12650
12704
receiver_node_id,
12651
12705
payment_hash,
@@ -12654,6 +12708,7 @@ where
12654
12708
htlcs: payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(),
12655
12709
sender_intended_total_msat: payment.htlcs.first().map(|htlc| htlc.total_msat),
12656
12710
onion_fields: payment.onion_fields,
12711
+ payment_id: Some(payment_id),
12657
12712
}, None));
12658
12713
}
12659
12714
}
0 commit comments