@@ -1453,6 +1453,20 @@ impl<'a> CandidateRouteHop<'a> {
1453
1453
CandidateRouteHop :: OneHopBlinded ( _) => None ,
1454
1454
}
1455
1455
}
1456
+ /// Whether this candidate is an unblinded forwarding hop along the path, i.e. not the final
1457
+ /// hop or part of a blinded path.
1458
+ pub fn is_intermediate_hop ( & self , payer_node_id : & NodeId , payee_node_id_opt : & Option < NodeId > ) -> bool {
1459
+ match self {
1460
+ // Never count first hops because we can end up with a path of FirstHopCandidate ->
1461
+ // BlindedPathCandidate, in which case there are 0 intermediate hops.
1462
+ CandidateRouteHop :: FirstHop ( _) => false ,
1463
+ CandidateRouteHop :: PublicHop ( _) =>
1464
+ & self . source ( ) != payer_node_id || & self . target ( ) != payee_node_id_opt,
1465
+ CandidateRouteHop :: PrivateHop ( _) => & self . target ( ) != payee_node_id_opt,
1466
+ CandidateRouteHop :: Blinded ( _) => false ,
1467
+ CandidateRouteHop :: OneHopBlinded ( _) => false ,
1468
+ }
1469
+ }
1456
1470
}
1457
1471
1458
1472
/// A unique(ish) identifier for a specific [`CandidateRouteHop`].
@@ -1860,6 +1874,7 @@ pub(crate) fn get_route<L: Deref, S: ScoreLookUp>(
1860
1874
where L :: Target : Logger {
1861
1875
1862
1876
let payment_params = & route_params. payment_params ;
1877
+ let max_intermediate_hops = core:: cmp:: min ( payment_params. max_intermediate_hops , MAX_PATH_LENGTH_ESTIMATE ) ;
1863
1878
let final_value_msat = route_params. final_value_msat ;
1864
1879
// If we're routing to a blinded recipient, we won't have their node id. Therefore, keep the
1865
1880
// unblinded payee id as an option. We also need a non-optional "payee id" for path construction,
@@ -2155,8 +2170,10 @@ where L::Target: Logger {
2155
2170
// Verify the liquidity offered by this channel complies to the minimal contribution.
2156
2171
let contributes_sufficient_value = available_value_contribution_msat >= minimal_value_contribution_msat;
2157
2172
// 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 ;
2173
+ let intermediate_path_length_to_node = $next_hops_path_length
2174
+ + if $candidate. is_intermediate_hop( & our_node_id, & payee_node_id_opt) { 1 } else { 0 } ;
2175
+
2176
+ let exceeds_max_path_length = intermediate_path_length_to_node > max_intermediate_hops;
2160
2177
2161
2178
// Do not consider candidates that exceed the maximum total cltv expiry limit.
2162
2179
// In order to already account for some of the privacy enhancing random CLTV
@@ -2367,7 +2384,7 @@ where L::Target: Logger {
2367
2384
score: cmp:: max( total_fee_msat, path_htlc_minimum_msat) . saturating_add( path_penalty_msat) ,
2368
2385
total_cltv_delta: hop_total_cltv_delta,
2369
2386
value_contribution_msat,
2370
- path_length_to_node,
2387
+ path_length_to_node: intermediate_path_length_to_node ,
2371
2388
} ;
2372
2389
targets. push( new_graph_node) ;
2373
2390
old_entry. next_hops_fee_msat = $next_hops_fee_msat;
@@ -2610,9 +2627,8 @@ where L::Target: Logger {
2610
2627
} ;
2611
2628
let path_min = candidate. htlc_minimum_msat ( ) . saturating_add (
2612
2629
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 ) ) ;
2630
+ add_entry ! ( & first_hop_candidate, blinded_path_fee, path_contribution_msat, path_min,
2631
+ 0_u64 , candidate. cltv_expiry_delta( ) , 0 ) ;
2616
2632
}
2617
2633
}
2618
2634
}
0 commit comments