Skip to content

Commit c93f4bc

Browse files
committed
feat: add utilities for testing persistence
Added `persist_txgraph_changeset` function and supporting functions.
1 parent a48c97a commit c93f4bc

File tree

3 files changed

+106
-1
lines changed

3 files changed

+106
-1
lines changed

crates/testenv/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ readme = "README.md"
1616
workspace = true
1717

1818
[dependencies]
19-
bdk_chain = { path = "../chain", version = "0.23.0", default-features = false }
19+
bdk_chain = { version = "0.23.0"}
2020
electrsd = { version = "0.28.0", features = [ "legacy" ], default-features = false }
21+
anyhow = "1.0.98"
22+
tempfile = "3.20.0"
2123

2224
[dev-dependencies]
2325
bdk_testenv = { path = "." }

crates/testenv/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod persist_test_utils;
12
pub mod utils;
23

34
use bdk_chain::{
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use crate::block_id;
2+
use bdk_chain::{
3+
bitcoin::{
4+
absolute, transaction, Amount, OutPoint, ScriptBuf, Transaction, TxIn, TxOut,
5+
Txid,
6+
},
7+
tx_graph, ConfirmationBlockTime, Merge,
8+
};
9+
use bdk_chain::bitcoin::{self, hashes::Hash};
10+
use std::path::Path;
11+
use std::sync::Arc;
12+
13+
pub fn create_one_inp_one_out_tx(txid: Txid, amount: u64) -> Transaction {
14+
Transaction {
15+
version: transaction::Version::ONE,
16+
lock_time: absolute::LockTime::ZERO,
17+
input: vec![TxIn {
18+
previous_output: OutPoint::new(txid, 0),
19+
..TxIn::default()
20+
}],
21+
output: vec![TxOut {
22+
value: Amount::from_sat(amount),
23+
script_pubkey: ScriptBuf::new(),
24+
}],
25+
}
26+
}
27+
28+
pub fn persist_txgraph_changeset<Db, CreateDb, Initialize, Persist>(
29+
filename: &str,
30+
create_db: CreateDb,
31+
initialize: Initialize,
32+
persist: Persist,
33+
)
34+
// Can we have this for generic anchor type?
35+
where
36+
CreateDb: Fn(&Path) -> anyhow::Result<Db>,
37+
Initialize: Fn(&mut Db) -> anyhow::Result<tx_graph::ChangeSet<ConfirmationBlockTime>>,
38+
Persist: Fn(&mut Db, &tx_graph::ChangeSet<ConfirmationBlockTime>) -> anyhow::Result<()>,
39+
// A: std::fmt::Debug + PartialEq, // decent assumptions since we should be able to
40+
// // decide if two anchors are same or different
41+
{
42+
let temp_dir = tempfile::tempdir().expect("must create tempdir");
43+
let file_path = temp_dir.path().join(filename);
44+
let mut db = create_db(&file_path).expect("db should get created");
45+
let tx1 = Arc::new(create_one_inp_one_out_tx(
46+
Txid::from_byte_array([0; 32]),
47+
30_000,
48+
));
49+
let block_id = block_id!(100, "B");
50+
51+
let conf_anchor: ConfirmationBlockTime = ConfirmationBlockTime {
52+
block_id,
53+
confirmation_time: 1,
54+
};
55+
56+
let mut tx_graph_changeset1 = tx_graph::ChangeSet::<ConfirmationBlockTime> {
57+
txs: [tx1.clone()].into(),
58+
txouts: [].into(),
59+
anchors: [(conf_anchor, tx1.compute_txid())].into(),
60+
last_seen: [(tx1.compute_txid(), 100)].into(),
61+
first_seen: [(tx1.compute_txid(), 50)].into(),
62+
last_evicted: [(tx1.compute_txid(), 150)].into(),
63+
};
64+
65+
let changeset = initialize(&mut db).expect("should load empty changeset");
66+
assert_eq!(
67+
changeset,
68+
tx_graph::ChangeSet::<ConfirmationBlockTime>::default()
69+
);
70+
71+
persist(&mut db, &tx_graph_changeset1).unwrap();
72+
73+
let changeset = initialize(&mut db).unwrap();
74+
assert_eq!(changeset, tx_graph_changeset1);
75+
76+
let tx2 = Arc::new(create_one_inp_one_out_tx(tx1.compute_txid(), 20_000));
77+
let block_id = block_id!(101, "REDB");
78+
79+
let conf_anchor: ConfirmationBlockTime = ConfirmationBlockTime {
80+
block_id,
81+
confirmation_time: 1,
82+
};
83+
84+
let tx_graph_changeset2 = tx_graph::ChangeSet::<ConfirmationBlockTime> {
85+
txs: [tx2.clone()].into(),
86+
txouts: [].into(),
87+
anchors: [(conf_anchor, tx2.compute_txid())].into(),
88+
last_seen: [(tx2.compute_txid(), 200)].into(),
89+
first_seen: [(tx2.compute_txid(), 100)].into(),
90+
last_evicted: [(tx2.compute_txid(), 150)].into(),
91+
};
92+
93+
persist(&mut db, &tx_graph_changeset2).unwrap();
94+
95+
let changeset = initialize(&mut db).unwrap();
96+
97+
tx_graph_changeset1.merge(tx_graph_changeset2);
98+
99+
assert_eq!(tx_graph_changeset1, changeset);
100+
}
101+
102+
// perhaps add test for file_store, sqlite, redb here.

0 commit comments

Comments
 (0)