Skip to content

Commit cfb6055

Browse files
committed
Unify route benchmarking with route tests
There's a few route tests which do the same thing as the benchmarks as they're also a good test. However, they didn't share code, which is somewhat wasteful, so we fix that here.
1 parent ec3aa49 commit cfb6055

File tree

1 file changed

+111
-118
lines changed

1 file changed

+111
-118
lines changed

lightning/src/routing/router.rs

Lines changed: 111 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -5676,29 +5676,15 @@ mod tests {
56765676
return;
56775677
},
56785678
};
5679+
56795680
let logger = ln_test_utils::TestLogger::new();
56805681
let graph = NetworkGraph::read(&mut d, &logger).unwrap();
5681-
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
5682-
let random_seed_bytes = keys_manager.get_secure_random_bytes();
56835682

5684-
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
5685-
let mut seed = random_init_seed() as usize;
5686-
let nodes = graph.read_only().nodes().clone();
5687-
'load_endpoints: for _ in 0..10 {
5688-
loop {
5689-
seed = seed.overflowing_mul(0xdeadbeef).0;
5690-
let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5691-
seed = seed.overflowing_mul(0xdeadbeef).0;
5692-
let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5693-
let payment_params = PaymentParameters::from_node_id(dst, 42);
5694-
let amt = seed as u64 % 200_000_000;
5695-
let params = ProbabilisticScoringParameters::default();
5696-
let scorer = ProbabilisticScorer::new(params, &graph, &logger);
5697-
if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() {
5698-
continue 'load_endpoints;
5699-
}
5700-
}
5701-
}
5683+
let params = ProbabilisticScoringParameters::default();
5684+
let mut scorer = ProbabilisticScorer::new(params, &graph, &logger);
5685+
let features = super::InvoiceFeatures::empty();
5686+
5687+
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed() as usize, 2);
57025688
}
57035689

57045690
#[test]
@@ -5715,28 +5701,12 @@ mod tests {
57155701
};
57165702
let logger = ln_test_utils::TestLogger::new();
57175703
let graph = NetworkGraph::read(&mut d, &logger).unwrap();
5718-
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
5719-
let random_seed_bytes = keys_manager.get_secure_random_bytes();
5720-
let config = UserConfig::default();
57215704

5722-
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
5723-
let mut seed = random_init_seed() as usize;
5724-
let nodes = graph.read_only().nodes().clone();
5725-
'load_endpoints: for _ in 0..10 {
5726-
loop {
5727-
seed = seed.overflowing_mul(0xdeadbeef).0;
5728-
let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5729-
seed = seed.overflowing_mul(0xdeadbeef).0;
5730-
let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5731-
let payment_params = PaymentParameters::from_node_id(dst, 42).with_features(channelmanager::provided_invoice_features(&config));
5732-
let amt = seed as u64 % 200_000_000;
5733-
let params = ProbabilisticScoringParameters::default();
5734-
let scorer = ProbabilisticScorer::new(params, &graph, &logger);
5735-
if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() {
5736-
continue 'load_endpoints;
5737-
}
5738-
}
5739-
}
5705+
let params = ProbabilisticScoringParameters::default();
5706+
let mut scorer = ProbabilisticScorer::new(params, &graph, &logger);
5707+
let features = channelmanager::provided_invoice_features(&UserConfig::default());
5708+
5709+
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed() as usize, 2);
57405710
}
57415711

