Skip to content

Commit 5df03f7

Browse files
committed
fix: persistence tests
1 parent ddcc565 commit 5df03f7

File tree

1 file changed

+115
-80
lines changed

1 file changed

+115
-80
lines changed

wallet/src/persist_test_utils.rs

Lines changed: 115 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#![allow(missing_docs)]
22
use crate::{
33
bitcoin::{
4-
absolute, hashes::Hash, transaction, Amount, BlockHash, Network, OutPoint, ScriptBuf,
5-
Transaction, TxIn, TxOut, Txid,
4+
absolute, hashes::Hash, key::Secp256k1, transaction, Address, Amount, BlockHash, Network,
5+
OutPoint, ScriptBuf, Transaction, TxIn, TxOut, Txid,
66
},
77
chain::{keychain_txout, local_chain, tx_graph, ConfirmationBlockTime, DescriptorExt, Merge},
88
miniscript::descriptor::{Descriptor, DescriptorPublicKey},
@@ -12,13 +12,14 @@ use bdk_testenv::{block_id, hash};
1212
use std::collections::BTreeMap;
1313
use std::fmt::Debug;
1414
use std::path::Path;
15+
use std::str::FromStr;
1516
use std::sync::Arc;
1617

17-
pub const DESCRIPTORS: [&str; 4] = [
18-
"tr([5940b9b9/86'/0'/0']tpubDDVNqmq75GNPWQ9UNKfP43UwjaHU4GYfoPavojQbfpyfZp2KetWgjGBRRAy4tYCrAA6SB11mhQAkqxjh1VtQHyKwT4oYxpwLaGHvoKmtxZf/1/*)#ypcpw2dr",
18+
const DESCRIPTORS: [&str; 4] = [
1919
"tr([5940b9b9/86'/0'/0']tpubDDVNqmq75GNPWQ9UNKfP43UwjaHU4GYfoPavojQbfpyfZp2KetWgjGBRRAy4tYCrAA6SB11mhQAkqxjh1VtQHyKwT4oYxpwLaGHvoKmtxZf/0/*)#44aqnlam",
20-
"wpkh([41f2aed0/84h/1h/0h]tpubDDFSdQWw75hk1ewbwnNpPp5DvXFRKt68ioPoyJDY752cNHKkFxPWqkqCyCf4hxrEfpuxh46QisehL3m8Bi6MsAv394QVLopwbtfvryFQNUH/1/*)#emtwewtk",
20+
"tr([5940b9b9/86'/0'/0']tpubDDVNqmq75GNPWQ9UNKfP43UwjaHU4GYfoPavojQbfpyfZp2KetWgjGBRRAy4tYCrAA6SB11mhQAkqxjh1VtQHyKwT4oYxpwLaGHvoKmtxZf/1/*)#ypcpw2dr",
2121
"wpkh([41f2aed0/84h/1h/0h]tpubDDFSdQWw75hk1ewbwnNpPp5DvXFRKt68ioPoyJDY752cNHKkFxPWqkqCyCf4hxrEfpuxh46QisehL3m8Bi6MsAv394QVLopwbtfvryFQNUH/0/*)#g0w0ymmw",
22+
"wpkh([41f2aed0/84h/1h/0h]tpubDDFSdQWw75hk1ewbwnNpPp5DvXFRKt68ioPoyJDY752cNHKkFxPWqkqCyCf4hxrEfpuxh46QisehL3m8Bi6MsAv394QVLopwbtfvryFQNUH/1/*)#emtwewtk",
2223
];
2324

2425
pub fn create_one_inp_one_out_tx(txid: Txid, amount: u64) -> Transaction {
@@ -31,33 +32,49 @@ pub fn create_one_inp_one_out_tx(txid: Txid, amount: u64) -> Transaction {
3132
}],
3233
output: vec![TxOut {
3334
value: Amount::from_sat(amount),
34-
script_pubkey: ScriptBuf::new(),
35+
script_pubkey: Address::from_str("bcrt1q3qtze4ys45tgdvguj66zrk4fu6hq3a3v9pfly5")
36+
.unwrap()
37+
.assume_checked()
38+
.script_pubkey(),
3539
}],
3640
}
3741
}
3842

