diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/chain_manager.go | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go index 9ef091c3c..4c7db6e2e 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -85,12 +85,14 @@ type ChainManager struct { lastBlockHash []byte transState *state.StateDB + txState *state.StateDB } func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager { bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux} bc.setLastBlock() bc.transState = bc.State().Copy() + bc.txState = bc.State().Copy() return bc } @@ -138,6 +140,19 @@ func (self *ChainManager) TransState() *state.StateDB { return self.transState } +func (self *ChainManager) TxState() *state.StateDB { + self.tsmu.RLock() + defer self.tsmu.RUnlock() + + return self.txState +} + +func (self *ChainManager) setTxState(state *state.StateDB) { + self.tsmu.Lock() + defer self.tsmu.Unlock() + self.txState = state +} + func (self *ChainManager) setTransState(statedb *state.StateDB) { self.transState = statedb } @@ -363,6 +378,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { defer self.tsmu.Unlock() for _, block := range chain { + // Call in to the block processor and check for errors. It's likely that if one block fails + // all others will fail too (unless a known block is returned). td, err := self.processor.Process(block) if err != nil { if IsKnownBlockErr(err) { @@ -377,11 +394,15 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } block.Td = td - var chain, split bool + var canonical, split bool self.mu.Lock() { + // Write block to database. Eventually we'll have to improve on this and throw away blocks that are + // not in the canonical chain. self.write(block) cblock := self.currentBlock + // Compare the TD of the last known block in the canonical chain to make sure it's greater. + // At this point it's possible that a different chain (fork) becomes the new canonical chain. if td.Cmp(self.td) > 0 { if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, ethutil.Big1)) < 0 { chainlogger.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, block.Hash()[:4], td, cblock.Header().Number, cblock.Hash()[:4], self.td) @@ -391,17 +412,18 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.setTotalDifficulty(td) self.insert(block) - chain = true + canonical = true } } self.mu.Unlock() - if chain { + if canonical { + self.setTransState(state.New(block.Root(), self.db)) self.eventMux.Post(ChainEvent{block, td}) } if split { - self.setTransState(state.New(block.Root(), self.db)) + self.setTxState(state.New(block.Root(), self.db)) self.eventMux.Post(ChainSplitEvent{block}) } } |