diff options
author | obscuren <geffobscura@gmail.com> | 2015-04-04 22:35:23 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-04-04 22:35:23 +0800 |
commit | e1ed8c33bd99a87d2c3339fe28a602b1af8b85fc (patch) | |
tree | fcbb59358cab8df4e6aa005e22e5e9a22edcb5b4 /core/chain_manager.go | |
parent | 29f120206e16f80176a0cb309162cc7f889be0b0 (diff) | |
download | go-tangerine-e1ed8c33bd99a87d2c3339fe28a602b1af8b85fc.tar.gz go-tangerine-e1ed8c33bd99a87d2c3339fe28a602b1af8b85fc.tar.zst go-tangerine-e1ed8c33bd99a87d2c3339fe28a602b1af8b85fc.zip |
Improved chain manager, improved block processor, fixed tests
* ChainManager allows cached future blocks for later processing
* BlockProcessor allows a 4 second window on future blocks
* Fixed tests
Diffstat (limited to 'core/chain_manager.go')
-rw-r--r-- | core/chain_manager.go | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go index c1a07b0cf..7b4034b63 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -6,6 +6,7 @@ import ( "io" "math/big" "sync" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" @@ -95,7 +96,8 @@ type ChainManager struct { transState *state.StateDB txState *state.ManagedState - cache *BlockCache + cache *BlockCache + futureBlocks *BlockCache quit chan struct{} } @@ -107,6 +109,7 @@ func NewChainManager(blockDb, stateDb common.Database, mux *event.TypeMux) *Chai // Take ownership of this particular state bc.txState = state.ManageState(bc.State().Copy()) + bc.futureBlocks = NewBlockCache(254) bc.makeCache() go bc.update() @@ -433,6 +436,19 @@ type queueEvent struct { splitCount int } +func (self *ChainManager) procFutureBlocks() { + self.futureBlocks.mu.Lock() + + blocks := make([]*types.Block, len(self.futureBlocks.blocks)) + for i, hash := range self.futureBlocks.hashes { + blocks[i] = self.futureBlocks.Get(hash) + } + self.futureBlocks.mu.Unlock() + + types.BlockBy(types.Number).Sort(blocks) + self.InsertChain(blocks) +} + func (self *ChainManager) InsertChain(chain types.Blocks) error { //self.tsmu.Lock() //defer self.tsmu.Unlock() @@ -452,12 +468,27 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { continue } - if err == BlockEqualTSErr { - //queue[i] = ChainSideEvent{block, logs} - // XXX silently discard it? + block.Td = new(big.Int) + // Do not penelise on future block. We'll need a block queue eventually that will queue + // future block for future use + if err == BlockFutureErr { + self.futureBlocks.Push(block) + continue + } + + if IsParentErr(err) && self.futureBlocks.Has(block.ParentHash()) { + self.futureBlocks.Push(block) continue } + /* + if err == BlockEqualTSErr { + //queue[i] = ChainSideEvent{block, logs} + // XXX silently discard it? + continue + } + */ + h := block.Header() chainlogger.Errorf("INVALID block #%v (%x)\n", h.Number, h.Hash().Bytes()[:4]) chainlogger.Errorln(err) @@ -513,6 +544,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } self.mu.Unlock() + self.futureBlocks.Delete(block.Hash()) + } if len(chain) > 0 && glog.V(logger.Info) { @@ -527,7 +560,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { func (self *ChainManager) update() { events := self.eventMux.Subscribe(queueEvent{}) - + futureTimer := time.NewTicker(5 * time.Second) out: for { select { @@ -553,6 +586,8 @@ out: self.eventMux.Post(event) } } + case <-futureTimer.C: + self.procFutureBlocks() case <-self.quit: break out } |