Skip to content

Commit 8e3660a

Browse files
authored
Merge pull request #4697 from valentinewallace/2026-06-blinded-fwd-underflow
Fix underflow in blinded path amt_to_forward
2 parents bfaedff + e560ec1 commit 8e3660a

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

lightning/src/blinded_path/payment.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ pub(crate) fn amt_to_forward_msat(
940940
(post_base_fee_inbound_amt * 1_000_000 + 1_000_000 + prop - 1) / (prop + 1_000_000);
941941

942942
let fee = ((amt_to_forward * prop) / 1_000_000) + base;
943-
if inbound_amt - fee < amt_to_forward {
943+
if inbound_amt.checked_sub(fee)? < amt_to_forward {
944944
// Rounding up the forwarded amount resulted in underpaying this node, so take an extra 1 msat
945945
// in fee to compensate.
946946
amt_to_forward -= 1;
@@ -1415,4 +1415,19 @@ mod tests {
14151415
.unwrap();
14161416
assert_eq!(blinded_payinfo.htlc_maximum_msat, 3997);
14171417
}
1418+
1419+
#[test]
1420+
fn amt_to_forward_msat_underflow() {
1421+
// `amt_to_forward_msat` is documented to return `None` if underflow occurs, but the
1422+
// `inbound_amt - fee` subtraction was previously unguarded. With a high proportional fee
1423+
// and a small inbound amount, rounding the forwarded amount up leaves `fee` larger than
1424+
// `inbound_amt`, so the subtraction underflows (panicking in debug builds and returning a
1425+
// nonsensical result in release). Ensure we instead return `None`.
1426+
let payment_relay = PaymentRelay {
1427+
cltv_expiry_delta: 0,
1428+
fee_proportional_millionths: u32::MAX,
1429+
fee_base_msat: 1,
1430+
};
1431+
assert!(super::amt_to_forward_msat(2, &payment_relay).is_none());
1432+
}
14181433
}

0 commit comments

Comments
 (0)