11#![ allow( missing_docs) ]
22use 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};
1212use std:: collections:: BTreeMap ;
1313use std:: fmt:: Debug ;
1414use std:: path:: Path ;
15+ use std:: str:: FromStr ;
1516use 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
2425pub 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
4051where
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 (
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+
173215pub 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 )
229271where
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 )
259300where
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 )
293332where
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 )
327364where
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