@@ -93,10 +93,11 @@ type BlockChain struct {
9393 currentBlock * types.Block // Current head of the block chain
9494 currentFastBlock * types.Block // Current head of the fast-sync chain (may be above the block chain!)
9595
96- bodyCache * lru.Cache // Cache for the most recent block bodies
97- bodyRLPCache * lru.Cache // Cache for the most recent block bodies in RLP encoded format
98- blockCache * lru.Cache // Cache for the most recent entire blocks
99- futureBlocks * lru.Cache // future blocks are blocks added for later processing
96+ stateCache * state.StateDB // State database to reuse between imports (contains state cache)
97+ bodyCache * lru.Cache // Cache for the most recent block bodies
98+ bodyRLPCache * lru.Cache // Cache for the most recent block bodies in RLP encoded format
99+ blockCache * lru.Cache // Cache for the most recent entire blocks
100+ futureBlocks * lru.Cache // future blocks are blocks added for later processing
100101
101102 quit chan struct {} // blockchain quit channel
102103 running int32 // running must be called atomically
@@ -196,7 +197,15 @@ func (self *BlockChain) loadLastState() error {
196197 self .currentFastBlock = block
197198 }
198199 }
199- // Issue a status log and return
200+ // Initialize a statedb cache to ensure singleton account bloom filter generation
201+ statedb , err := state .New (self .currentBlock .Root (), self .chainDb )
202+ if err != nil {
203+ return err
204+ }
205+ self .stateCache = statedb
206+ self .stateCache .GetAccount (common.Address {})
207+
208+ // Issue a status log for the user
200209 headerTd := self .GetTd (currentHeader .Hash (), currentHeader .Number .Uint64 ())
201210 blockTd := self .GetTd (self .currentBlock .Hash (), self .currentBlock .NumberU64 ())
202211 fastTd := self .GetTd (self .currentFastBlock .Hash (), self .currentFastBlock .NumberU64 ())
@@ -826,7 +835,6 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
826835 tstart = time .Now ()
827836
828837 nonceChecked = make ([]bool , len (chain ))
829- statedb * state.StateDB
830838 )
831839
832840 // Start the parallel nonce verifier.
@@ -893,29 +901,30 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
893901
894902 // Create a new statedb using the parent block and report an
895903 // error if it fails.
896- if statedb == nil {
897- statedb , err = state .New (self .GetBlock (block .ParentHash (), block .NumberU64 ()- 1 ).Root (), self .chainDb )
898- } else {
899- err = statedb .Reset (chain [i - 1 ].Root ())
904+ switch {
905+ case i == 0 :
906+ err = self .stateCache .Reset (self .GetBlock (block .ParentHash (), block .NumberU64 ()- 1 ).Root ())
907+ default :
908+ err = self .stateCache .Reset (chain [i - 1 ].Root ())
900909 }
901910 if err != nil {
902911 reportBlock (block , err )
903912 return i , err
904913 }
905914 // Process block using the parent state as reference point.
906- receipts , logs , usedGas , err := self .processor .Process (block , statedb , self .config .VmConfig )
915+ receipts , logs , usedGas , err := self .processor .Process (block , self . stateCache , self .config .VmConfig )
907916 if err != nil {
908917 reportBlock (block , err )
909918 return i , err
910919 }
911920 // Validate the state using the default validator
912- err = self .Validator ().ValidateState (block , self .GetBlock (block .ParentHash (), block .NumberU64 ()- 1 ), statedb , receipts , usedGas )
921+ err = self .Validator ().ValidateState (block , self .GetBlock (block .ParentHash (), block .NumberU64 ()- 1 ), self . stateCache , receipts , usedGas )
913922 if err != nil {
914923 reportBlock (block , err )
915924 return i , err
916925 }
917926 // Write state changes to database
918- _ , err = statedb .Commit ()
927+ _ , err = self . stateCache .Commit ()
919928 if err != nil {
920929 return i , err
921930 }
0 commit comments