@@ -120,7 +120,10 @@ pub(super) struct PendingHTLCInfo {
120120 pub ( super ) routing : PendingHTLCRouting ,
121121 pub ( super ) incoming_shared_secret : [ u8 ; 32 ] ,
122122 payment_hash : PaymentHash ,
123+ /// Amount received
123124 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)
124127 pub ( super ) outgoing_amt_msat : u64 ,
125128 pub ( super ) outgoing_cltv_value : u32 ,
126129}
@@ -192,6 +195,9 @@ struct ClaimableHTLC {
192195 cltv_expiry : u32 ,
193196 /// The amount (in msats) of this MPP part
194197 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 ,
195201 onion_payload : OnionPayload ,
196202 timer_ticks : u8 ,
197203 /// The total value received for a payment (sum of all MPP parts if the payment is a MPP).
@@ -2181,7 +2187,7 @@ where
21812187 payment_hash,
21822188 incoming_shared_secret : shared_secret,
21832189 incoming_amt_msat : Some ( amt_msat) ,
2184- outgoing_amt_msat : amt_msat ,
2190+ outgoing_amt_msat : hop_data . amt_to_forward ,
21852191 outgoing_cltv_value : hop_data. outgoing_cltv_value ,
21862192 } )
21872193 }
@@ -3261,7 +3267,7 @@ where
32613267 HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
32623268 prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
32633269 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, ..
32653271 }
32663272 } ) => {
32673273 let ( cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing {
@@ -3283,7 +3289,11 @@ where
32833289 incoming_packet_shared_secret : incoming_shared_secret,
32843290 phantom_shared_secret,
32853291 } ,
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,
32873297 timer_ticks : 0 ,
32883298 total_value_received : None ,
32893299 total_msat : if let Some ( data) = & payment_data { data. total_msat } else { outgoing_amt_msat } ,
@@ -3339,9 +3349,9 @@ where
33393349 continue
33403350 }
33413351 }
3342- let mut total_value = claimable_htlc. value ;
3352+ let mut total_value = claimable_htlc. sender_intended_value ;
33433353 for htlc in htlcs. iter( ) {
3344- total_value += htlc. value ;
3354+ total_value += htlc. sender_intended_value ;
33453355 match & htlc. onion_payload {
33463356 OnionPayload :: Invoice { .. } => {
33473357 if htlc. total_msat != $payment_data. total_msat {
@@ -3354,9 +3364,11 @@ where
33543364 _ => unreachable!( ) ,
33553365 }
33563366 }
3367+ // The condition determining whether an MPP is complete must
3368+ // match exactly the condition used in `timer_tick_occurred`
33573369 if total_value >= msgs:: MAX_VALUE_MSAT {
33583370 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 {
33603372 log_trace!( self . logger, "Failing HTLC with payment_hash {} as payment is already claimable" ,
33613373 log_bytes!( payment_hash. 0 ) ) ;
33623374 fail_htlc!( claimable_htlc, payment_hash) ;
@@ -3431,7 +3443,7 @@ where
34313443 new_events. push ( events:: Event :: PaymentClaimable {
34323444 receiver_node_id : Some ( receiver_node_id) ,
34333445 payment_hash,
3434- amount_msat : outgoing_amt_msat ,
3446+ amount_msat,
34353447 purpose,
34363448 via_channel_id : Some ( prev_channel_id) ,
34373449 via_user_channel_id : Some ( prev_user_channel_id) ,
@@ -3691,7 +3703,9 @@ where
36913703 if let OnionPayload :: Invoice { .. } = htlcs[ 0 ] . onion_payload {
36923704 // Check if we've received all the parts we need for an MPP (the value of the parts adds to total_msat).
36933705 // 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 ) {
36953709 return true ;
36963710 } else if htlcs. into_iter ( ) . any ( |htlc| {
36973711 htlc. timer_ticks += 1 ;
@@ -6813,6 +6827,7 @@ impl Writeable for ClaimableHTLC {
68136827 ( 0 , self . prev_hop, required) ,
68146828 ( 1 , self . total_msat, required) ,
68156829 ( 2 , self . value, required) ,
6830+ ( 3 , self . sender_intended_value, required) ,
68166831 ( 4 , payment_data, option) ,
68176832 ( 5 , self . total_value_received, option) ,
68186833 ( 6 , self . cltv_expiry, required) ,
@@ -6826,6 +6841,7 @@ impl Readable for ClaimableHTLC {
68266841 fn read < R : Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
68276842 let mut prev_hop = crate :: util:: ser:: RequiredWrapper ( None ) ;
68286843 let mut value = 0 ;
6844+ let mut sender_intended_value = None ;
68296845 let mut payment_data: Option < msgs:: FinalOnionHopData > = None ;
68306846 let mut cltv_expiry = 0 ;
68316847 let mut total_value_received = None ;
@@ -6835,6 +6851,7 @@ impl Readable for ClaimableHTLC {
68356851 ( 0 , prev_hop, required) ,
68366852 ( 1 , total_msat, option) ,
68376853 ( 2 , value, required) ,
6854+ ( 3 , sender_intended_value, option) ,
68386855 ( 4 , payment_data, option) ,
68396856 ( 5 , total_value_received, option) ,
68406857 ( 6 , cltv_expiry, required) ,
@@ -6864,6 +6881,7 @@ impl Readable for ClaimableHTLC {
68646881 prev_hop : prev_hop. 0 . unwrap ( ) ,
68656882 timer_ticks : 0 ,
68666883 value,
6884+ sender_intended_value : sender_intended_value. unwrap_or ( value) ,
68676885 total_value_received,
68686886 total_msat : total_msat. unwrap ( ) ,
68696887 onion_payload,
0 commit comments