@@ -1622,9 +1622,13 @@ where L::Target: Logger {
1622
1622
|info| info. features . supports_basic_mpp ( ) ) )
1623
1623
} else { false } ;
1624
1624
1625
- log_trace ! ( logger, "Searching for a route from payer {} to {} {} MPP and {} first hops {}overriding the network graph" , our_node_pubkey,
1626
- LoggedPayeePubkey ( payment_params. payee. node_id( ) ) , if allow_mpp { "with" } else { "without" } ,
1627
- first_hops. map( |hops| hops. len( ) ) . unwrap_or( 0 ) , if first_hops. is_some( ) { "" } else { "not " } ) ;
1625
+ let max_total_routing_fee_msat = route_params. max_total_routing_fee_msat . unwrap_or ( u64:: max_value ( ) ) ;
1626
+
1627
+ log_trace ! ( logger, "Searching for a route from payer {} to {} {} MPP and {} first hops {}overriding the network graph with a fee limit of {} msat" ,
1628
+ our_node_pubkey, LoggedPayeePubkey ( payment_params. payee. node_id( ) ) ,
1629
+ if allow_mpp { "with" } else { "without" } ,
1630
+ first_hops. map( |hops| hops. len( ) ) . unwrap_or( 0 ) , if first_hops. is_some( ) { "" } else { "not " } ,
1631
+ max_total_routing_fee_msat) ;
1628
1632
1629
1633
// Step (1).
1630
1634
// Prepare the data we'll use for payee-to-payer search by
@@ -1788,9 +1792,9 @@ where L::Target: Logger {
1788
1792
#[ allow( unused_comparisons) ] // $next_hops_path_htlc_minimum_msat is 0 in some calls so rustc complains
1789
1793
let may_overpay_to_meet_path_minimum_msat =
1790
1794
( ( amount_to_transfer_over_msat < $candidate. htlc_minimum_msat( ) &&
1791
- recommended_value_msat > $candidate. htlc_minimum_msat( ) ) ||
1795
+ recommended_value_msat >= $candidate. htlc_minimum_msat( ) ) ||
1792
1796
( amount_to_transfer_over_msat < $next_hops_path_htlc_minimum_msat &&
1793
- recommended_value_msat > $next_hops_path_htlc_minimum_msat) ) ;
1797
+ recommended_value_msat >= $next_hops_path_htlc_minimum_msat) ) ;
1794
1798
1795
1799
let payment_failed_on_this_channel = scid_opt. map_or( false ,
1796
1800
|scid| payment_params. previously_failed_channels. contains( & scid) ) ;
@@ -1890,7 +1894,6 @@ where L::Target: Logger {
1890
1894
}
1891
1895
1892
1896
// Ignore hops if augmenting the current path to them would put us over `max_total_routing_fee_msat`
1893
- let max_total_routing_fee_msat = route_params. max_total_routing_fee_msat. unwrap_or( u64 :: max_value( ) ) ;
1894
1897
if total_fee_msat > max_total_routing_fee_msat {
1895
1898
if should_log_candidate {
1896
1899
log_trace!( logger, "Ignoring {} due to exceeding max total routing fee limit." , LoggedCandidateHop ( & $candidate) ) ;
@@ -2454,6 +2457,9 @@ where L::Target: Logger {
2454
2457
// because we deterministically terminated the search due to low liquidity.
2455
2458
if !found_new_path && channel_saturation_pow_half != 0 {
2456
2459
channel_saturation_pow_half = 0 ;
2460
+ } else if !found_new_path && hit_minimum_limit && already_collected_value_msat < final_value_msat && path_value_msat != recommended_value_msat {
2461
+ log_trace ! ( logger, "Failed to collect enough value, but running again to collect extra paths with a potentially higher limit." ) ;
2462
+ path_value_msat = recommended_value_msat;
2457
2463
} else if already_collected_value_msat >= recommended_value_msat || !found_new_path {
2458
2464
log_trace ! ( logger, "Have now collected {} msat (seeking {} msat) in paths. Last path loop {} a new path." ,
2459
2465
already_collected_value_msat, recommended_value_msat, if found_new_path { "found" } else { "did not find" } ) ;
@@ -2625,21 +2631,22 @@ where L::Target: Logger {
2625
2631
// Make sure we would never create a route with more paths than we allow.
2626
2632
debug_assert ! ( paths. len( ) <= payment_params. max_path_count. into( ) ) ;
2627
2633
2628
- // Make sure we would never create a route whose total fees exceed max_total_routing_fee_msat.
2629
- if let Some ( max_total_routing_fee_msat) = route_params. max_total_routing_fee_msat {
2630
- if paths. iter ( ) . map ( |p| p. fee_msat ( ) ) . sum :: < u64 > ( ) > max_total_routing_fee_msat {
2631
- return Err ( LightningError { err : format ! ( "Failed to find route that adheres to the maximum total fee limit of {}msat" ,
2632
- max_total_routing_fee_msat) , action : ErrorAction :: IgnoreError } ) ;
2633
- }
2634
- }
2635
-
2636
2634
if let Some ( node_features) = payment_params. payee . node_features ( ) {
2637
2635
for path in paths. iter_mut ( ) {
2638
2636
path. hops . last_mut ( ) . unwrap ( ) . node_features = node_features. clone ( ) ;
2639
2637
}
2640
2638
}
2641
2639
2642
2640
let route = Route { paths, route_params : Some ( route_params. clone ( ) ) } ;
2641
+
2642
+ // Make sure we would never create a route whose total fees exceed max_total_routing_fee_msat.
2643
+ if let Some ( max_total_routing_fee_msat) = route_params. max_total_routing_fee_msat {
2644
+ if route. get_total_fees ( ) > max_total_routing_fee_msat {
2645
+ return Err ( LightningError { err : format ! ( "Failed to find route that adheres to the maximum total fee limit of {}msat" ,
2646
+ max_total_routing_fee_msat) , action : ErrorAction :: IgnoreError } ) ;
2647
+ }
2648
+ }
2649
+
2643
2650
log_info ! ( logger, "Got route: {}" , log_route!( route) ) ;
2644
2651
Ok ( route)
2645
2652
}
@@ -3223,6 +3230,67 @@ mod tests {
3223
3230
assert_eq ! ( fees, 5_000 ) ;
3224
3231
}
3225
3232
3233
+ #[ test]
3234
+ fn htlc_minimum_recipient_overpay_test ( ) {
3235
+ let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph ( ) ;
3236
+ let ( _, our_id, privkeys, nodes) = get_nodes ( & secp_ctx) ;
3237
+ let config = UserConfig :: default ( ) ;
3238
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 2 ] , 42 ) . with_bolt11_features ( channelmanager:: provided_invoice_features ( & config) ) . unwrap ( ) ;
3239
+ let scorer = ln_test_utils:: TestScorer :: new ( ) ;
3240
+ let keys_manager = ln_test_utils:: TestKeysInterface :: new ( & [ 0u8 ; 32 ] , Network :: Testnet ) ;
3241
+ let random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ;
3242
+
3243
+ // Route to node2 over a single path which requires overpaying the recipient themselves.
3244
+
3245
+ // First disable all paths except the us -> node1 -> node2 path
3246
+ update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
3247
+ chain_hash : genesis_block ( Network :: Testnet ) . header . block_hash ( ) ,
3248
+ short_channel_id : 13 ,
3249
+ timestamp : 2 ,
3250
+ flags : 3 ,
3251
+ cltv_expiry_delta : 0 ,
3252
+ htlc_minimum_msat : 0 ,
3253
+ htlc_maximum_msat : 0 ,
3254
+ fee_base_msat : 0 ,
3255
+ fee_proportional_millionths : 0 ,
3256
+ excess_data : Vec :: new ( )
3257
+ } ) ;
3258
+
3259
+ // Set channel 4 to free but with a high htlc_minimum_msat
3260
+ update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , UnsignedChannelUpdate {
3261
+ chain_hash : genesis_block ( Network :: Testnet ) . header . block_hash ( ) ,
3262
+ short_channel_id : 4 ,
3263
+ timestamp : 2 ,
3264
+ flags : 0 ,
3265
+ cltv_expiry_delta : 0 ,
3266
+ htlc_minimum_msat : 15_000 ,
3267
+ htlc_maximum_msat : MAX_VALUE_MSAT ,
3268
+ fee_base_msat : 0 ,
3269
+ fee_proportional_millionths : 0 ,
3270
+ excess_data : Vec :: new ( )
3271
+ } ) ;
3272
+
3273
+ // Now check that we'll fail to find a path if we fail to find a path if the htlc_minimum
3274
+ // is overrun. Note that the fees are actually calculated on 3*payment amount as that's
3275
+ // what we try to find a route for, so this test only just happens to work out to exactly
3276
+ // the fee limit.
3277
+ let mut route_params = RouteParameters :: from_payment_params_and_value (
3278
+ payment_params. clone ( ) , 5_000 ) ;
3279
+ route_params. max_total_routing_fee_msat = Some ( 9_999 ) ;
3280
+ if let Err ( LightningError { err, action : ErrorAction :: IgnoreError } ) = get_route ( & our_id,
3281
+ & route_params, & network_graph. read_only ( ) , None , Arc :: clone ( & logger) , & scorer,
3282
+ & Default :: default ( ) , & random_seed_bytes) {
3283
+ assert_eq ! ( err, "Failed to find route that adheres to the maximum total fee limit of 9999msat" ) ;
3284
+ } else { panic ! ( ) ; }
3285
+
3286
+ let mut route_params = RouteParameters :: from_payment_params_and_value (
3287
+ payment_params. clone ( ) , 5_000 ) ;
3288
+ route_params. max_total_routing_fee_msat = Some ( 10_000 ) ;
3289
+ let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
3290
+ Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
3291
+ assert_eq ! ( route. get_total_fees( ) , 10_000 ) ;
3292
+ }
3293
+
3226
3294
#[ test]
3227
3295
fn disable_channels_test ( ) {
3228
3296
let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph ( ) ;
0 commit comments