@@ -2102,9 +2102,10 @@ where L::Target: Logger {
21022102 Some ( fee) => fee,
21032103 None => continue
21042104 } ;
2105+ let path_min = candidate. htlc_minimum_msat ( ) . saturating_add (
2106+ compute_fees_saturating ( candidate. htlc_minimum_msat ( ) , candidate. fees ( ) ) ) ;
21052107 add_entry ! ( first_hop_candidate, our_node_id, intro_node_id, blinded_path_fee,
2106- path_contribution_msat, candidate. htlc_minimum_msat( ) , 0_u64 ,
2107- candidate. cltv_expiry_delta( ) ,
2108+ path_contribution_msat, path_min, 0_u64 , candidate. cltv_expiry_delta( ) ,
21082109 candidate. blinded_path( ) . map_or( 1 , |bp| bp. blinded_hops. len( ) as u8 ) ) ;
21092110 }
21102111 }
@@ -7287,6 +7288,10 @@ mod tests {
72877288
72887289 #[ test]
72897290 fn min_htlc_overpay_violates_max_htlc ( ) {
7291+ do_min_htlc_overpay_violates_max_htlc ( true ) ;
7292+ do_min_htlc_overpay_violates_max_htlc ( false ) ;
7293+ }
7294+ fn do_min_htlc_overpay_violates_max_htlc ( blinded_payee : bool ) {
72907295 // Test that if overpaying to meet a later hop's min_htlc and causes us to violate an earlier
72917296 // hop's max_htlc, we don't consider that candidate hop valid. Previously we would add this hop
72927297 // to `targets` and build an invalid path with it, and subsquently hit a debug panic asserting
@@ -7310,7 +7315,27 @@ mod tests {
73107315
73117316 let base_fee = 1_6778_3453 ;
73127317 let htlc_min = 2_5165_8240 ;
7313- let payment_params = {
7318+ let payment_params = if blinded_payee {
7319+ let blinded_path = BlindedPath {
7320+ introduction_node_id : nodes[ 0 ] ,
7321+ blinding_point : ln_test_utils:: pubkey ( 42 ) ,
7322+ blinded_hops : vec ! [
7323+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) } ,
7324+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) }
7325+ ] ,
7326+ } ;
7327+ let blinded_payinfo = BlindedPayInfo {
7328+ fee_base_msat : base_fee,
7329+ fee_proportional_millionths : 0 ,
7330+ htlc_minimum_msat : htlc_min,
7331+ htlc_maximum_msat : htlc_min * 1000 ,
7332+ cltv_expiry_delta : 0 ,
7333+ features : BlindedHopFeatures :: empty ( ) ,
7334+ } ;
7335+ let bolt12_features: Bolt12InvoiceFeatures = channelmanager:: provided_invoice_features ( & config) . to_context ( ) ;
7336+ PaymentParameters :: blinded ( vec ! [ ( blinded_payinfo, blinded_path) ] )
7337+ . with_bolt12_features ( bolt12_features. clone ( ) ) . unwrap ( )
7338+ } else {
73147339 let route_hint = RouteHint ( vec ! [ RouteHintHop {
73157340 src_node_id: nodes[ 0 ] ,
73167341 short_channel_id: 42 ,
@@ -7341,6 +7366,11 @@ mod tests {
73417366
73427367 #[ test]
73437368 fn previously_used_liquidity_violates_max_htlc ( ) {
7369+ do_previously_used_liquidity_violates_max_htlc ( true ) ;
7370+ do_previously_used_liquidity_violates_max_htlc ( false ) ;
7371+
7372+ }
7373+ fn do_previously_used_liquidity_violates_max_htlc ( blinded_payee : bool ) {
73447374 // Test that if a candidate first_hop<>route_hint_src_node channel does not have enough
73457375 // contribution amount to cover the next hop's min_htlc plus fees, we will not consider that
73467376 // candidate. In this case, the candidate does not have enough due to a previous path taking up
@@ -7365,7 +7395,30 @@ mod tests {
73657395
73667396 let base_fees = [ 0 , 425_9840 , 0 , 0 ] ;
73677397 let htlc_mins = [ 1_4392 , 19_7401 , 1027 , 6_5535 ] ;
7368- let payment_params = {
7398+ let payment_params = if blinded_payee {
7399+ let blinded_path = BlindedPath {
7400+ introduction_node_id : nodes[ 0 ] ,
7401+ blinding_point : ln_test_utils:: pubkey ( 42 ) ,
7402+ blinded_hops : vec ! [
7403+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) } ,
7404+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 42 as u8 ) , encrypted_payload: Vec :: new( ) }
7405+ ] ,
7406+ } ;
7407+ let mut blinded_hints = Vec :: new ( ) ;
7408+ for ( base_fee, htlc_min) in base_fees. iter ( ) . zip ( htlc_mins. iter ( ) ) {
7409+ blinded_hints. push ( ( BlindedPayInfo {
7410+ fee_base_msat : * base_fee,
7411+ fee_proportional_millionths : 0 ,
7412+ htlc_minimum_msat : * htlc_min,
7413+ htlc_maximum_msat : htlc_min * 100 ,
7414+ cltv_expiry_delta : 10 ,
7415+ features : BlindedHopFeatures :: empty ( ) ,
7416+ } , blinded_path. clone ( ) ) ) ;
7417+ }
7418+ let bolt12_features: Bolt12InvoiceFeatures = channelmanager:: provided_invoice_features ( & config) . to_context ( ) ;
7419+ PaymentParameters :: blinded ( blinded_hints. clone ( ) )
7420+ . with_bolt12_features ( bolt12_features. clone ( ) ) . unwrap ( )
7421+ } else {
73697422 let mut route_hints = Vec :: new ( ) ;
73707423 for ( idx, ( base_fee, htlc_min) ) in base_fees. iter ( ) . zip ( htlc_mins. iter ( ) ) . enumerate ( ) {
73717424 route_hints. push ( RouteHint ( vec ! [ RouteHintHop {
0 commit comments