Skip to content

Commit de5c43f

Browse files
TheBlueMattadi2011
authored andcommitted
Clean up long_mpp_route_test and mpp_cheaper_route_test
These tests are a bit annoying to deal with and ultimately work on almost the same graph subset, so it makes sense to combine their graph layout logic and then call it twice. We do that here, combining them and also cleaning up the possible paths as there actually are paths that the router could select which don't meet the tests requirements.
1 parent 980bd1b commit de5c43f

File tree

1 file changed

+55
-232
lines changed

1 file changed

+55
-232
lines changed

lightning/src/routing/router.rs

Lines changed: 55 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -5774,187 +5774,33 @@ mod tests {
57745774
}
57755775

57765776
#[test]
5777-
fn long_mpp_route_test() {
5778-
let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
5779-
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
5780-
let scorer = ln_test_utils::TestScorer::new();
5781-
let random_seed_bytes = [42; 32];
5782-
let config = UserConfig::default();
5783-
let payment_params = PaymentParameters::from_node_id(nodes[3], 42)
5784-
.with_bolt11_features(channelmanager::provided_bolt11_invoice_features(&config))
5785-
.unwrap();
5786-
5787-
// We need a route consisting of 3 paths:
5788-
// From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}.
5789-
// Note that these paths overlap (channels 5, 12, 13).
5790-
// We will route 300 sats.
5791-
// Each path will have 100 sats capacity, those channels which
5792-
// are used twice will have 200 sats capacity.
5793-
5794-
// Disable other potential paths.
5795-
update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
5796-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5797-
short_channel_id: 2,
5798-
timestamp: 2,
5799-
message_flags: 1, // Only must_be_one
5800-
channel_flags: 2,
5801-
cltv_expiry_delta: 0,
5802-
htlc_minimum_msat: 0,
5803-
htlc_maximum_msat: 100_000,
5804-
fee_base_msat: 0,
5805-
fee_proportional_millionths: 0,
5806-
excess_data: Vec::new()
5807-
});
5808-
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
5809-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5810-
short_channel_id: 7,
5811-
timestamp: 2,
5812-
message_flags: 1, // Only must_be_one
5813-
channel_flags: 2,
5814-
cltv_expiry_delta: 0,
5815-
htlc_minimum_msat: 0,
5816-
htlc_maximum_msat: 100_000,
5817-
fee_base_msat: 0,
5818-
fee_proportional_millionths: 0,
5819-
excess_data: Vec::new()
5820-
});
5821-
5822-
// Path via {node0, node2} is channels {1, 3, 5}.
5823-
update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
5824-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5825-
short_channel_id: 1,
5826-
timestamp: 2,
5827-
message_flags: 1, // Only must_be_one
5828-
channel_flags: 0,
5829-
cltv_expiry_delta: 0,
5830-
htlc_minimum_msat: 0,
5831-
htlc_maximum_msat: 100_000,
5832-
fee_base_msat: 0,
5833-
fee_proportional_millionths: 0,
5834-
excess_data: Vec::new()
5835-
});
5836-
update_channel(&gossip_sync, &secp_ctx, &privkeys[0], UnsignedChannelUpdate {
5837-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5838-
short_channel_id: 3,
5839-
timestamp: 2,
5840-
message_flags: 1, // Only must_be_one
5841-
channel_flags: 0,
5842-
cltv_expiry_delta: 0,
5843-
htlc_minimum_msat: 0,
5844-
htlc_maximum_msat: 100_000,
5845-
fee_base_msat: 0,
5846-
fee_proportional_millionths: 0,
5847-
excess_data: Vec::new()
5848-
});
5849-
5850-
// Capacity of 200 sats because this channel will be used by 3rd path as well.
5851-
add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
5852-
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
5853-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5854-
short_channel_id: 5,
5855-
timestamp: 2,
5856-
message_flags: 1, // Only must_be_one
5857-
channel_flags: 0,
5858-
cltv_expiry_delta: 0,
5859-
htlc_minimum_msat: 0,
5860-
htlc_maximum_msat: 200_000,
5861-
fee_base_msat: 0,
5862-
fee_proportional_millionths: 0,
5863-
excess_data: Vec::new()
5864-
});
5865-
update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
5866-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5867-
short_channel_id: 5,
5868-
timestamp: 2,
5869-
message_flags: 1, // Only must_be_one
5870-
channel_flags: 3, // disable direction 1
5871-
cltv_expiry_delta: 0,
5872-
htlc_minimum_msat: 0,
5873-
htlc_maximum_msat: 200_000,
5874-
fee_base_msat: 0,
5875-
fee_proportional_millionths: 0,
5876-
excess_data: Vec::new()
5877-
});
5878-
5879-
// Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
5880-
// Add 100 sats to the capacities of {12, 13}, because these channels
5881-
// are also used for 3rd path. 100 sats for the rest. Total capacity: 100 sats.
5882-
update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
5883-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5884-
short_channel_id: 12,
5885-
timestamp: 2,
5886-
message_flags: 1, // Only must_be_one
5887-
channel_flags: 0,
5888-
cltv_expiry_delta: 0,
5889-
htlc_minimum_msat: 0,
5890-
htlc_maximum_msat: 200_000,
5891-
fee_base_msat: 0,
5892-
fee_proportional_millionths: 0,
5893-
excess_data: Vec::new()
5894-
});
5895-
update_channel(&gossip_sync, &secp_ctx, &privkeys[7], UnsignedChannelUpdate {
5896-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5897-
short_channel_id: 13,
5898-
timestamp: 2,
5899-
message_flags: 1, // Only must_be_one
5900-
channel_flags: 0,
5901-
cltv_expiry_delta: 0,
5902-
htlc_minimum_msat: 0,
5903-
htlc_maximum_msat: 200_000,
5904-
fee_base_msat: 0,
5905-
fee_proportional_millionths: 0,
5906-
excess_data: Vec::new()
5907-
});
5908-
5909-
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
5910-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5911-
short_channel_id: 6,
5912-
timestamp: 2,
5913-
message_flags: 1, // Only must_be_one
5914-
channel_flags: 0,
5915-
cltv_expiry_delta: 0,
5916-
htlc_minimum_msat: 0,
5917-
htlc_maximum_msat: 100_000,
5918-
fee_base_msat: 0,
5919-
fee_proportional_millionths: 0,
5920-
excess_data: Vec::new()
5921-
});
5922-
update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
5923-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5924-
short_channel_id: 11,
5925-
timestamp: 2,
5926-
message_flags: 1, // Only must_be_one
5927-
channel_flags: 0,
5928-
cltv_expiry_delta: 0,
5929-
htlc_minimum_msat: 0,
5930-
htlc_maximum_msat: 100_000,
5931-
fee_base_msat: 0,
5932-
fee_proportional_millionths: 0,
5933-
excess_data: Vec::new()
5934-
});
5935-
5936-
// Path via {node7, node2} is channels {12, 13, 5}.
5937-
// We already limited them to 200 sats (they are used twice for 100 sats).
5938-
// Nothing to do here.
5939-
5777+
fn mpp_tests() {
5778+
let secp_ctx = Secp256k1::new();
5779+
let (_, _, _, nodes) = get_nodes(&secp_ctx);
59405780
{
5941-
// Attempt to route more than available results in a failure.
5942-
let route_params = RouteParameters::from_payment_params_and_value(
5943-
payment_params.clone(), 350_000);
5944-
if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(
5945-
&our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger),
5946-
&scorer, &Default::default(), &random_seed_bytes) {
5947-
assert_eq!(err, "Failed to find a sufficient route to the given destination");
5948-
} else { panic!(); }
5949-
}
5781+
// Check that if we have two cheaper paths and a more expensive (fewer hops) path, we
5782+
// choose the two cheaper paths:
5783+
let route = do_mpp_route_tests(180_000).unwrap();
5784+
assert_eq!(route.paths.len(), 2);
59505785

