From a660685746db17a41cd67b05c614cdb29e49340c Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 27 Sep 2017 15:30:41 +0200 Subject: [PATCH] tests: add ethash difficulty tests (#15191) --- tests/difficulty_test.go | 87 +++++++++++++++++++++++++++++++++++ tests/difficulty_test_util.go | 70 ++++++++++++++++++++++++++++ tests/gen_difficultytest.go | 66 ++++++++++++++++++++++++++ tests/init_test.go | 1 + tests/state_test.go | 18 ++++---- tests/testdata | 2 +- 6 files changed, 235 insertions(+), 9 deletions(-) create mode 100644 tests/difficulty_test.go create mode 100644 tests/difficulty_test_util.go create mode 100644 tests/gen_difficultytest.go diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go new file mode 100644 index 000000000..a449b1cfa --- /dev/null +++ b/tests/difficulty_test.go @@ -0,0 +1,87 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +// + +package tests + +import ( + "testing" + + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" +) + +var ( + mainnetChainConfig = params.ChainConfig{ + ChainId: big.NewInt(1), + HomesteadBlock: big.NewInt(1150000), + DAOForkBlock: big.NewInt(1920000), + DAOForkSupport: true, + EIP150Block: big.NewInt(2463000), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(2675000), + EIP158Block: big.NewInt(2675000), + ByzantiumBlock: big.NewInt(4370000), + } +) + +func TestDifficulty(t *testing.T) { + t.Parallel() + + dt := new(testMatcher) + // Not difficulty-tests + dt.skipLoad("hexencodetest.*") + dt.skipLoad("crypto.*") + dt.skipLoad("blockgenesistest\\.json") + dt.skipLoad("genesishashestest\\.json") + dt.skipLoad("keyaddrtest\\.json") + dt.skipLoad("txtest\\.json") + + // files are 2 years old, contains strange values + dt.skipLoad("difficultyCustomHomestead\\.json") + dt.skipLoad("difficultyMorden\\.json") + dt.skipLoad("difficultyOlimpic\\.json") + + dt.config("Ropsten", *params.TestnetChainConfig) + dt.config("Morden", *params.TestnetChainConfig) + dt.config("Frontier", params.ChainConfig{}) + + dt.config("Homestead", params.ChainConfig{ + HomesteadBlock: big.NewInt(0), + }) + + dt.config("Byzantium", params.ChainConfig{ + ByzantiumBlock: big.NewInt(0), + }) + + dt.config("Frontier", *params.TestnetChainConfig) + dt.config("MainNetwork", mainnetChainConfig) + dt.config("CustomMainNetwork", mainnetChainConfig) + dt.config("difficulty.json", mainnetChainConfig) + + dt.walk(t, difficultyTestDir, func(t *testing.T, name string, test *DifficultyTest) { + cfg := dt.findConfig(name) + if test.ParentDifficulty.Cmp(params.MinimumDifficulty) < 0 { + t.Skip("difficulty below minimum") + return + } + if err := dt.checkFailure(t, name, test.Run(cfg)); err != nil { + t.Error(err) + } + }) +} diff --git a/tests/difficulty_test_util.go b/tests/difficulty_test_util.go new file mode 100644 index 000000000..754147793 --- /dev/null +++ b/tests/difficulty_test_util.go @@ -0,0 +1,70 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +// + +package tests + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" +) + +//go:generate gencodec -type DifficultyTest -field-override difficultyTestMarshaling -out gen_difficultytest.go + +type DifficultyTest struct { + ParentTimestamp *big.Int `json:"parentTimestamp"` + ParentDifficulty *big.Int `json:"parentDifficulty"` + UncleHash common.Hash `json:"parentUncles"` + CurrentTimestamp *big.Int `json:"currentTimestamp"` + CurrentBlockNumber uint64 `json:"currentBlockNumber"` + CurrentDifficulty *big.Int `json:"currentDifficulty"` +} + +type difficultyTestMarshaling struct { + ParentTimestamp *math.HexOrDecimal256 + ParentDifficulty *math.HexOrDecimal256 + CurrentTimestamp *math.HexOrDecimal256 + CurrentDifficulty *math.HexOrDecimal256 + UncleHash common.Hash + CurrentBlockNumber math.HexOrDecimal64 +} + +func (test *DifficultyTest) Run(config *params.ChainConfig) error { + parentNumber := big.NewInt(int64(test.CurrentBlockNumber - 1)) + parent := &types.Header{ + Difficulty: test.ParentDifficulty, + Time: test.ParentTimestamp, + Number: parentNumber, + UncleHash: test.UncleHash, + } + + actual := ethash.CalcDifficulty(config, test.CurrentTimestamp.Uint64(), parent) + exp := test.CurrentDifficulty + + if actual.Cmp(exp) != 0 { + return fmt.Errorf("parent[time %v diff %v unclehash:%x] child[time %v number %v] diff %v != expected %v", + test.ParentTimestamp, test.ParentDifficulty, test.UncleHash, + test.CurrentTimestamp, test.CurrentBlockNumber, actual, exp) + } + return nil + +} diff --git a/tests/gen_difficultytest.go b/tests/gen_difficultytest.go new file mode 100644 index 000000000..88f36ce99 --- /dev/null +++ b/tests/gen_difficultytest.go @@ -0,0 +1,66 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package tests + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" +) + +var _ = (*difficultyTestMarshaling)(nil) + +func (d DifficultyTest) MarshalJSON() ([]byte, error) { + type DifficultyTest struct { + ParentTimestamp *math.HexOrDecimal256 `json:"parentTimestamp"` + ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"` + UncleHash common.Hash `json:"parentUncles"` + CurrentTimestamp *math.HexOrDecimal256 `json:"currentTimestamp"` + CurrentBlockNumber math.HexOrDecimal64 `json:"currentBlockNumber"` + CurrentDifficulty *math.HexOrDecimal256 `json:"currentDifficulty"` + } + var enc DifficultyTest + enc.ParentTimestamp = (*math.HexOrDecimal256)(d.ParentTimestamp) + enc.ParentDifficulty = (*math.HexOrDecimal256)(d.ParentDifficulty) + enc.UncleHash = d.UncleHash + enc.CurrentTimestamp = (*math.HexOrDecimal256)(d.CurrentTimestamp) + enc.CurrentBlockNumber = math.HexOrDecimal64(d.CurrentBlockNumber) + enc.CurrentDifficulty = (*math.HexOrDecimal256)(d.CurrentDifficulty) + return json.Marshal(&enc) +} + +func (d *DifficultyTest) UnmarshalJSON(input []byte) error { + type DifficultyTest struct { + ParentTimestamp *math.HexOrDecimal256 `json:"parentTimestamp"` + ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"` + UncleHash *common.Hash `json:"parentUncles"` + CurrentTimestamp *math.HexOrDecimal256 `json:"currentTimestamp"` + CurrentBlockNumber *math.HexOrDecimal64 `json:"currentBlockNumber"` + CurrentDifficulty *math.HexOrDecimal256 `json:"currentDifficulty"` + } + var dec DifficultyTest + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ParentTimestamp != nil { + d.ParentTimestamp = (*big.Int)(dec.ParentTimestamp) + } + if dec.ParentDifficulty != nil { + d.ParentDifficulty = (*big.Int)(dec.ParentDifficulty) + } + if dec.UncleHash != nil { + d.UncleHash = *dec.UncleHash + } + if dec.CurrentTimestamp != nil { + d.CurrentTimestamp = (*big.Int)(dec.CurrentTimestamp) + } + if dec.CurrentBlockNumber != nil { + d.CurrentBlockNumber = uint64(*dec.CurrentBlockNumber) + } + if dec.CurrentDifficulty != nil { + d.CurrentDifficulty = (*big.Int)(dec.CurrentDifficulty) + } + return nil +} diff --git a/tests/init_test.go b/tests/init_test.go index 0adbb533d..ebb0d32c3 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -39,6 +39,7 @@ var ( transactionTestDir = filepath.Join(baseDir, "TransactionTests") vmTestDir = filepath.Join(baseDir, "VMTests") rlpTestDir = filepath.Join(baseDir, "RLPTests") + difficultyTestDir = filepath.Join(baseDir, "BasicTests") ) func readJson(reader io.Reader, value interface{}) error { diff --git a/tests/state_test.go b/tests/state_test.go index 9a7430fbe..5a67b290d 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -39,14 +39,16 @@ func TestState(t *testing.T) { st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/EIP158`, "bug in test") st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/Byzantium`, "bug in test") st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/Byzantium`, "bug in test") - st.fails( `^stRandom/randomStatetest645\.json/EIP150/.*`, "known bug #15119") - st.fails( `^stRandom/randomStatetest645\.json/Frontier/.*`, "known bug #15119") - st.fails( `^stRandom/randomStatetest645\.json/Homestead/.*`, "known bug #15119") - st.fails( `^stRandom/randomStatetest644\.json/EIP150/.*`, "known bug #15119") - st.fails( `^stRandom/randomStatetest644\.json/Frontier/.*`, "known bug #15119") - st.fails( `^stRandom/randomStatetest644\.json/Homestead/.*`, "known bug #15119") - - + st.fails(`^stRandom/randomStatetest645\.json/EIP150/.*`, "known bug #15119") + st.fails(`^stRandom/randomStatetest645\.json/Frontier/.*`, "known bug #15119") + st.fails(`^stRandom/randomStatetest645\.json/Homestead/.*`, "known bug #15119") + st.fails(`^stRandom/randomStatetest644\.json/EIP150/.*`, "known bug #15119") + st.fails(`^stRandom/randomStatetest644\.json/Frontier/.*`, "known bug #15119") + st.fails(`^stRandom/randomStatetest644\.json/Homestead/.*`, "known bug #15119") + st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/EIP158/2`, "known bug ") + st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/EIP158/3`, "known bug ") + st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/Byzantium/2`, "known bug ") + st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/Byzantium/3`, "known bug ") st.walk(t, stateTestDir, func(t *testing.T, name string, test *StateTest) { for _, subtest := range test.Subtests() { subtest := subtest diff --git a/tests/testdata b/tests/testdata index ca41e9063..37f555fbc 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit ca41e906351209481bce3a1b35501f25a79023c5 +Subproject commit 37f555fbc091fbf761aa6f02227132fb31f0681c