@@ -3492,9 +3492,13 @@ where
3492
3492
}
3493
3493
3494
3494
macro_rules! check_total_value {
3495
- ( $payment_data: expr, $payment_preimage: expr) => { {
3495
+ ( $payment_data: expr, $payment_preimage: expr, $is_keysend : expr ) => { {
3496
3496
let mut payment_claimable_generated = false ;
3497
- let purpose = || {
3497
+ let purpose = if $is_keysend {
3498
+ events:: PaymentPurpose :: SpontaneousPayment (
3499
+ $payment_preimage. expect( "Should never call check_total_value with $is_keysend as true but no preimage" )
3500
+ )
3501
+ } else {
3498
3502
events:: PaymentPurpose :: InvoicePayment {
3499
3503
payment_preimage: $payment_preimage,
3500
3504
payment_secret: $payment_data. payment_secret,
@@ -3510,7 +3514,7 @@ where
3510
3514
. or_insert_with( || {
3511
3515
committed_to_claimable = true ;
3512
3516
ClaimablePayment {
3513
- purpose: purpose( ) , htlcs: Vec :: new( ) , onion_fields: None ,
3517
+ purpose: purpose. clone ( ) , htlcs: Vec :: new( ) , onion_fields: None ,
3514
3518
}
3515
3519
} ) ;
3516
3520
if let Some ( earlier_fields) = & mut claimable_payment. onion_fields {
@@ -3521,7 +3525,7 @@ where
3521
3525
claimable_payment. onion_fields = Some ( onion_fields) ;
3522
3526
}
3523
3527
let ref mut htlcs = & mut claimable_payment. htlcs;
3524
- if htlcs. len ( ) == 1 {
3528
+ if ! htlcs. is_empty ( ) && !$is_keysend {
3525
3529
if let OnionPayload :: Spontaneous ( _) = htlcs[ 0 ] . onion_payload {
3526
3530
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 ) ) ;
3527
3531
fail_htlc!( claimable_htlc, payment_hash) ;
@@ -3532,17 +3536,12 @@ where
3532
3536
for htlc in htlcs. iter( ) {
3533
3537
total_value += htlc. sender_intended_value;
3534
3538
earliest_expiry = cmp:: min( earliest_expiry, htlc. cltv_expiry) ;
3535
- match & htlc. onion_payload {
3536
- OnionPayload :: Invoice { .. } => {
3537
- if htlc. total_msat != $payment_data. total_msat {
3538
- log_trace!( self . logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})" ,
3539
- log_bytes!( payment_hash. 0 ) , $payment_data. total_msat, htlc. total_msat) ;
3540
- total_value = msgs:: MAX_VALUE_MSAT ;
3541
- }
3542
- if total_value >= msgs:: MAX_VALUE_MSAT { break ; }
3543
- } ,
3544
- _ => unreachable!( ) ,
3539
+ if htlc. total_msat != $payment_data. total_msat {
3540
+ log_trace!( self . logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})" ,
3541
+ log_bytes!( payment_hash. 0 ) , $payment_data. total_msat, htlc. total_msat) ;
3542
+ total_value = msgs:: MAX_VALUE_MSAT ;
3545
3543
}
3544
+ if total_value >= msgs:: MAX_VALUE_MSAT { break ; }
3546
3545
}
3547
3546
// The condition determining whether an MPP is complete must
3548
3547
// match exactly the condition used in `timer_tick_occurred`
@@ -3563,7 +3562,7 @@ where
3563
3562
new_events. push( events:: Event :: PaymentClaimable {
3564
3563
receiver_node_id: Some ( receiver_node_id) ,
3565
3564
payment_hash,
3566
- purpose: purpose ( ) ,
3565
+ purpose,
3567
3566
amount_msat,
3568
3567
via_channel_id: Some ( prev_channel_id) ,
3569
3568
via_user_channel_id: Some ( prev_user_channel_id) ,
@@ -3611,40 +3610,44 @@ where
3611
3610
fail_htlc ! ( claimable_htlc, payment_hash) ;
3612
3611
}
3613
3612
}
3614
- check_total_value ! ( payment_data, payment_preimage) ;
3613
+ check_total_value ! ( payment_data, payment_preimage, false ) ;
3615
3614
} ,
3616
3615
OnionPayload :: Spontaneous ( preimage) => {
3617
- let mut claimable_payments = self . claimable_payments . lock ( ) . unwrap ( ) ;
3618
- if claimable_payments. pending_claiming_payments . contains_key ( & payment_hash) {
3619
- fail_htlc ! ( claimable_htlc, payment_hash) ;
3620
- }
3621
- match claimable_payments. claimable_payments . entry ( payment_hash) {
3622
- hash_map:: Entry :: Vacant ( e) => {
3623
- let amount_msat = claimable_htlc. value ;
3624
- claimable_htlc. total_value_received = Some ( amount_msat) ;
3625
- let claim_deadline = Some ( claimable_htlc. cltv_expiry - HTLC_FAIL_BACK_BUFFER ) ;
3626
- let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3627
- e. insert ( ClaimablePayment {
3628
- purpose : purpose. clone ( ) ,
3629
- onion_fields : Some ( onion_fields. clone ( ) ) ,
3630
- htlcs : vec ! [ claimable_htlc] ,
3631
- } ) ;
3632
- let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
3633
- new_events. push ( events:: Event :: PaymentClaimable {
3634
- receiver_node_id : Some ( receiver_node_id) ,
3635
- payment_hash,
3636
- amount_msat,
3637
- purpose,
3638
- via_channel_id : Some ( prev_channel_id) ,
3639
- via_user_channel_id : Some ( prev_user_channel_id) ,
3640
- claim_deadline,
3641
- onion_fields : Some ( onion_fields) ,
3642
- } ) ;
3643
- } ,
3644
- hash_map:: Entry :: Occupied ( _) => {
3645
- log_trace ! ( self . logger, "Failing new keysend HTLC with payment_hash {} for a duplicative payment hash" , log_bytes!( payment_hash. 0 ) ) ;
3616
+ if let Some ( payment_data) = payment_data {
3617
+ check_total_value ! ( payment_data, Some ( preimage) , true ) ;
3618
+ } else {
3619
+ let mut claimable_payments = self . claimable_payments . lock ( ) . unwrap ( ) ;
3620
+ if claimable_payments. pending_claiming_payments . contains_key ( & payment_hash) {
3646
3621
fail_htlc ! ( claimable_htlc, payment_hash) ;
3647
3622
}
3623
+ match claimable_payments. claimable_payments . entry ( payment_hash) {
3624
+ hash_map:: Entry :: Vacant ( e) => {
3625
+ let amount_msat = claimable_htlc. value ;
3626
+ claimable_htlc. total_value_received = Some ( amount_msat) ;
3627
+ let claim_deadline = Some ( claimable_htlc. cltv_expiry - HTLC_FAIL_BACK_BUFFER ) ;
3628
+ let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3629
+ e. insert ( ClaimablePayment {
3630
+ purpose : purpose. clone ( ) ,
3631
+ onion_fields : Some ( onion_fields. clone ( ) ) ,
3632
+ htlcs : vec ! [ claimable_htlc] ,
3633
+ } ) ;
3634
+ let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
3635
+ new_events. push ( events:: Event :: PaymentClaimable {
3636
+ receiver_node_id : Some ( receiver_node_id) ,
3637
+ payment_hash,
3638
+ amount_msat,
3639
+ purpose,
3640
+ via_channel_id : Some ( prev_channel_id) ,
3641
+ via_user_channel_id : Some ( prev_user_channel_id) ,
3642
+ claim_deadline,
3643
+ onion_fields : Some ( onion_fields) ,
3644
+ } ) ;
3645
+ } ,
3646
+ hash_map:: Entry :: Occupied ( _) => {
3647
+ log_trace ! ( self . logger, "Failing new keysend HTLC with payment_hash {} for a duplicative payment hash" , log_bytes!( payment_hash. 0 ) ) ;
3648
+ fail_htlc ! ( claimable_htlc, payment_hash) ;
3649
+ }
3650
+ }
3648
3651
}
3649
3652
}
3650
3653
}
@@ -3663,7 +3666,7 @@ where
3663
3666
log_bytes!( payment_hash. 0 ) , payment_data. total_msat, inbound_payment. get( ) . min_value_msat. unwrap( ) ) ;
3664
3667
fail_htlc ! ( claimable_htlc, payment_hash) ;
3665
3668
} else {
3666
- let payment_claimable_generated = check_total_value ! ( payment_data, inbound_payment. get( ) . payment_preimage) ;
3669
+ let payment_claimable_generated = check_total_value ! ( payment_data, inbound_payment. get( ) . payment_preimage, false ) ;
3667
3670
if payment_claimable_generated {
3668
3671
inbound_payment. remove_entry ( ) ;
3669
3672
}
@@ -4138,12 +4141,16 @@ where
4138
4141
/// event matches your expectation. If you fail to do so and call this method, you may provide
4139
4142
/// the sender "proof-of-payment" when they did not fulfill the full expected payment.
4140
4143
///
4144
+ /// To accept multi-part keysend payments you must set [`UserConfig::accept_mpp_keysend`] to
4145
+ /// true.
4146
+ ///
4141
4147
/// [`Event::PaymentClaimable`]: crate::events::Event::PaymentClaimable
4142
4148
/// [`Event::PaymentClaimable::claim_deadline`]: crate::events::Event::PaymentClaimable::claim_deadline
4143
4149
/// [`Event::PaymentClaimed`]: crate::events::Event::PaymentClaimed
4144
4150
/// [`process_pending_events`]: EventsProvider::process_pending_events
4145
4151
/// [`create_inbound_payment`]: Self::create_inbound_payment
4146
4152
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
4153
+ /// [`UserConfig::accept_mpp_keysend`]: crate::util::config::UserConfig::accept_mpp_keysend
4147
4154
pub fn claim_funds ( & self , payment_preimage : PaymentPreimage ) {
4148
4155
let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
4149
4156
@@ -4204,9 +4211,9 @@ where
4204
4211
expected_amt_msat = htlc. total_value_received ;
4205
4212
4206
4213
if let OnionPayload :: Spontaneous ( _) = & htlc. onion_payload {
4207
- // We don't currently support MPP for spontaneous payments, so just check
4214
+ // If the user chooses not to support MPP for spontaneous payments, just check
4208
4215
// that there's one payment here and move on.
4209
- if sources. len ( ) != 1 {
4216
+ if ! self . default_configuration . accept_mpp_keysend && sources. len ( ) != 1 {
4210
4217
log_error ! ( self . logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!" ) ;
4211
4218
debug_assert ! ( false ) ;
4212
4219
valid_mpp = false ;
0 commit comments