@@ -1167,3 +1167,105 @@ fn high_prop_fees() {
1167
1167
let expected_fee = pass_claimed_payment_along_route ( args) ;
1168
1168
expect_payment_sent ( & nodes[ 0 ] , payment_preimage, Some ( Some ( expected_fee) ) , true , true ) ;
1169
1169
}
1170
+
1171
+ #[ cfg( feature = "std" ) ]
1172
+ #[ test]
1173
+ fn prop_fees_rng ( ) {
1174
+ do_prop_fees_rng ( true ) ;
1175
+ do_prop_fees_rng ( false ) ;
1176
+ }
1177
+
1178
+ #[ cfg( feature = "std" ) ]
1179
+ fn do_prop_fees_rng ( send_min : bool ) {
1180
+ use std:: hash:: { BuildHasher , Hasher } ;
1181
+ // Ensure the proportional fees are calculated correctly for `BlindedPayInfo`.
1182
+ let chanmon_cfgs = create_chanmon_cfgs ( 5 ) ;
1183
+ const PROP_LIMIT : u64 = 1_000_000 ;
1184
+ let base_limit: u64 = if send_min { 1_000_000 } else { 15_000_000 } ;
1185
+ const MIN_HTLC_LIMIT : u64 = 15_000_000 ;
1186
+ let node_cfgs = create_node_cfgs ( 5 , & chanmon_cfgs) ;
1187
+
1188
+ let mut node_1_cfg = test_default_channel_config ( ) ;
1189
+ node_1_cfg. channel_config . forwarding_fee_base_msat =
1190
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % base_limit) as u32 ;
1191
+ node_1_cfg. channel_config . forwarding_fee_proportional_millionths =
1192
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % PROP_LIMIT ) as u32 ;
1193
+ if send_min {
1194
+ node_1_cfg. channel_handshake_config . our_htlc_minimum_msat =
1195
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % MIN_HTLC_LIMIT ) as u64 ;
1196
+ }
1197
+
1198
+ let mut node_2_cfg = test_default_channel_config ( ) ;
1199
+ node_2_cfg. channel_config . forwarding_fee_base_msat =
1200
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % base_limit) as u32 ;
1201
+ node_2_cfg. channel_config . forwarding_fee_proportional_millionths =
1202
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % PROP_LIMIT ) as u32 ;
1203
+ if send_min {
1204
+ node_2_cfg. channel_handshake_config . our_htlc_minimum_msat =
1205
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % MIN_HTLC_LIMIT ) as u64 ;
1206
+ }
1207
+
1208
+ let mut node_3_cfg = test_default_channel_config ( ) ;
1209
+ node_3_cfg. channel_config . forwarding_fee_base_msat =
1210
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % base_limit) as u32 ;
1211
+ node_3_cfg. channel_config . forwarding_fee_proportional_millionths =
1212
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % PROP_LIMIT ) as u32 ;
1213
+ if send_min {
1214
+ node_3_cfg. channel_handshake_config . our_htlc_minimum_msat =
1215
+ ( std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) % MIN_HTLC_LIMIT ) as u64 ;
1216
+ }
1217
+
1218
+ println ! ( "Randomly selected node parameters:" ) ;
1219
+ for ( idx, node) in [ node_1_cfg, node_2_cfg, node_3_cfg] . iter ( ) . enumerate ( ) {
1220
+ println ! ( " node {}: forwarding_fee_base_msat: {}, forwarding_fee_proportional_millionths: {}, our_htlc_minimum_msat: {}" , idx, node. channel_config. forwarding_fee_base_msat, node. channel_config. forwarding_fee_proportional_millionths, node. channel_handshake_config. our_htlc_minimum_msat) ;
1221
+ }
1222
+
1223
+ let node_chanmgrs = create_node_chanmgrs ( 5 , & node_cfgs, & [ None , Some ( node_1_cfg) , Some ( node_2_cfg) , Some ( node_3_cfg) , None ] ) ;
1224
+ let nodes = create_network ( 5 , & node_cfgs, & node_chanmgrs) ;
1225
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
1226
+ let chan_1_2 = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) ;
1227
+ let chan_2_3 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) ;
1228
+ let chan_3_4 = create_announced_chan_between_nodes_with_value ( & nodes, 3 , 4 , 1_000_000 , 0 ) ;
1229
+
1230
+ let amt_msat = if send_min {
1231
+ get_blinded_route_parameters (
1232
+ 42 , PaymentSecret ( [ 0 ; 32 ] ) , chan_1_2. 1 . contents . htlc_minimum_msat ,
1233
+ chan_1_2. 1 . contents . htlc_maximum_msat ,
1234
+ nodes. iter ( ) . skip ( 1 ) . map ( |node| node. node . get_our_node_id ( ) ) . collect ( ) ,
1235
+ & [ & chan_1_2. 0 . contents , & chan_2_3. 0 . contents , & chan_3_4. 0 . contents ] ,
1236
+ & chanmon_cfgs[ 4 ] . keys_manager
1237
+ )
1238
+ . payment_params . payee . blinded_route_hints ( ) [ 0 ] . 0 . htlc_minimum_msat
1239
+ } else { 100_000 } ;
1240
+ let ( payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 4 ] , Some ( amt_msat) , None ) ;
1241
+
1242
+ let mut route_params = get_blinded_route_parameters ( amt_msat, payment_secret,
1243
+ chan_1_2. 1 . contents . htlc_minimum_msat , chan_1_2. 1 . contents . htlc_maximum_msat ,
1244
+ nodes. iter ( ) . skip ( 1 ) . map ( |node| node. node . get_our_node_id ( ) ) . collect ( ) ,
1245
+ & [ & chan_1_2. 0 . contents , & chan_2_3. 0 . contents , & chan_3_4. 0 . contents ] ,
1246
+ & chanmon_cfgs[ 4 ] . keys_manager ) ;
1247
+ route_params. max_total_routing_fee_msat = None ;
1248
+
1249
+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) , PaymentId ( payment_hash. 0 ) , route_params. clone ( ) , Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
1250
+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
1251
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
1252
+ assert_eq ! ( events. len( ) , 1 ) ;
1253
+ let event = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
1254
+ let expected_path = & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] , & nodes[ 4 ] ] ;
1255
+
1256
+ let args = PassAlongPathArgs :: new ( & nodes[ 0 ] , expected_path, amt_msat, payment_hash, event)
1257
+ . with_payment_secret ( payment_secret)
1258
+ . with_overpay_limit ( if send_min { 40 } else { 3 } ) ;
1259
+ let claimable_ev = do_pass_along_path ( args) ;
1260
+ let claim_amt = if let Some ( crate :: events:: Event :: PaymentClaimable { amount_msat, .. } ) = claimable_ev {
1261
+ amount_msat
1262
+ } else { panic ! ( ) } ;
1263
+ let overpayment_amt = claim_amt. checked_sub ( amt_msat) . unwrap ( ) ;
1264
+
1265
+ nodes[ 4 ] . node . claim_funds ( payment_preimage) ;
1266
+ let expected_route = & [ & expected_path[ ..] ] ;
1267
+ let mut claim_args = ClaimAlongRouteArgs :: new ( & nodes[ 0 ] , & expected_route[ ..] , payment_preimage)
1268
+ . allow_1_msat_fee_overpay ( ) ;
1269
+ let expected_fee = pass_claimed_payment_along_route ( claim_args) ;
1270
+ expect_payment_sent ( & nodes[ 0 ] , payment_preimage, Some ( Some ( expected_fee + overpayment_amt) ) , true , true ) ;
1271
+ }
0 commit comments