@@ -120,7 +120,10 @@ pub(super) struct PendingHTLCInfo {
120
120
pub ( super ) routing : PendingHTLCRouting ,
121
121
pub ( super ) incoming_shared_secret : [ u8 ; 32 ] ,
122
122
payment_hash : PaymentHash ,
123
+ /// Amount received
123
124
pub ( super ) incoming_amt_msat : Option < u64 > , // Added in 0.0.113
125
+ /// Sender intended amount to forward or receive (actual amount received
126
+ /// may overshoot this in either case)
124
127
pub ( super ) outgoing_amt_msat : u64 ,
125
128
pub ( super ) outgoing_cltv_value : u32 ,
126
129
}
@@ -192,6 +195,9 @@ struct ClaimableHTLC {
192
195
cltv_expiry : u32 ,
193
196
/// The amount (in msats) of this MPP part
194
197
value : u64 ,
198
+ /// The amount (in msats) that the sender intended to be sent in this MPP
199
+ /// part (used for validating total MPP amount)
200
+ sender_intended_value : u64 ,
195
201
onion_payload : OnionPayload ,
196
202
timer_ticks : u8 ,
197
203
/// The total value received for a payment (sum of all MPP parts if the payment is a MPP).
@@ -2181,7 +2187,7 @@ where
2181
2187
payment_hash,
2182
2188
incoming_shared_secret : shared_secret,
2183
2189
incoming_amt_msat : Some ( amt_msat) ,
2184
- outgoing_amt_msat : amt_msat ,
2190
+ outgoing_amt_msat : hop_data . amt_to_forward ,
2185
2191
outgoing_cltv_value : hop_data. outgoing_cltv_value ,
2186
2192
} )
2187
2193
}
@@ -3261,7 +3267,7 @@ where
3261
3267
HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
3262
3268
prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
3263
3269
forward_info : PendingHTLCInfo {
3264
- routing, incoming_shared_secret, payment_hash, outgoing_amt_msat, ..
3270
+ routing, incoming_shared_secret, payment_hash, incoming_amt_msat , outgoing_amt_msat, ..
3265
3271
}
3266
3272
} ) => {
3267
3273
let ( cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing {
@@ -3283,7 +3289,11 @@ where
3283
3289
incoming_packet_shared_secret : incoming_shared_secret,
3284
3290
phantom_shared_secret,
3285
3291
} ,
3286
- value : outgoing_amt_msat,
3292
+ // We differentiate the received value from the sender intended value
3293
+ // if possible so that we don't prematurely mark MPP payments complete
3294
+ // if routing nodes overpay
3295
+ value : incoming_amt_msat. unwrap_or ( outgoing_amt_msat) ,
3296
+ sender_intended_value : outgoing_amt_msat,
3287
3297
timer_ticks : 0 ,
3288
3298
total_value_received : None ,
3289
3299
total_msat : if let Some ( data) = & payment_data { data. total_msat } else { outgoing_amt_msat } ,
@@ -3339,9 +3349,9 @@ where
3339
3349
continue
3340
3350
}
3341
3351
}
3342
- let mut total_value = claimable_htlc. value ;
3352
+ let mut total_value = claimable_htlc. sender_intended_value ;
3343
3353
for htlc in htlcs. iter( ) {
3344
- total_value += htlc. value ;
3354
+ total_value += htlc. sender_intended_value ;
3345
3355
match & htlc. onion_payload {
3346
3356
OnionPayload :: Invoice { .. } => {
3347
3357
if htlc. total_msat != $payment_data. total_msat {
@@ -3354,9 +3364,11 @@ where
3354
3364
_ => unreachable!( ) ,
3355
3365
}
3356
3366
}
3367
+ // The condition determining whether an MPP is complete must
3368
+ // match exactly the condition used in `timer_tick_occurred`
3357
3369
if total_value >= msgs:: MAX_VALUE_MSAT {
3358
3370
fail_htlc!( claimable_htlc, payment_hash) ;
3359
- } else if total_value - claimable_htlc. value >= $payment_data. total_msat {
3371
+ } else if total_value - claimable_htlc. sender_intended_value >= $payment_data. total_msat {
3360
3372
log_trace!( self . logger, "Failing HTLC with payment_hash {} as payment is already claimable" ,
3361
3373
log_bytes!( payment_hash. 0 ) ) ;
3362
3374
fail_htlc!( claimable_htlc, payment_hash) ;
@@ -3431,7 +3443,7 @@ where
3431
3443
new_events. push ( events:: Event :: PaymentClaimable {
3432
3444
receiver_node_id : Some ( receiver_node_id) ,
3433
3445
payment_hash,
3434
- amount_msat : outgoing_amt_msat ,
3446
+ amount_msat,
3435
3447
purpose,
3436
3448
via_channel_id : Some ( prev_channel_id) ,
3437
3449
via_user_channel_id : Some ( prev_user_channel_id) ,
@@ -3691,7 +3703,9 @@ where
3691
3703
if let OnionPayload :: Invoice { .. } = htlcs[ 0 ] . onion_payload {
3692
3704
// Check if we've received all the parts we need for an MPP (the value of the parts adds to total_msat).
3693
3705
// In this case we're not going to handle any timeouts of the parts here.
3694
- if htlcs[ 0 ] . total_msat <= htlcs. iter ( ) . fold ( 0 , |total, htlc| total + htlc. value ) {
3706
+ // This condition determining whether the MPP is complete here must match
3707
+ // exactly the condition used in `process_pending_htlc_forwards`.
3708
+ if htlcs[ 0 ] . total_msat <= htlcs. iter ( ) . fold ( 0 , |total, htlc| total + htlc. sender_intended_value ) {
3695
3709
return true ;
3696
3710
} else if htlcs. into_iter ( ) . any ( |htlc| {
3697
3711
htlc. timer_ticks += 1 ;
@@ -6813,6 +6827,7 @@ impl Writeable for ClaimableHTLC {
6813
6827
( 0 , self . prev_hop, required) ,
6814
6828
( 1 , self . total_msat, required) ,
6815
6829
( 2 , self . value, required) ,
6830
+ ( 3 , self . sender_intended_value, required) ,
6816
6831
( 4 , payment_data, option) ,
6817
6832
( 5 , self . total_value_received, option) ,
6818
6833
( 6 , self . cltv_expiry, required) ,
@@ -6826,6 +6841,7 @@ impl Readable for ClaimableHTLC {
6826
6841
fn read < R : Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
6827
6842
let mut prev_hop = crate :: util:: ser:: RequiredWrapper ( None ) ;
6828
6843
let mut value = 0 ;
6844
+ let mut sender_intended_value = None ;
6829
6845
let mut payment_data: Option < msgs:: FinalOnionHopData > = None ;
6830
6846
let mut cltv_expiry = 0 ;
6831
6847
let mut total_value_received = None ;
@@ -6835,6 +6851,7 @@ impl Readable for ClaimableHTLC {
6835
6851
( 0 , prev_hop, required) ,
6836
6852
( 1 , total_msat, option) ,
6837
6853
( 2 , value, required) ,
6854
+ ( 3 , sender_intended_value, option) ,
6838
6855
( 4 , payment_data, option) ,
6839
6856
( 5 , total_value_received, option) ,
6840
6857
( 6 , cltv_expiry, required) ,
@@ -6864,6 +6881,7 @@ impl Readable for ClaimableHTLC {
6864
6881
prev_hop : prev_hop. 0 . unwrap ( ) ,
6865
6882
timer_ticks : 0 ,
6866
6883
value,
6884
+ sender_intended_value : sender_intended_value. unwrap_or ( value) ,
6867
6885
total_value_received,
6868
6886
total_msat : total_msat. unwrap ( ) ,
6869
6887
onion_payload,
0 commit comments