Skip to content

Commit 6715bc1

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 157af6e commit 6715bc1

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
@@ -5542,29 +5542,15 @@ mod tests {
55425542
return;
55435543
},
55445544
};
5545+
55455546
let logger = ln_test_utils::TestLogger::new();
55465547
let graph = NetworkGraph::read(&mut d, &logger).unwrap();
5547-
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
5548-
let random_seed_bytes = keys_manager.get_secure_random_bytes();
55495548

5550-
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
5551-
let mut seed = random_init_seed() as usize;
5552-
let nodes = graph.read_only().nodes().clone();
5553-
'load_endpoints: for _ in 0..10 {
5554-
loop {
5555-
seed = seed.overflowing_mul(0xdeadbeef).0;
5556-
let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5557-
seed = seed.overflowing_mul(0xdeadbeef).0;
5558-
let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5559-
let payment_params = PaymentParameters::from_node_id(dst, 42);
5560-
let amt = seed as u64 % 200_000_000;
5561-
let params = ProbabilisticScoringParameters::default();
5562-
let scorer = ProbabilisticScorer::new(params, &graph, &logger);
5563-
if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() {
5564-
continue 'load_endpoints;
5565-
}
5566-
}
5567-
}
5549+
let params = ProbabilisticScoringParameters::default();
5550+
let mut scorer = ProbabilisticScorer::new(params, &graph, &logger);
5551+
let features = super::InvoiceFeatures::empty();
5552+
5553+
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed() as usize, 2);
55685554
}
55695555

55705556
#[test]
@@ -5581,28 +5567,12 @@ mod tests {
55815567
};
55825568
let logger = ln_test_utils::TestLogger::new();
55835569
let graph = NetworkGraph::read(&mut d, &logger).unwrap();
5584-
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
5585-
let random_seed_bytes = keys_manager.get_secure_random_bytes();
5586-
let config = UserConfig::default();
55875570

5588-
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
5589-
let mut seed = random_init_seed() as usize;
5590-
let nodes = graph.read_only().nodes().clone();
5591-
'load_endpoints: for _ in 0..10 {
5592-
loop {
5593-
seed = seed.overflowing_mul(0xdeadbeef).0;
5594-
let src = &PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5595-
seed = seed.overflowing_mul(0xdeadbeef).0;
5596-
let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5597-
let payment_params = PaymentParameters::from_node_id(dst, 42).with_features(channelmanager::provided_invoice_features(&config));
5598-
let amt = seed as u64 % 200_000_000;
5599-
let params = ProbabilisticScoringParameters::default();
5600-
let scorer = ProbabilisticScorer::new(params, &graph, &logger);
5601-
if get_route(src, &payment_params, &graph.read_only(), None, amt, 42, &logger, &scorer, &random_seed_bytes).is_ok() {
5602-
continue 'load_endpoints;
5603-
}
5604-
}
5605-
}
5571+
let params = ProbabilisticScoringParameters::default();
5572+
let mut scorer = ProbabilisticScorer::new(params, &graph, &logger);
5573+
let features = channelmanager::provided_invoice_features(&UserConfig::default());
5574+
5575+
super::bench_utils::generate_test_routes(&graph, &mut scorer, features, random_init_seed() as usize, 2);
56065576
}
56075577

56085578
#[test]
@@ -5645,7 +5615,21 @@ mod tests {
56455615

56465616
#[cfg(all(test, not(feature = "no-std")))]
56475617
pub(crate) mod bench_utils {
5618+
use super::*;
56485619
use std::fs::File;
5620+
5621+
use bitcoin::hashes::Hash;
5622+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
5623+
5624+
use crate::chain::transaction::OutPoint;
5625+
use crate::chain::keysinterface::{EntropySource, KeysManager};
5626+
use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
5627+
use crate::ln::features::InvoiceFeatures;
5628+
use crate::routing::gossip::NetworkGraph;
5629+
use crate::util::config::UserConfig;
5630+
use crate::util::ser::ReadableArgs;
5631+
use crate::util::test_utils::TestLogger;
5632+
56495633
/// Tries to open a network graph file, or panics with a URL to fetch it.
56505634
pub(crate) fn get_route_file() -> Result<std::fs::File, &'static str> {
56515635
let res = File::open("net_graph-2023-01-18.bin") // By default we're run in RL/lightning
@@ -5668,42 +5652,18 @@ pub(crate) mod bench_utils {
56685652
#[cfg(not(require_route_graph_test))]
56695653
return res;
56705654
}
5671-
}
5672-
5673-
#[cfg(all(test, feature = "_bench_unstable", not(feature = "no-std")))]
5674-
mod benches {
5675-
use super::*;
5676-
use bitcoin::hashes::Hash;
5677-
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
5678-
use crate::chain::transaction::OutPoint;
5679-
use crate::chain::keysinterface::{EntropySource, KeysManager};
5680-
use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails};
5681-
use crate::ln::features::InvoiceFeatures;
5682-
use crate::routing::gossip::NetworkGraph;
5683-
use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters};
5684-
use crate::util::config::UserConfig;
5685-
use crate::util::logger::{Logger, Record};
5686-
use crate::util::ser::ReadableArgs;
56875655

