Skip to content

Commit 7ef91d1

Browse files
authored
Merge pull request #4555 from TheBlueMatt/2026-04-bp-cltv-check
Correct blinded path forwarding CLTV expiry check
2 parents a737eb8 + 8d8313d commit 7ef91d1

2 files changed

Lines changed: 14 additions & 15 deletions

File tree

lightning/src/ln/async_payments_tests.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,8 +1886,9 @@ fn expired_static_invoice_payment_path() {
18861886
}
18871887
};
18881888

1889-
// Mine a bunch of blocks so the hardcoded path's `max_cltv_expiry` is expired at the recipient's
1890-
// end by the time the payment arrives.
1889+
// Mine a bunch of blocks on the sender so the hardcoded path's `max_cltv_expiry` is expired.
1890+
// Note that the path expires "all at once" and will be invalid at the intro point so will be
1891+
// rejected before it reaches the destination.
18911892
let min_cltv_expiry_delta = test_default_channel_config().channel_config.cltv_expiry_delta;
18921893
connect_blocks(
18931894
&nodes[0],
@@ -1902,7 +1903,6 @@ fn expired_static_invoice_payment_path() {
19021903
&nodes[1],
19031904
final_max_cltv_expiry
19041905
- nodes[1].best_block_info().1
1905-
// Don't expire the path for nodes[1]
19061906
- min_cltv_expiry_delta as u32
19071907
- HTLC_FAIL_BACK_BUFFER
19081908
- LATENCY_GRACE_PERIOD_BLOCKS
@@ -1939,18 +1939,17 @@ fn expired_static_invoice_payment_path() {
19391939
let payment_hash = extract_payment_hash(&ev);
19401940
check_added_monitors(&nodes[0], 1);
19411941

1942-
let route: &[&[&Node]] = &[&[&nodes[1], &nodes[2]]];
1943-
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
1944-
.without_claimable_event()
1945-
.expect_failure(HTLCHandlingFailureType::Receive { payment_hash })
1946-
.with_dummy_tlvs(&[DummyTlvs::default(); DEFAULT_PAYMENT_DUMMY_HOPS]);
1947-
do_pass_along_path(args);
1948-
fail_blinded_htlc_backwards(payment_hash, 1, &[&nodes[0], &nodes[1], &nodes[2]], false);
1949-
nodes[2].logger.assert_log_contains(
1950-
"lightning::ln::channelmanager",
1951-
"violated blinded payment constraints",
1952-
1,
1942+
let payment_event = SendEvent::from_event(ev);
1943+
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
1944+
check_added_monitors(&nodes[1], 0);
1945+
do_commitment_signed_dance(&nodes[1], &nodes[0], &payment_event.commitment_msg, false, true);
1946+
expect_and_process_pending_htlcs(&nodes[1], false);
1947+
expect_htlc_handling_failed_destinations!(
1948+
nodes[1].node.get_and_clear_pending_events(),
1949+
&[HTLCHandlingFailureType::InvalidOnion]
19531950
);
1951+
check_added_monitors(&nodes[1], 1);
1952+
fail_blinded_htlc_backwards(payment_hash, 1, &[&nodes[0], &nodes[1]], false);
19541953
}
19551954

19561955
#[cfg_attr(feature = "std", ignore)]

lightning/src/ln/onion_payment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fn check_blinded_forward(
6666
let outgoing_cltv_value = inbound_cltv_expiry.checked_sub(
6767
payment_relay.cltv_expiry_delta as u32
6868
).ok_or(())?;
69-
check_blinded_payment_constraints(inbound_amt_msat, outgoing_cltv_value, payment_constraints)?;
69+
check_blinded_payment_constraints(inbound_amt_msat, inbound_cltv_expiry, payment_constraints)?;
7070

7171
if features.requires_unknown_bits_from(&BlindedHopFeatures::empty()) { return Err(()) }
7272
Ok((amt_to_forward, outgoing_cltv_value))

0 commit comments

Comments
 (0)