11use  std:: { 
2-     collections:: BTreeMap , 
2+     collections:: { BTreeMap ,   BTreeSet } , 
33    io:: { self ,  Write } , 
44    sync:: Mutex , 
55} ; 
66
77use  bdk_chain:: { 
88    bitcoin:: { Address ,  Network ,  OutPoint ,  ScriptBuf ,  Txid } , 
9-     indexed_tx_graph:: { self ,   IndexedTxGraph } , 
9+     indexed_tx_graph:: IndexedTxGraph , 
1010    keychain:: WalletChangeSet , 
1111    local_chain:: { CheckPoint ,  LocalChain } , 
1212    Append ,  ConfirmationTimeAnchor , 
@@ -114,17 +114,15 @@ fn main() -> anyhow::Result<()> {
114114        } 
115115    } ; 
116116
117-     // This is where we will accumulate changes of `IndexedTxGraph` and `LocalChain` and persist 
118-     // these changes as a batch at the end. 
119-     let  mut  changeset = WalletChangeSet :: < Keychain ,  ConfirmationTimeAnchor > :: default ( ) ; 
120- 
121117    // Prepare the `IndexedTxGraph` update based on whether we are scanning or syncing. 
122118    // Scanning: We are iterating through spks of all keychains and scanning for transactions for 
123119    //   each spk. We start with the lowest derivation index spk and stop scanning after `stop_gap` 
124-     //   number of consecutive spks have no transaction history. 
120+     //   number of consecutive spks have no transaction history. A Scan is done in situations of 
121+     //   wallet restoration. It is a special case. Applications should use "sync" style updates 
122+     //   after an initial scan. 
125123    // Syncing: We only check for specified spks, utxos and txids to update their confirmation 
126124    //   status or fetch missing transactions. 
127-     let  graph_update  = match  & esplora_cmd { 
125+     let  indexed_tx_graph_changeset  = match  & esplora_cmd { 
128126        EsploraCommands :: Scan  { 
129127            stop_gap, 
130128            scan_options, 
@@ -155,7 +153,7 @@ fn main() -> anyhow::Result<()> {
155153            // is reached. It returns a `TxGraph` update (`graph_update`) and a structure that 
156154            // represents the last active spk derivation indices of keychains 
157155            // (`keychain_indices_update`). 
158-             let  ( graph_update,  keychain_indices_update )  = client
156+             let  ( graph_update,  last_active_indices )  = client
159157                . update_tx_graph ( 
160158                    keychain_spks, 
161159                    core:: iter:: empty ( ) , 
@@ -165,18 +163,15 @@ fn main() -> anyhow::Result<()> {
165163                ) 
166164                . context ( "scanning for transactions" ) ?; 
167165
168-             // Update the index in `IndexedTxGraph` with `keychain_indices_update`. The resultant 
169-             // changes are appended to `changeset`. 
170-             changeset. append ( { 
171-                 let  ( _,  index_additions)  = graph
172-                     . lock ( ) 
173-                     . expect ( "mutex must not be poisoned" ) 
174-                     . index 
175-                     . reveal_to_target_multi ( & keychain_indices_update) ; 
176-                 WalletChangeSet :: from ( indexed_tx_graph:: ChangeSet :: from ( index_additions) ) 
177-             } ) ; 
178- 
179-             graph_update
166+             let  mut  graph = graph. lock ( ) . expect ( "mutex must not be poisoned" ) ; 
167+             // Because we did a stop gap based scan we are likely to have some updates to our 
168+             // deriviation indices. Usually before a scan you are on a fresh wallet with no 
169+             // addresses derived so we need to derive up to last active addresses the scan found 
170+             // before adding the transactions. 
171+             let  ( _,  index_changeset)  = graph. index . reveal_to_target_multi ( & last_active_indices) ; 
172+             let  mut  indexed_tx_graph_changeset = graph. apply_update ( graph_update) ; 
173+             indexed_tx_graph_changeset. append ( index_changeset. into ( ) ) ; 
174+             indexed_tx_graph_changeset
180175        } 
181176        EsploraCommands :: Sync  { 
182177            mut  unused_spks, 
@@ -281,42 +276,31 @@ fn main() -> anyhow::Result<()> {
281276                } 
282277            } 
283278
284-             client. update_tx_graph_without_keychain ( 
279+             let  graph_update =  client. update_tx_graph_without_keychain ( 
285280                spks, 
286281                txids, 
287282                outpoints, 
288283                scan_options. parallel_requests , 
289-             ) ?
284+             ) ?; 
285+ 
286+             graph. lock ( ) . unwrap ( ) . apply_update ( graph_update) 
290287        } 
291288    } ; 
292289
293290    println ! ( ) ; 
294291
295-     // We apply the `TxGraph` update, and append the resultant changes to `changeset` 
296-     // (for persistance) 
297-     changeset. append ( { 
298-         let  indexed_graph_additions = graph. lock ( ) . unwrap ( ) . apply_update ( graph_update) ; 
299-         WalletChangeSet :: from ( indexed_graph_additions) 
300-     } ) ; 
301- 
302-     // Now that we're done updating the `TxGraph`, it's time to update the `LocalChain`! 
303-     // We want the `LocalChain` to have data about all the anchors in the `TxGraph` - for this 
304-     // reason, we want retrieve the heights of the newly added anchors, and fetch the corresponding 
305-     // blocks. 
306- 
307-     // We get the heights of all the anchors introduced by the changeset, and the local chain tip. 
308-     // Note that the latter is only used for logging. 
292+     // Now that we're done updating the `IndexedTxGraph`, it's time to update the `LocalChain`! We 
293+     // want the `LocalChain` to have data about all the anchors in the `TxGraph` - for this reason, 
294+     // we want retrieve the blocks at the heights of the newly added anchors that are missing from 
295+     // our view of the chain. 
309296    let  ( missing_block_heights,  tip)  = { 
310297        let  chain = & * chain. lock ( ) . unwrap ( ) ; 
311-         let  heights_to_fetch = changeset
312-             . indexed_tx_graph 
298+         let  missing_block_heights = indexed_tx_graph_changeset
313299            . graph 
314-             . anchors 
315-             . iter ( ) 
316-             . map ( |( a,  _) | a. confirmation_height ) 
317-             . collect :: < Vec < _ > > ( ) ; 
300+             . missing_heights_from ( chain) 
301+             . collect :: < BTreeSet < _ > > ( ) ; 
318302        let  tip = chain. tip ( ) ; 
319-         ( heights_to_fetch ,  tip) 
303+         ( missing_block_heights ,  tip) 
320304    } ; 
321305
322306    println ! ( "prev tip: {}" ,  tip. as_ref( ) . map_or( 0 ,  CheckPoint :: height) ) ; 
@@ -329,16 +313,12 @@ fn main() -> anyhow::Result<()> {
329313
330314    println ! ( "new tip: {}" ,  chain_update. tip. height( ) ) ; 
331315
332-     // We apply the `LocalChain` update, and append the resultant changes to `changeset` 
333-     // (for persistance). 
334-     changeset. append ( { 
335-         let  chain_additions = chain. lock ( ) . unwrap ( ) . apply_update ( chain_update) ?; 
336-         WalletChangeSet :: from ( chain_additions) 
337-     } ) ; 
338- 
339-     // We persist `changeset`. 
316+     // We persist the changes 
340317    let  mut  db = db. lock ( ) . unwrap ( ) ; 
341-     db. stage ( changeset) ; 
318+     db. stage ( WalletChangeSet  { 
319+         chain :  chain. lock ( ) . unwrap ( ) . apply_update ( chain_update) ?, 
320+         indexed_tx_graph :  indexed_tx_graph_changeset, 
321+     } ) ; 
342322    db. commit ( ) ?; 
343323    Ok ( ( ) ) 
344324} 
0 commit comments