@@ -192,6 +192,7 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
192192 return
193193 }
194194 }
195+
195196 threshold , err := f .freezeThreshold (nfdb )
196197 if err != nil {
197198 backoff = true
@@ -200,6 +201,50 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) {
200201 }
201202 frozen , _ := f .Ancients () // no error will occur, safe to ignore
202203
204+ // Back fill transactions bloom untill it catches up then resume normal freezing
205+ txbFrozen , err := f .AncientItems (ChainFreezerTransactionBloomTable )
206+ if err != nil {
207+ log .Error ("Failed to check frozen transaction bloom" , "err" , err )
208+ backoff = true
209+ continue
210+ }
211+
212+ if txbFrozen < frozen {
213+ var (
214+ first = txbFrozen
215+ last = threshold
216+ )
217+ if last - first + 1 > freezerBatchLimit {
218+ last = freezerBatchLimit + first - 1
219+ }
220+ // Don't go ahead of the rest of the frozen datas
221+ if last > frozen {
222+ last = frozen - 1
223+ }
224+
225+ log .Debug ("Freezing historical tx bloom" , "from" , first , "to" , last )
226+ txAncients , err := f .freezeTxBloomRange (nfdb , first , last )
227+ if err != nil {
228+ log .Error ("Error in tx bloom freeze operation" , "err" , err )
229+ backoff = true
230+ continue
231+ }
232+
233+ // Wipe out all data from the active database
234+ batch := db .NewBatch ()
235+ for i := 0 ; i < len (txAncients ); i ++ {
236+ // Always keep the genesis block in active database
237+ if first + uint64 (i ) != 0 {
238+ DeleteTxBloom (batch , txAncients [i ], first + uint64 (i ))
239+ }
240+ }
241+ if err := batch .Write (); err != nil {
242+ log .Crit ("Failed to delete frozen canonical blocks" , "err" , err )
243+ }
244+ batch .Reset ()
245+ continue
246+ }
247+
203248 // Short circuit if the blocks below threshold are already frozen.
204249 if frozen != 0 && frozen - 1 >= threshold {
205250 backoff = true
@@ -353,7 +398,7 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
353398 // TODO this can throw an error when rewinding to a block
354399 txBloom := ReadTxBloomRLP (nfdb , hash , number )
355400 if len (txBloom ) == 0 && ! outOfShard {
356- return fmt .Errorf ("total transaction bloom, can't freeze block %d" , number )
401+ return fmt .Errorf ("total transaction bloom missing , can't freeze block %d" , number )
357402 }
358403
359404 // Write to the batch.
@@ -379,3 +424,50 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
379424 })
380425 return hashes , err
381426}
427+
428+ // Back fill transactions bloom data
429+ func (f * chainFreezer ) freezeTxBloomRange (nfdb * nofreezedb , number , limit uint64 ) (hashes []common.Hash , err error ) {
430+ hashes = make ([]common.Hash , 0 , limit - number + 1 )
431+
432+ dataConfig := ReadChainDataConfig (nfdb )
433+
434+ _ , err = f .ModifyAncients (func (op ethdb.AncientWriteOp ) error {
435+ for ; number <= limit ; number ++ {
436+
437+ // If the data is out of the shard range then we allow writing empty data, this will allow truncating the tail of the freezer later
438+ outOfShard := false
439+ if dataConfig != nil && dataConfig .DesiredChainDataStart != nil {
440+ outOfShard = number < * dataConfig .DesiredChainDataStart
441+ }
442+
443+ // Retrieve all the components of the canonical block.
444+ hash := ReadCanonicalHash (nfdb , number )
445+ if hash == (common.Hash {}) {
446+ // Get the hash from the freezer, its probably already frozen
447+ data , err := f .AncientStore .Ancient (ChainFreezerHashTable , number )
448+ if err != nil || len (data ) == 0 {
449+ return fmt .Errorf ("canonical hash missing from freezer, can't freeze block %d" , number )
450+ }
451+ hash = common .BytesToHash (data )
452+ if hash == (common.Hash {}) && ! outOfShard {
453+ return fmt .Errorf ("canonical hash missing, can't freeze block %d" , number )
454+ }
455+ }
456+ // TODO this can throw an error when rewinding to a block
457+ // This can happen when the tx bloom indexer has not yet indexed the block, it will abort the current batch but eventually complete
458+ txBloom := ReadTxBloomRLP (nfdb , hash , number )
459+ if len (txBloom ) == 0 && ! outOfShard {
460+ return fmt .Errorf ("total transaction bloom missing, can't freeze block %d" , number )
461+ }
462+
463+ // Write to the batch.
464+ if err := op .AppendRaw (ChainFreezerTransactionBloomTable , number , txBloom ); err != nil {
465+ return fmt .Errorf ("can't write transaction bloom to Freezer: %v" , err )
466+ }
467+
468+ hashes = append (hashes , hash )
469+ }
470+ return nil
471+ })
472+ return hashes , err
473+ }
0 commit comments