aboutsummaryrefslogtreecommitdiffstats
path: root/core/blockchain.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2016-09-23 03:04:58 +0800
committerFelix Lange <fjl@twurst.com>2016-09-26 16:09:52 +0800
commita59a93f476434f2805c8fd3e10bf1b2f579b078f (patch)
tree17d1f3abefabfd7f8cb9149994a4788d2c0f08bc /core/blockchain.go
parente859f3696783ec75d9bb39c0c66eda3a88cea8c6 (diff)
downloaddexon-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.go35
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
}