@@ -193,7 +193,10 @@ struct ClaimableHTLC {
193
193
value : u64 ,
194
194
onion_payload : OnionPayload ,
195
195
timer_ticks : u8 ,
196
- /// The sum total of all MPP parts
196
+ /// The total value received for a payment (sum of all MPP parts if the payment is a MPP).
197
+ /// Gets set to the amount reported when pushing [`Event::PaymentClaimable`].
198
+ total_value_received : Option < u64 > ,
199
+ /// The sender intended sum total of all MPP parts specified in the onion
197
200
total_msat : u64 ,
198
201
}
199
202
@@ -3246,7 +3249,7 @@ where
3246
3249
panic ! ( "short_channel_id == 0 should imply any pending_forward entries are of type Receive" ) ;
3247
3250
}
3248
3251
} ;
3249
- let claimable_htlc = ClaimableHTLC {
3252
+ let mut claimable_htlc = ClaimableHTLC {
3250
3253
prev_hop : HTLCPreviousHopData {
3251
3254
short_channel_id : prev_short_channel_id,
3252
3255
outpoint : prev_funding_outpoint,
@@ -3256,6 +3259,7 @@ where
3256
3259
} ,
3257
3260
value : outgoing_amt_msat,
3258
3261
timer_ticks : 0 ,
3262
+ total_value_received : None ,
3259
3263
total_msat : if let Some ( data) = & payment_data { data. total_msat } else { outgoing_amt_msat } ,
3260
3264
cltv_expiry,
3261
3265
onion_payload,
@@ -3300,7 +3304,7 @@ where
3300
3304
fail_htlc!( claimable_htlc, payment_hash) ;
3301
3305
continue
3302
3306
}
3303
- let ( _, htlcs) = claimable_payments. claimable_htlcs. entry( payment_hash)
3307
+ let ( _, ref mut htlcs) = claimable_payments. claimable_htlcs. entry( payment_hash)
3304
3308
. or_insert_with( || ( purpose( ) , Vec :: new( ) ) ) ;
3305
3309
if htlcs. len( ) == 1 {
3306
3310
if let OnionPayload :: Spontaneous ( _) = htlcs[ 0 ] . onion_payload {
@@ -3331,11 +3335,13 @@ where
3331
3335
} else if total_value == $payment_data. total_msat {
3332
3336
let prev_channel_id = prev_funding_outpoint. to_channel_id( ) ;
3333
3337
htlcs. push( claimable_htlc) ;
3338
+ let amount_msat = htlcs. iter( ) . map( |htlc| htlc. value) . sum( ) ;
3339
+ htlcs. iter_mut( ) . for_each( |htlc| htlc. total_value_received = Some ( amount_msat) ) ;
3334
3340
new_events. push( events:: Event :: PaymentClaimable {
3335
3341
receiver_node_id: Some ( receiver_node_id) ,
3336
3342
payment_hash,
3337
3343
purpose: purpose( ) ,
3338
- amount_msat: total_value ,
3344
+ amount_msat,
3339
3345
via_channel_id: Some ( prev_channel_id) ,
3340
3346
via_user_channel_id: Some ( prev_user_channel_id) ,
3341
3347
} ) ;
@@ -3389,6 +3395,8 @@ where
3389
3395
}
3390
3396
match claimable_payments. claimable_htlcs . entry ( payment_hash) {
3391
3397
hash_map:: Entry :: Vacant ( e) => {
3398
+ let amount_msat = claimable_htlc. value ;
3399
+ claimable_htlc. total_value_received = Some ( amount_msat) ;
3392
3400
let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3393
3401
e. insert ( ( purpose. clone ( ) , vec ! [ claimable_htlc] ) ) ;
3394
3402
let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
@@ -3931,6 +3939,7 @@ where
3931
3939
// provide the preimage, so worrying too much about the optimal handling isn't worth
3932
3940
// it.
3933
3941
let mut claimable_amt_msat = 0 ;
3942
+ let mut prev_total_msat = None ;
3934
3943
let mut expected_amt_msat = None ;
3935
3944
let mut valid_mpp = true ;
3936
3945
let mut errs = Vec :: new ( ) ;
@@ -3958,14 +3967,22 @@ where
3958
3967
break ;
3959
3968
}
3960
3969
3961
- if expected_amt_msat . is_some ( ) && expected_amt_msat != Some ( htlc. total_msat ) {
3962
- log_error ! ( self . logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!" ) ;
3970
+ if prev_total_msat . is_some ( ) && prev_total_msat != Some ( htlc. total_msat ) {
3971
+ log_error ! ( self . logger, "Somehow ended up with an MPP payment with different expected total amounts - this should not be reachable!" ) ;
3963
3972
debug_assert ! ( false ) ;
3964
3973
valid_mpp = false ;
3965
3974
break ;
3966
3975
}
3976
+ prev_total_msat = Some ( htlc. total_msat ) ;
3977
+
3978
+ if expected_amt_msat. is_some ( ) && expected_amt_msat != htlc. total_value_received {
3979
+ log_error ! ( self . logger, "Somehow ended up with an MPP payment with different received total amounts - this should not be reachable!" ) ;
3980
+ debug_assert ! ( false ) ;
3981
+ valid_mpp = false ;
3982
+ break ;
3983
+ }
3984
+ expected_amt_msat = htlc. total_value_received ;
3967
3985
3968
- expected_amt_msat = Some ( htlc. total_msat ) ;
3969
3986
if let OnionPayload :: Spontaneous ( _) = & htlc. onion_payload {
3970
3987
// We don't currently support MPP for spontaneous payments, so just check
3971
3988
// that there's one payment here and move on.
@@ -6766,6 +6783,7 @@ impl Writeable for ClaimableHTLC {
6766
6783
( 1 , self . total_msat, required) ,
6767
6784
( 2 , self . value, required) ,
6768
6785
( 4 , payment_data, option) ,
6786
+ ( 5 , self . total_value_received, option) ,
6769
6787
( 6 , self . cltv_expiry, required) ,
6770
6788
( 8 , keysend_preimage, option) ,
6771
6789
} ) ;
@@ -6779,13 +6797,15 @@ impl Readable for ClaimableHTLC {
6779
6797
let mut value = 0 ;
6780
6798
let mut payment_data: Option < msgs:: FinalOnionHopData > = None ;
6781
6799
let mut cltv_expiry = 0 ;
6800
+ let mut total_value_received = None ;
6782
6801
let mut total_msat = None ;
6783
6802
let mut keysend_preimage: Option < PaymentPreimage > = None ;
6784
6803
read_tlv_fields ! ( reader, {
6785
6804
( 0 , prev_hop, required) ,
6786
6805
( 1 , total_msat, option) ,
6787
6806
( 2 , value, required) ,
6788
6807
( 4 , payment_data, option) ,
6808
+ ( 5 , total_value_received, option) ,
6789
6809
( 6 , cltv_expiry, required) ,
6790
6810
( 8 , keysend_preimage, option)
6791
6811
} ) ;
@@ -6813,6 +6833,7 @@ impl Readable for ClaimableHTLC {
6813
6833
prev_hop : prev_hop. 0 . unwrap ( ) ,
6814
6834
timer_ticks : 0 ,
6815
6835
value,
6836
+ total_value_received,
6816
6837
total_msat : total_msat. unwrap ( ) ,
6817
6838
onion_payload,
6818
6839
cltv_expiry,
0 commit comments