diff options
author | Jeffrey Wilcke <geffobscura@gmail.com> | 2015-06-30 00:55:49 +0800 |
---|---|---|
committer | Jeffrey Wilcke <geffobscura@gmail.com> | 2015-06-30 00:55:49 +0800 |
commit | a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9 (patch) | |
tree | f8e1fd5f084193389eaeaa6314979e96c86a3a70 /core/chain_manager.go | |
parent | 5d9df7348d80fbd5de9a92d7f6abe6c02646c24d (diff) | |
parent | b39042db5672e830ddec41ea97c642d93be61c30 (diff) | |
download | dexon-a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9.tar dexon-a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9.tar.gz dexon-a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9.tar.bz2 dexon-a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9.tar.lz dexon-a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9.tar.xz dexon-a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9.tar.zst dexon-a8ebf756c7ea9e2d516d57aae6ee504e9acb21d9.zip |
Merge branch 'miner-broadcast' into core-optimisations-2
Conflicts:
core/chain_manager.go
miner/worker.go
Diffstat (limited to 'core/chain_manager.go')
-rw-r--r-- | core/chain_manager.go | 110 |
1 files changed, 67 insertions, 43 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go index a4c8563c3..daae24709 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -541,6 +541,58 @@ func (self *ChainManager) flushQueuedBlocks() { } } +type writeStatus byte + +const ( + nonStatTy writeStatus = iota + canonStatTy + splitStatTy + sideStatTy +) + +func (self *ChainManager) WriteBlock(block *types.Block) (status writeStatus, err error) { + self.wg.Add(1) + defer self.wg.Done() + + 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 block.Td.Cmp(self.Td()) > 0 { + // chain fork + if block.ParentHash() != cblock.Hash() { + // during split we merge two different chains and create the new canonical chain + err := self.merge(cblock, block) + if err != nil { + return nonStatTy, err + } + + status = splitStatTy + } + + self.mu.Lock() + self.setTotalDifficulty(block.Td) + self.insert(block) + self.mu.Unlock() + + self.setTransState(state.New(block.Root(), self.stateDb)) + self.txState.SetState(state.New(block.Root(), self.stateDb)) + + status = canonStatTy + } else { + status = sideStatTy + } + + // Write block to database. Eventually we'll have to improve on this and throw away blocks that are + // not in the canonical chain. + self.mu.Lock() + self.enqueueForWrite(block) + self.mu.Unlock() + // Delete from future blocks + self.futureBlocks.Delete(block.Hash()) + + return +} + // InsertChain will attempt to insert the given chain in to the canonical chain or, otherwise, create a fork. It an error is returned // it will return the index number of the failing block as well an error describing what went wrong (for possible errors see core/errors.go). func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { @@ -635,57 +687,29 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { txcount += len(block.Transactions()) - 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 block.Td.Cmp(self.Td()) > 0 { - // chain fork - if block.ParentHash() != cblock.Hash() { - // during split we merge two different chains and create the new canonical chain - err := self.merge(cblock, block) - if err != nil { - return i, err - } - - queue[i] = ChainSplitEvent{block, logs} - queueEvent.splitCount++ - } - - self.mu.Lock() - self.setTotalDifficulty(block.Td) - self.insert(block) - self.mu.Unlock() - - jsonlogger.LogJson(&logger.EthChainNewHead{ - BlockHash: block.Hash().Hex(), - BlockNumber: block.Number(), - ChainHeadHash: cblock.Hash().Hex(), - BlockPrevHash: block.ParentHash().Hex(), - }) - - self.setTransState(state.New(block.Root(), self.stateDb)) - self.txState.SetState(state.New(block.Root(), self.stateDb)) - - queue[i] = ChainEvent{block, block.Hash(), logs} - queueEvent.canonicalCount++ - + // write the block to the chain and get the status + status, err := self.WriteBlock(block) + if err != nil { + return i, err + } + switch status { + case canonStatTy: if glog.V(logger.Debug) { glog.Infof("[%v] inserted block #%d (%d TXs %d UNCs) (%x...). Took %v\n", time.Now().UnixNano(), block.Number(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart)) } - } else { + queue[i] = ChainEvent{block, block.Hash(), logs} + queueEvent.canonicalCount++ + case sideStatTy: if glog.V(logger.Detail) { glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart)) } - queue[i] = ChainSideEvent{block, logs} queueEvent.sideCount++ + case splitStatTy: + queue[i] = ChainSplitEvent{block, logs} + queueEvent.splitCount++ } - self.enqueueForWrite(block) - // Delete from future blocks - self.futureBlocks.Delete(block.Hash()) - stats.processed++ - blockInsertTimer.UpdateSince(bstart) } if (stats.queued > 0 || stats.processed > 0 || stats.ignored > 0) && bool(glog.V(logger.Info)) { @@ -744,9 +768,9 @@ func (self *ChainManager) diff(oldBlock, newBlock *types.Block) (types.Blocks, e } } - if glog.V(logger.Info) { + if glog.V(logger.Debug) { commonHash := commonBlock.Hash() - glog.Infof("Fork detected @ %x. Reorganising chain from #%v %x to %x", commonHash[:4], numSplit, oldStart.Hash().Bytes()[:4], newStart.Hash().Bytes()[:4]) + glog.Infof("Chain split detected @ %x. Reorganising chain from #%v %x to %x", commonHash[:4], numSplit, oldStart.Hash().Bytes()[:4], newStart.Hash().Bytes()[:4]) } return newChain, nil |