@@ -2053,22 +2053,28 @@ fn accept_underpaying_htlcs_config() {
2053
2053
fn do_accept_underpaying_htlcs_config ( num_mpp_parts : usize ) {
2054
2054
let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
2055
2055
let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
2056
+ let max_in_flight_percent = 10 ;
2056
2057
let mut intercept_forwards_config = test_default_channel_config ( ) ;
2057
2058
intercept_forwards_config. accept_intercept_htlcs = true ;
2059
+ intercept_forwards_config. channel_handshake_config . max_inbound_htlc_value_in_flight_percent_of_channel = max_in_flight_percent;
2058
2060
let mut underpay_config = test_default_channel_config ( ) ;
2059
2061
underpay_config. channel_config . accept_underpaying_htlcs = true ;
2062
+ underpay_config. channel_handshake_config . max_inbound_htlc_value_in_flight_percent_of_channel = max_in_flight_percent;
2060
2063
let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , Some ( intercept_forwards_config) , Some ( underpay_config) ] ) ;
2061
2064
let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
2062
2065
2066
+ let amt_msat = 900_000 ;
2067
+
2063
2068
let mut chan_ids = Vec :: new ( ) ;
2064
2069
for _ in 0 ..num_mpp_parts {
2065
- let _ = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000 , 0 ) ;
2066
- let channel_id = create_unannounced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 2_000_000 , 0 ) . 0 . channel_id ;
2070
+ // We choose the channel size so that there can be at most one part pending on each channel.
2071
+ let channel_size = amt_msat / 1000 / num_mpp_parts as u64 * 100 / max_in_flight_percent as u64 + 100 ;
2072
+ let _ = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , channel_size, 0 ) ;
2073
+ let channel_id = create_unannounced_chan_between_nodes_with_value ( & nodes, 1 , 2 , channel_size, 0 ) . 0 . channel_id ;
2067
2074
chan_ids. push ( channel_id) ;
2068
2075
}
2069
2076
2070
2077
// Send the initial payment.
2071
- let amt_msat = 900_000 ;
2072
2078
let skimmed_fee_msat = 20 ;
2073
2079
let mut route_hints = Vec :: new ( ) ;
2074
2080
for _ in 0 ..num_mpp_parts {
@@ -4098,7 +4104,7 @@ fn do_test_payment_metadata_consistency(do_reload: bool, do_modify: bool) {
4098
4104
4099
4105
// Create a new channel between C and D as A will refuse to retry on the existing one because
4100
4106
// it just failed.
4101
- let chan_id_cd_2 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) . 2 ;
4107
+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) ;
4102
4108
4103
4109
// Now retry the failed HTLC.
4104
4110
nodes[ 0 ] . node . process_pending_htlc_forwards ( ) ;
@@ -4110,6 +4116,7 @@ fn do_test_payment_metadata_consistency(do_reload: bool, do_modify: bool) {
4110
4116
expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
4111
4117
check_added_monitors ( & nodes[ 2 ] , 1 ) ;
4112
4118
let cs_forward = SendEvent :: from_node ( & nodes[ 2 ] ) ;
4119
+ let cd_channel_used = cs_forward. msgs [ 0 ] . channel_id ;
4113
4120
nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & cs_forward. msgs [ 0 ] ) ;
4114
4121
commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 2 ] , cs_forward. commitment_msg, false , true ) ;
4115
4122
@@ -4129,7 +4136,7 @@ fn do_test_payment_metadata_consistency(do_reload: bool, do_modify: bool) {
4129
4136
nodes[ 2 ] . node . handle_update_fail_htlc ( & nodes[ 3 ] . node . get_our_node_id ( ) , & ds_fail. update_fail_htlcs [ 0 ] ) ;
4130
4137
commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 3 ] , ds_fail. commitment_signed, false , true ) ;
4131
4138
expect_pending_htlcs_forwardable_conditions ( nodes[ 2 ] . node . get_and_clear_pending_events ( ) ,
4132
- & [ HTLCDestination :: NextHopChannel { node_id : Some ( nodes[ 3 ] . node . get_our_node_id ( ) ) , channel_id : chan_id_cd_2 } ] ) ;
4139
+ & [ HTLCDestination :: NextHopChannel { node_id : Some ( nodes[ 3 ] . node . get_our_node_id ( ) ) , channel_id : cd_channel_used } ] ) ;
4133
4140
} else {
4134
4141
expect_pending_htlcs_forwardable ! ( nodes[ 3 ] ) ;
4135
4142
expect_payment_claimable ! ( nodes[ 3 ] , payment_hash, payment_secret, amt_msat) ;
@@ -4294,3 +4301,94 @@ fn peel_payment_onion_custom_tlvs() {
4294
4301
_ => panic ! ( )
4295
4302
}
4296
4303
}
4304
+
4305
+ #[ test]
4306
+ fn test_non_strict_forwarding ( ) {
4307
+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
4308
+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
4309
+ let mut config = test_default_channel_config ( ) ;
4310
+ config. channel_handshake_config . max_inbound_htlc_value_in_flight_percent_of_channel = 100 ;
4311
+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ Some ( config) , Some ( config) , Some ( config) ] ) ;
4312
+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
4313
+
4314
+ // Create a routing node with two outbound channels, each of which can forward 2 payments of
4315
+ // the given value.
4316
+ let payment_value = 1_500_000 ;
4317
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 100_000 , 0 ) ;
4318
+ let ( chan_update_1, _, channel_id_1, _) = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 4_950 , 0 ) ;
4319
+ let ( chan_update_2, _, channel_id_2, _) = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 5_000 , 0 ) ;
4320
+
4321
+ // Create a route once.
4322
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 2 ] . node . get_our_node_id ( ) , TEST_FINAL_CLTV )
4323
+ . with_bolt11_features ( nodes[ 2 ] . node . bolt11_invoice_features ( ) ) . unwrap ( ) ;
4324
+ let route_params = RouteParameters :: from_payment_params_and_value ( payment_params, payment_value) ;
4325
+ let route = functional_test_utils:: get_route ( & nodes[ 0 ] , & route_params) . unwrap ( ) ;
4326
+
4327
+ // Send 4 payments over the same route.
4328
+ for i in 0 ..4 {
4329
+ let ( payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 2 ] , Some ( payment_value) , None ) ;
4330
+ nodes[ 0 ] . node . send_payment_with_route ( & route, payment_hash,
4331
+ RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
4332
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
4333
+ let mut msg_events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
4334
+ assert_eq ! ( msg_events. len( ) , 1 ) ;
4335
+ let mut send_event = SendEvent :: from_event ( msg_events. remove ( 0 ) ) ;
4336
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & send_event. msgs [ 0 ] ) ;
4337
+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , & send_event. commitment_msg, false ) ;
4338
+
4339
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
4340
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
4341
+ msg_events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
4342
+ assert_eq ! ( msg_events. len( ) , 1 ) ;
4343
+ send_event = SendEvent :: from_event ( msg_events. remove ( 0 ) ) ;
4344
+ // The HTLC will be forwarded over the most appropriate channel with the corresponding peer,
4345
+ // applying non-strict forwarding.
4346
+ // The channel with the least amount of outbound liquidity will be used to maximize the
4347
+ // probability of being able to successfully forward a subsequent HTLC.
4348
+ assert_eq ! ( send_event. msgs[ 0 ] . channel_id, if i < 2 {
4349
+ channel_id_1
4350
+ } else {
4351
+ channel_id_2
4352
+ } ) ;
4353
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & send_event. msgs [ 0 ] ) ;
4354
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 1 ] , & send_event. commitment_msg, false ) ;
4355
+
4356
+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
4357
+ let events = nodes[ 2 ] . node . get_and_clear_pending_events ( ) ;
4358
+ assert_eq ! ( events. len( ) , 1 ) ;
4359
+ assert ! ( matches!( events[ 0 ] , Event :: PaymentClaimable { .. } ) ) ;
4360
+
4361
+ claim_payment_along_route (
4362
+ ClaimAlongRouteArgs :: new ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 2 ] ] ] , payment_preimage)
4363
+ ) ;
4364
+ }
4365
+
4366
+ // Send a 5th payment which will fail.
4367
+ let ( _, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 2 ] , Some ( payment_value) , None ) ;
4368
+ nodes[ 0 ] . node . send_payment_with_route ( & route, payment_hash,
4369
+ RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
4370
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
4371
+ let mut msg_events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
4372
+ assert_eq ! ( msg_events. len( ) , 1 ) ;
4373
+ let mut send_event = SendEvent :: from_event ( msg_events. remove ( 0 ) ) ;
4374
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & send_event. msgs [ 0 ] ) ;
4375
+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , & send_event. commitment_msg, false ) ;
4376
+
4377
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
4378
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
4379
+ let routed_scid = route. paths [ 0 ] . hops [ 1 ] . short_channel_id ;
4380
+ let routed_channel_id = match routed_scid {
4381
+ scid if scid == chan_update_1. contents . short_channel_id => channel_id_1,
4382
+ scid if scid == chan_update_2. contents . short_channel_id => channel_id_2,
4383
+ _ => panic ! ( "Unexpected short channel id in route" ) ,
4384
+ } ;
4385
+ // The failure to forward will refer to the channel given in the onion.
4386
+ expect_pending_htlcs_forwardable_conditions ( nodes[ 1 ] . node . get_and_clear_pending_events ( ) ,
4387
+ & [ HTLCDestination :: NextHopChannel { node_id : Some ( nodes[ 2 ] . node . get_our_node_id ( ) ) , channel_id : routed_channel_id } ] ) ;
4388
+
4389
+ let updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
4390
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & updates. update_fail_htlcs [ 0 ] ) ;
4391
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , updates. commitment_signed, false ) ;
4392
+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
4393
+ expect_payment_failed_conditions_event ( events, payment_hash, false , PaymentFailedConditions :: new ( ) . blamed_scid ( routed_scid) ) ;
4394
+ }
0 commit comments