11use crate :: block_id;
2+ use crate :: hash;
23use bdk_chain:: bitcoin:: { self , hashes:: Hash } ;
34use bdk_chain:: miniscript:: { Descriptor , DescriptorPublicKey } ;
45use bdk_chain:: {
56 bitcoin:: { absolute, transaction, Amount , OutPoint , ScriptBuf , Transaction , TxIn , TxOut , Txid } ,
67 indexer:: keychain_txout,
7- local_chain, tx_graph, ConfirmationBlockTime , DescriptorExt , Merge
8+ local_chain, tx_graph, ConfirmationBlockTime , DescriptorExt , Merge ,
89} ;
9- use crate :: hash;
1010use std:: path:: Path ;
1111use std:: sync:: Arc ;
12+ use std:: collections:: { BTreeMap , BTreeSet } ;
1213
1314pub fn create_one_inp_one_out_tx ( txid : Txid , amount : u64 ) -> Transaction {
1415 Transaction {
@@ -183,11 +184,7 @@ pub fn persist_local_chain_changeset<Db, CreateDb, Initialize, Persist>(
183184
184185 // create a local_chain_changeset, persist that and read it
185186 let local_chain_changeset = local_chain:: ChangeSet {
186- blocks : [
187- ( 0 , Some ( hash ! ( "B" ) ) ) ,
188- ( 1 , Some ( hash ! ( "D" ) ) ) ,
189- ]
190- . into ( ) ,
187+ blocks : [ ( 0 , Some ( hash ! ( "B" ) ) ) , ( 1 , Some ( hash ! ( "D" ) ) ) ] . into ( ) ,
191188 } ;
192189 let changeset = initialize ( & mut db) . expect ( "should load empty changeset" ) ;
193190 assert_eq ! ( changeset, local_chain:: ChangeSet :: default ( ) ) ;
@@ -207,10 +204,117 @@ pub fn persist_local_chain_changeset<Db, CreateDb, Initialize, Persist>(
207204 let changeset = initialize ( & mut db) . unwrap ( ) ;
208205
209206 let local_chain_changeset = local_chain:: ChangeSet {
210- blocks : [ ( 0 , Some ( hash ! ( "B" ) ) ) , ( 1 , Some ( hash ! ( "D" ) ) ) , ( 2 , Some ( hash ! ( "K" ) ) ) ] . into ( ) ,
207+ blocks : [
208+ ( 0 , Some ( hash ! ( "B" ) ) ) ,
209+ ( 1 , Some ( hash ! ( "D" ) ) ) ,
210+ ( 2 , Some ( hash ! ( "K" ) ) ) ,
211+ ]
212+ . into ( ) ,
211213 } ;
212214
213215 assert_eq ! ( local_chain_changeset, changeset) ;
214216}
215217
218+ // no use of adding a persist_blocks fn since local_chain is just blocks rn
219+ // pub fn persist_blocks<Db, CreateDb, Initialize, Persist>(
220+ // filename: &str,
221+ // create_db: CreateDb,
222+ // initialize: Initialize,
223+ // persist: Persist,
224+ // ) where
225+ // CreateDb: Fn(&Path) -> anyhow::Result<Db>,
226+ // Initialize: Fn(&mut Db) -> anyhow::Result<local_chain::ChangeSet>,
227+ // Persist: Fn(&mut Db, &local_chain::ChangeSet) -> anyhow::Result<()>,
228+ // {
229+ // let temp_dir = tempfile::tempdir().expect("must create tempdir");
230+ // let file_path = temp_dir.path().join(filename);
231+ // let mut db = create_db(&file_path).expect("db should get created");
232+
233+ // // create a local_chain_changeset, persist that and read it
234+ // let local_chain_changeset = local_chain::ChangeSet {
235+ // blocks: [
236+ // (0, Some(hash!("B"))),
237+ // (1, Some(hash!("D"))),
238+ // ]
239+ // .into(),
240+ // };
241+ // let changeset = initialize(&mut db).expect("should load empty changeset");
242+ // assert_eq!(changeset, local_chain::ChangeSet::default());
243+
244+ // persist(&mut db, &local_chain_changeset).expect("should persist changeset");
245+
246+ // let changeset = initialize(&mut db).expect("should load persisted changeset");
247+ // assert_eq!(local_chain_changeset, changeset);
248+
249+ // // create another local_chain_changeset, persist that and read it
250+ // let local_chain_changeset = local_chain::ChangeSet {
251+ // blocks: [(2, Some(hash!("K")))].into(),
252+ // };
253+
254+ // persist(&mut db, &local_chain_changeset).expect("should persist changeset");
255+
256+ // let changeset = initialize(&mut db).unwrap();
257+
258+ // let local_chain_changeset = local_chain::ChangeSet {
259+ // blocks: [(0, Some(hash!("B"))), (1, Some(hash!("D"))), (2, Some(hash!("K")))].into(),
260+ // };
261+
262+ // assert_eq!(local_chain_changeset, changeset);
263+ // }
264+
216265// perhaps add test for file_store, sqlite, redb here.
266+
267+ pub fn persist_last_seen < Db , CreateDb , Initialize , Persist > (
268+ filename : & str ,
269+ create_db : CreateDb ,
270+ initialize : Initialize ,
271+ persist : Persist ,
272+ ) where
273+ CreateDb : Fn ( & Path ) -> anyhow:: Result < Db > ,
274+ Initialize : Fn ( & mut Db ) -> anyhow:: Result < tx_graph:: ChangeSet < ConfirmationBlockTime > > ,
275+ Persist : Fn ( & mut Db , & tx_graph:: ChangeSet < ConfirmationBlockTime > ) -> anyhow:: Result < ( ) > ,
276+ {
277+ use tx_graph:: ChangeSet ;
278+ let temp_dir = tempfile:: tempdir ( ) . expect ( "must create tempdir" ) ;
279+ let file_path = temp_dir. path ( ) . join ( filename) ;
280+ let mut db = create_db ( & file_path) . expect ( "db should get created" ) ;
281+
282+ let tx1 = Arc :: new ( create_one_inp_one_out_tx (
283+ Txid :: from_byte_array ( [ 0 ; 32 ] ) ,
284+ 30_000 ,
285+ ) ) ;
286+ let tx2 = Arc :: new ( create_one_inp_one_out_tx ( tx1. compute_txid ( ) , 20_000 ) ) ;
287+ let tx3 = Arc :: new ( create_one_inp_one_out_tx ( tx2. compute_txid ( ) , 19_000 ) ) ;
288+
289+ // try persisting and reading last_seen
290+ let txs: BTreeSet < Arc < Transaction > > = [ tx1. clone ( ) , tx2. clone ( ) ] . into ( ) ;
291+ let mut last_seen: BTreeMap < Txid , u64 > =
292+ [ ( tx1. compute_txid ( ) , 100 ) , ( tx2. compute_txid ( ) , 120 ) ] . into ( ) ;
293+
294+
295+ let changeset = initialize ( & mut db) . expect ( "db should initialize and we should get empty changeset" ) ;
296+ assert_eq ! ( changeset, ChangeSet :: default ( ) ) ;
297+
298+ let changeset = ChangeSet { txs : txs, ..ChangeSet :: default ( ) } ;
299+ persist ( & mut db, & changeset) . expect ( "should persist changeset" ) ;
300+
301+ // to hit the branch for the case when tx is persisted but not in changeset
302+ let txs: BTreeSet < Arc < Transaction > > = BTreeSet :: new ( ) ;
303+
304+ let changeset = ChangeSet { txs : txs, last_seen : last_seen. clone ( ) , ..ChangeSet :: default ( ) } ;
305+ persist ( & mut db, & changeset) . expect ( "should persist changeset" ) ;
306+
307+ let changeset_read = initialize ( & mut db) . expect ( "should load persisted changeset" ) ;
308+ assert_eq ! ( changeset_read. last_seen, last_seen) ;
309+
310+ // persist another last_seen and see if what is read is same as merged one
311+ let txs_new: BTreeSet < Arc < Transaction > > = [ tx3. clone ( ) ] . into ( ) ;
312+ let last_seen_new: BTreeMap < Txid , u64 > = [ ( tx3. compute_txid ( ) , 200 ) ] . into ( ) ;
313+
314+ let changeset = ChangeSet { txs : txs_new, last_seen : last_seen_new. clone ( ) , ..ChangeSet :: default ( ) } ;
315+ persist ( & mut db, & changeset) . expect ( "should persist changeset" ) ;
316+
317+ let changeset_read_new = initialize ( & mut db) . expect ( "should load persisted changeset" ) ;
318+ last_seen. merge ( last_seen_new) ;
319+ assert_eq ! ( changeset_read_new. last_seen, last_seen) ;
320+ }
0 commit comments