Skip to content

Commit 54783b1

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 0e8da58 commit 54783b1

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
@@ -5671,29 +5671,15 @@ mod tests {
56715671
return;
56725672
},
56735673
};
5674+
56745675
let logger = ln_test_utils::TestLogger::new();
56755676
let graph = NetworkGraph::read(&mut d, &logger).unwrap();
5676-
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
5677-
let random_seed_bytes = keys_manager.get_secure_random_bytes();
56785677

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

56995685
#[test]
@@ -5710,28 +5696,12 @@ mod tests {
57105696
};
57115697
let logger = ln_test_utils::TestLogger::new();
57125698
let graph = NetworkGraph::read(&mut d, &logger).unwrap();
5713-
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
5714-
let random_seed_bytes = keys_manager.get_secure_random_bytes();
5715-
let config = UserConfig::default();
57165699

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

57375707
#[test]
@@ -5919,7 +5889,21 @@ mod tests {
59195889

59205890
#[cfg(all(test, not(feature = "no-std")))]
59215891
pub(crate) mod bench_utils {
5892+
use super::*;
59225893
use std::fs::File;
5894+
5895+
use bitcoin::hashes::Hash;
5896+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
5897+
5898+
use crate::chain::transaction::OutPoint;
5899+
use crate::chain::keysinterface::{EntropySource, KeysManager};
5900+
use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
5901+
use crate::ln::features::InvoiceFeatures;
5902+
use crate::routing::gossip::NetworkGraph;
5903+
use crate::util::config::UserConfig;
5904+
use crate::util::ser::ReadableArgs;
5905+
use crate::util::test_utils::TestLogger;
5906+
59235907
/// Tries to open a network graph file, or panics with a URL to fetch it.
59245908
pub(crate) fn get_route_file() -> Result<std::fs::File, &'static str> {
59255909
let res = File::open("net_graph-2023-01-18.bin") // By default we're run in RL/lightning
@@ -5942,42 +5926,18 @@ pub(crate) mod bench_utils {
59425926
#[cfg(not(require_route_graph_test))]
59435927
return res;
59445928
}
5945-
}
5946-
5947-
#[cfg(all(test, feature = "_bench_unstable", not(feature = "no-std")))]
5948-
mod benches {
5949-
use super::*;
5950-
use bitcoin::hashes::Hash;
5951-
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
5952-
use crate::chain::transaction::OutPoint;
5953-
use crate::chain::keysinterface::{EntropySource, KeysManager};
5954-
use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
5955-
use crate::ln::features::InvoiceFeatures;
5956-
use crate::routing::gossip::NetworkGraph;
5957-
use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters};
5958-
use crate::util::config::UserConfig;
5959-
use crate::util::logger::{Logger, Record};
5960-
use crate::util::ser::ReadableArgs;
59615929

5962-
use test::Bencher;
5963-
5964-
struct DummyLogger {}
5965-
impl Logger for DummyLogger {
5966-
fn log(&self, _record: &Record) {}
5967-
}
5968-
5969-
fn read_network_graph(logger: &DummyLogger) -> NetworkGraph<&DummyLogger> {
5970-
let mut d = bench_utils::get_route_file().unwrap();
5971-
NetworkGraph::read(&mut d, logger).unwrap()
5930+
pub(crate) fn read_network_graph(logger: &TestLogger) -> Result<NetworkGraph<&TestLogger>, &'static str> {
5931+
get_route_file().map(|mut f| NetworkGraph::read(&mut f, logger).unwrap())
59725932
}
59735933

5974-
fn payer_pubkey() -> PublicKey {
5934+
pub(crate) fn payer_pubkey() -> PublicKey {
59755935
let secp_ctx = Secp256k1::new();
59765936
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap())
59775937
}
59785938

59795939
#[inline]
5980-
fn first_hop(node_id: PublicKey) -> ChannelDetails {
5940+
pub(crate) fn first_hop(node_id: PublicKey) -> ChannelDetails {
59815941
ChannelDetails {
59825942
channel_id: [0; 32],
59835943
counterparty: ChannelCounterparty {
@@ -6016,63 +5976,27 @@ mod benches {
60165976
}
60175977
}
60185978

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

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

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

0 commit comments

Comments
 (0)