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