@@ -2061,9 +2061,19 @@ where L::Target: Logger {
2061
2061
Some ( fee) => fee,
2062
2062
None => continue
2063
2063
} ;
2064
+ let path_min = {
2065
+ let blinded_path_min = candidate. htlc_minimum_msat ( ) ;
2066
+ let path_min_fees = match compute_fees ( blinded_path_min, candidate. fees ( ) ) {
2067
+ Some ( fee) => fee,
2068
+ None => continue
2069
+ } ;
2070
+ match blinded_path_min. checked_add ( path_min_fees) {
2071
+ Some ( min) => min,
2072
+ None => continue
2073
+ }
2074
+ } ;
2064
2075
add_entry ! ( first_hop_candidate, our_node_id, intro_node_id, blinded_path_fee,
2065
- path_contribution_msat, candidate. htlc_minimum_msat( ) , 0_u64 ,
2066
- candidate. cltv_expiry_delta( ) ,
2076
+ path_contribution_msat, path_min, 0_u64 , candidate. cltv_expiry_delta( ) ,
2067
2077
candidate. blinded_path( ) . map_or( 1 , |bp| bp. blinded_hops. len( ) as u8 ) ) ;
2068
2078
}
2069
2079
}
@@ -7190,6 +7200,10 @@ mod tests {
7190
7200
7191
7201
#[ test]
7192
7202
fn min_htlc_overpay_violates_max_htlc ( ) {
7203
+ do_min_htlc_overpay_violates_max_htlc ( true ) ;
7204
+ do_min_htlc_overpay_violates_max_htlc ( false ) ;
7205
+ }
7206
+ fn do_min_htlc_overpay_violates_max_htlc ( blinded_payee : bool ) {
7193
7207
// Test that if overpaying to meet a later hop's min_htlc and causes us to violate an earlier
7194
7208
// hop's max_htlc, we discard that invalid path. Previously we would consider the path to be
7195
7209
// valid and hit a debug panic asserting that the used liquidity for a hop was less than its
@@ -7211,21 +7225,45 @@ mod tests {
7211
7225
first_hop_outbound_capacity
7212
7226
) ] ;
7213
7227
7214
- let route_hint = RouteHint ( vec ! [ RouteHintHop {
7215
- src_node_id: nodes[ 0 ] ,
7216
- short_channel_id: 44 ,
7217
- fees: RoutingFees {
7218
- base_msat: 1_6778_3453 ,
7219
- proportional_millionths: 0 ,
7220
- } ,
7221
- cltv_expiry_delta: 10 ,
7222
- htlc_minimum_msat: Some ( 2_5165_8240 ) ,
7223
- htlc_maximum_msat: None ,
7224
- } ] ) ;
7228
+ let base_fee = 1_6778_3453 ;
7229
+ let htlc_min = 2_5165_8240 ;
7230
+ let payment_params = if blinded_payee {
7231
+ let blinded_path = BlindedPath {
7232
+ introduction_node_id : nodes[ 0 ] ,
7233
+ blinding_point : ln_test_utils:: pubkey ( 42 ) ,
7234
+ blinded_hops : vec ! [
7235
+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) } ,
7236
+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) }
7237
+ ] ,
7238
+ } ;
7239
+ let blinded_payinfo = BlindedPayInfo {
7240
+ fee_base_msat : base_fee,
7241
+ fee_proportional_millionths : 0 ,
7242
+ htlc_minimum_msat : htlc_min,
7243
+ htlc_maximum_msat : htlc_min * 1000 ,
7244
+ cltv_expiry_delta : 0 ,
7245
+ features : BlindedHopFeatures :: empty ( ) ,
7246
+ } ;
7247
+ let bolt12_features: Bolt12InvoiceFeatures = channelmanager:: provided_invoice_features ( & config) . to_context ( ) ;
7248
+ PaymentParameters :: blinded ( vec ! [ ( blinded_payinfo, blinded_path) ] )
7249
+ . with_bolt12_features ( bolt12_features. clone ( ) ) . unwrap ( )
7250
+ } else {
7251
+ let route_hint = RouteHint ( vec ! [ RouteHintHop {
7252
+ src_node_id: nodes[ 0 ] ,
7253
+ short_channel_id: 44 ,
7254
+ fees: RoutingFees {
7255
+ base_msat: base_fee,
7256
+ proportional_millionths: 0 ,
7257
+ } ,
7258
+ cltv_expiry_delta: 10 ,
7259
+ htlc_minimum_msat: Some ( htlc_min) ,
7260
+ htlc_maximum_msat: None ,
7261
+ } ] ) ;
7225
7262
7226
- let payment_params = PaymentParameters :: from_node_id ( nodes[ 1 ] , 42 )
7227
- . with_route_hints ( vec ! [ route_hint] ) . unwrap ( )
7228
- . with_bolt11_features ( channelmanager:: provided_invoice_features ( & config) ) . unwrap ( ) ;
7263
+ PaymentParameters :: from_node_id ( nodes[ 1 ] , 42 )
7264
+ . with_route_hints ( vec ! [ route_hint] ) . unwrap ( )
7265
+ . with_bolt11_features ( channelmanager:: provided_invoice_features ( & config) ) . unwrap ( )
7266
+ } ;
7229
7267
7230
7268
let netgraph = network_graph. read_only ( ) ;
7231
7269
let route_params = RouteParameters :: from_payment_params_and_value (
@@ -7240,6 +7278,11 @@ mod tests {
7240
7278
7241
7279
#[ test]
7242
7280
fn previously_used_liquidity_violates_max_htlc ( ) {
7281
+ do_previously_used_liquidity_violates_max_htlc ( true ) ;
7282
+ do_previously_used_liquidity_violates_max_htlc ( false ) ;
7283
+
7284
+ }
7285
+ fn do_previously_used_liquidity_violates_max_htlc ( blinded_payee : bool ) {
7243
7286
// Test that if a candidate hop would cause us to violate an upstream hop's available
7244
7287
// contribution amount due to a previously found path, we will not consider that candidate in
7245
7288
// path construction. Previously we would construct an invalid path and hit a debug panic
@@ -7261,51 +7304,50 @@ mod tests {
7261
7304
Some ( 122 ) , nodes[ 0 ] , channelmanager:: provided_init_features( & config) , 179_5000
7262
7305
) ] ;
7263
7306
7264
- let route_hints = vec ! [ RouteHint ( vec![ RouteHintHop {
7265
- src_node_id: nodes[ 0 ] ,
7266
- short_channel_id: 42 ,
7267
- fees: RoutingFees {
7268
- base_msat: 0 ,
7269
- proportional_millionths: 0 ,
7270
- } ,
7271
- cltv_expiry_delta: 10 ,
7272
- htlc_minimum_msat: Some ( 1_4392 ) ,
7273
- htlc_maximum_msat: Some ( 143_9200 ) ,
7274
- } ] ) , RouteHint ( vec![ RouteHintHop {
7275
- src_node_id: nodes[ 0 ] ,
7276
- short_channel_id: 43 ,
7277
- fees: RoutingFees {
7278
- base_msat: 425_9840 ,
7279
- proportional_millionths: 0 ,
7280
- } ,
7281
- cltv_expiry_delta: 10 ,
7282
- htlc_minimum_msat: Some ( 19_7401 ) ,
7283
- htlc_maximum_msat: Some ( 1974_0100 ) ,
7284
- } ] ) , RouteHint ( vec![ RouteHintHop {
7285
- src_node_id: nodes[ 0 ] ,
7286
- short_channel_id: 44 ,
7287
- fees: RoutingFees {
7288
- base_msat: 0 ,
7289
- proportional_millionths: 0 ,
7290
- } ,
7291
- cltv_expiry_delta: 10 ,
7292
- htlc_minimum_msat: Some ( 1027 ) ,
7293
- htlc_maximum_msat: Some ( 10_2700 ) ,
7294
- } ] ) , RouteHint ( vec![ RouteHintHop {
7295
- src_node_id: nodes[ 0 ] ,
7296
- short_channel_id: 45 ,
7297
- fees: RoutingFees {
7298
- base_msat: 0 ,
7299
- proportional_millionths: 0 ,
7300
- } ,
7301
- cltv_expiry_delta: 10 ,
7302
- htlc_minimum_msat: Some ( 6_5535 ) ,
7303
- htlc_maximum_msat: Some ( 655_3500 ) ,
7304
- } ] ) ] ;
7305
-
7306
- let payment_params = PaymentParameters :: from_node_id ( nodes[ 1 ] , 42 )
7307
- . with_route_hints ( route_hints) . unwrap ( )
7308
- . with_bolt11_features ( channelmanager:: provided_invoice_features ( & config) ) . unwrap ( ) ;
7307
+ let base_fees = [ 0 , 425_9840 , 0 , 0 ] ;
7308
+ let htlc_mins = [ 1_4392 , 19_7401 , 1027 , 6_5535 ] ;
7309
+ let payment_params = if blinded_payee {
7310
+ let blinded_path = BlindedPath {
7311
+ introduction_node_id : nodes[ 0 ] ,
7312
+ blinding_point : ln_test_utils:: pubkey ( 42 ) ,
7313
+ blinded_hops : vec ! [
7314
+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) } ,
7315
+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) }
7316
+ ] ,
7317
+ } ;
7318
+ let mut blinded_hints = Vec :: new ( ) ;
7319
+ for ( base_fee, htlc_min) in base_fees. iter ( ) . zip ( htlc_mins. iter ( ) ) {
7320
+ blinded_hints. push ( ( BlindedPayInfo {
7321
+ fee_base_msat : * base_fee,
7322
+ fee_proportional_millionths : 0 ,
7323
+ htlc_minimum_msat : * htlc_min,
7324
+ htlc_maximum_msat : htlc_min * 100 ,
7325
+ cltv_expiry_delta : 10 ,
7326
+ features : BlindedHopFeatures :: empty ( ) ,
7327
+ } , blinded_path. clone ( ) ) ) ;
7328
+ }
7329
+ let bolt12_features: Bolt12InvoiceFeatures = channelmanager:: provided_invoice_features ( & config) . to_context ( ) ;
7330
+ PaymentParameters :: blinded ( blinded_hints. clone ( ) )
7331
+ . with_bolt12_features ( bolt12_features. clone ( ) ) . unwrap ( )
7332
+ } else {
7333
+ let mut route_hints = Vec :: new ( ) ;
7334
+ for ( idx, ( base_fee, htlc_min) ) in base_fees. iter ( ) . zip ( htlc_mins. iter ( ) ) . enumerate ( ) {
7335
+ route_hints. push ( RouteHint ( vec ! [ RouteHintHop {
7336
+ src_node_id: nodes[ 0 ] ,
7337
+ short_channel_id: 42 + idx as u64 ,
7338
+ fees: RoutingFees {
7339
+ base_msat: * base_fee,
7340
+ proportional_millionths: 0 ,
7341
+ } ,
7342
+ cltv_expiry_delta: 10 ,
7343
+ htlc_minimum_msat: Some ( * htlc_min) ,
7344
+ htlc_maximum_msat: Some ( htlc_min * 100 ) ,
7345
+ } ] ) ) ;
7346
+ }
7347
+ PaymentParameters :: from_node_id ( nodes[ 1 ] , 42 )
7348
+ . with_route_hints ( route_hints) . unwrap ( )
7349
+ . with_bolt11_features ( channelmanager:: provided_invoice_features ( & config) ) . unwrap ( )
7350
+ } ;
7309
7351
7310
7352
let netgraph = network_graph. read_only ( ) ;
7311
7353
let route_params = RouteParameters :: from_payment_params_and_value (
0 commit comments