Skip to content

Commit ea64aef

Browse files
committed
bench(chain): Add reindex_tx_graph benchmark
1 parent 603f133 commit ea64aef

2 files changed

Lines changed: 126 additions & 0 deletions

File tree

crates/chain/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,7 @@ rusqlite = ["std", "dep:rusqlite", "serde"]
4040
[[bench]]
4141
name = "canonicalization"
4242
harness = false
43+
44+
[[bench]]
45+
name = "indexer"
46+
harness = false

crates/chain/benches/indexer.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use bdk_chain::{
2+
keychain_txout::KeychainTxOutIndex, local_chain::LocalChain, CanonicalizationParams,
3+
IndexedTxGraph,
4+
};
5+
use bdk_core::{BlockId, CheckPoint, ConfirmationBlockTime, TxUpdate};
6+
use bitcoin::{
7+
absolute, constants, hashes::Hash, key::Secp256k1, transaction, Amount, BlockHash, Network,
8+
Transaction, TxIn, TxOut,
9+
};
10+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
11+
use miniscript::Descriptor;
12+
use std::sync::Arc;
13+
14+
type Keychain = ();
15+
type KeychainTxGraph = IndexedTxGraph<ConfirmationBlockTime, KeychainTxOutIndex<Keychain>>;
16+
17+
const DESC: &str = "tr([ab28dc00/86h/1h/0h]tpubDCdDtzAMZZrkwKBxwNcGCqe4FRydeD9rfMisoi7qLdraG79YohRfPW4YgdKQhpgASdvh612xXNY5xYzoqnyCgPbkpK4LSVcH5Xv4cK7johH/0/*)";
18+
const LOOKAHEAD: u32 = 10;
19+
const LAST_REVEALED: u32 = 500;
20+
const TX_CT: u32 = 21;
21+
const USE_SPK_CACHE: bool = true;
22+
const AMOUNT: Amount = Amount::from_sat(1_000);
23+
24+
fn new_tx(lt: u32) -> Transaction {
25+
Transaction {
26+
version: transaction::Version::TWO,
27+
lock_time: absolute::LockTime::from_consensus(lt),
28+
input: vec![],
29+
output: vec![TxOut::NULL],
30+
}
31+
}
32+
33+
fn genesis_block_id() -> BlockId {
34+
BlockId {
35+
height: 0,
36+
hash: constants::genesis_block(Network::Regtest).block_hash(),
37+
}
38+
}
39+
40+
fn tip_block_id() -> BlockId {
41+
BlockId {
42+
height: 100,
43+
hash: BlockHash::all_zeros(),
44+
}
45+
}
46+
47+
fn setup<F: Fn(&mut KeychainTxGraph, &LocalChain)>(f: F) -> (KeychainTxGraph, LocalChain) {
48+
let desc = Descriptor::parse_descriptor(&Secp256k1::new(), DESC)
49+
.unwrap()
50+
.0;
51+
52+
let cp = CheckPoint::from_block_ids([genesis_block_id(), tip_block_id()]).unwrap();
53+
let chain = LocalChain::from_tip(cp).unwrap();
54+
55+
let mut index = KeychainTxOutIndex::new(LOOKAHEAD, USE_SPK_CACHE);
56+
index.insert_descriptor((), desc).unwrap();
57+
let mut tx_graph = KeychainTxGraph::new(index);
58+
59+
f(&mut tx_graph, &chain);
60+
61+
(tx_graph, chain)
62+
}
63+
64+
fn do_bench(indexed_tx_graph: &mut KeychainTxGraph, chain: &LocalChain) {
65+
let desc = Descriptor::parse_descriptor(&Secp256k1::new(), DESC)
66+
.unwrap()
67+
.0;
68+
let changeset = indexed_tx_graph.initial_changeset();
69+
70+
// Now recover
71+
let graph =
72+
KeychainTxGraph::from_changeset(changeset, |c| -> Result<_, core::convert::Infallible> {
73+
let mut index = KeychainTxOutIndex::from_changeset(LOOKAHEAD, USE_SPK_CACHE, c);
74+
let _ = index.insert_descriptor((), desc);
75+
Ok(index)
76+
})
77+
.unwrap()
78+
.0;
79+
80+
// Check balance
81+
let chain_tip = chain.tip().block_id();
82+
let op = graph.index.outpoints().clone();
83+
let bal = graph.graph().balance(
84+
chain,
85+
chain_tip,
86+
CanonicalizationParams::default(),
87+
op,
88+
|_, _| false,
89+
);
90+
assert_eq!(bal.total(), AMOUNT * TX_CT as u64);
91+
}
92+
93+
pub fn reindex_tx_graph(c: &mut Criterion) {
94+
let (mut graph, chain) = black_box(setup(|graph, _chain| {
95+
// Add relevant txs to graph
96+
for i in 0..TX_CT {
97+
let script_pubkey = graph.index.reveal_next_spk(()).unwrap().0 .1;
98+
let tx = Transaction {
99+
input: vec![TxIn::default()],
100+
output: vec![TxOut {
101+
script_pubkey,
102+
value: Amount::from_sat(1_000),
103+
}],
104+
..new_tx(i)
105+
};
106+
let txid = tx.compute_txid();
107+
let mut update = TxUpdate::default();
108+
update.seen_ats = [(txid, i as u64)].into();
109+
update.txs = vec![Arc::new(tx)];
110+
let _ = graph.apply_update(update);
111+
}
112+
// Reveal some more addresses
113+
let _ = graph.index.reveal_to_target((), LAST_REVEALED);
114+
}));
115+
116+
c.bench_function("reindex_tx_graph", {
117+
move |b| b.iter(|| do_bench(&mut graph, &chain))
118+
});
119+
}
120+
121+
criterion_group!(benches, reindex_tx_graph);
122+
criterion_main!(benches);

0 commit comments

Comments
 (0)