Skip to content

Commit 04aa0e8

Browse files
Abide by max path length param in router.
Also adds some testing by augmenting existing tests.
1 parent a590bad commit 04aa0e8

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
@@ -1420,6 +1420,12 @@ impl<'a> CandidateRouteHop<'a> {
14201420
_ => None,
14211421
}
14221422
}
1423+
fn is_one_hop_blinded_path(&self) -> bool {
1424+
match self {
1425+
Self::OneHopBlinded(_) => true,
1426+
_ => false,
1427+
}
1428+
}
14231429
/// Returns the source node id of current hop.
14241430
///
14251431
/// Source node id refers to the node forwarding the HTLC through this hop.
@@ -1861,6 +1867,7 @@ pub(crate) fn get_route<L: Deref, S: ScoreLookUp>(
18611867
where L::Target: Logger {
18621868

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

21622170
// Do not consider candidates that exceed the maximum total cltv expiry limit.
21632171
// In order to already account for some of the privacy enhancing random CLTV
@@ -2611,9 +2619,9 @@ where L::Target: Logger {
26112619
};
26122620
let path_min = candidate.htlc_minimum_msat().saturating_add(
26132621
compute_fees_saturating(candidate.htlc_minimum_msat(), candidate.fees()));
2614-
add_entry!(&first_hop_candidate, blinded_path_fee,
2615-
path_contribution_msat, path_min, 0_u64, candidate.cltv_expiry_delta(),
2616-
candidate.blinded_path().map_or(1, |bp| bp.blinded_hops.len() as u8));
2622+
add_entry!(&first_hop_candidate, blinded_path_fee, path_contribution_msat, path_min,
2623+
0_u64, candidate.cltv_expiry_delta(),
2624+
candidate.blinded_path().map_or(0, |path| path.blinded_hops.len().saturating_sub(1)) as u8);
26172625
}
26182626
}
26192627
}
@@ -3373,7 +3381,7 @@ mod tests {
33733381
fn simple_route_test() {
33743382
let (secp_ctx, network_graph, _, _, logger) = build_graph();
33753383
let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
3376-
let payment_params = PaymentParameters::from_node_id(nodes[2], 42);
3384+
let mut payment_params = PaymentParameters::from_node_id(nodes[2], 42);
33773385
let scorer = ln_test_utils::TestScorer::new();
33783386
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
33793387
let random_seed_bytes = keys_manager.get_secure_random_bytes();
@@ -3388,7 +3396,8 @@ mod tests {
33883396
assert_eq!(err, "Cannot send a payment of 0 msat");
33893397
} else { panic!(); }
33903398

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

34113424
#[test]
@@ -3810,7 +3823,7 @@ mod tests {
38103823
});
38113824

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

4069-
let payment_params = PaymentParameters::from_node_id(nodes[6], 42)
4083+
let mut payment_params = PaymentParameters::from_node_id(nodes[6], 42)
40704084
.with_route_hints(last_hops_multi_private_channels(&nodes)).unwrap();
4085+
payment_params.max_path_length = 5;
40714086
let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100);
40724087
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
40734088
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
@@ -4225,7 +4240,8 @@ mod tests {
42254240
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
42264241
let random_seed_bytes = keys_manager.get_secure_random_bytes();
42274242
// Test through channels 2, 3, 0xff00, 0xff01.
4228-
// Test shows that multiple hop hints are considered.
4243+
// Test shows that multi-hop route hints are considered and factored correctly into the
4244+
// max path length.
42294245

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

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

42904310
#[test]

0 commit comments

Comments
 (0)