5786+
let mut total_value_transferred_msat = 0;
5787+
let mut total_paid_msat = 0;
5788+
for path in &route.paths {
5789+
assert_eq!(path.hops.last().unwrap().pubkey, nodes[3]);
5790+
total_value_transferred_msat += path.final_value_msat();
5791+
for hop in &path.hops {
5792+
total_paid_msat += hop.fee_msat;
5793+
}
5794+
}
5795+
// If we paid fee, this would be higher.
5796+
assert_eq!(total_value_transferred_msat, 180_000);
5797+
let total_fees_paid = total_paid_msat - total_value_transferred_msat;
5798+
assert_eq!(total_fees_paid, 0);
5799+
}
59515800
{
5952-
// Now, attempt to route 300 sats (exact amount we can route).
5953-
// Our algorithm should provide us with these 3 paths, 100 sats each.
5954-
let route_params = RouteParameters::from_payment_params_and_value(
5955-
payment_params, 300_000);
5956-
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
5957-
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
5801+
// Check that if we use the same channels but need to send more than we could fit in
5802+
// the cheaper paths we select all three paths:
5803+
let route = do_mpp_route_tests(300_000).unwrap();
59585804
assert_eq!(route.paths.len(), 3);
59595805

59605806
let mut total_amount_paid_msat = 0;
@@ -5964,11 +5810,11 @@ mod tests {
59645810
}
59655811
assert_eq!(total_amount_paid_msat, 300_000);
59665812
}
5967-
5813+
// Check that trying to pay more than our available liquidity fails.
5814+
assert!(do_mpp_route_tests(300_001).is_err());
59685815
}
59695816

