@@ -1420,6 +1420,12 @@ impl<'a> CandidateRouteHop<'a> {
1420
1420
_ => None ,
1421
1421
}
1422
1422
}
1423
+ fn is_one_hop_blinded_path ( & self ) -> bool {
1424
+ match self {
1425
+ Self :: OneHopBlinded ( _) => true ,
1426
+ _ => false ,
1427
+ }
1428
+ }
1423
1429
/// Returns the source node id of current hop.
1424
1430
///
1425
1431
/// 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>(
1861
1867
where L :: Target : Logger {
1862
1868
1863
1869
let payment_params = & route_params. payment_params ;
1870
+ let max_path_length = core:: cmp:: min ( payment_params. max_path_length , MAX_PATH_LENGTH_ESTIMATE ) ;
1864
1871
let final_value_msat = route_params. final_value_msat ;
1865
1872
// If we're routing to a blinded recipient, we won't have their node id. Therefore, keep the
1866
1873
// 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 {
2156
2163
// Verify the liquidity offered by this channel complies to the minimal contribution.
2157
2164
let contributes_sufficient_value = available_value_contribution_msat >= minimal_value_contribution_msat;
2158
2165
// 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;
2161
2169
2162
2170
// Do not consider candidates that exceed the maximum total cltv expiry limit.
2163
2171
// In order to already account for some of the privacy enhancing random CLTV
@@ -2611,9 +2619,9 @@ where L::Target: Logger {
2611
2619
} ;
2612
2620
let path_min = candidate. htlc_minimum_msat ( ) . saturating_add (
2613
2621
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 ) ;
2617
2625
}
2618
2626
}
2619
2627
}
@@ -3373,7 +3381,7 @@ mod tests {
3373
3381
fn simple_route_test ( ) {
3374
3382
let ( secp_ctx, network_graph, _, _, logger) = build_graph ( ) ;
3375
3383
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 ) ;
3377
3385
let scorer = ln_test_utils:: TestScorer :: new ( ) ;
3378
3386
let keys_manager = ln_test_utils:: TestKeysInterface :: new ( & [ 0u8 ; 32 ] , Network :: Testnet ) ;
3379
3387
let random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ;
@@ -3388,7 +3396,8 @@ mod tests {
3388
3396
assert_eq ! ( err, "Cannot send a payment of 0 msat" ) ;
3389
3397
} else { panic ! ( ) ; }
3390
3398
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 ) ;
3392
3401
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
3393
3402
Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
3394
3403
assert_eq ! ( route. paths[ 0 ] . hops. len( ) , 2 ) ;
@@ -3406,6 +3415,10 @@ mod tests {
3406
3415
assert_eq ! ( route. paths[ 0 ] . hops[ 1 ] . cltv_expiry_delta, 42 ) ;
3407
3416
assert_eq ! ( route. paths[ 0 ] . hops[ 1 ] . node_features. le_flags( ) , & id_to_feature_flags( 3 ) ) ;
3408
3417
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 ( ) ;
3409
3422
}
3410
3423
3411
3424
#[ test]
@@ -3810,7 +3823,7 @@ mod tests {
3810
3823
} ) ;
3811
3824
3812
3825
// 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 ) ;
3814
3827
if let Err ( LightningError { err, action : ErrorAction :: IgnoreError } ) = get_route ( & our_id,
3815
3828
& route_params, & network_graph. read_only ( ) , None , Arc :: clone ( & logger) , & scorer,
3816
3829
& Default :: default ( ) , & random_seed_bytes) {
@@ -3820,6 +3833,7 @@ mod tests {
3820
3833
// If we specify a channel to node7, that overrides our local channel view and that gets used
3821
3834
let our_chans = vec ! [ get_channel_details( Some ( 42 ) , nodes[ 7 ] . clone( ) ,
3822
3835
InitFeatures :: from_le_bytes( vec![ 0b11 ] ) , 250_000_000 ) ] ;
3836
+ route_params. payment_params . max_path_length = 2 ;
3823
3837
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) ,
3824
3838
Some ( & our_chans. iter ( ) . collect :: < Vec < _ > > ( ) ) , Arc :: clone ( & logger) , & scorer,
3825
3839
& Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
@@ -4066,8 +4080,9 @@ mod tests {
4066
4080
} else { panic ! ( ) ; }
4067
4081
}
4068
4082
4069
- let payment_params = PaymentParameters :: from_node_id ( nodes[ 6 ] , 42 )
4083
+ let mut payment_params = PaymentParameters :: from_node_id ( nodes[ 6 ] , 42 )
4070
4084
. with_route_hints ( last_hops_multi_private_channels ( & nodes) ) . unwrap ( ) ;
4085
+ payment_params. max_path_length = 5 ;
4071
4086
let route_params = RouteParameters :: from_payment_params_and_value ( payment_params, 100 ) ;
4072
4087
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
4073
4088
Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
@@ -4225,7 +4240,8 @@ mod tests {
4225
4240
let keys_manager = ln_test_utils:: TestKeysInterface :: new ( & [ 0u8 ; 32 ] , Network :: Testnet ) ;
4226
4241
let random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ;
4227
4242
// 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.
4229
4245
4230
4246
// Disabling channels 6 & 7 by flags=2
4231
4247
update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
@@ -4253,7 +4269,8 @@ mod tests {
4253
4269
excess_data : Vec :: new ( )
4254
4270
} ) ;
4255
4271
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 ;
4257
4274
let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
4258
4275
Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
4259
4276
assert_eq ! ( route. paths[ 0 ] . hops. len( ) , 4 ) ;
@@ -4285,6 +4302,9 @@ mod tests {
4285
4302
assert_eq ! ( route. paths[ 0 ] . hops[ 3 ] . cltv_expiry_delta, 42 ) ;
4286
4303
assert_eq ! ( route. paths[ 0 ] . hops[ 3 ] . node_features. le_flags( ) , default_node_features( ) . le_flags( ) ) ; // We dont pass flags in from invoices yet
4287
4304
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 ( ) ;
4288
4308
}
4289
4309
4290
4310
#[ test]
0 commit comments