5688-
use test::Bencher;
5689-
5690-
struct DummyLogger {}
5691-
impl Logger for DummyLogger {
5692-
fn log(&self, _record: &Record) {}
5693-
}
5694-
5695-
fn read_network_graph(logger: &DummyLogger) -> NetworkGraph<&DummyLogger> {
5696-
let mut d = bench_utils::get_route_file().unwrap();
5697-
NetworkGraph::read(&mut d, logger).unwrap()
5656+
pub(crate) fn read_network_graph(logger: &TestLogger) -> Result<NetworkGraph<&TestLogger>, &'static str> {
5657+
get_route_file().map(|mut f| NetworkGraph::read(&mut f, logger).unwrap())
56985658
}
56995659

5700-
fn payer_pubkey() -> PublicKey {
5660+
pub(crate) fn payer_pubkey() -> PublicKey {
57015661
let secp_ctx = Secp256k1::new();
57025662
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap())
57035663
}
57045664

57055665
#[inline]
5706-
fn first_hop(node_id: PublicKey) -> ChannelDetails {
5666+
pub(crate) fn first_hop(node_id: PublicKey) -> ChannelDetails {
57075667
ChannelDetails {
57085668
channel_id: [0; 32],
57095669
counterparty: ChannelCounterparty {
@@ -5742,63 +5702,27 @@ mod benches {
57425702
}
57435703
}
57445704

5745-
#[bench]
5746-
fn generate_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
5747-
let logger = DummyLogger {};
5748-
let network_graph = read_network_graph(&logger);
5749-
let scorer = FixedPenaltyScorer::with_penalty(0);
5750-
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
5751-
}
5752-
5753-
#[bench]
5754-
fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
5755-
let logger = DummyLogger {};
5756-
let network_graph = read_network_graph(&logger);
5757-
let scorer = FixedPenaltyScorer::with_penalty(0);
5758-
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
5759-
}
5760-
5761-
#[bench]
5762-
fn generate_routes_with_probabilistic_scorer(bench: &mut Bencher) {
5763-
let logger = DummyLogger {};
5764-
let network_graph = read_network_graph(&logger);
5765-
let params = ProbabilisticScoringParameters::default();
5766-
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
5767-
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
5768-
}
5769-
5770-
#[bench]
5771-
fn generate_mpp_routes_with_probabilistic_scorer(bench: &mut Bencher) {
5772-
let logger = DummyLogger {};
5773-
let network_graph = read_network_graph(&logger);
5774-
let params = ProbabilisticScoringParameters::default();
5775-
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
5776-
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
5777-
}
5778-
5779-
fn generate_routes<S: Score>(
5780-
bench: &mut Bencher, graph: &NetworkGraph<&DummyLogger>, mut scorer: S,
5781-
features: InvoiceFeatures
5782-
) {
5783-
let nodes = graph.read_only().nodes().clone();
5705+
pub(crate) fn generate_test_routes<S: Score>(graph: &NetworkGraph<&TestLogger>, scorer: &mut S,
5706+
features: InvoiceFeatures, mut seed: usize, route_count: usize,
5707+
) -> Vec<(ChannelDetails, PaymentParameters, u64)> {
57845708
let payer = payer_pubkey();
57855709
let keys_manager = KeysManager::new(&[0u8; 32], 42, 42);
57865710
let random_seed_bytes = keys_manager.get_secure_random_bytes();
57875711

5788-
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
5789-
let mut routes = Vec::new();
5712+
let nodes = graph.read_only().nodes().clone();
57905713
let mut route_endpoints = Vec::new();
5791-
let mut seed: usize = 0xdeadbeef;
5792-
'load_endpoints: for _ in 0..150 {
5714+
let mut routes = Vec::new();
5715+
5716+
'load_endpoints: for _ in 0..route_count * 3 /2 {
57935717
loop {
5794-
seed *= 0xdeadbeef;
5718+
seed = seed.overflowing_mul(0xdeadbeef).0;
57955719
let src = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
5796-
seed *= 0xdeadbeef;
5720+
seed = seed.overflowing_mul(0xdeadbeef).0;
57975721
let dst = PublicKey::from_slice(nodes.unordered_keys().skip(seed % nodes.len()).next().unwrap().as_slice()).unwrap();
57985722
let params = PaymentParameters::from_node_id(dst, 42).with_features(features.clone());
57995723
let first_hop = first_hop(src);
58005724
let amt = seed as u64 % 1_000_000;
5801-
if let Ok(route) = get_route(&payer, &params, &graph.read_only(), Some(&[&first_hop]), amt, 42, &DummyLogger{}, &scorer, &random_seed_bytes) {
5725+
if let Ok(route) = get_route(&payer, &params, &graph.read_only(), Some(&[&first_hop]), amt, 42, &TestLogger::new(), &scorer, &random_seed_bytes) {
58025726
routes.push(route);
58035727
route_endpoints.push((first_hop, params, amt));
58045728
continue 'load_endpoints;
@@ -5825,10 +5749,79 @@ mod benches {
58255749
// selected destinations, possibly causing us to fail because, eg, the newly-selected path
58265750
// requires a too-high CLTV delta.
58275751
route_endpoints.retain(|(first_hop, params, amt)| {
5828-
get_route(&payer, params, &graph.read_only(), Some(&[first_hop]), *amt, 42, &DummyLogger{}, &scorer, &random_seed_bytes).is_ok()
5752+
get_route(&payer, params, &graph.read_only(), Some(&[first_hop]), *amt, 42, &TestLogger::new(), &scorer, &random_seed_bytes).is_ok()
58295753
});
5830-
route_endpoints.truncate(100);
5831-
assert_eq!(route_endpoints.len(), 100);
5754+
route_endpoints.truncate(route_count);
5755+
assert_eq!(route_endpoints.len(), route_count);
5756+
route_endpoints
5757+
}
5758+
}
5759+
5760+
#[cfg(all(test, feature = "_bench_unstable", not(feature = "no-std")))]
5761+
mod benches {
5762+
use super::*;
5763+
use crate::chain::keysinterface::{EntropySource, KeysManager};
5764+
use crate::ln::channelmanager;
5765+
use crate::ln::features::InvoiceFeatures;
5766+
use crate::routing::gossip::NetworkGraph;
5767+
use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringParameters};
5768+
use crate::util::config::UserConfig;
5769+
use crate::util::logger::{Logger, Record};
5770+
use crate::util::test_utils::TestLogger;
5771+
5772+
use test::Bencher;
5773+
5774+
struct DummyLogger {}
5775+
impl Logger for DummyLogger {
5776+
fn log(&self, _record: &Record) {}
5777+
}
5778+
5779+
5780+
#[bench]
5781+
fn generate_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
5782+
let logger = TestLogger::new();
5783+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
5784+
let scorer = FixedPenaltyScorer::with_penalty(0);
5785+
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
5786+
}
5787+
5788+
#[bench]
5789+
fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Bencher) {
5790+
let logger = TestLogger::new();
5791+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
5792+
let scorer = FixedPenaltyScorer::with_penalty(0);
5793+
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
5794+
}
5795+
5796+
#[bench]
5797+
fn generate_routes_with_probabilistic_scorer(bench: &mut Bencher) {
5798+
let logger = TestLogger::new();
5799+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
5800+
let params = ProbabilisticScoringParameters::default();
5801+
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
5802+
generate_routes(bench, &network_graph, scorer, InvoiceFeatures::empty());
5803+
}
5804+
5805+
#[bench]
5806+
fn generate_mpp_routes_with_probabilistic_scorer(bench: &mut Bencher) {
5807+
let logger = TestLogger::new();
5808+
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
5809+
let params = ProbabilisticScoringParameters::default();
5810+
let scorer = ProbabilisticScorer::new(params, &network_graph, &logger);
5811+
generate_routes(bench, &network_graph, scorer, channelmanager::provided_invoice_features(&UserConfig::default()));
5812+
}
5813+
5814+
5815+
fn generate_routes<S: Score>(
5816+
bench: &mut Bencher, graph: &NetworkGraph<&TestLogger>, mut scorer: S,
5817+
features: InvoiceFeatures,
5818+
) {
5819+
let payer = bench_utils::payer_pubkey();
5820+
let keys_manager = KeysManager::new(&[0u8; 32], 42, 42);
5821+
let random_seed_bytes = keys_manager.get_secure_random_bytes();
5822+
5823+
// 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);
58325825

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

0 commit comments

Comments
 (0)