diff options
author | Martin Holst Swende <martin@swende.se> | 2017-02-14 04:44:06 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2017-02-14 04:44:06 +0800 |
commit | 72dcd3c58bec0a281280d5d42ed53b6e429ce4af (patch) | |
tree | b14f34e256b0a2aaa71413bfa3fc66f52edc92d9 /core | |
parent | 4ece9c6cb0a75e0ba6c67f8b1e5200f652e5b3d4 (diff) | |
download | go-tangerine-72dcd3c58bec0a281280d5d42ed53b6e429ce4af.tar.gz go-tangerine-72dcd3c58bec0a281280d5d42ed53b6e429ce4af.tar.zst go-tangerine-72dcd3c58bec0a281280d5d42ed53b6e429ce4af.zip |
core, eth, internal: Added `debug_getBadBlocks()` method (#3654)
* core,eth,internal: Added `debug_getBadBlocks()` method
When bad blocks are discovered, these are stored within geth.
An RPC-endpoint makes them availablewithin the `debug`
namespace. This feature makes it easier to discover network forks.
```
* core, api: go format + docs
* core/blockchain: Documentation, fix minor nitpick
* core: fix failing blockchain test
Diffstat (limited to 'core')
-rw-r--r-- | core/blockchain.go | 30 | ||||
-rw-r--r-- | core/blockchain_test.go | 1 |
2 files changed, 30 insertions, 1 deletions
diff --git a/core/blockchain.go b/core/blockchain.go index 281f28f36..ae4fbbcd7 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -60,6 +60,7 @@ const ( // must be bumped when consensus algorithm is changed, this forces the upgradedb // command to be run (forces the blocks to be imported again using the new algorithm) BlockChainVersion = 3 + badBlockLimit = 10 ) // BlockChain represents the canonical chain given a database with a genesis @@ -108,6 +109,8 @@ type BlockChain struct { processor Processor // block processor interface validator Validator // block and state validator interface vmConfig vm.Config + + badBlocks *lru.Cache // Bad block cache } // NewBlockChain returns a fully initialised block chain using information @@ -118,6 +121,7 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, pow pow.P bodyRLPCache, _ := lru.New(bodyCacheLimit) blockCache, _ := lru.New(blockCacheLimit) futureBlocks, _ := lru.New(maxFutureBlocks) + badBlocks, _ := lru.New(badBlockLimit) bc := &BlockChain{ config: config, @@ -130,6 +134,7 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, pow pow.P futureBlocks: futureBlocks, pow: pow, vmConfig: vmConfig, + badBlocks: badBlocks, } bc.SetValidator(NewBlockValidator(config, bc, pow)) bc.SetProcessor(NewStateProcessor(config, bc)) @@ -893,7 +898,6 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) { glog.V(logger.Debug).Infoln("Premature abort during block chain processing") break } - bstart := time.Now() // Wait for block i's nonce to be verified before processing // its state transition. @@ -1242,8 +1246,32 @@ func (self *BlockChain) update() { } } +// BadBlockArgs represents the entries in the list returned when bad blocks are queried. +type BadBlockArgs struct { + Hash common.Hash `json:"hash"` + Header *types.Header `json:"header"` +} + +// BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network +func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) { + headers := make([]BadBlockArgs, 0, bc.badBlocks.Len()) + for _, hash := range bc.badBlocks.Keys() { + if hdr, exist := bc.badBlocks.Peek(hash); exist { + header := hdr.(*types.Header) + headers = append(headers, BadBlockArgs{header.Hash(), header}) + } + } + return headers, nil +} + +// addBadBlock adds a bad block to the bad-block LRU cache +func (bc *BlockChain) addBadBlock(block *types.Block) { + bc.badBlocks.Add(block.Header().Hash(), block.Header()) +} + // reportBlock logs a bad block error. func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { + bc.addBadBlock(block) if glog.V(logger.Error) { var receiptString string for _, receipt := range receipts { diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 8f1383acd..16bea9d7c 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -485,6 +485,7 @@ func chm(genesis *types.Block, db ethdb.Database) *BlockChain { bc.bodyRLPCache, _ = lru.New(100) bc.blockCache, _ = lru.New(100) bc.futureBlocks, _ = lru.New(100) + bc.badBlocks, _ = lru.New(10) bc.SetValidator(bproc{}) bc.SetProcessor(bproc{}) bc.ResetWithGenesisBlock(genesis) |