11//! Manages connection with a Bitcoin Core RPC.
22//!
3- use std:: { convert:: TryFrom , thread} ;
3+ use std:: { convert:: TryFrom , ops :: Mul , thread} ;
44
5- use bitcoind:: bitcoincore_rpc:: { json:: ListUnspentResultEntry , Auth , Client , RpcApi } ;
5+ use bitcoind:: bitcoincore_rpc:: {
6+ json:: { ListUnspentResultEntry , ScanningDetails } ,
7+ Auth , Client , RpcApi ,
8+ } ;
69use serde_json:: { json, Value } ;
710
811use crate :: { utill:: HEART_BEAT_INTERVAL , wallet:: api:: KeychainKind } ;
@@ -130,40 +133,43 @@ impl Wallet {
130133 return Ok ( ( ) ) ;
131134 }
132135
133- log:: debug!( "Importing Wallet spks/descriptors" ) ;
134-
135136 self . import_descriptors ( & descriptors_to_import, None ) ?;
136137
137- // Now run the scan
138- log:: debug!( "Initializing TxOut scan. This may take a while." ) ;
139-
140138 // Sometimes in test multiple wallet scans can occur at same time, resulting in error.
141- // Just retry after 3 sec.
139+ let last_synced_height = self
140+ . store
141+ . last_synced_height
142+ . unwrap_or ( 0 )
143+ . min ( self . store . wallet_birthday . unwrap_or ( 0 ) ) ;
144+ let node_synced = self . rpc . get_block_count ( ) ?;
145+ log:: info!( "Re-scanning Blockchain from:{last_synced_height} to:{node_synced}" ) ;
146+
147+ let _ = self . rpc . rescan_blockchain (
148+ Some ( last_synced_height as usize ) ,
149+ Some ( node_synced as usize ) ,
150+ ) ;
151+
152+ // Returns when the scanning is complete
142153 loop {
143- let last_synced_height = self
144- . store
145- . last_synced_height
146- . unwrap_or ( 0 )
147- . max ( self . store . wallet_birthday . unwrap_or ( 0 ) ) ;
148- let node_synced = self . rpc . get_block_count ( ) ?;
149- log:: debug!( "Re-scanning Blockchain from:{last_synced_height} to:{node_synced}" ) ;
150- match self . rpc . rescan_blockchain (
151- Some ( last_synced_height as usize ) ,
152- Some ( node_synced as usize ) ,
153- ) {
154- Ok ( _) => {
155- self . store . last_synced_height = Some ( node_synced) ;
154+ let wallet_info = self . rpc . get_wallet_info ( ) ?;
155+ match wallet_info. scanning {
156+ Some ( ScanningDetails :: Scanning { duration, progress } ) => {
157+ log:: info!( "Scanning for {}s - {:.2}%" , duration, progress. mul( 100.0 ) ) ;
158+ thread:: sleep ( HEART_BEAT_INTERVAL ) ;
159+ continue ;
160+ }
161+ Some ( ScanningDetails :: NotScanning ( _) ) => {
162+ log:: info!( "Scanning completed" ) ;
156163 break ;
157164 }
158-
159- Err ( e) => {
160- log:: warn!( "Sync Error, Retrying: {e}" ) ;
165+ None => {
166+ log:: info!( "No scan is in progress or Scanning completed" ) ;
161167 thread:: sleep ( HEART_BEAT_INTERVAL ) ;
162- continue ;
168+ break ;
163169 }
164170 }
165171 }
166-
172+ self . store . last_synced_height = Some ( node_synced ) ;
167173 self . update_utxo_cache ( self . get_all_utxo_from_rpc ( ) ?) ;
168174
169175 let max_external_index = self . find_hd_next_index ( KeychainKind :: External ) ?;
@@ -177,6 +183,7 @@ impl Wallet {
177183 fn sync_no_fail ( & mut self ) {
178184 while let Err ( e) = self . sync ( ) {
179185 log:: error!( "Blockchain sync failed. Retrying. | {e:?}" ) ;
186+ thread:: sleep ( HEART_BEAT_INTERVAL ) ;
180187 }
181188 }
182189
0 commit comments