Skip to content

Commit 5d3314d

Browse files
committed
f test
1 parent cbc5aaa commit 5d3314d

File tree

2 files changed

+174
-2
lines changed

2 files changed

+174
-2
lines changed

lightning/src/routing/router.rs

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2964,7 +2964,7 @@ where L::Target: Logger {
29642964
// Ignore hops if augmenting the current path to them would put us over `max_total_routing_fee_msat`
29652965
if total_fee_msat > max_total_routing_fee_msat {
29662966
if should_log_candidate {
2967-
log_trace!(logger, "Ignoring {} due to exceeding max total routing fee limit.", LoggedCandidateHop(&$candidate));
2967+
log_trace!(logger, "Ignoring {} with fee {total_fee_msat} due to exceeding max total routing fee limit {max_total_routing_fee_msat}.", LoggedCandidateHop(&$candidate));
29682968

29692969
if let Some(_) = first_hop_details {
29702970
log_trace!(logger,
@@ -9036,6 +9036,178 @@ mod tests {
90369036

90379037
assert_eq!(route.paths[0].hops[0].short_channel_id, 44);
90389038
}
9039+
9040+
#[test]
9041+
fn prefers_paths_by_cost_amt_ratio() {
9042+
// Previously, we preferred paths during MPP selection based on their absolute cost, rather
9043+
// than the cost-per-amount-transferred. This could result in selecting many MPP paths with
9044+
// relatively low value contribution, rather than one large path which is ultimately
9045+
// cheaper. While this is a tradeoff (and not universally better), in practice the old
9046+
// behavior was problematic, so we shifted to a proportional cost.
9047+
//
9048+
// Here we check that the proportional cost is being used in a somewhat absurd setup where
9049+
// we have one good path and several cheaper, but smaller paths.
9050+
let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
9051+
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
9052+
let scorer = ln_test_utils::TestScorer::new();
9053+
let random_seed_bytes = [42; 32];
9054+
9055+
// Enable channel 1
9056+
update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
9057+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9058+
short_channel_id: 1,
9059+
timestamp: 2,
9060+
message_flags: 1, // Only must_be_one
9061+
channel_flags: 0,
9062+
cltv_expiry_delta: (1 << 4) | 1,
9063+
htlc_minimum_msat: 0,
9064+
htlc_maximum_msat: 10_000_000,
9065+
fee_base_msat: 0,
9066+
fee_proportional_millionths: 0,
9067+
excess_data: Vec::new()
9068+
});
9069+
9070+
// Set the fee on channel 3 to 1 sat, max HTLC to 1M msat
9071+
update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
9072+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9073+
short_channel_id: 3,
9074+
timestamp: 2,
9075+
message_flags: 1, // Only must_be_one
9076+
channel_flags: 0,
9077+
cltv_expiry_delta: (3 << 4) | 1,
9078+
htlc_minimum_msat: 0,
9079+
htlc_maximum_msat: 1_000_000,
9080+
fee_base_msat: 1_000,
9081+
fee_proportional_millionths: 0,
9082+
excess_data: Vec::new()
9083+
});
9084+
9085+
// Set the fee on channel 13 to 1 sat, max HTLC to 1M msat
9086+
update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
9087+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9088+
short_channel_id: 13,
9089+
timestamp: 2,
9090+
message_flags: 1, // Only must_be_one
9091+
channel_flags: 0,
9092+
cltv_expiry_delta: (13 << 4) | 1,
9093+
htlc_minimum_msat: 0,
9094+
htlc_maximum_msat: 1_000_000,
9095+
fee_base_msat: 1_000,
9096+
fee_proportional_millionths: 0,
9097+
excess_data: Vec::new()
9098+
});
9099+
9100+
// Set the fee on channel 4 to 1 sat, max HTLC to 1M msat
9101+
update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
9102+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9103+
short_channel_id: 4,
9104+
timestamp: 2,
9105+
message_flags: 1, // Only must_be_one
9106+
channel_flags: 0,
9107+
cltv_expiry_delta: (4 << 4) | 1,
9108+
htlc_minimum_msat: 0,
9109+
htlc_maximum_msat: 1_000_000,
9110+
fee_base_msat: 1_000,
9111+
fee_proportional_millionths: 0,
9112+
excess_data: Vec::new()
9113+
});
9114+
9115+
// The router will attempt to gather 3x the requested amount, and if it finds the new path
9116+
// through channel 16, added below, it'll always prefer that, even prior to the changes
9117+
// which introduced this test.
9118+
// Instead, we add 6 additional channels so that the pathfinder always just gathers useless
9119+
// paths first.
9120+
for i in 0..6 {
9121+
// Finally, create a single channel with fee of 2 sat from node 1 to node 2 which allows
9122+
// for a larger payment.
9123+
add_channel(&gossip_sync, &secp_ctx, &privkeys[7], &privkeys[2], ChannelFeatures::from_le_bytes(vec![]), i + 42);
9124+
9125+
// Set the fee on channel 16 to 2 sats, max HTLC to 3M msat
9126+
update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
9127+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9128+
short_channel_id: i + 42,
9129+
timestamp: 2,
9130+
message_flags: 1, // Only must_be_one
9131+
channel_flags: 0,
9132+
cltv_expiry_delta: (42 << 4) | 1,
9133+
htlc_minimum_msat: 0,
9134+
htlc_maximum_msat: 1_000_000,
9135+
fee_base_msat: 1_000,
9136+
fee_proportional_millionths: 0,
9137+
excess_data: Vec::new()
9138+
});
9139+
9140+
// Enable channel 16 by providing an update in both directions
9141+
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
9142+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9143+
short_channel_id: i + 42,
9144+
timestamp: 2,
9145+
message_flags: 1, // Only must_be_one
9146+
channel_flags: 1,
9147+
cltv_expiry_delta: (42 << 4) | 1,
9148+
htlc_minimum_msat: 0,
9149+
htlc_maximum_msat: 10_000_000,
9150+
fee_base_msat: u32::MAX,
9151+
fee_proportional_millionths: 0,
9152+
excess_data: Vec::new()
9153+
});
9154+
}
9155+
9156+
// Ensure that we can build a route for 3M msat across the three paths to node 2.
9157+
let config = UserConfig::default();
9158+
let mut payment_params = PaymentParameters::from_node_id(nodes[2], 42)
9159+
.with_bolt11_features(channelmanager::provided_bolt11_invoice_features(&config))
9160+
.unwrap();
9161+
payment_params.max_channel_saturation_power_of_half = 0;
9162+
let route_params = RouteParameters::from_payment_params_and_value(payment_params, 3_000_000);
9163+
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
9164+
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
9165+
assert_eq!(route.paths.len(), 3);
9166+
for path in route.paths {
9167+
assert_eq!(path.hops.len(), 2);
9168+
}
9169+
9170+
// Finally, create a single channel with fee of 2 sat from node 1 to node 2 which allows
9171+
// for a larger payment.
9172+
add_channel(&gossip_sync, &secp_ctx, &privkeys[1], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(16)), 16);
9173+
9174+
// Set the fee on channel 16 to 2 sats, max HTLC to 3M msat
9175+
update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
9176+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9177+
short_channel_id: 16,
9178+
timestamp: 2,
9179+
message_flags: 1, // Only must_be_one
9180+
channel_flags: 0,
9181+
cltv_expiry_delta: (16 << 4) | 1,
9182+
htlc_minimum_msat: 0,
9183+
htlc_maximum_msat: 3_000_000,
9184+
fee_base_msat: 2_000,
9185+
fee_proportional_millionths: 0,
9186+
excess_data: Vec::new()
9187+
});
9188+
9189+
// Enable channel 16 by providing an update in both directions
9190+
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
9191+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
9192+
short_channel_id: 16,
9193+
timestamp: 2,
9194+
message_flags: 1, // Only must_be_one
9195+
channel_flags: 1,
9196+
cltv_expiry_delta: (16 << 4) | 1,
9197+
htlc_minimum_msat: 0,
9198+
htlc_maximum_msat: 10_000_000,
9199+
fee_base_msat: u32::MAX,
9200+
fee_proportional_millionths: 0,
9201+
excess_data: Vec::new()
9202+
});
9203+
9204+
// Ensure that we now build a route for 3M msat across just the new path
9205+
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
9206+
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
9207+
assert_eq!(route.paths.len(), 1);
9208+
assert_eq!(route.paths[0].hops.len(), 2);
9209+
assert_eq!(route.paths[0].hops[1].short_channel_id, 16);
9210+
}
90399211
}
90409212

90419213
#[cfg(any(test, ldk_bench))]

lightning/src/routing/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub(crate) fn update_channel(
112112

113113
match gossip_sync.handle_channel_update(Some(node_pubkey), &valid_channel_update) {
114114
Ok(res) => assert!(res),
115-
Err(_) => panic!()
115+
Err(e) => panic!("{e:?}")
116116
};
117117
}
118118

0 commit comments

Comments
 (0)