diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/block_processor.go | 36 | ||||
-rw-r--r-- | core/chain_manager.go | 5 | ||||
-rw-r--r-- | core/error.go | 5 |
3 files changed, 31 insertions, 15 deletions
diff --git a/core/block_processor.go b/core/block_processor.go index 99c5fea05..ae8d5fe7b 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -166,9 +166,15 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big // Create a new state based on the parent's root (e.g., create copy) state := state.New(parent.Root(), sm.db) + // track (possible) uncle block + var uncle bool // Block validation if err = sm.ValidateHeader(block.Header(), parent.Header()); err != nil { - return + if err != BlockEqualTSErr { + return + } + err = nil + uncle = true } // There can be at most two uncles @@ -223,14 +229,22 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big td = CalculateTD(block, parent) // Sync the current block's state to the database state.Sync() - // Remove transactions from the pool - sm.txpool.RemoveSet(block.Transactions()) + + if !uncle { + // Remove transactions from the pool + sm.txpool.RemoveSet(block.Transactions()) + } for _, tx := range block.Transactions() { putTx(sm.extraDb, tx) } - chainlogger.Infof("processed block #%d (%x...)\n", header.Number, block.Hash().Bytes()[0:4]) + if uncle { + chainlogger.Infof("found possible uncle block #%d (%x...)\n", header.Number, block.Hash().Bytes()[0:4]) + return td, nil, BlockEqualTSErr + } else { + chainlogger.Infof("processed block #%d (%x...)\n", header.Number, block.Hash().Bytes()[0:4]) + } return td, state.Logs(), nil } @@ -255,10 +269,6 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error { return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) } - if block.Time <= parent.Time { - return ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time) - } - if int64(block.Time) > time.Now().Unix() { return BlockFutureErr } @@ -272,6 +282,10 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error { return ValidationError("Block's nonce is invalid (= %x)", block.Nonce) } + if block.Time <= parent.Time { + return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time) + } + return nil } @@ -307,14 +321,10 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4])) } - if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash]); err != nil { + if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash]); err != nil && err != BlockEqualTSErr { return ValidationError(fmt.Sprintf("%v", err)) } - if !sm.Pow.Verify(types.NewBlockWithHeader(uncle)) { - return ValidationError("Uncle's nonce is invalid (= %x)", uncle.Nonce) - } - r := new(big.Int) r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16)) diff --git a/core/chain_manager.go b/core/chain_manager.go index 755487900..192fa1df0 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -447,6 +447,11 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { continue } + if err == BlockEqualTSErr { + queue[i] = ChainSideEvent{block, logs} + continue + } + h := block.Header() chainlogger.Infof("INVALID block #%v (%x)\n", h.Number, h.Hash().Bytes()[:4]) chainlogger.Infoln(err) diff --git a/core/error.go b/core/error.go index f6ac26cff..0642948cd 100644 --- a/core/error.go +++ b/core/error.go @@ -9,8 +9,9 @@ import ( ) var ( - BlockNumberErr = errors.New("block number invalid") - BlockFutureErr = errors.New("block time is in the future") + BlockNumberErr = errors.New("block number invalid") + BlockFutureErr = errors.New("block time is in the future") + BlockEqualTSErr = errors.New("block time stamp equal to previous") ) // Parent error. In case a parent is unknown this error will be thrown |