diff --git a/core/chain_manager.go b/core/chain_manager.go index 29830188e3..59f3c20878 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -571,8 +571,15 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { // 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 { + //key := append(blockNumPre, block.Number().Bytes()...) + //self.blockDb.Put(key, block.Hash().Bytes()) // Check for chain forks. If H(block.num - 1) != block.parent, we're on a fork and need to do some merging - if previous := self.getBlockByNumber(block.NumberU64() - 1); previous.Hash() != block.ParentHash() { + previous := self.getBlockByNumber(block.NumberU64() - 1) + if previous == nil { + glog.V(logger.Error).Infof("INVALID block #%v (%x)\n", block.Header().Number, block.Header().Hash().Bytes()) + return i, BlockNumberErr + } + if previous.Hash() != block.ParentHash() { chash := cblock.Hash() hash := block.Hash() diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go index 50915459b9..486acf4f80 100644 --- a/core/chain_manager_test.go +++ b/core/chain_manager_test.go @@ -241,6 +241,24 @@ func TestBrokenChain(t *testing.T) { } } +func TestChainForkWithWrongBlockNum(t *testing.T) { + db, _ := ethdb.NewMemDatabase() + genesis := GenesisBlock(db) + bc := chm(genesis, db) + + chain1 := makeChainWithDiff(genesis, []int{1, 2, 3}, 10) + chain2 := makeChainWithDiff(genesis, []int{4, 5}, 11) + chain2[0].Header().Number = big.NewInt(int64(6)) + chain2[1].Header().Number = big.NewInt(int64(7)) + + _, _ = bc.InsertChain(chain1) + _, err := bc.InsertChain(chain2) + + if err != BlockNumberErr { + t.Errorf("should have failed with BlockNumberErr") + } +} + func TestChainInsertions(t *testing.T) { t.Skip() // travil fails.