@@ -194,7 +194,10 @@ struct ClaimableHTLC {
194
194
value : u64 ,
195
195
onion_payload : OnionPayload ,
196
196
timer_ticks : u8 ,
197
- /// The sum total of all MPP parts
197
+ /// The total value received for a payment (sum of all MPP parts if the payment is a MPP).
198
+ /// Gets set to the amount reported when pushing [`Event::PaymentClaimable`].
199
+ total_value_received : Option < u64 > ,
200
+ /// The sender intended sum total of all MPP parts specified in the onion
198
201
total_msat : u64 ,
199
202
}
200
203
@@ -3272,7 +3275,7 @@ where
3272
3275
panic ! ( "short_channel_id == 0 should imply any pending_forward entries are of type Receive" ) ;
3273
3276
}
3274
3277
} ;
3275
- let claimable_htlc = ClaimableHTLC {
3278
+ let mut claimable_htlc = ClaimableHTLC {
3276
3279
prev_hop : HTLCPreviousHopData {
3277
3280
short_channel_id : prev_short_channel_id,
3278
3281
outpoint : prev_funding_outpoint,
@@ -3282,6 +3285,7 @@ where
3282
3285
} ,
3283
3286
value : outgoing_amt_msat,
3284
3287
timer_ticks : 0 ,
3288
+ total_value_received : None ,
3285
3289
total_msat : if let Some ( data) = & payment_data { data. total_msat } else { outgoing_amt_msat } ,
3286
3290
cltv_expiry,
3287
3291
onion_payload,
@@ -3326,7 +3330,7 @@ where
3326
3330
fail_htlc!( claimable_htlc, payment_hash) ;
3327
3331
continue
3328
3332
}
3329
- let ( _, htlcs) = claimable_payments. claimable_htlcs. entry( payment_hash)
3333
+ let ( _, ref mut htlcs) = claimable_payments. claimable_htlcs. entry( payment_hash)
3330
3334
. or_insert_with( || ( purpose( ) , Vec :: new( ) ) ) ;
3331
3335
if htlcs. len( ) == 1 {
3332
3336
if let OnionPayload :: Spontaneous ( _) = htlcs[ 0 ] . onion_payload {
@@ -3357,11 +3361,13 @@ where
3357
3361
} else if total_value == $payment_data. total_msat {
3358
3362
let prev_channel_id = prev_funding_outpoint. to_channel_id( ) ;
3359
3363
htlcs. push( claimable_htlc) ;
3364
+ let amount_msat = htlcs. iter( ) . map( |htlc| htlc. value) . sum( ) ;
3365
+ htlcs. iter_mut( ) . for_each( |htlc| htlc. total_value_received = Some ( amount_msat) ) ;
3360
3366
new_events. push( events:: Event :: PaymentClaimable {
3361
3367
receiver_node_id: Some ( receiver_node_id) ,
3362
3368
payment_hash,
3363
3369
purpose: purpose( ) ,
3364
- amount_msat: total_value ,
3370
+ amount_msat,
3365
3371
via_channel_id: Some ( prev_channel_id) ,
3366
3372
via_user_channel_id: Some ( prev_user_channel_id) ,
3367
3373
} ) ;
@@ -3415,6 +3421,8 @@ where
3415
3421
}
3416
3422
match claimable_payments. claimable_htlcs . entry ( payment_hash) {
3417
3423
hash_map:: Entry :: Vacant ( e) => {
3424
+ let amount_msat = claimable_htlc. value ;
3425
+ claimable_htlc. total_value_received = Some ( amount_msat) ;
3418
3426
let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3419
3427
e. insert ( ( purpose. clone ( ) , vec ! [ claimable_htlc] ) ) ;
3420
3428
let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
@@ -3960,6 +3968,7 @@ where
3960
3968
// provide the preimage, so worrying too much about the optimal handling isn't worth
3961
3969
// it.
3962
3970
let mut claimable_amt_msat = 0 ;
3971
+ let mut prev_total_msat = None ;
3963
3972
let mut expected_amt_msat = None ;
3964
3973
let mut valid_mpp = true ;
3965
3974
let mut errs = Vec :: new ( ) ;
@@ -3987,14 +3996,22 @@ where
3987
3996
break ;
3988
3997
}
3989
3998
3990
- if expected_amt_msat . is_some ( ) && expected_amt_msat != Some ( htlc. total_msat ) {
3991
- log_error ! ( self . logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!" ) ;
3999
+ if prev_total_msat . is_some ( ) && prev_total_msat != Some ( htlc. total_msat ) {
4000
+ log_error ! ( self . logger, "Somehow ended up with an MPP payment with different expected total amounts - this should not be reachable!" ) ;
3992
4001
debug_assert ! ( false ) ;
3993
4002
valid_mpp = false ;
3994
4003
break ;
3995
4004
}
4005
+ prev_total_msat = Some ( htlc. total_msat ) ;
4006
+
4007
+ if expected_amt_msat. is_some ( ) && expected_amt_msat != htlc. total_value_received {
4008
+ log_error ! ( self . logger, "Somehow ended up with an MPP payment with different received total amounts - this should not be reachable!" ) ;
4009
+ debug_assert ! ( false ) ;
4010
+ valid_mpp = false ;
4011
+ break ;
4012
+ }
4013
+ expected_amt_msat = htlc. total_value_received ;
3996
4014
3997
- expected_amt_msat = Some ( htlc. total_msat ) ;
3998
4015
if let OnionPayload :: Spontaneous ( _) = & htlc. onion_payload {
3999
4016
// We don't currently support MPP for spontaneous payments, so just check
4000
4017
// that there's one payment here and move on.
@@ -6795,6 +6812,7 @@ impl Writeable for ClaimableHTLC {
6795
6812
( 1 , self . total_msat, required) ,
6796
6813
( 2 , self . value, required) ,
6797
6814
( 4 , payment_data, option) ,
6815
+ ( 5 , self . total_value_received, option) ,
6798
6816
( 6 , self . cltv_expiry, required) ,
6799
6817
( 8 , keysend_preimage, option) ,
6800
6818
} ) ;
@@ -6808,13 +6826,15 @@ impl Readable for ClaimableHTLC {
6808
6826
let mut value = 0 ;
6809
6827
let mut payment_data: Option < msgs:: FinalOnionHopData > = None ;
6810
6828
let mut cltv_expiry = 0 ;
6829
+ let mut total_value_received = None ;
6811
6830
let mut total_msat = None ;
6812
6831
let mut keysend_preimage: Option < PaymentPreimage > = None ;
6813
6832
read_tlv_fields ! ( reader, {
6814
6833
( 0 , prev_hop, required) ,
6815
6834
( 1 , total_msat, option) ,
6816
6835
( 2 , value, required) ,
6817
6836
( 4 , payment_data, option) ,
6837
+ ( 5 , total_value_received, option) ,
6818
6838
( 6 , cltv_expiry, required) ,
6819
6839
( 8 , keysend_preimage, option)
6820
6840
} ) ;
@@ -6842,6 +6862,7 @@ impl Readable for ClaimableHTLC {
6842
6862
prev_hop : prev_hop. 0 . unwrap ( ) ,
6843
6863
timer_ticks : 0 ,
6844
6864
value,
6865
+ total_value_received,
6845
6866
total_msat : total_msat. unwrap ( ) ,
6846
6867
onion_payload,
6847
6868
cltv_expiry,
0 commit comments