Skip to content

Commit 1ab3454

Browse files
committed
Make max_total_cltv_expiry_delta include the final CLTV
This fixes an integer underflow found by the `router` fuzz target in CI.
1 parent c7f88a0 commit 1ab3454

File tree

2 files changed

+9
-5
lines changed

2 files changed

+9
-5
lines changed

lightning/src/ln/functional_tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6493,7 +6493,8 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() {
64936493
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
64946494
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0, InitFeatures::known(), InitFeatures::known());
64956495

6496-
let (route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], vec![], 100000000, 500000001);
6496+
let (mut route, our_payment_hash, _, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], vec![], 100000000, 0);
6497+
route.paths[0].last_mut().unwrap().cltv_expiry_delta = 500000001;
64976498
unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::RouteError { ref err },
64986499
assert_eq!(err, &"Channel CLTV overflowed?"));
64996500
}

lightning/src/routing/router.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,9 @@ where L::Target: Logger {
670670
}
671671
}
672672
}
673+
if payment_params.max_total_cltv_expiry_delta <= final_cltv_expiry_delta {
674+
return Err(LightningError{err: "Can't find a route where the total CLTV expiry delta is below the final CLTV expiry.".to_owned(), action: ErrorAction::IgnoreError});
675+
}
673676

674677
// The general routing idea is the following:
675678
// 1. Fill first/last hops communicated by the caller.
@@ -866,9 +869,9 @@ where L::Target: Logger {
866869
// In order to already account for some of the privacy enhancing random CLTV
867870
// expiry delta offset we add on top later, we subtract a rough estimate
868871
// (2*MEDIAN_HOP_CLTV_EXPIRY_DELTA) here.
869-
let max_total_cltv_expiry_delta = payment_params.max_total_cltv_expiry_delta
872+
let max_total_cltv_expiry_delta = (payment_params.max_total_cltv_expiry_delta - final_cltv_expiry_delta)
870873
.checked_sub(2*MEDIAN_HOP_CLTV_EXPIRY_DELTA)
871-
.unwrap_or(payment_params.max_total_cltv_expiry_delta);
874+
.unwrap_or(payment_params.max_total_cltv_expiry_delta - final_cltv_expiry_delta);
872875
let hop_total_cltv_delta = ($next_hops_cltv_delta as u32)
873876
.checked_add($candidate.cltv_expiry_delta())
874877
.unwrap_or(u32::max_value());
@@ -5091,15 +5094,15 @@ mod tests {
50915094
.with_max_total_cltv_expiry_delta(feasible_max_total_cltv_delta);
50925095
let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
50935096
let random_seed_bytes = keys_manager.get_secure_random_bytes();
5094-
let route = get_route(&our_id, &feasible_payment_params, &network_graph, None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
5097+
let route = get_route(&our_id, &feasible_payment_params, &network_graph, None, 100, 0, Arc::clone(&logger), &scorer, &random_seed_bytes).unwrap();
50955098
let path = route.paths[0].iter().map(|hop| hop.short_channel_id).collect::<Vec<_>>();
50965099
assert_ne!(path.len(), 0);
50975100

50985101
// But not if we exclude all paths on the basis of their accumulated CLTV delta
50995102
let fail_max_total_cltv_delta = 23;
51005103
let fail_payment_params = PaymentParameters::from_node_id(nodes[6]).with_route_hints(last_hops(&nodes))
51015104
.with_max_total_cltv_expiry_delta(fail_max_total_cltv_delta);
5102-
match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, 42, Arc::clone(&logger), &scorer, &random_seed_bytes)
5105+
match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, 0, Arc::clone(&logger), &scorer, &random_seed_bytes)
51035106
{
51045107
Err(LightningError { err, .. } ) => {
51055108
assert_eq!(err, "Failed to find a path to the given destination");

0 commit comments

Comments
 (0)