@@ -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
@@ -357,7 +402,7 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
357402 // TODO this can throw an error when rewinding to a block
358403 txBloom := ReadTxBloomRLP (nfdb , hash , number )
359404 if len (txBloom ) == 0 && ! outOfShard {
360- return fmt .Errorf ("total transaction bloom, can't freeze block %d" , number )
405+ return fmt .Errorf ("total transaction bloom missing , can't freeze block %d" , number )
361406 }
362407
363408 // Write to the batch.
@@ -386,3 +431,50 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
386431 })
387432 return hashes , err
388433}
434+
435+ // Back fill transactions bloom data
436+ func (f * chainFreezer ) freezeTxBloomRange (nfdb * nofreezedb , number , limit uint64 ) (hashes []common.Hash , err error ) {
437+ hashes = make ([]common.Hash , 0 , limit - number + 1 )
438+
439+ dataConfig := ReadChainDataConfig (nfdb )
440+
441+ _ , err = f .ModifyAncients (func (op ethdb.AncientWriteOp ) error {
442+ for ; number <= limit ; number ++ {
443+
444+ // 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
445+ outOfShard := false
446+ if dataConfig != nil && dataConfig .DesiredChainDataStart != nil {
447+ outOfShard = number < * dataConfig .DesiredChainDataStart
448+ }
449+
450+ // Retrieve all the components of the canonical block.
451+ hash := ReadCanonicalHash (nfdb , number )
452+ if hash == (common.Hash {}) {
453+ // Get the hash from the freezer, its probably already frozen
454+ data , err := f .AncientStore .Ancient (ChainFreezerHashTable , number )
455+ if err != nil || len (data ) == 0 {
456+ return fmt .Errorf ("canonical hash missing from freezer, can't freeze block %d" , number )
457+ }
458+ hash = common .BytesToHash (data )
459+ if hash == (common.Hash {}) && ! outOfShard {
460+ return fmt .Errorf ("canonical hash missing, can't freeze block %d" , number )
461+ }
462+ }
463+ // TODO this can throw an error when rewinding to a block
464+ // This can happen when the tx bloom indexer has not yet indexed the block, it will abort the current batch but eventually complete
465+ txBloom := ReadTxBloomRLP (nfdb , hash , number )
466+ if len (txBloom ) == 0 && ! outOfShard {
467+ return fmt .Errorf ("total transaction bloom missing, can't freeze block %d" , number )
468+ }
469+
470+ // Write to the batch.
471+ if err := op .AppendRaw (ChainFreezerTransactionBloomTable , number , txBloom ); err != nil {
472+ return fmt .Errorf ("can't write transaction bloom to Freezer: %v" , err )
473+ }
474+
475+ hashes = append (hashes , hash )
476+ }
477+ return nil
478+ })
479+ return hashes , err
480+ }
0 commit comments