diff --git a/core/blockchain.go b/core/blockchain.go index 2559930fb4..3e2d74e586 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -906,7 +906,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. defer bc.mu.Unlock() currentBlock := bc.CurrentBlock() - //localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) + localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) externTd := new(big.Int).Add(block.Difficulty(), ptd) // Irrelevant of the canonical status, write the block itself to the database @@ -981,8 +981,13 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf - reorg := block.NumberU64() > currentBlock.NumberU64() - if reorg { + reorg := externTd.Cmp(localTd) > 0 + currentBlock = bc.CurrentBlock() + if !reorg && externTd.Cmp(localTd) == 0 { + // Split same-difficulty blocks by number + reorg = block.NumberU64() > currentBlock.NumberU64() + } + if reorg { // Reorganise the chain if the parent is not the head block if block.ParentHash() != currentBlock.Hash() { if err := bc.reorg(currentBlock, block); err != nil { diff --git a/eth/handler.go b/eth/handler.go index cdbcab8aaf..3266c78a57 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -657,18 +657,15 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { trueTD = new(big.Int).Sub(request.TD, request.Block.Difficulty()) ) // Update the peers total difficulty if better than the previous - _, td := p.Head() - currentBlock := pm.blockchain.CurrentBlock() - currentTd := pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) - log.Debug("NewBlockMsg", "p", p, "number", request.Block.NumberU64(), "trueTD", trueTD, "td", td, "currentTd", currentTd) - if trueTD.Cmp(td) > 0 { + if _, td := p.Head(); trueTD.Cmp(td) > 0 { p.SetHead(trueHead, trueTD) // Schedule a sync if above ours. Note, this will not fire a sync for a gap of // a singe block (as the true TD is below the propagated block), however this // scenario should easily be covered by the fetcher. - if trueTD.Cmp(currentTd) > 0 { - go pm.synchronise(p) + currentBlock := pm.blockchain.CurrentBlock() + if trueTD.Cmp(pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())) > 0 { + go pm.synchronise(p) } } diff --git a/miner/worker.go b/miner/worker.go index ca601f3d56..186de2ac87 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -472,17 +472,6 @@ func abs(x int64) int64 { return x } -func hop(len, pre, cur int) int { - switch { - case pre < cur: - return cur - (pre + 1) - case pre > cur: - return (len - pre) + (cur - 1) - default: - return len - 1 - } -} - func (self *worker) commitNewWork() { self.mu.Lock() defer self.mu.Unlock() @@ -508,14 +497,7 @@ func (self *worker) commitNewWork() { if self.config.XDPoS != nil { // get masternodes set from latest checkpoint c := self.engine.(*XDPoS.XDPoS) - masternodes := c.GetMasternodes(self.chain, parent.Header()) - snap, err := c.GetSnapshot(self.chain, parent.Header()) - if err != nil { - log.Error("Failed when trying to commit new work", "err", err) - return - } - signers = snap.Signers - preIndex, curIndex, ok, err := XDPoS.YourTurn(masternodes, snap, parent.Header(), self.coinbase) + len, preIndex, curIndex, ok, err := c.YourTurn(self.chain, parent.Header()) if err != nil { log.Error("Failed when trying to commit new work", "err", err) return @@ -531,7 +513,7 @@ func (self *worker) commitNewWork() { // you're not allowed to create this block return } - h := hop(len(masternodes), preIndex, curIndex) + h := XDPoS.Hop(len, preIndex, curIndex) gap := waitPeriod * int64(h) // Check nearest checkpoint block in hop range. nearest := self.config.XDPoS.Epoch - (parent.Header().Number.Uint64() % self.config.XDPoS.Epoch)