57425712
#[test]
@@ -5924,7 +5894,21 @@ mod tests {
59245894

59255895
#[cfg(all(test, not(feature = "no-std")))]
59265896
pub(crate) mod bench_utils {
5897+
use super::*;
59275898
use std::fs::File;
5899+
5900+
use bitcoin::hashes::Hash;
5901+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
5902+
5903+
use crate::chain::transaction::OutPoint;
5904+
use crate::chain::keysinterface::{EntropySource, KeysManager};
5905+
use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
5906+
use crate::ln::features::InvoiceFeatures;
5907+
use crate::routing::gossip::NetworkGraph;
5908+
use crate::util::config::UserConfig;
5909+
use crate::util::ser::ReadableArgs;
5910+
use crate::util::test_utils::TestLogger;
5911+
59285912
/// Tries to open a network graph file, or panics with a URL to fetch it.
59295913
pub(crate) fn get_route_file() -> Result<std::fs::File, &'static str> {
59305914
let res = File::open("net_graph-2023-01-18.bin") // By default we're run in RL/lightning
@@ -5947,42 +5931,18 @@ pub(crate) mod bench_utils {
59475931
#[cfg(not(require_route_graph_test))]
59485932
return res;
59495933
}
5950-
}
5951-
5952-
#[cfg(all(test, feature = "_bench_unstable", not(feature = "no-std")))]
5953-
mod benches {
5954-
use super::*;
5955-
use bitcoin::hashes::Hash;
5956-
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
5957-
use crate::chain::transaction::OutPoint;
5958-
use crate::chain::keysinterface::{EntropySource, KeysManager};
5959-
use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
5960-
use crate::ln::features::InvoiceFeatures;
5961-
use crate::routing::gossip::NetworkGraph;
5962-
use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters};
5963-
use crate::util::config::UserConfig;
5964-
use crate::util::logger::{Logger, Record};
5965-
use crate::util::ser::ReadableArgs;
59665934

5967-
use test::Bencher;
5968-
5969-
struct DummyLogger {}
5970-
impl Logger for DummyLogger {
5971-
fn log(&self, _record: &Record) {}
5972-
}
5973-
5974-
fn read_network_graph(logger: &DummyLogger) -> NetworkGraph<&DummyLogger> {
5975-
let mut d = bench_utils::get_route_file().unwrap();
5976-
NetworkGraph::read(&mut d, logger).unwrap()
5935+
pub(crate) fn read_network_graph(logger: &TestLogger) -> Result<NetworkGraph<&TestLogger>, &'static str> {
5936+
get_route_file().map(|mut f| NetworkGraph::read(&mut f, logger).unwrap())
59775937
}
59785938

5979-
fn payer_pubkey() -> PublicKey {
5939+
pub(crate) fn payer_pubkey() -> PublicKey {
59805940
let secp_ctx = Secp256k1::new();
59815941
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap())
59825942
}
59835943

59845944
#[inline]
5985-
fn first_hop(node_id: PublicKey) -> ChannelDetails {
5945+
pub(crate) fn first_hop(node_id: PublicKey) -> ChannelDetails {
59865946
ChannelDetails {
59875947
channel_id: [0; 32],
59885948
counterparty: ChannelCounterparty {
@@ -6021,63 +5981,27 @@ mod benches {
60215981
}
60225982
}
60235983

6024-
#[bench]
6025-
fn generate_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
6026-
let logger = DummyLogger {};
6027-
let network_graph = read_network_graph(&logger);
6028-
let scorer = FixedPenaltyScorer::with_penalty(0);
6029-
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
6030-
}
6031-
6032-
#[bench]
6033-
fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
6034-
let logger = DummyLogger {};
6035-
let network_graph = read_network_graph(&logger);
6036-
let scorer = FixedPenaltyScorer::with_penalty(0);
6037-
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
6038-
}
6039-
6040-
#[bench]
6041-
fn generate_routes_with_probabilistic_scorer(bench: &mut Bencher) {
6042-
let logger = DummyLogger {};
6043-
let network_graph = read_network_graph(&logger);
6044-
let params = ProbabilisticScoringParameters::default();
6045-
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
6046-
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
6047-
}
6048-
6049-
#[bench]
6050-
fn generate_mpp_routes_with_probabilistic_scorer(bench: &mut Bencher) {
6051-
let logger = DummyLogger {};
6052-
let network_graph = read_network_graph(&logger);
6053-
let params = ProbabilisticScoringParameters::default();
6054-
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
6055-
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
6056-
}
6057-
6058-
fn generate_routes<S: Score>(
6059-
bench: &mut Bencher, graph: &NetworkGraph<&DummyLogger>, mut scorer: S,
6060-
features: InvoiceFeatures
6061-
) {
6062-
let nodes = graph.read_only().nodes().clone();
5984+
pub(crate) fn generate_test_routes<S: Score>(graph: &NetworkGraph<&TestLogger>, scorer: &mut S,
5985+
features: InvoiceFeatures, mut seed: usize, route_count: usize,
5986+
) -> Vec<(ChannelDetails, PaymentParameters, u64)> {
60635987
let payer = payer_pubkey();
60645988
let keys_manager = KeysManager::new(&[0u8; 32], 42, 42);
60655989
let random_seed_bytes = keys_manager.get_secure_random_bytes();
60665990

6067-
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
6068-
let mut routes = Vec::new();
5991+
let nodes = graph.read_only().nodes().clone();
60695992
let mut route_endpoints = Vec::new();
6070-
let mut seed: usize = 0xdeadbeef;
6071-
'load_endpoints: for _ in 0..150 {
5993+
let mut routes = Vec::new();
5994+
5995+
'load_endpoints: for _ in 0..route_count * 3 /2 {
60725996
loop {
6073-
seed *= 0xdeadbeef;
5997+
seed = seed.overflowing_mul(0xdeadbeef).0;
60745998
let src = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
6075-
seed *= 0xdeadbeef;
5999+
seed = seed.overflowing_mul(0xdeadbeef).0;
60766000
let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
60776001
let params = PaymentParameters::from_node_id(dst, 42).with_features(features.clone());
60786002
let first_hop = first_hop(src);
60796003
let amt = seed as u64 % 1_000_000;
6080-
if let Ok(route) = get_route(&payer, &params, &graph.read_only(), Some(&[&first_hop]), amt, 42, &DummyLogger{}, &scorer, &random_seed_bytes) {
6004+
if let Ok(route) = get_route(&payer, &params, &graph.read_only(), Some(&[&first_hop]), amt, 42, &TestLogger::new(), &scorer, &random_seed_bytes) {
60816005
routes.push(route);
60826006
route_endpoints.push((first_hop, params, amt));
60836007
continue 'load_endpoints;
@@ -6104,10 +6028,79 @@ mod benches {
61046028
// selected destinations, possibly causing us to fail because, eg, the newly-selected path
61056029
// requires a too-high CLTV delta.
61066030
route_endpoints.retain(|(first_hop, params, amt)| {
6107-
get_route(&payer, params, &graph.read_only(), Some(&[first_hop]), *amt, 42, &DummyLogger{}, &scorer, &random_seed_bytes).is_ok()
6031+
get_route(&payer, params, &graph.read_only(), Some(&[first_hop]), *amt, 42, &TestLogger::new(), &scorer, &random_seed_bytes).is_ok()
61086032
});
6109-
route_endpoints.truncate(100);
6110-
assert_eq!(route_endpoints.len(), 100);
6033+
route_endpoints.truncate(route_count);
6034+
assert_eq!(route_endpoints.len(), route_count);
6035+
route_endpoints
6036+
}
6037+
}
6038+
6039+
#[cfg(all(test, feature = "_bench_unstable", not(feature = "no-std")))]
6040+
mod benches {
6041+
use super::*;
6042+
use crate::chain::keysinterface::{EntropySource, KeysManager};
6043+
use crate::ln::channelmanager;
6044+
use crate::ln::features::InvoiceFeatures;
6045+
use crate::routing::gossip::NetworkGraph;
6046+
use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters};
6047+
use crate::util::config::UserConfig;
6048+
use crate::util::logger::{Logger, Record};
6049+
use crate::util::test_utils::TestLogger;
6050+
6051+
use test::Bencher;
6052+
6053+
struct DummyLogger {}
6054+
impl Logger for DummyLogger {
6055+
fn log(&self, _record: &Record) {}
6056+
}
6057+
6058+
6059+
#[bench]
6060+
fn generate_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
6061+
let logger = TestLogger::new();
6062+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
6063+
let scorer = FixedPenaltyScorer::with_penalty(0);
6064+
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
6065+
}
6066+
6067+
#[bench]
6068+
fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
6069+
let logger = TestLogger::new();
6070+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
6071+
let scorer = FixedPenaltyScorer::with_penalty(0);
6072+
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
6073+
}
6074+
6075+
#[bench]
6076+
fn generate_routes_with_probabilistic_scorer(bench: &mut Bencher) {
6077+
let logger = TestLogger::new();
6078+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
6079+
let params = ProbabilisticScoringParameters::default();
6080+
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
6081+
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
6082+
}
6083+
6084+
#[bench]
6085+
fn generate_mpp_routes_with_probabilistic_scorer(bench: &mut Bencher) {
6086+
let logger = TestLogger::new();
6087+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
6088+
let params = ProbabilisticScoringParameters::default();
6089+
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
6090+
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
6091+
}
6092+
6093+
6094+
fn generate_routes<S: Score>(
6095+
bench: &mut Bencher, graph: &NetworkGraph<&TestLogger>, mut scorer: S,
6096+
features: InvoiceFeatures,
6097+
) {
6098+
let payer = bench_utils::payer_pubkey();
6099+
let keys_manager = KeysManager::new(&[0u8; 32], 42, 42);
6100+
let random_seed_bytes = keys_manager.get_secure_random_bytes();
6101+
6102+
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
6103+
let route_endpoints = bench_utils::generate_test_routes(graph, &mut scorer, features, 0xdeadbeef, 100);
61116104

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

0 commit comments

Comments
 (0)