Skip to content

Commit 89ce35e

Browse files
committed
Use a real (probing-generated) scorer in benchmarks
Until now, our routing benchmarks used a synthetic scorer, generated by scoring random paths to build up some history. This is pretty far removed from real-world routing conditions, as alternative paths generally have no scoring information and even the paths we do take have only one or two past scoring results. Instead, we fetch a static serialized scorer, generated using minutely probes. This means future changes to the scorer's data may be harder to benchmark, but makes for substantially more realistic benchmarks for changes which don't impact the serialized state.
1 parent 2701bc5 commit 89ce35e

File tree

4 files changed

+93
-143
lines changed

4 files changed

+93
-143
lines changed

.github/workflows/build.yml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,36 @@ jobs:
8383
id: cache-graph
8484
uses: actions/cache@v3
8585
with:
86-
path: lightning/net_graph-2023-01-18.bin
87-
key: ldk-net_graph-v0.0.113-2023-01-18.bin
86+
path: lightning/net_graph-2023-12-10.bin
87+
key: ldk-net_graph-v0.0.118-2023-12-10.bin
8888
- name: Fetch routing graph snapshot
8989
if: steps.cache-graph.outputs.cache-hit != 'true'
9090
run: |
91-
curl --verbose -L -o lightning/net_graph-2023-01-18.bin https://bitcoin.ninja/ldk-net_graph-v0.0.113-2023-01-18.bin
92-
echo "Sha sum: $(sha256sum lightning/net_graph-2023-01-18.bin | awk '{ print $1 }')"
93-
if [ "$(sha256sum lightning/net_graph-2023-01-18.bin | awk '{ print $1 }')" != "${EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM}" ]; then
91+
curl --verbose -L -o lightning/net_graph-2023-12-10.bin https://bitcoin.ninja/ldk-net_graph-v0.0.118-2023-12-10.bin
92+
echo "Sha sum: $(sha256sum lightning/net_graph-2023-12-10.bin | awk '{ print $1 }')"
93+
if [ "$(sha256sum lightning/net_graph-2023-12-10.bin | awk '{ print $1 }')" != "${EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM}" ]; then
9494
echo "Bad hash"
9595
exit 1
9696
fi
9797
env:
98-
EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM: da6066f2bddcddbe7d8a6debbd53545697137b310bbb8c4911bc8c81fc5ff48c
98+
EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM: e94b38ef4b3ce683893bf6a3ee28d60cb37c73b059403ff77b7e7458157968c2
99+
- name: Cache scorer snapshot
100+
id: cache-scorer
101+
uses: actions/cache@v3
102+
with:
103+
path: lightning/scorer-2023-12-10.bin
104+
key: ldk-scorer-v0.0.118-2023-12-10.bin
105+
- name: Fetch scorer snapshot
106+
if: steps.cache-scorer.outputs.cache-hit != 'true'
107+
run: |
108+
curl --verbose -L -o lightning/scorer-2023-12-10.bin https://bitcoin.ninja/ldk-scorer-v0.0.118-2023-12-10.bin
109+
echo "Sha sum: $(sha256sum lightning/scorer-2023-12-10.bin | awk '{ print $1 }')"
110+
if [ "$(sha256sum lightning/scorer-2023-12-10.bin | awk '{ print $1 }')" != "${EXPECTED_SCORER_SNAPSHOT_SHASUM}" ]; then
111+
echo "Bad hash"
112+
exit 1
113+
fi
114+
env:
115+
EXPECTED_SCORER_SNAPSHOT_SHASUM: 570a26bb28870fe1da7e392cdec9fb794718826b04c43ca053d71a8a9bb9be69
99116
- name: Fetch rapid graph sync reference input
100117
run: |
101118
curl --verbose -L -o lightning-rapid-gossip-sync/res/full_graph.lngossip https://bitcoin.ninja/ldk-compressed_graph-285cb27df79-2022-07-21.bin

