Skip to content

Commit 0b549ce

Browse files
committed
Add an additional test/bench for routing larger amounts, score more
When benchmarking our router, we previously only ever tested with amounts under 1,000 sats, which is an incredibly small amount. While this ensures we have the maximal number of available channels to consider, it prevents our scorer from getting exercise across its range. Further, we only score the immediate path we are expecting to to send over, and not randomly but rather based on the amount sent. Here we try to make the benchmarks a bit more realistic by adding a new benchmark which attempts to send around 100K sats, which is a reasonable amount to send over a channel today. We also convert the scoring data to be randomized based on the seed as well as attempt to (possibly) find a new route for a much larger value and score based on that. This potentially allows us to score multiple potential paths between the source and destination as the large route-find may return an MPP result.
1 parent 7bd576f commit 0b549ce

File tree

1 file changed

+85
-39
lines changed

1 file changed

+85
-39
lines changed

lightning/src/routing/router.rs

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5550,7 +5550,7 @@ mod tests {
55505550
let mut scorer = ProbabilisticScorer::new(params, &graph, &logger);
55515551
let features = super::InvoiceFeatures::empty();
55525552

5553-
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed() as usize, 2);
5553+
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed(), 0, 2);
55545554
}
55555555

55565556
#[test]
@@ -5572,7 +5572,29 @@ mod tests {
55725572
let mut scorer = ProbabilisticScorer::new(params, &graph, &logger);
55735573
let features = channelmanager::provided_invoice_features(&UserConfig::default());
55745574

5575-
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed() as usize, 2);
5575+
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed(), 0, 2);
5576+
}
5577+
5578+
#[test]
5579+
#[cfg(not(feature = "no-std"))]
5580+
fn generate_large_mpp_routes() {
5581+
use crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters};
5582+
5583+
let mut d = match super::bench_utils::get_route_file() {
5584+
Ok(f) => f,
5585+
Err(e) => {
5586+
eprintln!("{}", e);
5587+
return;
5588+
},
5589+
};
5590+
let logger = ln_test_utils::TestLogger::new();
5591+
let graph = NetworkGraph::read(&mut d, &logger).unwrap();
5592+
5593+
let params = ProbabilisticScoringParameters::default();
5594+
let mut scorer = ProbabilisticScorer::new(params, &graph, &logger);
5595+
let features = channelmanager::provided_invoice_features(&UserConfig::default());
5596+
5597+
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed(), 1_000_000, 2);
55765598
}
55775599

