Skip to content

Commit e07ec1c

Browse files
committed
bench(chain): Add reindex_tx_graph benchmark
1 parent 63923c6 commit e07ec1c

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

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

0 commit comments

Comments
 (0)