diff options
-rw-r--r-- | VERSION | 1 | ||||
-rw-r--r-- | cmd/geth/blocktestcmd.go | 6 | ||||
-rw-r--r-- | core/chain_manager.go | 3 | ||||
-rw-r--r-- | core/chain_manager_test.go | 55 | ||||
-rw-r--r-- | core/error.go | 11 | ||||
-rw-r--r-- | rpc/api/eth.go | 48 |
6 files changed, 91 insertions, 33 deletions
diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..26aaba0e8 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.2.0 diff --git a/cmd/geth/blocktestcmd.go b/cmd/geth/blocktestcmd.go index d3257ca4d..d6195e025 100644 --- a/cmd/geth/blocktestcmd.go +++ b/cmd/geth/blocktestcmd.go @@ -91,7 +91,6 @@ func runBlockTest(ctx *cli.Context) { if err != nil { utils.Fatalf("%v", err) } - defer ethereum.Stop() if rpc { fmt.Println("Block Test post state validated, starting RPC interface.") startEth(ctx, ethereum) @@ -106,7 +105,6 @@ func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, er cfg.MaxPeers = 0 // disable network cfg.Shh = false // disable whisper cfg.NAT = nil // disable port mapping - ethereum, err := eth.New(cfg) if err != nil { return nil, err @@ -114,7 +112,6 @@ func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, er // import the genesis block ethereum.ResetWithGenesisBlock(test.Genesis) - // import pre accounts _, err = test.InsertPreState(ethereum) if err != nil { @@ -122,16 +119,13 @@ func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, er } cm := ethereum.ChainManager() - validBlocks, err := test.TryBlocksInsert(cm) if err != nil { return ethereum, fmt.Errorf("Block Test load error: %v", err) } - newDB := cm.State() if err := test.ValidatePostState(newDB); err != nil { return ethereum, fmt.Errorf("post state validation failed: %v", err) } - return ethereum, test.ValidateImportedHeaders(cm, validBlocks) } diff --git a/core/chain_manager.go b/core/chain_manager.go index 42f70af33..383fce70c 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -279,6 +279,7 @@ func (bc *ChainManager) ResetWithGenesisBlock(genesis *types.Block) { if err := WriteBlock(bc.chainDb, genesis); err != nil { glog.Fatalf("failed to write genesis block: %v", err) } + bc.genesisBlock = genesis bc.insert(bc.genesisBlock) bc.currentBlock = bc.genesisBlock bc.setTotalDifficulty(genesis.Difficulty()) @@ -641,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 +} diff --git a/rpc/api/eth.go b/rpc/api/eth.go index 30366a951..4cd5f2695 100644 --- a/rpc/api/eth.go +++ b/rpc/api/eth.go @@ -210,7 +210,7 @@ func (self *ethApi) GetTransactionCount(req *shared.Request) (interface{}, error } count := self.xeth.AtStateNum(args.BlockNumber).TxCountAt(args.Address) - return newHexNum(big.NewInt(int64(count)).Bytes()), nil + return fmt.Sprintf("%#x", count), nil } func (self *ethApi) GetBlockTransactionCountByHash(req *shared.Request) (interface{}, error) { @@ -218,14 +218,11 @@ func (self *ethApi) GetBlockTransactionCountByHash(req *shared.Request) (interfa if err := self.codec.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } - - raw := self.xeth.EthBlockByHash(args.Hash) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), false) + block := self.xeth.EthBlockByHash(args.Hash) if block == nil { return nil, nil - } else { - return newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes()), nil } + return fmt.Sprintf("%#x", len(block.Transactions())), nil } func (self *ethApi) GetBlockTransactionCountByNumber(req *shared.Request) (interface{}, error) { @@ -234,13 +231,11 @@ func (self *ethApi) GetBlockTransactionCountByNumber(req *shared.Request) (inter return nil, shared.NewDecodeParamError(err.Error()) } - raw := self.xeth.EthBlockByNumber(args.BlockNumber) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), false) + block := self.xeth.EthBlockByNumber(args.BlockNumber) if block == nil { return nil, nil - } else { - return newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes()), nil } + return fmt.Sprintf("%#x", len(block.Transactions())), nil } func (self *ethApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, error) { @@ -249,12 +244,11 @@ func (self *ethApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, return nil, shared.NewDecodeParamError(err.Error()) } - raw := self.xeth.EthBlockByHash(args.Hash) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), false) + block := self.xeth.EthBlockByHash(args.Hash) if block == nil { return nil, nil } - return newHexNum(big.NewInt(int64(len(block.Uncles))).Bytes()), nil + return fmt.Sprintf("%#x", len(block.Uncles())), nil } func (self *ethApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}, error) { @@ -263,12 +257,11 @@ func (self *ethApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{} return nil, shared.NewDecodeParamError(err.Error()) } - raw := self.xeth.EthBlockByNumber(args.BlockNumber) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), false) + block := self.xeth.EthBlockByNumber(args.BlockNumber) if block == nil { return nil, nil } - return newHexNum(big.NewInt(int64(len(block.Uncles))).Bytes()), nil + return fmt.Sprintf("%#x", len(block.Uncles())), nil } func (self *ethApi) GetData(req *shared.Request) (interface{}, error) { @@ -377,8 +370,10 @@ func (self *ethApi) GetBlockByHash(req *shared.Request) (interface{}, error) { if err := self.codec.Decode(req.Params, &args); err != nil { return nil, shared.NewDecodeParamError(err.Error()) } - block := self.xeth.EthBlockByHash(args.BlockHash) + if block == nil { + return nil, nil + } return NewBlockRes(block, self.xeth.Td(block.Hash()), args.IncludeTxs), nil } @@ -389,6 +384,9 @@ func (self *ethApi) GetBlockByNumber(req *shared.Request) (interface{}, error) { } block := self.xeth.EthBlockByNumber(args.BlockNumber) + if block == nil { + return nil, nil + } return NewBlockRes(block, self.xeth.Td(block.Hash()), args.IncludeTxs), nil } @@ -419,10 +417,10 @@ func (self *ethApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (inte } raw := self.xeth.EthBlockByHash(args.Hash) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) - if block == nil { + if raw == nil { return nil, nil } + block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) if args.Index >= int64(len(block.Transactions)) || args.Index < 0 { return nil, nil } else { @@ -437,10 +435,10 @@ func (self *ethApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (in } raw := self.xeth.EthBlockByNumber(args.BlockNumber) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) - if block == nil { + if raw == nil { return nil, nil } + block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) if args.Index >= int64(len(block.Transactions)) || args.Index < 0 { // return NewValidationError("Index", "does not exist") return nil, nil @@ -455,10 +453,10 @@ func (self *ethApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{ } raw := self.xeth.EthBlockByHash(args.Hash) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), false) - if block == nil { + if raw == nil { return nil, nil } + block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), false) if args.Index >= int64(len(block.Uncles)) || args.Index < 0 { // return NewValidationError("Index", "does not exist") return nil, nil @@ -473,10 +471,10 @@ func (self *ethApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interfac } raw := self.xeth.EthBlockByNumber(args.BlockNumber) - block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) - if block == nil { + if raw == nil { return nil, nil } + block := NewBlockRes(raw, self.xeth.Td(raw.Hash()), true) if args.Index >= int64(len(block.Uncles)) || args.Index < 0 { return nil, nil } else { |