|
10 | 10 | use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
11 | 11 | use crate::blinded_path::BlindedPath;
|
12 | 12 | use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, PaymentConstraints, PaymentRelay, ReceiveTlvs};
|
13 |
| -use crate::events::{HTLCDestination, MessageSendEvent, MessageSendEventsProvider}; |
| 13 | +use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider}; |
14 | 14 | use crate::ln::PaymentSecret;
|
15 | 15 | use crate::ln::channelmanager;
|
16 | 16 | use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
|
@@ -1050,3 +1050,100 @@ fn high_prop_fees() {
|
1050 | 1050 | let expected_fee = pass_claimed_payment_along_route(args);
|
1051 | 1051 | expect_payment_sent(&nodes[0], payment_preimage, Some(Some(expected_fee)), true, true);
|
1052 | 1052 | }
|
| 1053 | + |
| 1054 | +#[cfg(feature = "std")] |
| 1055 | +#[test] |
| 1056 | +fn prop_fees_rng() { |
| 1057 | + do_prop_fees_rng(true); |
| 1058 | + do_prop_fees_rng(false); |
| 1059 | +} |
| 1060 | + |
| 1061 | +#[cfg(feature = "std")] |
| 1062 | +fn do_prop_fees_rng(send_min: bool) { |
| 1063 | + use std::hash::{BuildHasher, Hasher}; |
| 1064 | + // Ensure the proportional fees are calculated correctly for `BlindedPayInfo`. |
| 1065 | + let chanmon_cfgs = create_chanmon_cfgs(5); |
| 1066 | + const PROP_LIMIT: u64 = 1_000_000; |
| 1067 | + let base_limit: u64 = if send_min { 1_000_000 } else { 15_000_000 }; |
| 1068 | + const MIN_HTLC_LIMIT: u64 = 15_000_000; |
| 1069 | + let node_cfgs = create_node_cfgs(5, &chanmon_cfgs); |
| 1070 | + |
| 1071 | + let mut node_1_cfg = test_default_channel_config(); |
| 1072 | + node_1_cfg.channel_config.forwarding_fee_base_msat = |
| 1073 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % base_limit) as u32; |
| 1074 | + node_1_cfg.channel_config.forwarding_fee_proportional_millionths = |
| 1075 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % PROP_LIMIT) as u32; |
| 1076 | + if send_min { |
| 1077 | + node_1_cfg.channel_handshake_config.our_htlc_minimum_msat = |
| 1078 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % MIN_HTLC_LIMIT) as u64; |
| 1079 | + } |
| 1080 | + |
| 1081 | + let mut node_2_cfg = test_default_channel_config(); |
| 1082 | + node_2_cfg.channel_config.forwarding_fee_base_msat = |
| 1083 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % base_limit) as u32; |
| 1084 | + node_2_cfg.channel_config.forwarding_fee_proportional_millionths = |
| 1085 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % PROP_LIMIT) as u32; |
| 1086 | + if send_min { |
| 1087 | + node_2_cfg.channel_handshake_config.our_htlc_minimum_msat = |
| 1088 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % MIN_HTLC_LIMIT) as u64; |
| 1089 | + } |
| 1090 | + |
| 1091 | + let mut node_3_cfg = test_default_channel_config(); |
| 1092 | + node_3_cfg.channel_config.forwarding_fee_base_msat = |
| 1093 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % base_limit) as u32; |
| 1094 | + node_3_cfg.channel_config.forwarding_fee_proportional_millionths = |
| 1095 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % PROP_LIMIT) as u32; |
| 1096 | + if send_min { |
| 1097 | + node_3_cfg.channel_handshake_config.our_htlc_minimum_msat = |
| 1098 | + (std::collections::hash_map::RandomState::new().build_hasher().finish() % MIN_HTLC_LIMIT) as u64; |
| 1099 | + } |
| 1100 | + |
| 1101 | + let node_chanmgrs = create_node_chanmgrs(5, &node_cfgs, &[None, Some(node_1_cfg), Some(node_2_cfg), Some(node_3_cfg), None]); |
| 1102 | + let nodes = create_network(5, &node_cfgs, &node_chanmgrs); |
| 1103 | + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0); |
| 1104 | + let chan_1_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0); |
| 1105 | + let chan_2_3 = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 1_000_000, 0); |
| 1106 | + let chan_3_4 = create_announced_chan_between_nodes_with_value(&nodes, 3, 4, 1_000_000, 0); |
| 1107 | + |
| 1108 | + let amt_msat = if send_min { |
| 1109 | + get_blinded_route_parameters( |
| 1110 | + 42, PaymentSecret([0; 32]), chan_1_2.1.contents.htlc_minimum_msat, |
| 1111 | + chan_1_2.1.contents.htlc_maximum_msat, |
| 1112 | + nodes.iter().skip(1).map(|node| node.node.get_our_node_id()).collect(), |
| 1113 | + &[&chan_1_2.0.contents, &chan_2_3.0.contents, &chan_3_4.0.contents], |
| 1114 | + &chanmon_cfgs[4].keys_manager |
| 1115 | + ) |
| 1116 | + .payment_params.payee.blinded_route_hints()[0].0.htlc_minimum_msat |
| 1117 | + } else { 100_000 }; |
| 1118 | + let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[4], Some(amt_msat), None); |
| 1119 | + |
| 1120 | + let mut route_params = get_blinded_route_parameters(amt_msat, payment_secret, |
| 1121 | + chan_1_2.1.contents.htlc_minimum_msat, chan_1_2.1.contents.htlc_maximum_msat, |
| 1122 | + nodes.iter().skip(1).map(|node| node.node.get_our_node_id()).collect(), |
| 1123 | + &[&chan_1_2.0.contents, &chan_2_3.0.contents, &chan_3_4.0.contents], |
| 1124 | + &chanmon_cfgs[4].keys_manager); |
| 1125 | + route_params.max_total_routing_fee_msat = None; |
| 1126 | + |
| 1127 | + nodes[0].node.send_payment(payment_hash, RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0), route_params.clone(), Retry::Attempts(0)).unwrap(); |
| 1128 | + check_added_monitors(&nodes[0], 1); |
| 1129 | + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); |
| 1130 | + assert_eq!(events.len(), 1); |
| 1131 | + let event = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events); |
| 1132 | + let expected_path = &[&nodes[1], &nodes[2], &nodes[3], &nodes[4]]; |
| 1133 | + |
| 1134 | + let args = PassAlongPathArgs::new(&nodes[0], expected_path, amt_msat, payment_hash, event) |
| 1135 | + .with_payment_secret(payment_secret) |
| 1136 | + .with_overpay_limit(if send_min { 40 } else { 3 }); |
| 1137 | + let claimable_ev = do_pass_along_path(args); |
| 1138 | + let claim_amt = if let Some(Event::PaymentClaimable { amount_msat, .. }) = claimable_ev { |
| 1139 | + amount_msat |
| 1140 | + } else { panic!() }; |
| 1141 | + let overpayment_amt = claim_amt.checked_sub(amt_msat).unwrap(); |
| 1142 | + |
| 1143 | + nodes[4].node.claim_funds(payment_preimage); |
| 1144 | + let expected_route = &[&expected_path[..]]; |
| 1145 | + let mut claim_args = ClaimAlongRouteArgs::new(&nodes[0], &expected_route[..], payment_preimage) |
| 1146 | + .allow_1_msat_fee_overpay(); |
| 1147 | + let expected_fee = pass_claimed_payment_along_route(claim_args); |
| 1148 | + expect_payment_sent(&nodes[0], payment_preimage, Some(Some(expected_fee + overpayment_amt)), true, true); |
| 1149 | +} |
0 commit comments