@@ -3468,9 +3468,13 @@ where
3468
3468
}
3469
3469
3470
3470
macro_rules! check_total_value {
3471
- ( $payment_data: expr, $payment_preimage: expr) => { {
3471
+ ( $payment_data: expr, $payment_preimage: expr, $is_keysend : expr ) => { {
3472
3472
let mut payment_claimable_generated = false ;
3473
- let purpose = || {
3473
+ let purpose = if $is_keysend {
3474
+ events:: PaymentPurpose :: SpontaneousPayment (
3475
+ $payment_preimage. expect( "Should never call check_total_value with $is_keysend as true but no preimage" )
3476
+ )
3477
+ } else {
3474
3478
events:: PaymentPurpose :: InvoicePayment {
3475
3479
payment_preimage: $payment_preimage,
3476
3480
payment_secret: $payment_data. payment_secret,
@@ -3486,7 +3490,7 @@ where
3486
3490
. or_insert_with( || {
3487
3491
committed_to_claimable = true ;
3488
3492
ClaimablePayment {
3489
- purpose: purpose( ) , htlcs: Vec :: new( ) , onion_fields: None ,
3493
+ purpose: purpose. clone ( ) , htlcs: Vec :: new( ) , onion_fields: None ,
3490
3494
}
3491
3495
} ) ;
3492
3496
if let Some ( earlier_fields) = & mut claimable_payment. onion_fields {
@@ -3497,7 +3501,7 @@ where
3497
3501
claimable_payment. onion_fields = Some ( onion_fields) ;
3498
3502
}
3499
3503
let ref mut htlcs = & mut claimable_payment. htlcs;
3500
- if htlcs. len( ) == 1 {
3504
+ if htlcs. len( ) == 1 && !$is_keysend {
3501
3505
if let OnionPayload :: Spontaneous ( _) = htlcs[ 0 ] . onion_payload {
3502
3506
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 ) ) ;
3503
3507
fail_htlc!( claimable_htlc, payment_hash) ;
@@ -3508,17 +3512,12 @@ where
3508
3512
for htlc in htlcs. iter( ) {
3509
3513
total_value += htlc. sender_intended_value;
3510
3514
earliest_expiry = cmp:: min( earliest_expiry, htlc. cltv_expiry) ;
3511
- match & htlc. onion_payload {
3512
- OnionPayload :: Invoice { .. } => {
3513
- if htlc. total_msat != $payment_data. total_msat {
3514
- log_trace!( self . logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})" ,
3515
- log_bytes!( payment_hash. 0 ) , $payment_data. total_msat, htlc. total_msat) ;
3516
- total_value = msgs:: MAX_VALUE_MSAT ;
3517
- }
3518
- if total_value >= msgs:: MAX_VALUE_MSAT { break ; }
3519
- } ,
3520
- _ => unreachable!( ) ,
3515
+ if htlc. total_msat != $payment_data. total_msat {
3516
+ log_trace!( self . logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})" ,
3517
+ log_bytes!( payment_hash. 0 ) , $payment_data. total_msat, htlc. total_msat) ;
3518
+ total_value = msgs:: MAX_VALUE_MSAT ;
3521
3519
}
3520
+ if total_value >= msgs:: MAX_VALUE_MSAT { break ; }
3522
3521
}
3523
3522
// The condition determining whether an MPP is complete must
3524
3523
// match exactly the condition used in `timer_tick_occurred`
@@ -3539,7 +3538,7 @@ where
3539
3538
new_events. push( events:: Event :: PaymentClaimable {
3540
3539
receiver_node_id: Some ( receiver_node_id) ,
3541
3540
payment_hash,
3542
- purpose: purpose ( ) ,
3541
+ purpose,
3543
3542
amount_msat,
3544
3543
via_channel_id: Some ( prev_channel_id) ,
3545
3544
via_user_channel_id: Some ( prev_user_channel_id) ,
@@ -3587,40 +3586,44 @@ where
3587
3586
fail_htlc ! ( claimable_htlc, payment_hash) ;
3588
3587
}
3589
3588
}
3590
- check_total_value ! ( payment_data, payment_preimage) ;
3589
+ check_total_value ! ( payment_data, payment_preimage, false ) ;
3591
3590
} ,
3592
3591
OnionPayload :: Spontaneous ( preimage) => {
3593
- let mut claimable_payments = self . claimable_payments . lock ( ) . unwrap ( ) ;
3594
- if claimable_payments. pending_claiming_payments . contains_key ( & payment_hash) {
3595
- fail_htlc ! ( claimable_htlc, payment_hash) ;
3596
- }
3597
- match claimable_payments. claimable_payments . entry ( payment_hash) {
3598
- hash_map:: Entry :: Vacant ( e) => {
3599
- let amount_msat = claimable_htlc. value ;
3600
- claimable_htlc. total_value_received = Some ( amount_msat) ;
3601
- let claim_deadline = Some ( claimable_htlc. cltv_expiry - HTLC_FAIL_BACK_BUFFER ) ;
3602
- let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3603
- e. insert ( ClaimablePayment {
3604
- purpose : purpose. clone ( ) ,
3605
- onion_fields : Some ( onion_fields. clone ( ) ) ,
3606
- htlcs : vec ! [ claimable_htlc] ,
3607
- } ) ;
3608
- let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
3609
- new_events. push ( events:: Event :: PaymentClaimable {
3610
- receiver_node_id : Some ( receiver_node_id) ,
3611
- payment_hash,
3612
- amount_msat,
3613
- purpose,
3614
- via_channel_id : Some ( prev_channel_id) ,
3615
- via_user_channel_id : Some ( prev_user_channel_id) ,
3616
- claim_deadline,
3617
- onion_fields : Some ( onion_fields) ,
3618
- } ) ;
3619
- } ,
3620
- hash_map:: Entry :: Occupied ( _) => {
3621
- log_trace ! ( self . logger, "Failing new keysend HTLC with payment_hash {} for a duplicative payment hash" , log_bytes!( payment_hash. 0 ) ) ;
3592
+ if let Some ( payment_data) = payment_data {
3593
+ check_total_value ! ( payment_data, Some ( preimage) , true ) ;
3594
+ } else {
3595
+ let mut claimable_payments = self . claimable_payments . lock ( ) . unwrap ( ) ;
3596
+ if claimable_payments. pending_claiming_payments . contains_key ( & payment_hash) {
3622
3597
fail_htlc ! ( claimable_htlc, payment_hash) ;
3623
3598
}
3599
+ match claimable_payments. claimable_payments . entry ( payment_hash) {
3600
+ hash_map:: Entry :: Vacant ( e) => {
3601
+ let amount_msat = claimable_htlc. value ;
3602
+ claimable_htlc. total_value_received = Some ( amount_msat) ;
3603
+ let claim_deadline = Some ( claimable_htlc. cltv_expiry - HTLC_FAIL_BACK_BUFFER ) ;
3604
+ let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3605
+ e. insert ( ClaimablePayment {
3606
+ purpose : purpose. clone ( ) ,
3607
+ onion_fields : Some ( onion_fields. clone ( ) ) ,
3608
+ htlcs : vec ! [ claimable_htlc] ,
3609
+ } ) ;
3610
+ let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
3611
+ new_events. push ( events:: Event :: PaymentClaimable {
3612
+ receiver_node_id : Some ( receiver_node_id) ,
3613
+ payment_hash,
3614
+ amount_msat,
3615
+ purpose,
3616
+ via_channel_id : Some ( prev_channel_id) ,
3617
+ via_user_channel_id : Some ( prev_user_channel_id) ,
3618
+ claim_deadline,
3619
+ onion_fields : Some ( onion_fields) ,
3620
+ } ) ;
3621
+ } ,
3622
+ hash_map:: Entry :: Occupied ( _) => {
3623
+ log_trace ! ( self . logger, "Failing new keysend HTLC with payment_hash {} for a duplicative payment hash" , log_bytes!( payment_hash. 0 ) ) ;
3624
+ fail_htlc ! ( claimable_htlc, payment_hash) ;
3625
+ }
3626
+ }
3624
3627
}
3625
3628
}
3626
3629
}
@@ -3639,7 +3642,7 @@ where
3639
3642
log_bytes!( payment_hash. 0 ) , payment_data. total_msat, inbound_payment. get( ) . min_value_msat. unwrap( ) ) ;
3640
3643
fail_htlc ! ( claimable_htlc, payment_hash) ;
3641
3644
} else {
3642
- let payment_claimable_generated = check_total_value ! ( payment_data, inbound_payment. get( ) . payment_preimage) ;
3645
+ let payment_claimable_generated = check_total_value ! ( payment_data, inbound_payment. get( ) . payment_preimage, false ) ;
3643
3646
if payment_claimable_generated {
3644
3647
inbound_payment. remove_entry ( ) ;
3645
3648
}
@@ -4114,12 +4117,16 @@ where
4114
4117
/// event matches your expectation. If you fail to do so and call this method, you may provide
4115
4118
/// the sender "proof-of-payment" when they did not fulfill the full expected payment.
4116
4119
///
4120
+ /// To accept multi-part keysend payments you must set [`UserConfig::accept_mpp_keysend`] to
4121
+ /// true.
4122
+ ///
4117
4123
/// [`Event::PaymentClaimable`]: crate::events::Event::PaymentClaimable
4118
4124
/// [`Event::PaymentClaimable::claim_deadline`]: crate::events::Event::PaymentClaimable::claim_deadline
4119
4125
/// [`Event::PaymentClaimed`]: crate::events::Event::PaymentClaimed
4120
4126
/// [`process_pending_events`]: EventsProvider::process_pending_events
4121
4127
/// [`create_inbound_payment`]: Self::create_inbound_payment
4122
4128
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
4129
+ /// [`UserConfig::accept_mpp_keysend`]: crate::util::config::UserConfig::accept_mpp_keysend
4123
4130
pub fn claim_funds ( & self , payment_preimage : PaymentPreimage ) {
4124
4131
let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
4125
4132
@@ -4180,9 +4187,9 @@ where
4180
4187
expected_amt_msat = htlc. total_value_received ;
4181
4188
4182
4189
if let OnionPayload :: Spontaneous ( _) = & htlc. onion_payload {
4183
- // We don't currently support MPP for spontaneous payments, so just check
4190
+ // If the user chooses not to support MPP for spontaneous payments, just check
4184
4191
// that there's one payment here and move on.
4185
- if sources. len ( ) != 1 {
4192
+ if ! self . default_configuration . accept_mpp_keysend && sources. len ( ) != 1 {
4186
4193
log_error ! ( self . logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!" ) ;
4187
4194
debug_assert ! ( false ) ;
4188
4195
valid_mpp = false ;
0 commit comments