@@ -1860,6 +1860,7 @@ pub(crate) fn get_route<L: Deref, S: ScoreLookUp>(
1860
1860
where L :: Target : Logger {
1861
1861
1862
1862
let payment_params = & route_params. payment_params ;
1863
+ let max_path_length = core:: cmp:: min ( payment_params. max_path_length , MAX_PATH_LENGTH_ESTIMATE ) ;
1863
1864
let final_value_msat = route_params. final_value_msat ;
1864
1865
// If we're routing to a blinded recipient, we won't have their node id. Therefore, keep the
1865
1866
// unblinded payee id as an option. We also need a non-optional "payee id" for path construction,
@@ -2155,8 +2156,9 @@ where L::Target: Logger {
2155
2156
// Verify the liquidity offered by this channel complies to the minimal contribution.
2156
2157
let contributes_sufficient_value = available_value_contribution_msat >= minimal_value_contribution_msat;
2157
2158
// 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 ;
2159
+ let path_length_to_node = $next_hops_path_length
2160
+ + if $candidate. blinded_hint_idx( ) . is_some( ) { 0 } else { 1 } ;
2161
+ let exceeds_max_path_length = path_length_to_node > max_path_length;
2160
2162
2161
2163
// Do not consider candidates that exceed the maximum total cltv expiry limit.
2162
2164
// In order to already account for some of the privacy enhancing random CLTV
@@ -2610,9 +2612,8 @@ where L::Target: Logger {
2610
2612
} ;
2611
2613
let path_min = candidate. htlc_minimum_msat ( ) . saturating_add (
2612
2614
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 ) ) ;
2615
+ add_entry ! ( & first_hop_candidate, blinded_path_fee, path_contribution_msat, path_min,
2616
+ 0_u64 , candidate. cltv_expiry_delta( ) , 0 ) ;
2616
2617
}
2617
2618
}
2618
2619
}
@@ -3372,7 +3373,7 @@ mod tests {
3372
3373
fn simple_route_test ( ) {
3373
3374
let ( secp_ctx, network_graph, _, _, logger) = build_graph ( ) ;
3374
3375
let ( _, our_id, _, nodes) = get_nodes ( & secp_ctx) ;
3375
- let payment_params = PaymentParameters :: from_node_id ( nodes[ 2 ] , 42 ) ;
3376
+ let mut payment_params = PaymentParameters :: from_node_id ( nodes[ 2 ] , 42 ) ;
3376
3377
let scorer = ln_test_utils:: TestScorer :: new ( ) ;
3377
3378
let keys_manager = ln_test_utils:: TestKeysInterface :: new ( & [ 0u8 ; 32 ] , Network :: Testnet ) ;
3378
3379
let random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ;
@@ -3387,7 +3388,8 @@ mod tests {
3387
3388
assert_eq ! ( err, "Cannot send a payment of 0 msat" ) ;
3388
3389
} else { panic ! ( ) ; }
3389
3390
3390
- let route_params = RouteParameters :: from_payment_params_and_value ( payment_params, 100 ) ;
3391
+ payment_params. max_path_length = 2 ;
3392
+ let mut route_params = RouteParameters :: from_payment_params_and_value ( payment_params, 100 ) ;
3391
3393
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
3392
3394
Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
3393
3395
assert_eq ! ( route. paths[ 0 ] . hops. len( ) , 2 ) ;
@@ -3405,6 +3407,10 @@ mod tests {
3405
3407
assert_eq ! ( route. paths[ 0 ] . hops[ 1 ] . cltv_expiry_delta, 42 ) ;
3406
3408
assert_eq ! ( route. paths[ 0 ] . hops[ 1 ] . node_features. le_flags( ) , & id_to_feature_flags( 3 ) ) ;
3407
3409
assert_eq ! ( route. paths[ 0 ] . hops[ 1 ] . channel_features. le_flags( ) , & id_to_feature_flags( 4 ) ) ;
3410
+
3411
+ route_params. payment_params . max_path_length = 1 ;
3412
+ get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
3413
+ Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap_err ( ) ;
3408
3414
}
3409
3415
3410
3416
#[ test]
@@ -3809,7 +3815,7 @@ mod tests {
3809
3815
} ) ;
3810
3816
3811
3817
// 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 ) ;
3818
+ let mut route_params = RouteParameters :: from_payment_params_and_value ( payment_params, 100 ) ;
3813
3819
if let Err ( LightningError { err, action : ErrorAction :: IgnoreError } ) = get_route ( & our_id,
3814
3820
& route_params, & network_graph. read_only ( ) , None , Arc :: clone ( & logger) , & scorer,
3815
3821
& Default :: default ( ) , & random_seed_bytes) {
@@ -3819,6 +3825,7 @@ mod tests {
3819
3825
// If we specify a channel to node7, that overrides our local channel view and that gets used
3820
3826
let our_chans = vec ! [ get_channel_details( Some ( 42 ) , nodes[ 7 ] . clone( ) ,
3821
3827
InitFeatures :: from_le_bytes( vec![ 0b11 ] ) , 250_000_000 ) ] ;
3828
+ route_params. payment_params . max_path_length = 2 ;
3822
3829
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) ,
3823
3830
Some ( & our_chans. iter ( ) . collect :: < Vec < _ > > ( ) ) , Arc :: clone ( & logger) , & scorer,
3824
3831
& Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
@@ -4065,8 +4072,9 @@ mod tests {
4065
4072
} else { panic ! ( ) ; }
4066
4073
}
4067
4074
4068
- let payment_params = PaymentParameters :: from_node_id ( nodes[ 6 ] , 42 )
4075
+ let mut payment_params = PaymentParameters :: from_node_id ( nodes[ 6 ] , 42 )
4069
4076
. with_route_hints ( last_hops_multi_private_channels ( & nodes) ) . unwrap ( ) ;
4077
+ payment_params. max_path_length = 5 ;
4070
4078
let route_params = RouteParameters :: from_payment_params_and_value ( payment_params, 100 ) ;
4071
4079
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
4072
4080
Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
@@ -4224,7 +4232,8 @@ mod tests {
4224
4232
let keys_manager = ln_test_utils:: TestKeysInterface :: new ( & [ 0u8 ; 32 ] , Network :: Testnet ) ;
4225
4233
let random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ;
4226
4234
// Test through channels 2, 3, 0xff00, 0xff01.
4227
- // Test shows that multiple hop hints are considered.
4235
+ // Test shows that multi-hop route hints are considered and factored correctly into the
4236
+ // max path length.
4228
4237
4229
4238
// Disabling channels 6 & 7 by flags=2
4230
4239
update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
@@ -4252,7 +4261,8 @@ mod tests {
4252
4261
excess_data : Vec :: new ( )
4253
4262
} ) ;
4254
4263
4255
- let route_params = RouteParameters :: from_payment_params_and_value ( payment_params, 100 ) ;
4264
+ let mut route_params = RouteParameters :: from_payment_params_and_value ( payment_params, 100 ) ;
4265
+ route_params. payment_params . max_path_length = 4 ;
4256
4266
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
4257
4267
Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
4258
4268
assert_eq ! ( route. paths[ 0 ] . hops. len( ) , 4 ) ;
@@ -4284,6 +4294,9 @@ mod tests {
4284
4294
assert_eq ! ( route. paths[ 0 ] . hops[ 3 ] . cltv_expiry_delta, 42 ) ;
4285
4295
assert_eq ! ( route. paths[ 0 ] . hops[ 3 ] . node_features. le_flags( ) , default_node_features( ) . le_flags( ) ) ; // We dont pass flags in from invoices yet
4286
4296
assert_eq ! ( route. paths[ 0 ] . hops[ 3 ] . channel_features. le_flags( ) , & Vec :: <u8 >:: new( ) ) ; // We can't learn any flags from invoices, sadly
4297
+ route_params. payment_params . max_path_length = 3 ;
4298
+ get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
4299
+ Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap_err ( ) ;
4287
4300
}
4288
4301
4289
4302
#[ test]
0 commit comments