@@ -3498,7 +3498,7 @@ where
3498
3498
panic ! ( "short_channel_id == 0 should imply any pending_forward entries are of type Receive" ) ;
3499
3499
}
3500
3500
} ;
3501
- let mut claimable_htlc = ClaimableHTLC {
3501
+ let claimable_htlc = ClaimableHTLC {
3502
3502
prev_hop : HTLCPreviousHopData {
3503
3503
short_channel_id : prev_short_channel_id,
3504
3504
outpoint : prev_funding_outpoint,
@@ -3548,25 +3548,33 @@ where
3548
3548
}
3549
3549
3550
3550
macro_rules! check_total_value {
3551
- ( $payment_data : expr, $payment_preimage: expr) => { {
3551
+ ( $payment_secret : expr, $payment_preimage: expr , $total_msat : expr , $is_keysend : expr) => { {
3552
3552
let mut payment_claimable_generated = false ;
3553
- let purpose = || {
3553
+ let purpose = if $is_keysend {
3554
+ events:: PaymentPurpose :: SpontaneousPayment (
3555
+ $payment_preimage. expect( "Should never call check_total_value with $is_keysend as true but no preimage" )
3556
+ )
3557
+ } else {
3554
3558
events:: PaymentPurpose :: InvoicePayment {
3555
3559
payment_preimage: $payment_preimage,
3556
- payment_secret: $payment_data . payment_secret,
3560
+ payment_secret: $payment_secret. expect ( "Should never call check_total_value with $is_keysend as false but no payment secret" ) ,
3557
3561
}
3558
3562
} ;
3559
3563
let mut claimable_payments = self . claimable_payments. lock( ) . unwrap( ) ;
3560
3564
if claimable_payments. pending_claiming_payments. contains_key( & payment_hash) {
3561
3565
fail_htlc!( claimable_htlc, payment_hash) ;
3562
3566
}
3567
+ if $is_keysend && $payment_secret. is_none( ) && claimable_payments. claimable_payments. get( & payment_hash) . is_some( ) {
3568
+ log_trace!( self . logger, "Failing new keysend HTLC with payment_hash {} for duplicative payment hash" , log_bytes!( payment_hash. 0 ) ) ;
3569
+ fail_htlc!( claimable_htlc, payment_hash) ;
3570
+ }
3563
3571
let ref mut claimable_payment = claimable_payments. claimable_payments
3564
3572
. entry( payment_hash)
3565
3573
// Note that if we insert here we MUST NOT fail_htlc!()
3566
3574
. or_insert_with( || {
3567
3575
committed_to_claimable = true ;
3568
3576
ClaimablePayment {
3569
- purpose: purpose( ) , htlcs: Vec :: new( ) , onion_fields: None ,
3577
+ purpose: purpose. clone ( ) , htlcs: Vec :: new( ) , onion_fields: None ,
3570
3578
}
3571
3579
} ) ;
3572
3580
if let Some ( earlier_fields) = & mut claimable_payment. onion_fields {
@@ -3577,7 +3585,7 @@ where
3577
3585
claimable_payment. onion_fields = Some ( onion_fields) ;
3578
3586
}
3579
3587
let ref mut htlcs = & mut claimable_payment. htlcs;
3580
- if htlcs. len ( ) == 1 {
3588
+ if ! htlcs. is_empty ( ) && !$is_keysend {
3581
3589
if let OnionPayload :: Spontaneous ( _) = htlcs[ 0 ] . onion_payload {
3582
3590
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 ) ) ;
3583
3591
fail_htlc!( claimable_htlc, payment_hash) ;
@@ -3588,27 +3596,22 @@ where
3588
3596
for htlc in htlcs. iter( ) {
3589
3597
total_value += htlc. sender_intended_value;
3590
3598
earliest_expiry = cmp:: min( earliest_expiry, htlc. cltv_expiry) ;
3591
- match & htlc. onion_payload {
3592
- OnionPayload :: Invoice { .. } => {
3593
- if htlc. total_msat != $payment_data. total_msat {
3594
- log_trace!( self . logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})" ,
3595
- log_bytes!( payment_hash. 0 ) , $payment_data. total_msat, htlc. total_msat) ;
3596
- total_value = msgs:: MAX_VALUE_MSAT ;
3597
- }
3598
- if total_value >= msgs:: MAX_VALUE_MSAT { break ; }
3599
- } ,
3600
- _ => unreachable!( ) ,
3599
+ if htlc. total_msat != $total_msat {
3600
+ log_trace!( self . logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})" ,
3601
+ log_bytes!( payment_hash. 0 ) , $total_msat, htlc. total_msat) ;
3602
+ total_value = msgs:: MAX_VALUE_MSAT ;
3601
3603
}
3604
+ if total_value >= msgs:: MAX_VALUE_MSAT { break ; }
3602
3605
}
3603
3606
// The condition determining whether an MPP is complete must
3604
3607
// match exactly the condition used in `timer_tick_occurred`
3605
3608
if total_value >= msgs:: MAX_VALUE_MSAT {
3606
3609
fail_htlc!( claimable_htlc, payment_hash) ;
3607
- } else if total_value - claimable_htlc. sender_intended_value >= $payment_data . total_msat {
3610
+ } else if total_value - claimable_htlc. sender_intended_value >= $total_msat {
3608
3611
log_trace!( self . logger, "Failing HTLC with payment_hash {} as payment is already claimable" ,
3609
3612
log_bytes!( payment_hash. 0 ) ) ;
3610
3613
fail_htlc!( claimable_htlc, payment_hash) ;
3611
- } else if total_value >= $payment_data . total_msat {
3614
+ } else if total_value >= $total_msat {
3612
3615
#[ allow( unused_assignments) ] {
3613
3616
committed_to_claimable = true ;
3614
3617
}
@@ -3619,7 +3622,7 @@ where
3619
3622
new_events. push_back( ( events:: Event :: PaymentClaimable {
3620
3623
receiver_node_id: Some ( receiver_node_id) ,
3621
3624
payment_hash,
3622
- purpose: purpose ( ) ,
3625
+ purpose,
3623
3626
amount_msat,
3624
3627
via_channel_id: Some ( prev_channel_id) ,
3625
3628
via_user_channel_id: Some ( prev_user_channel_id) ,
@@ -3667,41 +3670,10 @@ where
3667
3670
fail_htlc ! ( claimable_htlc, payment_hash) ;
3668
3671
}
3669
3672
}
3670
- check_total_value ! ( payment_data, payment_preimage) ;
3673
+ check_total_value ! ( Some ( payment_data. payment_secret ) , payment_preimage, payment_data . total_msat , false ) ;
3671
3674
} ,
3672
3675
OnionPayload :: Spontaneous ( preimage) => {
3673
- let mut claimable_payments = self . claimable_payments . lock ( ) . unwrap ( ) ;
3674
- if claimable_payments. pending_claiming_payments . contains_key ( & payment_hash) {
3675
- fail_htlc ! ( claimable_htlc, payment_hash) ;
3676
- }
3677
- match claimable_payments. claimable_payments . entry ( payment_hash) {
3678
- hash_map:: Entry :: Vacant ( e) => {
3679
- let amount_msat = claimable_htlc. value ;
3680
- claimable_htlc. total_value_received = Some ( amount_msat) ;
3681
- let claim_deadline = Some ( claimable_htlc. cltv_expiry - HTLC_FAIL_BACK_BUFFER ) ;
3682
- let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3683
- e. insert ( ClaimablePayment {
3684
- purpose : purpose. clone ( ) ,
3685
- onion_fields : Some ( onion_fields. clone ( ) ) ,
3686
- htlcs : vec ! [ claimable_htlc] ,
3687
- } ) ;
3688
- let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
3689
- new_events. push_back ( ( events:: Event :: PaymentClaimable {
3690
- receiver_node_id : Some ( receiver_node_id) ,
3691
- payment_hash,
3692
- amount_msat,
3693
- purpose,
3694
- via_channel_id : Some ( prev_channel_id) ,
3695
- via_user_channel_id : Some ( prev_user_channel_id) ,
3696
- claim_deadline,
3697
- onion_fields : Some ( onion_fields) ,
3698
- } , None ) ) ;
3699
- } ,
3700
- hash_map:: Entry :: Occupied ( _) => {
3701
- log_trace ! ( self . logger, "Failing new keysend HTLC with payment_hash {} for a duplicative payment hash" , log_bytes!( payment_hash. 0 ) ) ;
3702
- fail_htlc ! ( claimable_htlc, payment_hash) ;
3703
- }
3704
- }
3676
+ check_total_value ! ( payment_data. as_ref( ) . map( |d| d. payment_secret) , Some ( preimage) , payment_data. as_ref( ) . map_or( claimable_htlc. value, |d| d. total_msat) , true ) ;
3705
3677
}
3706
3678
}
3707
3679
} ,
@@ -3719,7 +3691,7 @@ where
3719
3691
log_bytes!( payment_hash. 0 ) , payment_data. total_msat, inbound_payment. get( ) . min_value_msat. unwrap( ) ) ;
3720
3692
fail_htlc ! ( claimable_htlc, payment_hash) ;
3721
3693
} else {
3722
- let payment_claimable_generated = check_total_value ! ( payment_data, inbound_payment. get( ) . payment_preimage) ;
3694
+ let payment_claimable_generated = check_total_value ! ( Some ( payment_data. payment_secret ) , inbound_payment. get( ) . payment_preimage, payment_data . total_msat , false ) ;
3723
3695
if payment_claimable_generated {
3724
3696
inbound_payment. remove_entry ( ) ;
3725
3697
}
@@ -4194,12 +4166,16 @@ where
4194
4166
/// event matches your expectation. If you fail to do so and call this method, you may provide
4195
4167
/// the sender "proof-of-payment" when they did not fulfill the full expected payment.
4196
4168
///
4169
+ /// To accept multi-part keysend payments you must set [`UserConfig::accept_mpp_keysend`] to
4170
+ /// true.
4171
+ ///
4197
4172
/// [`Event::PaymentClaimable`]: crate::events::Event::PaymentClaimable
4198
4173
/// [`Event::PaymentClaimable::claim_deadline`]: crate::events::Event::PaymentClaimable::claim_deadline
4199
4174
/// [`Event::PaymentClaimed`]: crate::events::Event::PaymentClaimed
4200
4175
/// [`process_pending_events`]: EventsProvider::process_pending_events
4201
4176
/// [`create_inbound_payment`]: Self::create_inbound_payment
4202
4177
/// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash
4178
+ /// [`UserConfig::accept_mpp_keysend`]: crate::util::config::UserConfig::accept_mpp_keysend
4203
4179
pub fn claim_funds ( & self , payment_preimage : PaymentPreimage ) {
4204
4180
let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
4205
4181
@@ -4260,11 +4236,8 @@ where
4260
4236
expected_amt_msat = htlc. total_value_received ;
4261
4237
4262
4238
if let OnionPayload :: Spontaneous ( _) = & htlc. onion_payload {
4263
- // We don't currently support MPP for spontaneous payments, so just check
4264
- // that there's one payment here and move on.
4265
- if sources. len ( ) != 1 {
4266
- log_error ! ( self . logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!" ) ;
4267
- debug_assert ! ( false ) ;
4239
+ if !self . default_configuration . accept_mpp_keysend && sources. len ( ) != 1 {
4240
+ log_info ! ( self . logger, "Rejecting a received MPP spontaneous payment since our config states we don't accept them." ) ;
4268
4241
valid_mpp = false ;
4269
4242
break ;
4270
4243
}
0 commit comments