39-
pub fn persist_wallet_changeset<Db, CreateDb>(filename: &str, create_db: CreateDb)
43+
fn spk_at_index(descriptor: &Descriptor<DescriptorPublicKey>, index: u32) -> ScriptBuf {
44+
descriptor
45+
.derived_descriptor(&Secp256k1::verification_only(), index)
46+
.expect("must derive")
47+
.script_pubkey()
48+
}
49+
50+
pub fn create_test_store<Store, CreateStore>(filename: &str, create_store: CreateStore) -> Store
4051
where
41-
CreateDb: Fn(&Path) -> anyhow::Result<Db>,
42-
Db: WalletPersister,
43-
Db::Error: Debug,
52+
CreateStore: Fn(&Path) -> anyhow::Result<Store>,
4453
{
4554
let temp_dir = tempfile::tempdir().expect("must create tempdir");
4655
let file_path = temp_dir.path().join(filename);
56+
create_store(&file_path).expect("store should get created")
57+
}
4758

48-
let mut db = create_db(&file_path).expect("db should get created");
59+
pub fn persist_wallet_changeset<Store, CreateStore>(filename: &str, create_store: CreateStore)
60+
where
61+
CreateStore: Fn(&Path) -> anyhow::Result<Store>,
62+
Store: WalletPersister,
63+
Store::Error: Debug,
64+
{
65+
let mut store = create_test_store(filename, create_store);
4966

5067
let changeset =
51-
WalletPersister::initialize(&mut db).expect("empty changeset should get loaded");
68+
WalletPersister::initialize(&mut store).expect("empty changeset should get loaded");
5269
assert_eq!(changeset, ChangeSet::default());
5370

5471
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[0].parse().unwrap();
5572
let change_descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[1].parse().unwrap();
5673

5774
let mut blocks: BTreeMap<u32, Option<BlockHash>> = BTreeMap::new();
58-
blocks.insert(0u32, Some(hash!("B")));
59-
blocks.insert(1u32, Some(hash!("T")));
60-
blocks.insert(2u32, Some(hash!("C")));
75+
blocks.insert(1u32, Some(hash!("B")));
76+
blocks.insert(2u32, Some(hash!("T")));
77+
blocks.insert(3u32, Some(hash!("C")));
6178
let local_chain_changeset = local_chain::ChangeSet { blocks };
6279

6380
let tx1 = Arc::new(create_one_inp_one_out_tx(
@@ -75,7 +92,23 @@ where
7592

7693
let tx_graph_changeset = tx_graph::ChangeSet::<ConfirmationBlockTime> {
7794
txs: [tx1.clone()].into(),
78-
txouts: [].into(),
95+
txouts: [
96+
(
97+
OutPoint::new(Txid::from_byte_array([0; 32]), 0),
98+
TxOut {
99+
value: Amount::from_sat(1300),
100+
script_pubkey: spk_at_index(&descriptor, 4),
101+
},
102+
),
103+
(
104+
OutPoint::new(Txid::from_byte_array([1; 32]), 0),
105+
TxOut {
106+
value: Amount::from_sat(1400),
107+
script_pubkey: spk_at_index(&descriptor, 10)
108+
},
109+
),
110+
]
111+
.into(),
79112
anchors: [(conf_anchor, tx1.compute_txid())].into(),
80113
last_seen: [(tx1.compute_txid(), 100)].into(),
81114
first_seen: [(tx1.compute_txid(), 80)].into(),
@@ -91,13 +124,13 @@ where
91124
spk_cache: [
92125
(
93126
descriptor.descriptor_id(),
94-
[(0u32, ScriptBuf::from_bytes(vec![245, 123, 112]))].into(),
127+
[(0u32, spk_at_index(&descriptor, 0))].into(),
95128
),
96129
(
97130
change_descriptor.descriptor_id(),
98131
[
99-
(100u32, ScriptBuf::from_bytes(vec![145, 234, 98])),
100-
(1000u32, ScriptBuf::from_bytes(vec![5, 6, 8])),
132+
(100u32, spk_at_index(&change_descriptor, 100)),
133+
(1000u32, spk_at_index(&change_descriptor, 1000)),
101134
]
102135
.into(),
103136
),
@@ -114,9 +147,10 @@ where
114147
indexer: keychain_txout_changeset,
115148
};
116149

117-
WalletPersister::persist(&mut db, &changeset).expect("changeset should get persisted");
150+
WalletPersister::persist(&mut store, &changeset).expect("changeset should get persisted");
118151

119-
let changeset_read = WalletPersister::initialize(&mut db).expect("changeset should get loaded");
152+
let changeset_read =
153+
WalletPersister::initialize(&mut store).expect("changeset should get loaded");
120154

121155
assert_eq!(changeset, changeset_read);
122156

@@ -134,7 +168,14 @@ where
134168

135169
let tx_graph_changeset = tx_graph::ChangeSet::<ConfirmationBlockTime> {
136170
txs: [tx2.clone()].into(),
137-
txouts: [].into(),
171+
txouts: [(
172+
OutPoint::new(Txid::from_byte_array([2; 32]), 0),
173+
TxOut {
174+
value: Amount::from_sat(10000),
175+
script_pubkey: spk_at_index(&descriptor, 21),
176+
},
177+
)]
178+
.into(),
138179
anchors: [(conf_anchor, tx2.compute_txid())].into(),
139180
last_seen: [(tx2.compute_txid(), 200)].into(),
140181
first_seen: [(tx2.compute_txid(), 160)].into(),
@@ -146,30 +187,31 @@ where
146187
spk_cache: [(
147188
change_descriptor.descriptor_id(),
148189
[
149-
(102u32, ScriptBuf::from_bytes(vec![8, 45, 78])),
150-
(1001u32, ScriptBuf::from_bytes(vec![29, 56, 47])),
190+
(102u32, spk_at_index(&change_descriptor, 102)),
191+
(1001u32, spk_at_index(&change_descriptor, 1001)),
151192
]
152193
.into(),
153194
)]
154195
.into(),
155196
};
156197

157198
let changeset_new = ChangeSet {
158-
descriptor: Some(descriptor),
159-
change_descriptor: Some(change_descriptor),
160-
network: Some(Network::Bitcoin),
199+
descriptor: None,
200+
change_descriptor: None,
201+
network: None,
161202
local_chain: local_chain_changeset,
162203
tx_graph: tx_graph_changeset,
163204
indexer: keychain_txout_changeset,
164205
};
165206

166-
WalletPersister::persist(&mut db, &changeset_new).expect("changeset should get persisted");
167-
let changeset_read_new = WalletPersister::initialize(&mut db).unwrap();
207+
WalletPersister::persist(&mut store, &changeset_new).expect("changeset should get persisted");
208+
let changeset_read_new = WalletPersister::initialize(&mut store).unwrap();
168209

169210
changeset.merge(changeset_new);
170211

171212
assert_eq!(changeset, changeset_read_new);
172213
}
214+
173215
pub fn persist_multiple_wallet_changesets<Store, CreateStores>(
174216
filename: &str,
175217
create_dbs: CreateStores,
@@ -184,6 +226,10 @@ pub fn persist_multiple_wallet_changesets<Store, CreateStores>(
184226
let (mut store_first, mut store_sec) =
185227
create_dbs(&file_path).expect("store should get created");
186228

229+
let changeset =
230+
WalletPersister::initialize(&mut store_first).expect("should load empty changeset");
231+
assert_eq!(changeset, ChangeSet::default());
232+
187233
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[0].parse().unwrap();
188234
let change_descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[1].parse().unwrap();
189235

@@ -194,10 +240,6 @@ pub fn persist_multiple_wallet_changesets<Store, CreateStores>(
194240
..ChangeSet::default()
195241
};
196242

197-
let changeset =
198-
WalletPersister::initialize(&mut store_first).expect("should load empty changeset");
199-
assert_eq!(changeset, ChangeSet::default());
200-
201243
WalletPersister::persist(&mut store_first, &changeset1).expect("should persist changeset");
202244

203245
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[2].parse().unwrap();
@@ -225,84 +267,79 @@ pub fn persist_multiple_wallet_changesets<Store, CreateStores>(
225267
assert_eq!(changeset_read, changeset2);
226268
}
227269

228-
pub fn persist_network<Db, CreateDb>(filename: &str, create_db: CreateDb)
270+
pub fn persist_network<Store, CreateStore>(filename: &str, create_store: CreateStore)
229271
where
230-
CreateDb: Fn(&Path) -> anyhow::Result<Db>,
231-
Db: WalletPersister,
232-
Db::Error: Debug,
272+
CreateStore: Fn(&Path) -> anyhow::Result<Store>,
273+
Store: WalletPersister,
274+
Store::Error: Debug,
233275
{
234276
// create db
235-
let temp_dir = tempfile::tempdir().expect("must create tempdir");
236-
let file_path = temp_dir.path().join(filename);
237-
let mut db = create_db(&file_path).expect("db should get created");
277+
let mut store = create_test_store(filename, create_store);
238278

239279
// initialize db
240-
let changeset =
241-
WalletPersister::initialize(&mut db).expect("should initialize and load empty changeset");
280+
let changeset = WalletPersister::initialize(&mut store)
281+
.expect("should initialize and load empty changeset");
242282
assert_eq!(changeset, ChangeSet::default());
243283

244284
// persist the network
245285
let changeset = ChangeSet {
246286
network: Some(Network::Bitcoin),
247287
..ChangeSet::default()
248288
};
249-
WalletPersister::persist(&mut db, &changeset).expect("should persist changeset");
289+
WalletPersister::persist(&mut store, &changeset).expect("should persist changeset");
250290

251291
// read the persisted changeset
252292
let changeset_read =
253-
WalletPersister::initialize(&mut db).expect("should load persisted changeset");
293+
WalletPersister::initialize(&mut store).expect("should load persisted changeset");
254294

255295
assert_eq!(changeset_read.network, Some(Network::Bitcoin));
256296
}
257297

258-
pub fn persist_keychains<Db, CreateDb>(filename: &str, create_db: CreateDb)
298+
// this is technically incorrect but helps in catching errors in impl which the first one doesn't
299+
pub fn persist_keychains<Store, CreateStore>(filename: &str, create_store: CreateStore)
259300
where
260-
CreateDb: Fn(&Path) -> anyhow::Result<Db>,
261-
Db: WalletPersister,
262-
Db::Error: Debug,
301+
CreateStore: Fn(&Path) -> anyhow::Result<Store>,
302+
Store: WalletPersister,
303+
Store::Error: Debug,
263304
{
264305
// create db
265-
let temp_dir = tempfile::tempdir().expect("must create tempdir");
266-
let file_path = temp_dir.path().join(filename);
267-
let mut db = create_db(&file_path).expect("db should get created");
306+
let mut store = create_test_store(filename, create_store);
268307

269308
// initialize db
270-
let changeset =
271-
WalletPersister::initialize(&mut db).expect("should initialize and load empty changeset");
309+
let changeset = WalletPersister::initialize(&mut store)
310+
.expect("should initialize and load empty changeset");
272311
assert_eq!(changeset, ChangeSet::default());
273312

274-
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[0].parse().unwrap();
275-
let change_descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[1].parse().unwrap();
313+
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[1].parse().unwrap();
314+
let change_descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[0].parse().unwrap();
276315

277316
let changeset = ChangeSet {
278317
descriptor: Some(descriptor.clone()),
279318
change_descriptor: Some(change_descriptor.clone()),
280319
..ChangeSet::default()
281320
};
282321

283-
WalletPersister::persist(&mut db, &changeset).expect("should persist descriptors");
322+
WalletPersister::persist(&mut store, &changeset).expect("should persist descriptors");
284323

285324
let changeset_read =
286-
WalletPersister::initialize(&mut db).expect("should read persisted changeset");
325+
WalletPersister::initialize(&mut store).expect("should read persisted changeset");
287326

288327
assert_eq!(changeset_read.descriptor.unwrap(), descriptor);
289328
assert_eq!(changeset_read.change_descriptor.unwrap(), change_descriptor);
290329
}
291330

292-
pub fn persist_keychains_reversed<Db, CreateDb>(filename: &str, create_db: CreateDb)
331+
pub fn persist_keychains_reversed<Store, CreateStore>(filename: &str, create_store: CreateStore)
293332
where
294-
CreateDb: Fn(&Path) -> anyhow::Result<Db>,
295-
Db: WalletPersister,
296-
Db::Error: Debug,
333+
CreateStore: Fn(&Path) -> anyhow::Result<Store>,
334+
Store: WalletPersister,
335+
Store::Error: Debug,
297336
{
298337
// create db
299-
let temp_dir = tempfile::tempdir().expect("must create tempdir");
300-
let file_path = temp_dir.path().join(filename);
301-
let mut db = create_db(&file_path).expect("db should get created");
338+
let mut store = create_test_store(filename, create_store);
302339

303340
// initialize db
304-
let changeset =
305-
WalletPersister::initialize(&mut db).expect("should initialize and load empty changeset");
341+
let changeset = WalletPersister::initialize(&mut store)
342+
.expect("should initialize and load empty changeset");
306343
assert_eq!(changeset, ChangeSet::default());
307344

308345
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[1].parse().unwrap();
@@ -314,42 +351,40 @@ where
314351
..ChangeSet::default()
315352
};
316353

317-
WalletPersister::persist(&mut db, &changeset).expect("should persist descriptors");
354+
WalletPersister::persist(&mut store, &changeset).expect("should persist descriptors");
318355

319356
let changeset_read =
320-
WalletPersister::initialize(&mut db).expect("should read persisted changeset");
357+
WalletPersister::initialize(&mut store).expect("should read persisted changeset");
321358

322359
assert_eq!(changeset_read.descriptor.unwrap(), descriptor);
323360
assert_eq!(changeset_read.change_descriptor.unwrap(), change_descriptor);
324361
}
325362

326-
pub fn persist_single_keychain<Db, CreateDb>(filename: &str, create_db: CreateDb)
363+
pub fn persist_single_keychain<Store, CreateStore>(filename: &str, create_store: CreateStore)
327364
where
328-
CreateDb: Fn(&Path) -> anyhow::Result<Db>,
329-
Db: WalletPersister,
330-
Db::Error: Debug,
365+
CreateStore: Fn(&Path) -> anyhow::Result<Store>,
366+
Store: WalletPersister,
367+
Store::Error: Debug,
331368
{
332369
// create db
333-
let temp_dir = tempfile::tempdir().expect("must create tempdir");
334-
let file_path = temp_dir.path().join(filename);
335-
let mut db = create_db(&file_path).expect("db should get created");
370+
let mut store = create_test_store(filename, create_store);
336371

337372
// initialize db
338-
let changeset =
339-
WalletPersister::initialize(&mut db).expect("should initialize and load empty changeset");
373+
let changeset = WalletPersister::initialize(&mut store)
374+
.expect("should initialize and load empty changeset");
340375
assert_eq!(changeset, ChangeSet::default());
341376

342-
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[1].parse().unwrap();
377+
let descriptor: Descriptor<DescriptorPublicKey> = DESCRIPTORS[0].parse().unwrap();
343378

344379
let changeset = ChangeSet {
345380
descriptor: Some(descriptor.clone()),
346381
..ChangeSet::default()
347382
};
348383

349-
WalletPersister::persist(&mut db, &changeset).expect("should persist descriptors");
384+
WalletPersister::persist(&mut store, &changeset).expect("should persist descriptors");
350385

351386
let changeset_read =
352-
WalletPersister::initialize(&mut db).expect("should read persisted changeset");
387+
WalletPersister::initialize(&mut store).expect("should read persisted changeset");
353388

354389
assert_eq!(changeset_read.descriptor.unwrap(), descriptor);
355390
assert_eq!(changeset_read.change_descriptor, None);

0 commit comments

Comments
 (0)