@@ -470,6 +470,11 @@ impl_writeable_tlv_based!(ClaimingPayment, {
470
470
( 4 , receiver_node_id, required) ,
471
471
} ) ;
472
472
473
+ struct ClaimablePayment {
474
+ purpose : events:: PaymentPurpose ,
475
+ htlcs : Vec < ClaimableHTLC > ,
476
+ }
477
+
473
478
/// Information about claimable or being-claimed payments
474
479
struct ClaimablePayments {
475
480
/// Map from payment hash to the payment data and any HTLCs which are to us and can be
@@ -480,7 +485,7 @@ struct ClaimablePayments {
480
485
///
481
486
/// When adding to the map, [`Self::pending_claiming_payments`] must also be checked to ensure
482
487
/// we don't get a duplicate payment.
483
- claimable_htlcs : HashMap < PaymentHash , ( events :: PaymentPurpose , Vec < ClaimableHTLC > ) > ,
488
+ claimable_payments : HashMap < PaymentHash , ClaimablePayment > ,
484
489
485
490
/// Map from payment hash to the payment data for HTLCs which we have begun claiming, but which
486
491
/// are waiting on a [`ChannelMonitorUpdate`] to complete in order to be surfaced to the user
@@ -1668,7 +1673,7 @@ where
1668
1673
pending_inbound_payments : Mutex :: new ( HashMap :: new ( ) ) ,
1669
1674
pending_outbound_payments : OutboundPayments :: new ( ) ,
1670
1675
forward_htlcs : Mutex :: new ( HashMap :: new ( ) ) ,
1671
- claimable_payments : Mutex :: new ( ClaimablePayments { claimable_htlcs : HashMap :: new ( ) , pending_claiming_payments : HashMap :: new ( ) } ) ,
1676
+ claimable_payments : Mutex :: new ( ClaimablePayments { claimable_payments : HashMap :: new ( ) , pending_claiming_payments : HashMap :: new ( ) } ) ,
1672
1677
pending_intercepted_htlcs : Mutex :: new ( HashMap :: new ( ) ) ,
1673
1678
id_to_peer : Mutex :: new ( HashMap :: new ( ) ) ,
1674
1679
short_to_chan_info : FairRwLock :: new ( HashMap :: new ( ) ) ,
@@ -3349,8 +3354,13 @@ where
3349
3354
fail_htlc!( claimable_htlc, payment_hash) ;
3350
3355
continue
3351
3356
}
3352
- let ( _, ref mut htlcs) = claimable_payments. claimable_htlcs. entry( payment_hash)
3353
- . or_insert_with( || ( purpose( ) , Vec :: new( ) ) ) ;
3357
+ let ref mut claimable_payment = claimable_payments. claimable_payments
3358
+ . entry( payment_hash)
3359
+ // Note that if we insert here we MUST NOT fail_htlc!()
3360
+ . or_insert_with( || ClaimablePayment {
3361
+ purpose: purpose( ) , htlcs: Vec :: new( )
3362
+ } ) ;
3363
+ let ref mut htlcs = & mut claimable_payment. htlcs;
3354
3364
if htlcs. len( ) == 1 {
3355
3365
if let OnionPayload :: Spontaneous ( _) = htlcs[ 0 ] . onion_payload {
3356
3366
log_trace!( self . logger, "Failing new HTLC with payment_hash {} as we already had an existing keysend HTLC with the same payment hash" , log_bytes!( payment_hash. 0 ) ) ;
@@ -3445,13 +3455,16 @@ where
3445
3455
fail_htlc ! ( claimable_htlc, payment_hash) ;
3446
3456
continue
3447
3457
}
3448
- match claimable_payments. claimable_htlcs . entry ( payment_hash) {
3458
+ match claimable_payments. claimable_payments . entry ( payment_hash) {
3449
3459
hash_map:: Entry :: Vacant ( e) => {
3450
3460
let amount_msat = claimable_htlc. value ;
3451
3461
claimable_htlc. total_value_received = Some ( amount_msat) ;
3452
3462
let claim_deadline = Some ( claimable_htlc. cltv_expiry - HTLC_FAIL_BACK_BUFFER ) ;
3453
3463
let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3454
- e. insert ( ( purpose. clone ( ) , vec ! [ claimable_htlc] ) ) ;
3464
+ e. insert ( ClaimablePayment {
3465
+ purpose : purpose. clone ( ) ,
3466
+ htlcs : vec ! [ claimable_htlc] ,
3467
+ } ) ;
3455
3468
let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
3456
3469
new_events. push ( events:: Event :: PaymentClaimable {
3457
3470
receiver_node_id : Some ( receiver_node_id) ,
@@ -3708,24 +3721,27 @@ where
3708
3721
}
3709
3722
}
3710
3723
3711
- self . claimable_payments . lock ( ) . unwrap ( ) . claimable_htlcs . retain ( |payment_hash, ( _ , htlcs ) | {
3712
- if htlcs. is_empty ( ) {
3724
+ self . claimable_payments . lock ( ) . unwrap ( ) . claimable_payments . retain ( |payment_hash, payment | {
3725
+ if payment . htlcs . is_empty ( ) {
3713
3726
// This should be unreachable
3714
3727
debug_assert ! ( false ) ;
3715
3728
return false ;
3716
3729
}
3717
- if let OnionPayload :: Invoice { .. } = htlcs[ 0 ] . onion_payload {
3730
+ if let OnionPayload :: Invoice { .. } = payment . htlcs [ 0 ] . onion_payload {
3718
3731
// Check if we've received all the parts we need for an MPP (the value of the parts adds to total_msat).
3719
3732
// In this case we're not going to handle any timeouts of the parts here.
3720
3733
// This condition determining whether the MPP is complete here must match
3721
3734
// exactly the condition used in `process_pending_htlc_forwards`.
3722
- if htlcs[ 0 ] . total_msat <= htlcs. iter ( ) . fold ( 0 , |total, htlc| total + htlc. sender_intended_value ) {
3735
+ if payment. htlcs [ 0 ] . total_msat <= payment. htlcs . iter ( )
3736
+ . fold ( 0 , |total, htlc| total + htlc. sender_intended_value )
3737
+ {
3723
3738
return true ;
3724
- } else if htlcs. into_iter ( ) . any ( |htlc| {
3739
+ } else if payment . htlcs . iter_mut ( ) . any ( |htlc| {
3725
3740
htlc. timer_ticks += 1 ;
3726
3741
return htlc. timer_ticks >= MPP_TIMEOUT_TICKS
3727
3742
} ) {
3728
- timed_out_mpp_htlcs. extend ( htlcs. drain ( ..) . map ( |htlc : ClaimableHTLC | ( htlc. prev_hop , * payment_hash) ) ) ;
3743
+ timed_out_mpp_htlcs. extend ( payment. htlcs . drain ( ..)
3744
+ . map ( |htlc : ClaimableHTLC | ( htlc. prev_hop , * payment_hash) ) ) ;
3729
3745
return false ;
3730
3746
}
3731
3747
}
@@ -3780,9 +3796,9 @@ where
3780
3796
pub fn fail_htlc_backwards_with_reason ( & self , payment_hash : & PaymentHash , failure_code : FailureCode ) {
3781
3797
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3782
3798
3783
- let removed_source = self . claimable_payments . lock ( ) . unwrap ( ) . claimable_htlcs . remove ( payment_hash) ;
3784
- if let Some ( ( _ , mut sources ) ) = removed_source {
3785
- for htlc in sources . drain ( .. ) {
3799
+ let removed_source = self . claimable_payments . lock ( ) . unwrap ( ) . claimable_payments . remove ( payment_hash) ;
3800
+ if let Some ( payment ) = removed_source {
3801
+ for htlc in payment . htlcs {
3786
3802
let reason = self . get_htlc_fail_reason_from_failure_code ( failure_code, & htlc) ;
3787
3803
let source = HTLCSource :: PreviousHopData ( htlc. prev_hop ) ;
3788
3804
let receiver = HTLCDestination :: FailedPayment { payment_hash : * payment_hash } ;
@@ -3959,9 +3975,9 @@ where
3959
3975
3960
3976
let mut sources = {
3961
3977
let mut claimable_payments = self . claimable_payments . lock ( ) . unwrap ( ) ;
3962
- if let Some ( ( payment_purpose , sources ) ) = claimable_payments. claimable_htlcs . remove ( & payment_hash) {
3978
+ if let Some ( payment ) = claimable_payments. claimable_payments . remove ( & payment_hash) {
3963
3979
let mut receiver_node_id = self . our_network_pubkey ;
3964
- for htlc in sources . iter ( ) {
3980
+ for htlc in payment . htlcs . iter ( ) {
3965
3981
if htlc. prev_hop . phantom_shared_secret . is_some ( ) {
3966
3982
let phantom_pubkey = self . node_signer . get_node_id ( Recipient :: PhantomNode )
3967
3983
. expect ( "Failed to get node_id for phantom node recipient" ) ;
@@ -3971,15 +3987,15 @@ where
3971
3987
}
3972
3988
3973
3989
let dup_purpose = claimable_payments. pending_claiming_payments . insert ( payment_hash,
3974
- ClaimingPayment { amount_msat : sources . iter ( ) . map ( |source| source. value ) . sum ( ) ,
3975
- payment_purpose, receiver_node_id,
3990
+ ClaimingPayment { amount_msat : payment . htlcs . iter ( ) . map ( |source| source. value ) . sum ( ) ,
3991
+ payment_purpose : payment . purpose , receiver_node_id,
3976
3992
} ) ;
3977
3993
if dup_purpose. is_some ( ) {
3978
3994
debug_assert ! ( false , "Shouldn't get a duplicate pending claim event ever" ) ;
3979
3995
log_error ! ( self . logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug" ,
3980
3996
log_bytes!( payment_hash. 0 ) ) ;
3981
3997
}
3982
- sources
3998
+ payment . htlcs
3983
3999
} else { return ; }
3984
4000
} ;
3985
4001
debug_assert ! ( !sources. is_empty( ) ) ;
@@ -6091,8 +6107,8 @@ where
6091
6107
}
6092
6108
6093
6109
if let Some ( height) = height_opt {
6094
- self . claimable_payments . lock ( ) . unwrap ( ) . claimable_htlcs . retain ( |payment_hash, ( _ , htlcs ) | {
6095
- htlcs. retain ( |htlc| {
6110
+ self . claimable_payments . lock ( ) . unwrap ( ) . claimable_payments . retain ( |payment_hash, payment | {
6111
+ payment . htlcs . retain ( |htlc| {
6096
6112
// If height is approaching the number of blocks we think it takes us to get
6097
6113
// our commitment transaction confirmed before the HTLC expires, plus the
6098
6114
// number of blocks we generally consider it to take to do a commitment update,
@@ -6107,7 +6123,7 @@ where
6107
6123
false
6108
6124
} else { true }
6109
6125
} ) ;
6110
- !htlcs. is_empty ( ) // Only retain this entry if htlcs has at least one entry.
6126
+ !payment . htlcs . is_empty ( ) // Only retain this entry if htlcs has at least one entry.
6111
6127
} ) ;
6112
6128
6113
6129
let mut intercepted_htlcs = self . pending_intercepted_htlcs . lock ( ) . unwrap ( ) ;
@@ -7028,14 +7044,14 @@ where
7028
7044
let pending_outbound_payments = self . pending_outbound_payments . pending_outbound_payments . lock ( ) . unwrap ( ) ;
7029
7045
7030
7046
let mut htlc_purposes: Vec < & events:: PaymentPurpose > = Vec :: new ( ) ;
7031
- ( claimable_payments. claimable_htlcs . len ( ) as u64 ) . write ( writer) ?;
7032
- for ( payment_hash, ( purpose , previous_hops ) ) in claimable_payments. claimable_htlcs . iter ( ) {
7047
+ ( claimable_payments. claimable_payments . len ( ) as u64 ) . write ( writer) ?;
7048
+ for ( payment_hash, payment ) in claimable_payments. claimable_payments . iter ( ) {
7033
7049
payment_hash. write ( writer) ?;
7034
- ( previous_hops . len ( ) as u64 ) . write ( writer) ?;
7035
- for htlc in previous_hops . iter ( ) {
7050
+ ( payment . htlcs . len ( ) as u64 ) . write ( writer) ?;
7051
+ for htlc in payment . htlcs . iter ( ) {
7036
7052
htlc. write ( writer) ?;
7037
7053
}
7038
- htlc_purposes. push ( purpose) ;
7054
+ htlc_purposes. push ( & payment . purpose ) ;
7039
7055
}
7040
7056
7041
7057
let mut monitor_update_blocked_actions_per_peer = None ;
@@ -7688,22 +7704,25 @@ where
7688
7704
let inbound_pmt_key_material = args. node_signer . get_inbound_payment_key_material ( ) ;
7689
7705
let expanded_inbound_key = inbound_payment:: ExpandedKey :: new ( & inbound_pmt_key_material) ;
7690
7706
7691
- let mut claimable_htlcs = HashMap :: with_capacity ( claimable_htlcs_list. len ( ) ) ;
7707
+ let mut claimable_payments = HashMap :: with_capacity ( claimable_htlcs_list. len ( ) ) ;
7692
7708
if let Some ( mut purposes) = claimable_htlc_purposes {
7693
7709
if purposes. len ( ) != claimable_htlcs_list. len ( ) {
7694
7710
return Err ( DecodeError :: InvalidValue ) ;
7695
7711
}
7696
- for ( purpose, ( payment_hash, previous_hops) ) in purposes. drain ( ..) . zip ( claimable_htlcs_list. drain ( ..) ) {
7697
- claimable_htlcs. insert ( payment_hash, ( purpose, previous_hops) ) ;
7712
+ for ( purpose, ( payment_hash, htlcs) ) in purposes. drain ( ..) . zip ( claimable_htlcs_list. drain ( ..) ) {
7713
+ let existing_payment = claimable_payments. insert ( payment_hash, ClaimablePayment {
7714
+ purpose, htlcs,
7715
+ } ) ;
7716
+ if existing_payment. is_some ( ) { return Err ( DecodeError :: InvalidValue ) ; }
7698
7717
}
7699
7718
} else {
7700
7719
// LDK versions prior to 0.0.107 did not write a `pending_htlc_purposes`, but do
7701
7720
// include a `_legacy_hop_data` in the `OnionPayload`.
7702
- for ( payment_hash, previous_hops ) in claimable_htlcs_list. drain ( ..) {
7703
- if previous_hops . is_empty ( ) {
7721
+ for ( payment_hash, htlcs ) in claimable_htlcs_list. drain ( ..) {
7722
+ if htlcs . is_empty ( ) {
7704
7723
return Err ( DecodeError :: InvalidValue ) ;
7705
7724
}
7706
- let purpose = match & previous_hops [ 0 ] . onion_payload {
7725
+ let purpose = match & htlcs [ 0 ] . onion_payload {
7707
7726
OnionPayload :: Invoice { _legacy_hop_data } => {
7708
7727
if let Some ( hop_data) = _legacy_hop_data {
7709
7728
events:: PaymentPurpose :: InvoicePayment {
@@ -7724,7 +7743,9 @@ where
7724
7743
OnionPayload :: Spontaneous ( payment_preimage) =>
7725
7744
events:: PaymentPurpose :: SpontaneousPayment ( * payment_preimage) ,
7726
7745
} ;
7727
- claimable_htlcs. insert ( payment_hash, ( purpose, previous_hops) ) ;
7746
+ claimable_payments. insert ( payment_hash, ClaimablePayment {
7747
+ purpose, htlcs,
7748
+ } ) ;
7728
7749
}
7729
7750
}
7730
7751
@@ -7776,17 +7797,17 @@ where
7776
7797
7777
7798
for ( _, monitor) in args. channel_monitors . iter ( ) {
7778
7799
for ( payment_hash, payment_preimage) in monitor. get_stored_preimages ( ) {
7779
- if let Some ( ( payment_purpose , claimable_htlcs ) ) = claimable_htlcs . remove ( & payment_hash) {
7800
+ if let Some ( payment ) = claimable_payments . remove ( & payment_hash) {
7780
7801
log_info ! ( args. logger, "Re-claiming HTLCs with payment hash {} as we've released the preimage to a ChannelMonitor!" , log_bytes!( payment_hash. 0 ) ) ;
7781
7802
let mut claimable_amt_msat = 0 ;
7782
7803
let mut receiver_node_id = Some ( our_network_pubkey) ;
7783
- let phantom_shared_secret = claimable_htlcs [ 0 ] . prev_hop . phantom_shared_secret ;
7804
+ let phantom_shared_secret = payment . htlcs [ 0 ] . prev_hop . phantom_shared_secret ;
7784
7805
if phantom_shared_secret. is_some ( ) {
7785
7806
let phantom_pubkey = args. node_signer . get_node_id ( Recipient :: PhantomNode )
7786
7807
. expect ( "Failed to get node_id for phantom node recipient" ) ;
7787
7808
receiver_node_id = Some ( phantom_pubkey)
7788
7809
}
7789
- for claimable_htlc in claimable_htlcs {
7810
+ for claimable_htlc in payment . htlcs {
7790
7811
claimable_amt_msat += claimable_htlc. value ;
7791
7812
7792
7813
// Add a holding-cell claim of the payment to the Channel, which should be
@@ -7820,7 +7841,7 @@ where
7820
7841
pending_events_read. push ( events:: Event :: PaymentClaimed {
7821
7842
receiver_node_id,
7822
7843
payment_hash,
7823
- purpose : payment_purpose ,
7844
+ purpose : payment . purpose ,
7824
7845
amount_msat : claimable_amt_msat,
7825
7846
} ) ;
7826
7847
}
@@ -7851,7 +7872,7 @@ where
7851
7872
pending_intercepted_htlcs : Mutex :: new ( pending_intercepted_htlcs. unwrap ( ) ) ,
7852
7873
7853
7874
forward_htlcs : Mutex :: new ( forward_htlcs) ,
7854
- claimable_payments : Mutex :: new ( ClaimablePayments { claimable_htlcs , pending_claiming_payments : pending_claiming_payments. unwrap ( ) } ) ,
7875
+ claimable_payments : Mutex :: new ( ClaimablePayments { claimable_payments , pending_claiming_payments : pending_claiming_payments. unwrap ( ) } ) ,
7855
7876
outbound_scid_aliases : Mutex :: new ( outbound_scid_aliases) ,
7856
7877
id_to_peer : Mutex :: new ( id_to_peer) ,
7857
7878
short_to_chan_info : FairRwLock :: new ( short_to_chan_info) ,
0 commit comments