diff options
author | Felix Lange <fjl@twurst.com> | 2016-09-23 03:04:58 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2016-09-26 16:09:52 +0800 |
commit | a59a93f476434f2805c8fd3e10bf1b2f579b078f (patch) | |
tree | 17d1f3abefabfd7f8cb9149994a4788d2c0f08bc /core/blockchain.go | |
parent | e859f3696783ec75d9bb39c0c66eda3a88cea8c6 (diff) | |
download | dexon-a59a93f476434f2805c8fd3e10bf1b2f579b078f.tar.gz dexon-a59a93f476434f2805c8fd3e10bf1b2f579b078f.tar.zst dexon-a59a93f476434f2805c8fd3e10bf1b2f579b078f.zip |
core/state: track all accounts in canon state
This change introduces a global, per-state cache that keeps account data
in the canon state. Thanks to @karalabe for lots of fixes.
Diffstat (limited to 'core/blockchain.go')
-rw-r--r-- | core/blockchain.go | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/core/blockchain.go b/core/blockchain.go index 888c98dce..a5f146a2d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -93,10 +93,11 @@ type BlockChain struct { currentBlock *types.Block // Current head of the block chain currentFastBlock *types.Block // Current head of the fast-sync chain (may be above the block chain!) - bodyCache *lru.Cache // Cache for the most recent block bodies - bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format - blockCache *lru.Cache // Cache for the most recent entire blocks - futureBlocks *lru.Cache // future blocks are blocks added for later processing + stateCache *state.StateDB // State database to reuse between imports (contains state cache) + bodyCache *lru.Cache // Cache for the most recent block bodies + bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format + blockCache *lru.Cache // Cache for the most recent entire blocks + futureBlocks *lru.Cache // future blocks are blocks added for later processing quit chan struct{} // blockchain quit channel running int32 // running must be called atomically @@ -196,7 +197,15 @@ func (self *BlockChain) loadLastState() error { self.currentFastBlock = block } } - // Issue a status log and return + // Initialize a statedb cache to ensure singleton account bloom filter generation + statedb, err := state.New(self.currentBlock.Root(), self.chainDb) + if err != nil { + return err + } + self.stateCache = statedb + self.stateCache.GetAccount(common.Address{}) + + // Issue a status log for the user headerTd := self.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) blockTd := self.GetTd(self.currentBlock.Hash(), self.currentBlock.NumberU64()) fastTd := self.GetTd(self.currentFastBlock.Hash(), self.currentFastBlock.NumberU64()) @@ -826,7 +835,6 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { tstart = time.Now() nonceChecked = make([]bool, len(chain)) - statedb *state.StateDB ) // Start the parallel nonce verifier. @@ -893,29 +901,30 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { // Create a new statedb using the parent block and report an // error if it fails. - if statedb == nil { - statedb, err = state.New(self.GetBlock(block.ParentHash(), block.NumberU64()-1).Root(), self.chainDb) - } else { - err = statedb.Reset(chain[i-1].Root()) + switch { + case i == 0: + err = self.stateCache.Reset(self.GetBlock(block.ParentHash(), block.NumberU64()-1).Root()) + default: + err = self.stateCache.Reset(chain[i-1].Root()) } if err != nil { reportBlock(block, err) return i, err } // Process block using the parent state as reference point. - receipts, logs, usedGas, err := self.processor.Process(block, statedb, self.config.VmConfig) + receipts, logs, usedGas, err := self.processor.Process(block, self.stateCache, self.config.VmConfig) if err != nil { reportBlock(block, err) return i, err } // Validate the state using the default validator - err = self.Validator().ValidateState(block, self.GetBlock(block.ParentHash(), block.NumberU64()-1), statedb, receipts, usedGas) + err = self.Validator().ValidateState(block, self.GetBlock(block.ParentHash(), block.NumberU64()-1), self.stateCache, receipts, usedGas) if err != nil { reportBlock(block, err) return i, err } // Write state changes to database - _, err = statedb.Commit() + _, err = self.stateCache.Commit() if err != nil { return i, err } |