lightning/src/routing/gossip.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3716,7 +3716,7 @@ pub mod benches {
37163716

37173717
pub fn read_network_graph(bench: &mut Criterion) {
37183718
let logger = crate::util::test_utils::TestLogger::new();
3719-
let mut d = crate::routing::router::bench_utils::get_route_file().unwrap();
3719+
let (mut d, _) = crate::routing::router::bench_utils::get_graph_scorer_file().unwrap();
37203720
let mut v = Vec::new();
37213721
d.read_to_end(&mut v).unwrap();
37223722
bench.bench_function("read_network_graph", |b| b.iter(||
@@ -3726,7 +3726,7 @@ pub mod benches {
37263726

37273727
pub fn write_network_graph(bench: &mut Criterion) {
37283728
let logger = crate::util::test_utils::TestLogger::new();
3729-
let mut d = crate::routing::router::bench_utils::get_route_file().unwrap();
3729+
let (mut d, _) = crate::routing::router::bench_utils::get_graph_scorer_file().unwrap();
37303730
let net_graph = NetworkGraph::read(&mut d, &logger).unwrap();
37313731
bench.bench_function("write_network_graph", |b| b.iter(||
37323732
black_box(&net_graph).encode()

lightning/src/routing/router.rs

Lines changed: 67 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -7115,19 +7115,18 @@ mod tests {
71157115
#[test]
71167116
#[cfg(feature = "std")]
71177117
fn generate_routes() {
7118-
use crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters};
7118+
use crate::routing::scoring::ProbabilisticScoringFeeParameters;
71197119

71207120
let logger = ln_test_utils::TestLogger::new();
7121-
let graph = match super::bench_utils::read_network_graph(&logger) {
7122-
Ok(f) => f,
7121+
let (graph, mut scorer) = match super::bench_utils::read_graph_scorer(&logger) {
7122+
Ok(res) => res,
71237123
Err(e) => {
71247124
eprintln!("{}", e);
71257125
return;
71267126
},
71277127
};
71287128

71297129
let params = ProbabilisticScoringFeeParameters::default();
7130-
let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &graph, &logger);
71317130
let features = super::Bolt11InvoiceFeatures::empty();
71327131

71337132
super::bench_utils::generate_test_routes(&graph, &mut scorer, &params, features, random_init_seed(), 0, 2);
@@ -7136,19 +7135,18 @@ mod tests {
71367135
#[test]
71377136
#[cfg(feature = "std")]
71387137
fn generate_routes_mpp() {
7139-
use crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters};
7138+
use crate::routing::scoring::ProbabilisticScoringFeeParameters;
71407139

71417140
let logger = ln_test_utils::TestLogger::new();
7142-
let graph = match super::bench_utils::read_network_graph(&logger) {
7143-
Ok(f) => f,
7141+
let (graph, mut scorer) = match super::bench_utils::read_graph_scorer(&logger) {
7142+
Ok(res) => res,
71447143
Err(e) => {
71457144
eprintln!("{}", e);
71467145
return;
71477146
},
71487147
};
71497148

71507149
let params = ProbabilisticScoringFeeParameters::default();
7151-
let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &graph, &logger);
71527150
let features = channelmanager::provided_bolt11_invoice_features(&UserConfig::default());
71537151

71547152
super::bench_utils::generate_test_routes(&graph, &mut scorer, &params, features, random_init_seed(), 0, 2);
@@ -7157,19 +7155,18 @@ mod tests {
71577155
#[test]
71587156
#[cfg(feature = "std")]
71597157
fn generate_large_mpp_routes() {
7160-
use crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters};
7158+
use crate::routing::scoring::ProbabilisticScoringFeeParameters;
71617159

71627160
let logger = ln_test_utils::TestLogger::new();
7163-
let graph = match super::bench_utils::read_network_graph(&logger) {
7164-
Ok(f) => f,
7161+
let (graph, mut scorer) = match super::bench_utils::read_graph_scorer(&logger) {
7162+
Ok(res) => res,
71657163
Err(e) => {
71667164
eprintln!("{}", e);
71677165
return;
71687166
},
71697167
};
71707168

71717169
let params = ProbabilisticScoringFeeParameters::default();
7172-
let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &graph, &logger);
71737170
let features = channelmanager::provided_bolt11_invoice_features(&UserConfig::default());
71747171

71757172
super::bench_utils::generate_test_routes(&graph, &mut scorer, &params, features, random_init_seed(), 1_000_000, 2);
@@ -8498,56 +8495,71 @@ mod tests {
84988495
pub(crate) mod bench_utils {
84998496
use super::*;
85008497
use std::fs::File;
8501-
use std::time::Duration;
85028498

85038499
use bitcoin::hashes::Hash;
85048500
use bitcoin::secp256k1::SecretKey;
85058501

85068502
use crate::chain::transaction::OutPoint;
8507-
use crate::routing::scoring::ScoreUpdate;
8503+
use crate::routing::scoring::{ProbabilisticScorer, ScoreUpdate};
85088504
use crate::sign::KeysManager;
85098505
use crate::ln::channel_state::{ChannelCounterparty, ChannelShutdownState};
85108506
use crate::ln::channelmanager;
85118507
use crate::ln::types::ChannelId;
85128508
use crate::util::config::UserConfig;
85138509
use crate::util::test_utils::TestLogger;
8510+
use crate::sync::Arc;
85148511

85158512
/// Tries to open a network graph file, or panics with a URL to fetch it.
8516-
pub(crate) fn get_route_file() -> Result<std::fs::File, &'static str> {
8517-
let res = File::open("net_graph-2023-01-18.bin") // By default we're run in RL/lightning
8518-
.or_else(|_| File::open("lightning/net_graph-2023-01-18.bin")) // We may be run manually in RL/
8519-
.or_else(|_| { // Fall back to guessing based on the binary location
8520-
// path is likely something like .../rust-lightning/target/debug/deps/lightning-...
8521-
let mut path = std::env::current_exe().unwrap();
8522-
path.pop(); // lightning-...
8523-
path.pop(); // deps
8524-
path.pop(); // debug
8525-
path.pop(); // target
8526-
path.push("lightning");
8527-
path.push("net_graph-2023-01-18.bin");
8528-
File::open(path)
8529-
})
8530-
.or_else(|_| { // Fall back to guessing based on the binary location for a subcrate
8531-
// path is likely something like .../rust-lightning/bench/target/debug/deps/bench..
8532-
let mut path = std::env::current_exe().unwrap();
8533-
path.pop(); // bench...
8534-
path.pop(); // deps
8535-
path.pop(); // debug
8536-
path.pop(); // target
8537-
path.pop(); // bench
8538-
path.push("lightning");
8539-
path.push("net_graph-2023-01-18.bin");
8540-
File::open(path)
8541-
})
8542-
.map_err(|_| "Please fetch https://bitcoin.ninja/ldk-net_graph-v0.0.113-2023-01-18.bin and place it at lightning/net_graph-2023-01-18.bin");
8513+
pub(crate) fn get_graph_scorer_file() -> Result<(std::fs::File, std::fs::File), &'static str> {
8514+
let load_file = |fname, err_str| {
8515+
File::open(fname) // By default we're run in RL/lightning
8516+
.or_else(|_| File::open(&format!("lightning/{}", fname))) // We may be run manually in RL/
8517+
.or_else(|_| { // Fall back to guessing based on the binary location
8518+
// path is likely something like .../rust-lightning/target/debug/deps/lightning-...
8519+
let mut path = std::env::current_exe().unwrap();
8520+
path.pop(); // lightning-...
8521+
path.pop(); // deps
8522+
path.pop(); // debug
8523+
path.pop(); // target
8524+
path.push("lightning");
8525+
path.push(fname);
8526+
File::open(path)
8527+
})
8528+
.or_else(|_| { // Fall back to guessing based on the binary location for a subcrate
8529+
// path is likely something like .../rust-lightning/bench/target/debug/deps/bench..
8530+
let mut path = std::env::current_exe().unwrap();
8531+
path.pop(); // bench...
8532+
path.pop(); // deps
8533+
path.pop(); // debug
8534+
path.pop(); // target
8535+
path.pop(); // bench
8536+
path.push("lightning");
8537+
path.push(fname);
8538+
File::open(path)
8539+
})
8540+
.map_err(|_| err_str)
8541+
};
8542+
let graph_res = load_file(
8543+
"net_graph-2023-12-10.bin",
8544+
"Please fetch https://bitcoin.ninja/ldk-net_graph-v0.0.118-2023-12-10.bin and place it at lightning/net_graph-2023-12-10.bin"
8545+
);
8546+
let scorer_res = load_file(
8547+
"scorer-2023-12-10.bin",
8548+
"Please fetch https://bitcoin.ninja/ldk-scorer-v0.0.118-2023-12-10.bin and place it at scorer-2023-12-10.bin"
8549+
);
85438550
#[cfg(require_route_graph_test)]
8544-
return Ok(res.unwrap());
8551+
return Ok((graph_res.unwrap(), scorer_res.unwrap()));
85458552
#[cfg(not(require_route_graph_test))]
8546-
return res;
8553+
return Ok((graph_res?, scorer_res?));
85478554
}
85488555

8549-
pub(crate) fn read_network_graph(logger: &TestLogger) -> Result<NetworkGraph<&TestLogger>, &'static str> {
8550-
get_route_file().map(|mut f| NetworkGraph::read(&mut f, logger).unwrap())
8556+
pub(crate) fn read_graph_scorer(logger: &TestLogger)
8557+
-> Result<(Arc<NetworkGraph<&TestLogger>>, ProbabilisticScorer<Arc<NetworkGraph<&TestLogger>>, &TestLogger>), &'static str> {
8558+
let (mut graph_file, mut scorer_file) = get_graph_scorer_file()?;
8559+
let graph = Arc::new(NetworkGraph::read(&mut graph_file, logger).unwrap());
8560+
let scorer_args = (Default::default(), Arc::clone(&graph), logger);
8561+
let scorer = ProbabilisticScorer::read(&mut scorer_file, scorer_args).unwrap();
8562+
Ok((graph, scorer))
85518563
}
85528564

85538565
pub(crate) fn payer_pubkey() -> PublicKey {
@@ -8609,9 +8621,7 @@ pub(crate) mod bench_utils {
86098621

86108622
let nodes = graph.read_only().nodes().clone();
86118623
let mut route_endpoints = Vec::new();
8612-
// Fetch 1.5x more routes than we need as after we do some scorer updates we may end up
8613-
// with some routes we picked being un-routable.
8614-
for _ in 0..route_count * 3 / 2 {
8624+
for _ in 0..route_count {
86158625
loop {
86168626
seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
86178627
let src = PublicKey::from_slice(nodes.unordered_keys()
@@ -8629,37 +8639,6 @@ pub(crate) mod bench_utils {
86298639
get_route(&payer, &route_params, &graph.read_only(), Some(&[&first_hop]),
86308640
&TestLogger::new(), scorer, score_params, &random_seed_bytes).is_ok();
86318641
if path_exists {
8632-
// ...and seed the scorer with success and failure data...
8633-
seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
8634-
let mut score_amt = seed % 1_000_000_000;
8635-
loop {
8636-
// Generate fail/success paths for a wider range of potential amounts with
8637-
// MPP enabled to give us a chance to apply penalties for more potential
8638-
// routes.
8639-
let mpp_features = channelmanager::provided_bolt11_invoice_features(&UserConfig::default());
8640-
let params = PaymentParameters::from_node_id(dst, 42)
8641-
.with_bolt11_features(mpp_features).unwrap();
8642-
let route_params = RouteParameters::from_payment_params_and_value(
8643-
params.clone(), score_amt);
8644-
let route_res = get_route(&payer, &route_params, &graph.read_only(),
8645-
Some(&[&first_hop]), &TestLogger::new(), scorer, score_params,
8646-
&random_seed_bytes);
8647-
if let Ok(route) = route_res {
8648-
for path in route.paths {
8649-
if seed & 0x80 == 0 {
8650-
scorer.payment_path_successful(&path, Duration::ZERO);
8651-
} else {
8652-
let short_channel_id = path.hops[path.hops.len() / 2].short_channel_id;
8653-
scorer.payment_path_failed(&path, short_channel_id, Duration::ZERO);
8654-
}
8655-
seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0;
8656-
}
8657-
break;
8658-
}
8659-
// If we couldn't find a path with a higher amount, reduce and try again.
8660-
score_amt /= 100;
8661-
}
8662-
86638642
route_endpoints.push((first_hop, params, amt_msat));
86648643
break;
86658644
}
@@ -8689,7 +8668,7 @@ pub mod benches {
86898668
use crate::ln::channelmanager;
86908669
use crate::ln::features::Bolt11InvoiceFeatures;
86918670
use crate::routing::gossip::NetworkGraph;
8692-
use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringFeeParameters, ProbabilisticScoringDecayParameters};
8671+
use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScoringFeeParameters};
86938672
use crate::util::config::UserConfig;
86948673
use crate::util::logger::{Logger, Record};
86958674
use crate::util::test_utils::TestLogger;
@@ -8703,15 +8682,15 @@ pub mod benches {
87038682

87048683
pub fn generate_routes_with_zero_penalty_scorer(bench: &mut Criterion) {
87058684
let logger = TestLogger::new();
8706-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8685+
let (network_graph, _) = bench_utils::read_graph_scorer(&logger).unwrap();
87078686
let scorer = FixedPenaltyScorer::with_penalty(0);
87088687
generate_routes(bench, &network_graph, scorer, &Default::default(),
87098688
Bolt11InvoiceFeatures::empty(), 0, "generate_routes_with_zero_penalty_scorer");
87108689
}
87118690

87128691
pub fn generate_mpp_routes_with_zero_penalty_scorer(bench: &mut Criterion) {
87138692
let logger = TestLogger::new();
8714-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8693+
let (network_graph, _) = bench_utils::read_graph_scorer(&logger).unwrap();
87158694
let scorer = FixedPenaltyScorer::with_penalty(0);
87168695
generate_routes(bench, &network_graph, scorer, &Default::default(),
87178696
channelmanager::provided_bolt11_invoice_features(&UserConfig::default()), 0,
@@ -8720,64 +8699,55 @@ pub mod benches {
87208699

87218700
pub fn generate_routes_with_probabilistic_scorer(bench: &mut Criterion) {
87228701
let logger = TestLogger::new();
8723-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8702+
let (network_graph, scorer) = bench_utils::read_graph_scorer(&logger).unwrap();
87248703
let params = ProbabilisticScoringFeeParameters::default();
8725-
let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
87268704
generate_routes(bench, &network_graph, scorer, &params, Bolt11InvoiceFeatures::empty(), 0,
87278705
"generate_routes_with_probabilistic_scorer");
87288706
}
87298707

87308708
pub fn generate_mpp_routes_with_probabilistic_scorer(bench: &mut Criterion) {
87318709
let logger = TestLogger::new();
8732-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8710+
let (network_graph, scorer) = bench_utils::read_graph_scorer(&logger).unwrap();
87338711
let params = ProbabilisticScoringFeeParameters::default();
8734-
let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
87358712
generate_routes(bench, &network_graph, scorer, &params,
87368713
channelmanager::provided_bolt11_invoice_features(&UserConfig::default()), 0,
87378714
"generate_mpp_routes_with_probabilistic_scorer");
87388715
}
87398716

87408717
pub fn generate_large_mpp_routes_with_probabilistic_scorer(bench: &mut Criterion) {
87418718
let logger = TestLogger::new();
8742-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8719+
let (network_graph, scorer) = bench_utils::read_graph_scorer(&logger).unwrap();
87438720
let params = ProbabilisticScoringFeeParameters::default();
8744-
let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
87458721
generate_routes(bench, &network_graph, scorer, &params,
87468722
channelmanager::provided_bolt11_invoice_features(&UserConfig::default()), 100_000_000,
87478723
"generate_large_mpp_routes_with_probabilistic_scorer");
87488724
}
87498725

87508726
pub fn generate_routes_with_nonlinear_probabilistic_scorer(bench: &mut Criterion) {
87518727
let logger = TestLogger::new();
8752-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8728+
let (network_graph, scorer) = bench_utils::read_graph_scorer(&logger).unwrap();
87538729
let mut params = ProbabilisticScoringFeeParameters::default();
87548730
params.linear_success_probability = false;
8755-
let scorer = ProbabilisticScorer::new(
8756-
ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
87578731
generate_routes(bench, &network_graph, scorer, &params,
87588732
channelmanager::provided_bolt11_invoice_features(&UserConfig::default()), 0,
87598733
"generate_routes_with_nonlinear_probabilistic_scorer");
87608734
}
87618735

87628736
pub fn generate_mpp_routes_with_nonlinear_probabilistic_scorer(bench: &mut Criterion) {
87638737
let logger = TestLogger::new();
8764-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8738+
let (network_graph, scorer) = bench_utils::read_graph_scorer(&logger).unwrap();
87658739
let mut params = ProbabilisticScoringFeeParameters::default();
87668740
params.linear_success_probability = false;
8767-
let scorer = ProbabilisticScorer::new(
8768-
ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
87698741
generate_routes(bench, &network_graph, scorer, &params,
87708742
channelmanager::provided_bolt11_invoice_features(&UserConfig::default()), 0,
87718743
"generate_mpp_routes_with_nonlinear_probabilistic_scorer");
87728744
}
87738745

87748746
pub fn generate_large_mpp_routes_with_nonlinear_probabilistic_scorer(bench: &mut Criterion) {
87758747
let logger = TestLogger::new();
8776-
let network_graph = bench_utils::read_network_graph(&logger).unwrap();
8748+
let (network_graph, scorer) = bench_utils::read_graph_scorer(&logger).unwrap();
87778749
let mut params = ProbabilisticScoringFeeParameters::default();
87788750
params.linear_success_probability = false;
8779-
let scorer = ProbabilisticScorer::new(
8780-
ProbabilisticScoringDecayParameters::default(), &network_graph, &logger);
87818751
generate_routes(bench, &network_graph, scorer, &params,
87828752
channelmanager::provided_bolt11_invoice_features(&UserConfig::default()), 100_000_000,
87838753
"generate_large_mpp_routes_with_nonlinear_probabilistic_scorer");

0 commit comments

Comments
 (0)