55785600
#[test]
@@ -5681,11 +5703,11 @@ pub(crate) mod bench_utils {
56815703
short_channel_id: Some(1),
56825704
inbound_scid_alias: None,
56835705
outbound_scid_alias: None,
5684-
channel_value_satoshis: 10_000_000,
5706+
channel_value_satoshis: 10_000_000_000,
56855707
user_channel_id: 0,
5686-
balance_msat: 10_000_000,
5687-
outbound_capacity_msat: 10_000_000,
5688-
next_outbound_htlc_limit_msat: 10_000_000,
5708+
balance_msat: 10_000_000_000,
5709+
outbound_capacity_msat: 10_000_000_000,
5710+
next_outbound_htlc_limit_msat: 10_000_000_000,
56895711
inbound_capacity_msat: 0,
56905712
unspendable_punishment_reserve: None,
56915713
confirmations_required: None,
@@ -5703,44 +5725,60 @@ pub(crate) mod bench_utils {
57035725
}
57045726

57055727
pub(crate) fn generate_test_routes<S: Score>(graph: &NetworkGraph<&TestLogger>, scorer: &mut S,
5706-
features: InvoiceFeatures, mut seed: usize, route_count: usize,
5728+
features: InvoiceFeatures, mut seed: u64, starting_amount: u64, route_count: usize,
57075729
) -> Vec<(ChannelDetails, PaymentParameters, u64)> {
57085730
let payer = payer_pubkey();
57095731
let keys_manager = KeysManager::new(&[0u8; 32], 42, 42);
57105732
let random_seed_bytes = keys_manager.get_secure_random_bytes();
57115733

57125734
let nodes = graph.read_only().nodes().clone();
57135735
let mut route_endpoints = Vec::new();
5714-
let mut routes = Vec::new();
5715-
5716-
'load_endpoints: for _ in 0..route_count * 3 /2 {
5736+
for _ in 0..route_count * 3 / 2 {
57175737
loop {
5718-
seed = seed.overflowing_mul(0xdeadbeef).0;
5719-
let src = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5720-
seed = seed.overflowing_mul(0xdeadbeef).0;
5721-
let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5738+
seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
5739+
let src = PublicKey::from_slice(nodes.unordered_keys()
5740+
.skip((seed as usize) % nodes.len()).next().unwrap().as_slice()).unwrap();
5741+
seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
5742+
let dst = PublicKey::from_slice(nodes.unordered_keys()
5743+
.skip((seed as usize) % nodes.len()).next().unwrap().as_slice()).unwrap();
57225744
let params = PaymentParameters::from_node_id(dst, 42).with_features(features.clone());
57235745
let first_hop = first_hop(src);
5724-
let amt = seed as u64 % 1_000_000;
5725-
if let Ok(route) = get_route(&payer, &params, &graph.read_only(), Some(&[&first_hop]), amt, 42, &TestLogger::new(), &scorer, &random_seed_bytes) {
5726-
routes.push(route);
5727-
route_endpoints.push((first_hop, params, amt));
5728-
continue 'load_endpoints;
5729-
}
5730-
}
5731-
}
5746+
let amt = starting_amount + seed % 1_000_000;
5747+
let path_exists =
5748+
get_route(&payer, &params, &graph.read_only(), Some(&[&first_hop]),
5749+
amt, 42, &TestLogger::new(), &scorer, &random_seed_bytes).is_ok();
5750+
if path_exists {
5751+
// ...and seed the scorer with success and failure data...
5752+
seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
5753+
let mut score_amt = seed % 1_000_000_000;
5754+
loop {
5755+
// Generate fail/success paths for a wider range of potential amounts with
5756+
// MPP enabled to give us a chance to apply penalties for more potential
5757+
// routes.
5758+
let mpp_features = channelmanager::provided_invoice_features(&UserConfig::default());
5759+
let params = PaymentParameters::from_node_id(dst, 42).with_features(mpp_features);
5760+
5761+
let route_res = get_route(&payer, &params, &graph.read_only(),
5762+
Some(&[&first_hop]), score_amt, 42, &TestLogger::new(), &scorer,
5763+
&random_seed_bytes);
5764+
if let Ok(route) = route_res {
5765+
for path in route.paths {
5766+
if seed & 0x80 == 0 {
5767+
scorer.payment_path_successful(&path.iter().collect::<Vec<_>>());
5768+
} else {
5769+
let short_channel_id = path[path.len() / 2].short_channel_id;
5770+
scorer.payment_path_failed(&path.iter().collect::<Vec<_>>(), short_channel_id);
5771+
}
5772+
seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
5773+
}
5774+
break;
5775+
}
5776+
// If we couldn't find a path with a higer amount, reduce and try again.
5777+
score_amt /= 100;
5778+
}
57325779

5733-
// ...and seed the scorer with success and failure data...
5734-
for route in routes {
5735-
let amount = route.get_total_amount();
5736-
if amount < 250_000 {
5737-
for path in route.paths {
5738-
scorer.payment_path_successful(&path.iter().collect::<Vec<_>>());
5739-
}
5740-
} else if amount > 750_000 {
5741-
for path in route.paths {
5742-
let short_channel_id = path[path.len() / 2].short_channel_id;
5743-
scorer.payment_path_failed(&path.iter().collect::<Vec<_>>(), short_channel_id);
5780+
route_endpoints.push((first_hop, params, amt));
5781+
break;
57445782
}
57455783
}
57465784
}
@@ -5782,15 +5820,15 @@ mod benches {
57825820
let logger = TestLogger::new();
57835821
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
57845822
let scorer = FixedPenaltyScorer::with_penalty(0);
5785-
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
5823+
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty(), 0);
57865824
}
57875825

57885826
#[bench]
57895827
fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
57905828
let logger = TestLogger::new();
57915829
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
57925830
let scorer = FixedPenaltyScorer::with_penalty(0);
5793-
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
5831+
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()), 0);
57945832
}
57955833

57965834
#[bench]
@@ -5799,7 +5837,7 @@ mod benches {
57995837
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
58005838
let params = ProbabilisticScoringParameters::default();
58015839
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
5802-
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
5840+
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty(), 0);
58035841
}
58045842

58055843
#[bench]
@@ -5808,20 +5846,28 @@ mod benches {
58085846
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
58095847
let params = ProbabilisticScoringParameters::default();
58105848
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
5811-
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
5849+
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()), 0);
58125850
}
58135851

5852+
#[bench]
5853+
fn generate_large_mpp_routes_with_probabilistic_scorer(bench: &mut Bencher) {
5854+
let logger = TestLogger::new();
5855+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
5856+
let params = ProbabilisticScoringParameters::default();
5857+
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
5858+
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()), 100_000_000);
5859+
}
58145860

58155861
fn generate_routes<S: Score>(
58165862
bench: &mut Bencher, graph: &NetworkGraph<&TestLogger>, mut scorer: S,
5817-
features: InvoiceFeatures,
5863+
features: InvoiceFeatures, starting_amount: u64,
58185864
) {
58195865
let payer = bench_utils::payer_pubkey();
58205866
let keys_manager = KeysManager::new(&[0u8; 32], 42, 42);
58215867
let random_seed_bytes = keys_manager.get_secure_random_bytes();
58225868

58235869
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
5824-
let route_endpoints = bench_utils::generate_test_routes(graph, &mut scorer, features, 0xdeadbeef, 100);
5870+
let route_endpoints = bench_utils::generate_test_routes(graph, &mut scorer, features, 0xdeadbeef, starting_amount, 50);
58255871

58265872
// ...then benchmark finding paths between the nodes we learned.
58275873
let mut idx = 0;

0 commit comments

Comments
 (0)