@@ -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
@@ -2283,6 +2329,9 @@ where
2283
2329
/// keeping additional state.
2284
2330
probing_cookie_secret: [u8; 32],
2285
2331
2332
+ /// When generating [`PaymentId`]s for inbound payments, we HMAC the HTLCs with this secret.
2333
+ inbound_payment_id_secret: [u8; 32],
2334
+
2286
2335
/// The highest block timestamp we've seen, which is usually a good guess at the current time.
2287
2336
/// Assuming most miners are generating blocks with reasonable timestamps, this shouldn't be
2288
2337
/// very far in the past, and can only ever be up to two hours in the future.
@@ -3176,6 +3225,7 @@ where
3176
3225
fake_scid_rand_bytes: entropy_source.get_secure_random_bytes(),
3177
3226
3178
3227
probing_cookie_secret: entropy_source.get_secure_random_bytes(),
3228
+ inbound_payment_id_secret: entropy_source.get_secure_random_bytes(),
3179
3229
3180
3230
highest_seen_timestamp: AtomicUsize::new(current_timestamp as usize),
3181
3231
@@ -5769,10 +5819,9 @@ where
5769
5819
} else {
5770
5820
claimable_payment.onion_fields = Some(onion_fields);
5771
5821
}
5772
- let ref mut htlcs = &mut claimable_payment.htlcs;
5773
5822
let mut total_value = claimable_htlc.sender_intended_value;
5774
5823
let mut earliest_expiry = claimable_htlc.cltv_expiry;
5775
- for htlc in htlcs.iter() {
5824
+ for htlc in claimable_payment. htlcs.iter() {
5776
5825
total_value += htlc.sender_intended_value;
5777
5826
earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
5778
5827
if htlc.total_msat != claimable_htlc.total_msat {
@@ -5794,13 +5843,18 @@ where
5794
5843
#[allow(unused_assignments)] {
5795
5844
committed_to_claimable = true;
5796
5845
}
5797
- htlcs.push(claimable_htlc);
5798
- let amount_msat = htlcs.iter().map(|htlc| htlc.value).sum();
5799
- htlcs.iter_mut().for_each(|htlc| htlc.total_value_received = Some(amount_msat));
5800
- 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()
5801
5852
.map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
5802
5853
debug_assert!(total_value.saturating_sub(amount_msat) <=
5803
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);
5804
5858
new_events.push_back((events::Event::PaymentClaimable {
5805
5859
receiver_node_id: Some(receiver_node_id),
5806
5860
payment_hash,
@@ -5811,13 +5865,14 @@ where
5811
5865
via_user_channel_id: Some(prev_user_channel_id),
5812
5866
claim_deadline: Some(earliest_expiry - HTLC_FAIL_BACK_BUFFER),
5813
5867
onion_fields: claimable_payment.onion_fields.clone(),
5868
+ payment_id: Some(payment_id),
5814
5869
}, None));
5815
5870
payment_claimable_generated = true;
5816
5871
} else {
5817
5872
// Nothing to do - we haven't reached the total
5818
5873
// payment value yet, wait until we receive more
5819
5874
// MPP parts.
5820
- htlcs.push(claimable_htlc);
5875
+ claimable_payment. htlcs.push(claimable_htlc);
5821
5876
#[allow(unused_assignments)] {
5822
5877
committed_to_claimable = true;
5823
5878
}
@@ -6614,6 +6669,7 @@ where
6614
6669
}
6615
6670
}
6616
6671
6672
+ let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6617
6673
let claiming_payment = claimable_payments.pending_claiming_payments
6618
6674
.entry(payment_hash)
6619
6675
.and_modify(|_| {
@@ -6631,6 +6687,7 @@ where
6631
6687
htlcs,
6632
6688
sender_intended_value,
6633
6689
onion_fields: payment.onion_fields,
6690
+ payment_id: Some(payment_id),
6634
6691
}
6635
6692
});
6636
6693
@@ -7148,6 +7205,7 @@ where
7148
7205
htlcs,
7149
7206
sender_intended_value: sender_intended_total_msat,
7150
7207
onion_fields,
7208
+ payment_id,
7151
7209
}) = payment {
7152
7210
self.pending_events.lock().unwrap().push_back((events::Event::PaymentClaimed {
7153
7211
payment_hash,
@@ -7157,6 +7215,7 @@ where
7157
7215
htlcs,
7158
7216
sender_intended_total_msat,
7159
7217
onion_fields,
7218
+ payment_id,
7160
7219
}, None));
7161
7220
}
7162
7221
},
@@ -12428,6 +12487,7 @@ where
12428
12487
let mut events_override = None;
12429
12488
let mut in_flight_monitor_updates: Option<HashMap<(PublicKey, OutPoint), Vec<ChannelMonitorUpdate>>> = None;
12430
12489
let mut decode_update_add_htlcs: Option<HashMap<u64, Vec<msgs::UpdateAddHTLC>>> = None;
12490
+ let mut inbound_payment_id_secret = None;
12431
12491
read_tlv_fields!(reader, {
12432
12492
(1, pending_outbound_payments_no_retry, option),
12433
12493
(2, pending_intercepted_htlcs, option),
@@ -12442,6 +12502,7 @@ where
12442
12502
(11, probing_cookie_secret, option),
12443
12503
(13, claimable_htlc_onion_fields, optional_vec),
12444
12504
(14, decode_update_add_htlcs, option),
12505
+ (15, inbound_payment_id_secret, option),
12445
12506
});
12446
12507
let mut decode_update_add_htlcs = decode_update_add_htlcs.unwrap_or_else(|| new_hash_map());
12447
12508
if fake_scid_rand_bytes.is_none() {
@@ -12452,6 +12513,10 @@ where
12452
12513
probing_cookie_secret = Some(args.entropy_source.get_secure_random_bytes());
12453
12514
}
12454
12515
12516
+ if inbound_payment_id_secret.is_none() {
12517
+ inbound_payment_id_secret = Some(args.entropy_source.get_secure_random_bytes());
12518
+ }
12519
+
12455
12520
if let Some(events) = events_override {
12456
12521
pending_events_read = events;
12457
12522
}
@@ -12900,6 +12965,7 @@ where
12900
12965
previous_hop_monitor.provide_payment_preimage(&payment_hash, &payment_preimage, &args.tx_broadcaster, &bounded_fee_estimator, &args.logger);
12901
12966
}
12902
12967
}
12968
+ let payment_id = payment.inbound_payment_id(&inbound_payment_id_secret.unwrap());
12903
12969
pending_events_read.push_back((events::Event::PaymentClaimed {
12904
12970
receiver_node_id,
12905
12971
payment_hash,
@@ -12908,6 +12974,7 @@ where
12908
12974
htlcs: payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(),
12909
12975
sender_intended_total_msat: payment.htlcs.first().map(|htlc| htlc.total_msat),
12910
12976
onion_fields: payment.onion_fields,
12977
+ payment_id: Some(payment_id),
12911
12978
}, None));
12912
12979
}
12913
12980
}
@@ -12978,6 +13045,7 @@ where
12978
13045
fake_scid_rand_bytes: fake_scid_rand_bytes.unwrap(),
12979
13046
12980
13047
probing_cookie_secret: probing_cookie_secret.unwrap(),
13048
+ inbound_payment_id_secret: inbound_payment_id_secret.unwrap(),
12981
13049
12982
13050
our_network_pubkey,
12983
13051
secp_ctx,
0 commit comments