diff options
-rw-r--r-- | core/chain_manager.go | 2 | ||||
-rw-r--r-- | core/chain_manager_test.go | 55 | ||||
-rw-r--r-- | core/error.go | 11 |
3 files changed, 66 insertions, 2 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go index 0ad4f86f9..383fce70c 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -642,7 +642,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { } if BadHashes[block.Hash()] { - err := fmt.Errorf("Found known bad hash in chain %x", block.Hash()) + err := BadHashError(block.Hash()) blockErr(block, err) return i, err } diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go index 0c77fc138..6cfafb8c0 100644 --- a/core/chain_manager_test.go +++ b/core/chain_manager_test.go @@ -75,7 +75,7 @@ func testFork(t *testing.T, bman *BlockProcessor, i, N int, f func(td1, td2 *big if err != nil { t.Fatal("could not make new canonical in testFork", err) } - // asert the bmans have the same block at i + // assert the bmans have the same block at i bi1 := bman.bc.GetBlockByNumber(uint64(i)).Hash() bi2 := bman2.bc.GetBlockByNumber(uint64(i)).Hash() if bi1 != bi2 { @@ -421,6 +421,59 @@ func TestReorgLongest(t *testing.T) { } } +func TestBadHashes(t *testing.T) { + db, _ := ethdb.NewMemDatabase() + genesis, err := WriteTestNetGenesisBlock(db, 0) + if err != nil { + t.Error(err) + t.FailNow() + } + bc := chm(genesis, db) + + chain := makeChainWithDiff(genesis, []int{1, 2, 4}, 10) + BadHashes[chain[2].Header().Hash()] = true + + _, err = bc.InsertChain(chain) + if !IsBadHashError(err) { + t.Errorf("error mismatch: want: BadHashError, have: %v", err) + } +} + +func TestReorgBadHashes(t *testing.T) { + db, _ := ethdb.NewMemDatabase() + genesis, err := WriteTestNetGenesisBlock(db, 0) + if err != nil { + t.Error(err) + t.FailNow() + } + bc := chm(genesis, db) + + chain := makeChainWithDiff(genesis, []int{1, 2, 3, 4}, 11) + bc.InsertChain(chain) + + if chain[3].Header().Hash() != bc.LastBlockHash() { + t.Errorf("last block hash mismatch: want: %x, have: %x", chain[3].Header().Hash(), bc.LastBlockHash()) + } + + // NewChainManager should check BadHashes when loading it db + BadHashes[chain[3].Header().Hash()] = true + + var eventMux event.TypeMux + ncm, err := NewChainManager(db, FakePow{}, &eventMux) + if err != nil { + t.Errorf("NewChainManager err: %s", err) + } + + // check it set head to (valid) parent of bad hash block + if chain[2].Header().Hash() != ncm.LastBlockHash() { + t.Errorf("last block hash mismatch: want: %x, have: %x", chain[2].Header().Hash(), ncm.LastBlockHash()) + } + + if chain[2].Header().GasLimit.Cmp(ncm.GasLimit()) != 0 { + t.Errorf("current block gasLimit mismatch: want: %x, have: %x", chain[2].Header().GasLimit, ncm.GasLimit()) + } +} + func TestReorgShortest(t *testing.T) { db, _ := ethdb.NewMemDatabase() genesis, err := WriteTestNetGenesisBlock(db, 0) diff --git a/core/error.go b/core/error.go index 09eea22d6..ff58d69d6 100644 --- a/core/error.go +++ b/core/error.go @@ -177,3 +177,14 @@ func IsValueTransferErr(e error) bool { _, ok := e.(*ValueTransferError) return ok } + +type BadHashError common.Hash + +func (h BadHashError) Error() string { + return fmt.Sprintf("Found known bad hash in chain %x", h) +} + +func IsBadHashError(err error) bool { + _, ok := err.(BadHashError) + return ok +} |