Skip to content

Commit e93cc70

Browse files
Abide by max path length param in router.
Also adds some testing by augmenting existing tests.
1 parent 2ca171a commit e93cc70

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

lightning/src/routing/router.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,12 @@ impl<'a> CandidateRouteHop<'a> {
14191419
_ => None,
14201420
}
14211421
}
1422+
fn is_one_hop_blinded_path(&self) -> bool {
1423+
match self {
1424+
Self::OneHopBlinded(_) => true,
1425+
_ => false,
1426+
}
1427+
}
14221428
/// Returns the source node id of current hop.
14231429
///
14241430
/// Source node id refers to the node forwarding the HTLC through this hop.
@@ -1860,6 +1866,7 @@ pub(crate) fn get_route<L: Deref, S: ScoreLookUp>(
18601866
where L::Target: Logger {
18611867

18621868
let payment_params = &route_params.payment_params;
1869+
let max_path_length = core::cmp::min(payment_params.max_path_length, MAX_PATH_LENGTH_ESTIMATE);
18631870
let final_value_msat = route_params.final_value_msat;
18641871
// If we're routing to a blinded recipient, we won't have their node id. Therefore, keep the
18651872
// unblinded payee id as an option. We also need a non-optional "payee id" for path construction,
@@ -2155,8 +2162,9 @@ where L::Target: Logger {
21552162
// Verify the liquidity offered by this channel complies to the minimal contribution.
21562163
let contributes_sufficient_value = available_value_contribution_msat >= minimal_value_contribution_msat;
21572164
// Do not consider candidate hops that would exceed the maximum path length.
2158-
let path_length_to_node = $next_hops_path_length + 1;
2159-
let exceeds_max_path_length = path_length_to_node > MAX_PATH_LENGTH_ESTIMATE;
2165+
let path_length_to_node = $next_hops_path_length
2166+
+ if $candidate.is_one_hop_blinded_path() { 0 } else { 1 };
2167+
let exceeds_max_path_length = path_length_to_node > max_path_length;
21602168

21612169
// Do not consider candidates that exceed the maximum total cltv expiry limit.
21622170
// In order to already account for some of the privacy enhancing random CLTV
@@ -2610,9 +2618,9 @@ where L::Target: Logger {
26102618
};
26112619
let path_min = candidate.htlc_minimum_msat().saturating_add(
26122620
compute_fees_saturating(candidate.htlc_minimum_msat(), candidate.fees()));
2613-
add_entry!(&first_hop_candidate, blinded_path_fee,
2614-
path_contribution_msat, path_min, 0_u64, candidate.cltv_expiry_delta(),
2615-
candidate.blinded_path().map_or(1, |bp| bp.blinded_hops.len() as u8));
2621+
add_entry!(&first_hop_candidate, blinded_path_fee, path_contribution_msat, path_min,
2622+
0_u64, candidate.cltv_expiry_delta(),
2623+
candidate.blinded_path().map_or(0, |path| path.blinded_hops.len().saturating_sub(1)) as u8);
26162624
}
26172625
}
26182626
}
@@ -3372,7 +3380,7 @@ mod tests {
33723380
fn simple_route_test() {
33733381
let (secp_ctx, network_graph, _, _, logger) = build_graph();
33743382
let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
3375-
let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
3383+
let mut payment_params = PaymentParameters::from_node_id(nodes[2], 42);
33763384
let scorer = ln_test_utils::TestScorer::new();
33773385
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
33783386
let random_seed_bytes = keys_manager.get_secure_random_bytes();
@@ -3387,7 +3395,8 @@ mod tests {
33873395
assert_eq!(err, "Cannot send a payment of 0 msat");
33883396
} else { panic!(); }
33893397

3390-
let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
3398+
payment_params.max_path_length = 2;
3399+
let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
33913400
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
33923401
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
33933402
assert_eq!(route.paths[0].hops.len(), 2);
@@ -3405,6 +3414,10 @@ mod tests {
34053414
assert_eq!(route.paths[0].hops[1].cltv_expiry_delta, 42);
34063415
assert_eq!(route.paths[0].hops[1].node_features.le_flags(), &id_to_feature_flags(3));
34073416
assert_eq!(route.paths[0].hops[1].channel_features.le_flags(), &id_to_feature_flags(4));
3417+
3418+
route_params.payment_params.max_path_length = 1;
3419+
get_route(&our_id, &route_params, &network_graph.read_only(), None,
3420+
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap_err();
34083421
}
34093422

34103423
#[test]
@@ -3809,7 +3822,7 @@ mod tests {
38093822
});
38103823

38113824
// If all the channels require some features we don't understand, route should fail
3812-
let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
3825+
let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
38133826
if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id,
38143827
&route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer,
38153828
&Default::default(), &random_seed_bytes) {
@@ -3819,6 +3832,7 @@ mod tests {
38193832
// If we specify a channel to node7, that overrides our local channel view and that gets used
38203833
let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(),
38213834
InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)];
3835+
route_params.payment_params.max_path_length = 2;
38223836
let route = get_route(&our_id, &route_params, &network_graph.read_only(),
38233837
Some(&our_chans.iter().collect::<Vec<_>>()), Arc::clone(&logger), &scorer,
38243838
&Default::default(), &random_seed_bytes).unwrap();
@@ -4065,8 +4079,9 @@ mod tests {
40654079
} else { panic!(); }
40664080
}
40674081

4068-
let payment_params = PaymentParameters::from_node_id(nodes[6], 42)
4082+
let mut payment_params = PaymentParameters::from_node_id(nodes[6], 42)
40694083
.with_route_hints(last_hops_multi_private_channels(&nodes)).unwrap();
4084+
payment_params.max_path_length = 5;
40704085
let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
40714086
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
40724087
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
@@ -4224,7 +4239,8 @@ mod tests {
42244239
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
42254240
let random_seed_bytes = keys_manager.get_secure_random_bytes();
42264241
// Test through channels 2, 3, 0xff00, 0xff01.
4227-
// Test shows that multiple hop hints are considered.
4242+
// Test shows that multi-hop route hints are considered and factored correctly into the
4243+
// max path length.
42284244

42294245
// Disabling channels 6 & 7 by flags=2
42304246
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
@@ -4252,7 +4268,8 @@ mod tests {
42524268
excess_data: Vec::new()
42534269
});
42544270

4255-
let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
4271+
let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
4272+
route_params.payment_params.max_path_length = 4;
42564273
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
42574274
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
42584275
assert_eq!(route.paths[0].hops.len(), 4);
@@ -4284,6 +4301,9 @@ mod tests {
42844301
assert_eq!(route.paths[0].hops[3].cltv_expiry_delta, 42);
42854302
assert_eq!(route.paths[0].hops[3].node_features.le_flags(), default_node_features().le_flags()); // We dont pass flags in from invoices yet
42864303
assert_eq!(route.paths[0].hops[3].channel_features.le_flags(), &Vec::<u8>::new()); // We can't learn any flags from invoices, sadly
4304+
route_params.payment_params.max_path_length = 3;
4305+
get_route(&our_id, &route_params, &network_graph.read_only(), None,
4306+
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap_err();
42874307
}
42884308

42894309
#[test]

0 commit comments

Comments
 (0)