@@ -21,7 +21,9 @@ pub enum Request<'a, D: BatchDatabase> {
2121 /// A request for full transaction details of some transactions.
2222 Tx ( TxReq < ' a , D > ) ,
2323 /// Requests are finished here's a batch database update to reflect data gathered.
24- Finish ( D :: Batch ) ,
24+ /// we also return a value which represents the minimum number of scripts that we should cache
25+ /// for next round (or the missing cache count)
26+ Finish ( D :: Batch , usize ) ,
2527}
2628
2729/// starts a sync
@@ -34,7 +36,8 @@ pub fn start<D: BatchDatabase>(db: &D, stop_gap: usize) -> Result<Request<'_, D>
3436 let scripts_needed = db
3537 . iter_script_pubkeys ( Some ( keychain) ) ?
3638 . into_iter ( )
37- . collect ( ) ;
39+ . collect :: < VecDeque < _ > > ( ) ;
40+ println ! ( "scripts_needed count: {}" , scripts_needed. len( ) ) ;
3841 let state = State :: new ( db) ;
3942
4043 Ok ( Request :: Script ( ScriptReq {
@@ -117,39 +120,57 @@ impl<'a, D: BatchDatabase> ScriptReq<'a, D> {
117120 self . scripts_needed . pop_front ( ) ;
118121 }
119122
120- let last_active_index = self
123+ // last active index
124+ // 0 => No last active
125+ let last = self
121126 . state
122127 . last_active_index
123128 . get ( & self . keychain )
124- . map ( |x| x + 1 )
125- . unwrap_or ( 0 ) ; // so no addresses active maps to 0
129+ . map ( |& l| l + 1 )
130+ . unwrap_or ( 0 ) ;
126131
127- Ok (
128- if self . script_index > last_active_index + self . stop_gap
129- || self . scripts_needed . is_empty ( )
130- {
132+ // difference between current index and last active index
133+ let diff = self . script_index - last;
134+
135+ if diff <= self . stop_gap {
136+ if !self . scripts_needed . is_empty ( ) {
137+ // we have not finished requesting txs with script batches, so continue
138+ return Ok ( Request :: Script ( self ) ) ;
139+ }
140+
141+ // if we obtained an active index in this sync, we have missing scripts in db cache,
142+ // report it
143+ if last > 0 {
131144 debug ! (
132- "finished scanning for transactions for keychain {:?} at index {}" ,
133- self . keychain , last_active_index
145+ "reporting missing with: current={}, last={}, diff={}, gap= {}" ,
146+ self . script_index , last , diff , self . stop_gap
134147 ) ;
135- // we're done here -- check if we need to do the next keychain
136- if let Some ( keychain) = self . next_keychains . pop ( ) {
137- self . keychain = keychain;
138- self . script_index = 0 ;
139- self . scripts_needed = self
140- . state
141- . db
142- . iter_script_pubkeys ( Some ( keychain) ) ?
143- . into_iter ( )
144- . collect ( ) ;
145- Request :: Script ( self )
146- } else {
147- Request :: Tx ( TxReq { state : self . state } )
148- }
149- } else {
150- Request :: Script ( self )
151- } ,
152- )
148+ self . state
149+ . missing_script_counts
150+ . insert ( self . keychain , self . stop_gap - diff) ;
151+ }
152+ }
153+
154+ debug ! (
155+ "finished scanning for txs of keychain {:?} at index {:?}" ,
156+ self . keychain, last
157+ ) ;
158+
159+ if let Some ( keychain) = self . next_keychains . pop ( ) {
160+ // we still have another keychain to request txs with
161+ self . keychain = keychain;
162+ self . script_index = 0 ;
163+ self . scripts_needed = self
164+ . state
165+ . db
166+ . iter_script_pubkeys ( Some ( keychain) ) ?
167+ . into_iter ( )
168+ . collect ( ) ;
169+ return Ok ( Request :: Script ( self ) ) ;
170+ }
171+
172+ // We have finished requesting txids, let's get the actual txs.
173+ Ok ( Request :: Tx ( TxReq { state : self . state } ) )
153174 }
154175}
155176
@@ -276,7 +297,18 @@ impl<'a, D: BatchDatabase> ConftimeReq<'a, D> {
276297 }
277298
278299 if self . state . tx_missing_conftime . is_empty ( ) {
279- Ok ( Request :: Finish ( self . state . into_db_update ( ) ?) )
300+ // Obtain largest missing count (between external/internal) for simplicity
301+ // The reasoning is that there is no point returning a map - in the future, a single
302+ // database will only handle a single descriptor
303+ let missing = self
304+ . state
305+ . missing_script_counts
306+ . clone ( )
307+ . into_values ( )
308+ . reduce ( std:: cmp:: max)
309+ . unwrap_or ( 0 ) ;
310+
311+ Ok ( Request :: Finish ( self . state . into_db_update ( ) ?, missing) )
280312 } else {
281313 Ok ( Request :: Conftime ( self ) )
282314 }
@@ -294,6 +326,8 @@ struct State<'a, D> {
294326 tx_missing_conftime : BTreeMap < Txid , TransactionDetails > ,
295327 /// The start of the sync
296328 start_time : Instant ,
329+ /// Missing number of scripts to cache per keychain
330+ missing_script_counts : HashMap < KeychainKind , usize > ,
297331}
298332
299333impl < ' a , D : BatchDatabase > State < ' a , D > {
@@ -305,6 +339,7 @@ impl<'a, D: BatchDatabase> State<'a, D> {
305339 tx_needed : BTreeSet :: default ( ) ,
306340 tx_missing_conftime : BTreeMap :: default ( ) ,
307341 start_time : Instant :: new ( ) ,
342+ missing_script_counts : HashMap :: default ( ) ,
308343 }
309344 }
310345 fn into_db_update ( self ) -> Result < D :: Batch , Error > {
0 commit comments