From 8a7c9ca61c9bc4937d63966110fb7d55faae55f5 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Wed, 6 May 2015 15:24:54 +0200 Subject: [PATCH] DoS fix: add check for wrong block number in chain fork --- core/chain_manager.go | 9 ++++++++- core/chain_manager_test.go | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) 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..eadcfd64b4 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(4)) + chain2[1].Header().Number = big.NewInt(int64(5)) + + _, _ = 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.