5970-
#[test]
5971-
fn mpp_cheaper_route_test() {
5817+
fn do_mpp_route_tests(amt: u64) -> Result<Route, LightningError> {
59725818
let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
59735819
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
59745820
let scorer = ln_test_utils::TestScorer::new();
@@ -5978,21 +5824,17 @@ mod tests {
59785824
.with_bolt11_features(channelmanager::provided_bolt11_invoice_features(&config))
59795825
.unwrap();
59805826

5981-
// This test checks that if we have two cheaper paths and one more expensive path,
5982-
// so that liquidity-wise any 2 of 3 combination is sufficient,
5983-
// two cheaper paths will be taken.
5984-
// These paths have equal available liquidity.
5985-
5986-
// We need a combination of 3 paths:
5987-
// From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}.
5988-
// Note that these paths overlap (channels 5, 12, 13).
5989-
// Each path will have 100 sats capacity, those channels which
5990-
// are used twice will have 200 sats capacity.
5827+
// Build a setup where we have three potential paths from us to node3:
5828+
// {node0, node2, node4} (channels 1, 3, 6, 11), fee 0 msat,
5829+
// {node7, node2, node4} (channels 12, 13, 6, 11), fee 0 msat, and
5830+
// {node1} (channel 2, then a new channel 16), fee 1000 msat.
5831+
// Note that these paths overlap on channels 6 and 11.
5832+
// Each channel will have 100 sats capacity except for 6 and 11, which have 200.
59915833

59925834
// Disable other potential paths.
5993-
update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
5835+
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
59945836
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5995-
short_channel_id: 2,
5837+
short_channel_id: 7,
59965838
timestamp: 2,
59975839
message_flags: 1, // Only must_be_one
59985840
channel_flags: 2,
@@ -6003,9 +5845,9 @@ mod tests {
60035845
fee_proportional_millionths: 0,
60045846
excess_data: Vec::new()
60055847
});
6006-
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
5848+
update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
60075849
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6008-
short_channel_id: 7,
5850+
short_channel_id: 4,
60095851
timestamp: 2,
60105852
message_flags: 1, // Only must_be_one
60115853
channel_flags: 2,
@@ -6045,31 +5887,30 @@ mod tests {
60455887
excess_data: Vec::new()
60465888
});
60475889

6048-
// Capacity of 200 sats because this channel will be used by 3rd path as well.
6049-
add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
6050-
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
5890+
add_channel(&gossip_sync, &secp_ctx, &privkeys[1], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(16)), 16);
5891+
update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
60515892
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6052-
short_channel_id: 5,
5893+
short_channel_id: 16,
60535894
timestamp: 2,
60545895
message_flags: 1, // Only must_be_one
60555896
channel_flags: 0,
60565897
cltv_expiry_delta: 0,
60575898
htlc_minimum_msat: 0,
6058-
htlc_maximum_msat: 200_000,
6059-
fee_base_msat: 0,
5899+
htlc_maximum_msat: 100_000,
5900+
fee_base_msat: 1_000,
60605901
fee_proportional_millionths: 0,
60615902
excess_data: Vec::new()
60625903
});
60635904
update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
60645905
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6065-
short_channel_id: 5,
5906+
short_channel_id: 16,
60665907
timestamp: 2,
60675908
message_flags: 1, // Only must_be_one
60685909
channel_flags: 3, // disable direction 1
60695910
cltv_expiry_delta: 0,
60705911
htlc_minimum_msat: 0,
6071-
htlc_maximum_msat: 200_000,
6072-
fee_base_msat: 0,
5912+
htlc_maximum_msat: 100_000,
5913+
fee_base_msat: 1_000,
60735914
fee_proportional_millionths: 0,
60745915
excess_data: Vec::new()
60755916
});
@@ -6085,7 +5926,7 @@ mod tests {
60855926
channel_flags: 0,
60865927
cltv_expiry_delta: 0,
60875928
htlc_minimum_msat: 0,
6088-
htlc_maximum_msat: 200_000,
5929+
htlc_maximum_msat: 100_000,
60895930
fee_base_msat: 0,
60905931
fee_proportional_millionths: 0,
60915932
excess_data: Vec::new()
@@ -6098,7 +5939,7 @@ mod tests {
60985939
channel_flags: 0,
60995940
cltv_expiry_delta: 0,
61005941
htlc_minimum_msat: 0,
6101-
htlc_maximum_msat: 200_000,
5942+
htlc_maximum_msat: 100_000,
61025943
fee_base_msat: 0,
61035944
fee_proportional_millionths: 0,
61045945
excess_data: Vec::new()
@@ -6112,8 +5953,8 @@ mod tests {
61125953
channel_flags: 0,
61135954
cltv_expiry_delta: 0,
61145955
htlc_minimum_msat: 0,
6115-
htlc_maximum_msat: 100_000,
6116-
fee_base_msat: 1_000,
5956+
htlc_maximum_msat: 200_000,
5957+
fee_base_msat: 0,
61175958
fee_proportional_millionths: 0,
61185959
excess_data: Vec::new()
61195960
});
@@ -6125,7 +5966,7 @@ mod tests {
61255966
channel_flags: 0,
61265967
cltv_expiry_delta: 0,
61275968
htlc_minimum_msat: 0,
6128-
htlc_maximum_msat: 100_000,
5969+
htlc_maximum_msat: 200_000,
61295970
fee_base_msat: 0,
61305971
fee_proportional_millionths: 0,
61315972
excess_data: Vec::new()
@@ -6135,29 +5976,11 @@ mod tests {
61355976
// We already limited them to 200 sats (they are used twice for 100 sats).
61365977
// Nothing to do here.
61375978

6138-
{
6139-
// Now, attempt to route 180 sats.
6140-
// Our algorithm should provide us with these 2 paths.
6141-
let route_params = RouteParameters::from_payment_params_and_value(
6142-
payment_params, 180_000);
6143-
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
6144-
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
6145-
assert_eq!(route.paths.len(), 2);
6146-
6147-
let mut total_value_transferred_msat = 0;
6148-
let mut total_paid_msat = 0;
6149-
for path in &route.paths {
6150-
assert_eq!(path.hops.last().unwrap().pubkey, nodes[3]);
6151-
total_value_transferred_msat += path.final_value_msat();
6152-
for hop in &path.hops {
6153-
total_paid_msat += hop.fee_msat;
6154-
}
6155-
}
6156-
// If we paid fee, this would be higher.
6157-
assert_eq!(total_value_transferred_msat, 180_000);
6158-
let total_fees_paid = total_paid_msat - total_value_transferred_msat;
6159-
assert_eq!(total_fees_paid, 0);
6160-
}
5979+
let route_params = RouteParameters::from_payment_params_and_value(
5980+
payment_params, amt);
5981+
let res = get_route(&our_id, &route_params, &network_graph.read_only(), None,
5982+
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes);
5983+
res
61615984
}
61625985

61635986
#[test]

0 commit comments

Comments
 (0)