diff --git a/tests/block_test.go b/tests/block_test.go deleted file mode 100644 index aa6f27b8f3..0000000000 --- a/tests/block_test.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2015 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 ( - "math/rand" - "runtime" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" -) - -func TestBlockchain(t *testing.T) { - bt := new(testMatcher) - // General state tests are 'exported' as blockchain tests, but we can run them natively. - // For speedier CI-runs, the line below can be uncommented, so those are skipped. - // For now, in hardfork-times (Berlin), we run the tests both as StateTests and - // as blockchain tests, since the latter also covers things like receipt root - bt.skipLoad(`^GeneralStateTests/`) - - // Skip random failures due to selfish mining test - bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`) - - // Slow tests - bt.slow(`.*bcExploitTest/DelegateCallSpam.json`) - bt.slow(`.*bcExploitTest/ShanghaiLove.json`) - bt.slow(`.*bcExploitTest/SuicideIssue.json`) - bt.slow(`.*/bcForkStressTest/`) - bt.slow(`.*/bcGasPricerTest/RPC_API_Test.json`) - bt.slow(`.*/bcWalletTest/`) - - // Very slow test - bt.skipLoad(`.*/stTimeConsuming/.*`) - // test takes a lot for time and goes easily OOM because of sha3 calculation on a huge range, - // using 4.6 TGas - bt.skipLoad(`.*randomStatetest94.json.*`) - - bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { - if runtime.GOARCH == "386" && runtime.GOOS == "windows" && rand.Int63()%2 == 0 { - t.Skip("test (randomly) skipped on 32-bit windows") - } - execBlockTest(t, bt, test) - }) - // There is also a LegacyTests folder, containing blockchain tests generated - // prior to Istanbul. However, they are all derived from GeneralStateTests, - // which run natively, so there's no reason to run them here. -} - -// TestExecutionSpec runs the test fixtures from execution-spec-tests. -func TestExecutionSpec(t *testing.T) { - if !common.FileExist(executionSpecDir) { - t.Skipf("directory %s does not exist", executionSpecDir) - } - bt := new(testMatcher) - - bt.walk(t, executionSpecDir, func(t *testing.T, name string, test *BlockTest) { - execBlockTest(t, bt, test) - }) -} - -func execBlockTest(t *testing.T, bt *testMatcher, test *BlockTest) { - if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil, nil)); err != nil { - t.Errorf("test in hash mode without snapshotter failed: %v", err) - return - } - if err := bt.checkFailure(t, test.Run(true, rawdb.HashScheme, nil, nil)); err != nil { - t.Errorf("test in hash mode with snapshotter failed: %v", err) - return - } - if err := bt.checkFailure(t, test.Run(false, rawdb.PathScheme, nil, nil)); err != nil { - t.Errorf("test in path mode without snapshotter failed: %v", err) - return - } - if err := bt.checkFailure(t, test.Run(true, rawdb.PathScheme, nil, nil)); err != nil { - t.Errorf("test in path mode with snapshotter failed: %v", err) - return - } -} diff --git a/tests/block_test_util.go b/tests/block_test_util.go deleted file mode 100644 index e0130be48a..0000000000 --- a/tests/block_test_util.go +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright 2015 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 implements execution of Ethereum JSON tests. -package tests - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - "os" - "reflect" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/consensus/beacon" - "github.com/ethereum/go-ethereum/consensus/ethash" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/trie/triedb/hashdb" - "github.com/ethereum/go-ethereum/trie/triedb/pathdb" -) - -// A BlockTest checks handling of entire blocks. -type BlockTest struct { - json btJSON -} - -// UnmarshalJSON implements json.Unmarshaler interface. -func (t *BlockTest) UnmarshalJSON(in []byte) error { - return json.Unmarshal(in, &t.json) -} - -type btJSON struct { - Blocks []btBlock `json:"blocks"` - Genesis btHeader `json:"genesisBlockHeader"` - Pre core.GenesisAlloc `json:"pre"` - Post core.GenesisAlloc `json:"postState"` - BestBlock common.UnprefixedHash `json:"lastblockhash"` - Network string `json:"network"` - SealEngine string `json:"sealEngine"` -} - -type btBlock struct { - BlockHeader *btHeader - ExpectException string - Rlp string - UncleHeaders []*btHeader -} - -//go:generate go run github.com/fjl/gencodec -type btHeader -field-override btHeaderMarshaling -out gen_btheader.go - -type btHeader struct { - Bloom types.Bloom - Coinbase common.Address - MixHash common.Hash - Nonce types.BlockNonce - Number *big.Int - Hash common.Hash - ParentHash common.Hash - ReceiptTrie common.Hash - StateRoot common.Hash - TransactionsTrie common.Hash - UncleHash common.Hash - ExtraData []byte - Difficulty *big.Int - GasLimit uint64 - GasUsed uint64 - Timestamp uint64 - BaseFeePerGas *big.Int - WithdrawalsRoot *common.Hash - BlobGasUsed *uint64 - ExcessBlobGas *uint64 - ParentBeaconBlockRoot *common.Hash -} - -type btHeaderMarshaling struct { - ExtraData hexutil.Bytes - Number *math.HexOrDecimal256 - Difficulty *math.HexOrDecimal256 - GasLimit math.HexOrDecimal64 - GasUsed math.HexOrDecimal64 - Timestamp math.HexOrDecimal64 - BaseFeePerGas *math.HexOrDecimal256 - BlobGasUsed *math.HexOrDecimal64 - ExcessBlobGas *math.HexOrDecimal64 -} - -func (t *BlockTest) Run(snapshotter bool, scheme string, tracer vm.EVMLogger, postCheck func(error, *core.BlockChain)) (result error) { - config, ok := Forks[t.json.Network] - if !ok { - return UnsupportedForkError{t.json.Network} - } - // import pre accounts & construct test genesis block & state root - var ( - db = rawdb.NewMemoryDatabase() - tconf = &trie.Config{ - Preimages: true, - } - ) - if scheme == rawdb.PathScheme { - tconf.PathDB = pathdb.Defaults - } else { - tconf.HashDB = hashdb.Defaults - } - // Commit genesis state - gspec := t.genesis(config) - triedb := trie.NewDatabase(db, tconf) - gblock, err := gspec.Commit(db, triedb) - if err != nil { - return err - } - triedb.Close() // close the db to prevent memory leak - - if gblock.Hash() != t.json.Genesis.Hash { - return fmt.Errorf("genesis block hash doesn't match test: computed=%x, test=%x", gblock.Hash().Bytes()[:6], t.json.Genesis.Hash[:6]) - } - if gblock.Root() != t.json.Genesis.StateRoot { - return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes()[:6], t.json.Genesis.StateRoot[:6]) - } - // Wrap the original engine within the beacon-engine - engine := beacon.New(ethash.NewFaker()) - - cache := &core.CacheConfig{TrieCleanLimit: 0, StateScheme: scheme, Preimages: true} - if snapshotter { - cache.SnapshotLimit = 1 - cache.SnapshotWait = true - } - chain, err := core.NewBlockChain(db, cache, gspec, nil, engine, vm.Config{ - Tracer: tracer, - }, nil, nil) - if err != nil { - return err - } - defer chain.Stop() - - validBlocks, err := t.insertBlocks(chain) - if err != nil { - return err - } - // Import succeeded: regardless of whether the _test_ succeeds or not, schedule - // the post-check to run - if postCheck != nil { - defer postCheck(result, chain) - } - cmlast := chain.CurrentBlock().Hash() - if common.Hash(t.json.BestBlock) != cmlast { - return fmt.Errorf("last block hash validation mismatch: want: %x, have: %x", t.json.BestBlock, cmlast) - } - newDB, err := chain.State() - if err != nil { - return err - } - if err = t.validatePostState(newDB); err != nil { - return fmt.Errorf("post state validation failed: %v", err) - } - // Cross-check the snapshot-to-hash against the trie hash - if snapshotter { - if err := chain.Snapshots().Verify(chain.CurrentBlock().Root); err != nil { - return err - } - } - return t.validateImportedHeaders(chain, validBlocks) -} - -func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { - return &core.Genesis{ - Config: config, - Nonce: t.json.Genesis.Nonce.Uint64(), - Timestamp: t.json.Genesis.Timestamp, - ParentHash: t.json.Genesis.ParentHash, - ExtraData: t.json.Genesis.ExtraData, - GasLimit: t.json.Genesis.GasLimit, - GasUsed: t.json.Genesis.GasUsed, - Difficulty: t.json.Genesis.Difficulty, - Mixhash: t.json.Genesis.MixHash, - Coinbase: t.json.Genesis.Coinbase, - Alloc: t.json.Pre, - BaseFee: t.json.Genesis.BaseFeePerGas, - BlobGasUsed: t.json.Genesis.BlobGasUsed, - ExcessBlobGas: t.json.Genesis.ExcessBlobGas, - } -} - -/* -See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II - - Whether a block is valid or not is a bit subtle, it's defined by presence of - blockHeader, transactions and uncleHeaders fields. If they are missing, the block is - invalid and we must verify that we do not accept it. - - Since some tests mix valid and invalid blocks we need to check this for every block. - - If a block is invalid it does not necessarily fail the test, if it's invalidness is - expected we are expected to ignore it and continue processing and then validate the - post state. -*/ -func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) { - validBlocks := make([]btBlock, 0) - // insert the test blocks, which will execute all transactions - for bi, b := range t.json.Blocks { - cb, err := b.decode() - if err != nil { - if b.BlockHeader == nil { - continue // OK - block is supposed to be invalid, continue with next block - } else { - return nil, fmt.Errorf("block RLP decoding failed when expected to succeed: %v", err) - } - } - // RLP decoding worked, try to insert into chain: - blocks := types.Blocks{cb} - i, err := blockchain.InsertChain(blocks) - if err != nil { - if b.BlockHeader == nil { - continue // OK - block is supposed to be invalid, continue with next block - } else { - return nil, fmt.Errorf("block #%v insertion into chain failed: %v", blocks[i].Number(), err) - } - } - if b.BlockHeader == nil { - if data, err := json.MarshalIndent(cb.Header(), "", " "); err == nil { - fmt.Fprintf(os.Stderr, "block (index %d) insertion should have failed due to: %v:\n%v\n", - bi, b.ExpectException, string(data)) - } - return nil, fmt.Errorf("block (index %d) insertion should have failed due to: %v", - bi, b.ExpectException) - } - - // validate RLP decoding by checking all values against test file JSON - if err = validateHeader(b.BlockHeader, cb.Header()); err != nil { - return nil, fmt.Errorf("deserialised block header validation failed: %v", err) - } - validBlocks = append(validBlocks, b) - } - return validBlocks, nil -} - -func validateHeader(h *btHeader, h2 *types.Header) error { - if h.Bloom != h2.Bloom { - return fmt.Errorf("bloom: want: %x have: %x", h.Bloom, h2.Bloom) - } - if h.Coinbase != h2.Coinbase { - return fmt.Errorf("coinbase: want: %x have: %x", h.Coinbase, h2.Coinbase) - } - if h.MixHash != h2.MixDigest { - return fmt.Errorf("MixHash: want: %x have: %x", h.MixHash, h2.MixDigest) - } - if h.Nonce != h2.Nonce { - return fmt.Errorf("nonce: want: %x have: %x", h.Nonce, h2.Nonce) - } - if h.Number.Cmp(h2.Number) != 0 { - return fmt.Errorf("number: want: %v have: %v", h.Number, h2.Number) - } - if h.ParentHash != h2.ParentHash { - return fmt.Errorf("parent hash: want: %x have: %x", h.ParentHash, h2.ParentHash) - } - if h.ReceiptTrie != h2.ReceiptHash { - return fmt.Errorf("receipt hash: want: %x have: %x", h.ReceiptTrie, h2.ReceiptHash) - } - if h.TransactionsTrie != h2.TxHash { - return fmt.Errorf("tx hash: want: %x have: %x", h.TransactionsTrie, h2.TxHash) - } - if h.StateRoot != h2.Root { - return fmt.Errorf("state hash: want: %x have: %x", h.StateRoot, h2.Root) - } - if h.UncleHash != h2.UncleHash { - return fmt.Errorf("uncle hash: want: %x have: %x", h.UncleHash, h2.UncleHash) - } - if !bytes.Equal(h.ExtraData, h2.Extra) { - return fmt.Errorf("extra data: want: %x have: %x", h.ExtraData, h2.Extra) - } - if h.Difficulty.Cmp(h2.Difficulty) != 0 { - return fmt.Errorf("difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty) - } - if h.GasLimit != h2.GasLimit { - return fmt.Errorf("gasLimit: want: %d have: %d", h.GasLimit, h2.GasLimit) - } - if h.GasUsed != h2.GasUsed { - return fmt.Errorf("gasUsed: want: %d have: %d", h.GasUsed, h2.GasUsed) - } - if h.Timestamp != h2.Time { - return fmt.Errorf("timestamp: want: %v have: %v", h.Timestamp, h2.Time) - } - if !reflect.DeepEqual(h.BaseFeePerGas, h2.BaseFee) { - return fmt.Errorf("baseFeePerGas: want: %v have: %v", h.BaseFeePerGas, h2.BaseFee) - } - if !reflect.DeepEqual(h.WithdrawalsRoot, h2.WithdrawalsHash) { - return fmt.Errorf("withdrawalsRoot: want: %v have: %v", h.WithdrawalsRoot, h2.WithdrawalsHash) - } - if !reflect.DeepEqual(h.BlobGasUsed, h2.BlobGasUsed) { - return fmt.Errorf("blobGasUsed: want: %v have: %v", h.BlobGasUsed, h2.BlobGasUsed) - } - if !reflect.DeepEqual(h.ExcessBlobGas, h2.ExcessBlobGas) { - return fmt.Errorf("excessBlobGas: want: %v have: %v", h.ExcessBlobGas, h2.ExcessBlobGas) - } - if !reflect.DeepEqual(h.ParentBeaconBlockRoot, h2.ParentBeaconRoot) { - return fmt.Errorf("parentBeaconBlockRoot: want: %v have: %v", h.ParentBeaconBlockRoot, h2.ParentBeaconRoot) - } - return nil -} - -func (t *BlockTest) validatePostState(statedb *state.StateDB) error { - // validate post state accounts in test file against what we have in state db - for addr, acct := range t.json.Post { - // address is indirectly verified by the other fields, as it's the db key - code2 := statedb.GetCode(addr) - balance2 := statedb.GetBalance(addr) - nonce2 := statedb.GetNonce(addr) - if !bytes.Equal(code2, acct.Code) { - return fmt.Errorf("account code mismatch for addr: %s want: %v have: %s", addr, acct.Code, hex.EncodeToString(code2)) - } - if balance2.Cmp(acct.Balance) != 0 { - return fmt.Errorf("account balance mismatch for addr: %s, want: %d, have: %d", addr, acct.Balance, balance2) - } - if nonce2 != acct.Nonce { - return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addr, acct.Nonce, nonce2) - } - for k, v := range acct.Storage { - v2 := statedb.GetState(addr, k) - if v2 != v { - return fmt.Errorf("account storage mismatch for addr: %s, slot: %x, want: %x, have: %x", addr, k, v, v2) - } - } - } - return nil -} - -func (t *BlockTest) validateImportedHeaders(cm *core.BlockChain, validBlocks []btBlock) error { - // to get constant lookup when verifying block headers by hash (some tests have many blocks) - bmap := make(map[common.Hash]btBlock, len(t.json.Blocks)) - for _, b := range validBlocks { - bmap[b.BlockHeader.Hash] = b - } - // iterate over blocks backwards from HEAD and validate imported - // headers vs test file. some tests have reorgs, and we import - // block-by-block, so we can only validate imported headers after - // all blocks have been processed by BlockChain, as they may not - // be part of the longest chain until last block is imported. - for b := cm.CurrentBlock(); b != nil && b.Number.Uint64() != 0; b = cm.GetBlockByHash(b.ParentHash).Header() { - if err := validateHeader(bmap[b.Hash()].BlockHeader, b); err != nil { - return fmt.Errorf("imported block header validation failed: %v", err) - } - } - return nil -} - -func (bb *btBlock) decode() (*types.Block, error) { - data, err := hexutil.Decode(bb.Rlp) - if err != nil { - return nil, err - } - var b types.Block - err = rlp.DecodeBytes(data, &b) - return &b, err -} diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go deleted file mode 100644 index 03e14df7c4..0000000000 --- a/tests/difficulty_test.go +++ /dev/null @@ -1,111 +0,0 @@ -// 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 ( - "math/big" - "testing" - - "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), - EIP155Block: big.NewInt(2675000), - EIP158Block: big.NewInt(2675000), - ByzantiumBlock: big.NewInt(4370000), - } - - ropstenChainConfig = params.ChainConfig{ - ChainID: big.NewInt(3), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: nil, - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(10), - EIP158Block: big.NewInt(10), - ByzantiumBlock: big.NewInt(1_700_000), - ConstantinopleBlock: big.NewInt(4_230_000), - PetersburgBlock: big.NewInt(4_939_394), - IstanbulBlock: big.NewInt(6_485_846), - MuirGlacierBlock: big.NewInt(7_117_117), - BerlinBlock: big.NewInt(9_812_189), - LondonBlock: big.NewInt(10_499_401), - TerminalTotalDifficulty: new(big.Int).SetUint64(50_000_000_000_000_000), - TerminalTotalDifficultyPassed: true, - } -) - -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.config("Ropsten", ropstenChainConfig) - 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", ropstenChainConfig) - dt.config("MainNetwork", mainnetChainConfig) - dt.config("CustomMainNetwork", mainnetChainConfig) - dt.config("Constantinople", params.ChainConfig{ - ConstantinopleBlock: big.NewInt(0), - }) - dt.config("EIP2384", params.ChainConfig{ - MuirGlacierBlock: big.NewInt(0), - }) - dt.config("EIP4345", params.ChainConfig{ - ArrowGlacierBlock: big.NewInt(0), - }) - dt.config("EIP5133", params.ChainConfig{ - GrayGlacierBlock: big.NewInt(0), - }) - dt.config("difficulty.json", mainnetChainConfig) - - dt.walk(t, difficultyTestDir, func(t *testing.T, name string, test *DifficultyTest) { - cfg := dt.findConfig(t) - if test.ParentDifficulty.Cmp(params.MinimumDifficulty) < 0 { - t.Skip("difficulty below minimum") - return - } - if err := dt.checkFailure(t, test.Run(cfg)); err != nil { - t.Error(err) - } - }) -} diff --git a/tests/difficulty_test_util.go b/tests/difficulty_test_util.go deleted file mode 100644 index 62b978f9ef..0000000000 --- a/tests/difficulty_test_util.go +++ /dev/null @@ -1,68 +0,0 @@ -// 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 go run github.com/fjl/gencodec -type DifficultyTest -field-override difficultyTestMarshaling -out gen_difficultytest.go - -type DifficultyTest struct { - ParentTimestamp uint64 `json:"parentTimestamp"` - ParentDifficulty *big.Int `json:"parentDifficulty"` - UncleHash common.Hash `json:"parentUncles"` - CurrentTimestamp uint64 `json:"currentTimestamp"` - CurrentBlockNumber uint64 `json:"currentBlockNumber"` - CurrentDifficulty *big.Int `json:"currentDifficulty"` -} - -type difficultyTestMarshaling struct { - ParentTimestamp math.HexOrDecimal64 - ParentDifficulty *math.HexOrDecimal256 - CurrentTimestamp math.HexOrDecimal64 - 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, 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/evm-benchmarks b/tests/evm-benchmarks deleted file mode 160000 index d8b88f4046..0000000000 --- a/tests/evm-benchmarks +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d8b88f4046a87d6b902378cef752591f95427b43 diff --git a/tests/gen_btheader.go b/tests/gen_btheader.go deleted file mode 100644 index 80ad89e03b..0000000000 --- a/tests/gen_btheader.go +++ /dev/null @@ -1,160 +0,0 @@ -// 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/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/types" -) - -var _ = (*btHeaderMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (b btHeader) MarshalJSON() ([]byte, error) { - type btHeader struct { - Bloom types.Bloom - Coinbase common.Address - MixHash common.Hash - Nonce types.BlockNonce - Number *math.HexOrDecimal256 - Hash common.Hash - ParentHash common.Hash - ReceiptTrie common.Hash - StateRoot common.Hash - TransactionsTrie common.Hash - UncleHash common.Hash - ExtraData hexutil.Bytes - Difficulty *math.HexOrDecimal256 - GasLimit math.HexOrDecimal64 - GasUsed math.HexOrDecimal64 - Timestamp math.HexOrDecimal64 - BaseFeePerGas *math.HexOrDecimal256 - WithdrawalsRoot *common.Hash - BlobGasUsed *math.HexOrDecimal64 - ExcessBlobGas *math.HexOrDecimal64 - ParentBeaconBlockRoot *common.Hash - } - var enc btHeader - enc.Bloom = b.Bloom - enc.Coinbase = b.Coinbase - enc.MixHash = b.MixHash - enc.Nonce = b.Nonce - enc.Number = (*math.HexOrDecimal256)(b.Number) - enc.Hash = b.Hash - enc.ParentHash = b.ParentHash - enc.ReceiptTrie = b.ReceiptTrie - enc.StateRoot = b.StateRoot - enc.TransactionsTrie = b.TransactionsTrie - enc.UncleHash = b.UncleHash - enc.ExtraData = b.ExtraData - enc.Difficulty = (*math.HexOrDecimal256)(b.Difficulty) - enc.GasLimit = math.HexOrDecimal64(b.GasLimit) - enc.GasUsed = math.HexOrDecimal64(b.GasUsed) - enc.Timestamp = math.HexOrDecimal64(b.Timestamp) - enc.BaseFeePerGas = (*math.HexOrDecimal256)(b.BaseFeePerGas) - enc.WithdrawalsRoot = b.WithdrawalsRoot - enc.BlobGasUsed = (*math.HexOrDecimal64)(b.BlobGasUsed) - enc.ExcessBlobGas = (*math.HexOrDecimal64)(b.ExcessBlobGas) - enc.ParentBeaconBlockRoot = b.ParentBeaconBlockRoot - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (b *btHeader) UnmarshalJSON(input []byte) error { - type btHeader struct { - Bloom *types.Bloom - Coinbase *common.Address - MixHash *common.Hash - Nonce *types.BlockNonce - Number *math.HexOrDecimal256 - Hash *common.Hash - ParentHash *common.Hash - ReceiptTrie *common.Hash - StateRoot *common.Hash - TransactionsTrie *common.Hash - UncleHash *common.Hash - ExtraData *hexutil.Bytes - Difficulty *math.HexOrDecimal256 - GasLimit *math.HexOrDecimal64 - GasUsed *math.HexOrDecimal64 - Timestamp *math.HexOrDecimal64 - BaseFeePerGas *math.HexOrDecimal256 - WithdrawalsRoot *common.Hash - BlobGasUsed *math.HexOrDecimal64 - ExcessBlobGas *math.HexOrDecimal64 - ParentBeaconBlockRoot *common.Hash - } - var dec btHeader - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Bloom != nil { - b.Bloom = *dec.Bloom - } - if dec.Coinbase != nil { - b.Coinbase = *dec.Coinbase - } - if dec.MixHash != nil { - b.MixHash = *dec.MixHash - } - if dec.Nonce != nil { - b.Nonce = *dec.Nonce - } - if dec.Number != nil { - b.Number = (*big.Int)(dec.Number) - } - if dec.Hash != nil { - b.Hash = *dec.Hash - } - if dec.ParentHash != nil { - b.ParentHash = *dec.ParentHash - } - if dec.ReceiptTrie != nil { - b.ReceiptTrie = *dec.ReceiptTrie - } - if dec.StateRoot != nil { - b.StateRoot = *dec.StateRoot - } - if dec.TransactionsTrie != nil { - b.TransactionsTrie = *dec.TransactionsTrie - } - if dec.UncleHash != nil { - b.UncleHash = *dec.UncleHash - } - if dec.ExtraData != nil { - b.ExtraData = *dec.ExtraData - } - if dec.Difficulty != nil { - b.Difficulty = (*big.Int)(dec.Difficulty) - } - if dec.GasLimit != nil { - b.GasLimit = uint64(*dec.GasLimit) - } - if dec.GasUsed != nil { - b.GasUsed = uint64(*dec.GasUsed) - } - if dec.Timestamp != nil { - b.Timestamp = uint64(*dec.Timestamp) - } - if dec.BaseFeePerGas != nil { - b.BaseFeePerGas = (*big.Int)(dec.BaseFeePerGas) - } - if dec.WithdrawalsRoot != nil { - b.WithdrawalsRoot = dec.WithdrawalsRoot - } - if dec.BlobGasUsed != nil { - b.BlobGasUsed = (*uint64)(dec.BlobGasUsed) - } - if dec.ExcessBlobGas != nil { - b.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) - } - if dec.ParentBeaconBlockRoot != nil { - b.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot - } - return nil -} diff --git a/tests/gen_difficultytest.go b/tests/gen_difficultytest.go deleted file mode 100644 index cd15ae31b5..0000000000 --- a/tests/gen_difficultytest.go +++ /dev/null @@ -1,68 +0,0 @@ -// 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) - -// MarshalJSON marshals as JSON. -func (d DifficultyTest) MarshalJSON() ([]byte, error) { - type DifficultyTest struct { - ParentTimestamp math.HexOrDecimal64 `json:"parentTimestamp"` - ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"` - UncleHash common.Hash `json:"parentUncles"` - CurrentTimestamp math.HexOrDecimal64 `json:"currentTimestamp"` - CurrentBlockNumber math.HexOrDecimal64 `json:"currentBlockNumber"` - CurrentDifficulty *math.HexOrDecimal256 `json:"currentDifficulty"` - } - var enc DifficultyTest - enc.ParentTimestamp = math.HexOrDecimal64(d.ParentTimestamp) - enc.ParentDifficulty = (*math.HexOrDecimal256)(d.ParentDifficulty) - enc.UncleHash = d.UncleHash - enc.CurrentTimestamp = math.HexOrDecimal64(d.CurrentTimestamp) - enc.CurrentBlockNumber = math.HexOrDecimal64(d.CurrentBlockNumber) - enc.CurrentDifficulty = (*math.HexOrDecimal256)(d.CurrentDifficulty) - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (d *DifficultyTest) UnmarshalJSON(input []byte) error { - type DifficultyTest struct { - ParentTimestamp *math.HexOrDecimal64 `json:"parentTimestamp"` - ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"` - UncleHash *common.Hash `json:"parentUncles"` - CurrentTimestamp *math.HexOrDecimal64 `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 = uint64(*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 = uint64(*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/gen_stenv.go b/tests/gen_stenv.go deleted file mode 100644 index a5bd0d5fcb..0000000000 --- a/tests/gen_stenv.go +++ /dev/null @@ -1,85 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package tests - -import ( - "encoding/json" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" -) - -var _ = (*stEnvMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (s stEnv) MarshalJSON() ([]byte, error) { - type stEnv struct { - Coinbase common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"optional"` - Random *math.HexOrDecimal256 `json:"currentRandom" gencodec:"optional"` - GasLimit math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"` - Number math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"` - Timestamp math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"` - BaseFee *math.HexOrDecimal256 `json:"currentBaseFee" gencodec:"optional"` - ExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas" gencodec:"optional"` - } - var enc stEnv - enc.Coinbase = common.UnprefixedAddress(s.Coinbase) - enc.Difficulty = (*math.HexOrDecimal256)(s.Difficulty) - enc.Random = (*math.HexOrDecimal256)(s.Random) - enc.GasLimit = math.HexOrDecimal64(s.GasLimit) - enc.Number = math.HexOrDecimal64(s.Number) - enc.Timestamp = math.HexOrDecimal64(s.Timestamp) - enc.BaseFee = (*math.HexOrDecimal256)(s.BaseFee) - enc.ExcessBlobGas = (*math.HexOrDecimal64)(s.ExcessBlobGas) - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (s *stEnv) UnmarshalJSON(input []byte) error { - type stEnv struct { - Coinbase *common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"optional"` - Random *math.HexOrDecimal256 `json:"currentRandom" gencodec:"optional"` - GasLimit *math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"` - Number *math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"` - Timestamp *math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"` - BaseFee *math.HexOrDecimal256 `json:"currentBaseFee" gencodec:"optional"` - ExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas" gencodec:"optional"` - } - var dec stEnv - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Coinbase == nil { - return errors.New("missing required field 'currentCoinbase' for stEnv") - } - s.Coinbase = common.Address(*dec.Coinbase) - if dec.Difficulty != nil { - s.Difficulty = (*big.Int)(dec.Difficulty) - } - if dec.Random != nil { - s.Random = (*big.Int)(dec.Random) - } - if dec.GasLimit == nil { - return errors.New("missing required field 'currentGasLimit' for stEnv") - } - s.GasLimit = uint64(*dec.GasLimit) - if dec.Number == nil { - return errors.New("missing required field 'currentNumber' for stEnv") - } - s.Number = uint64(*dec.Number) - if dec.Timestamp == nil { - return errors.New("missing required field 'currentTimestamp' for stEnv") - } - s.Timestamp = uint64(*dec.Timestamp) - if dec.BaseFee != nil { - s.BaseFee = (*big.Int)(dec.BaseFee) - } - if dec.ExcessBlobGas != nil { - s.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) - } - return nil -} diff --git a/tests/init.go b/tests/init.go deleted file mode 100644 index 99b7e4d333..0000000000 --- a/tests/init.go +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2015 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" - "sort" - - "github.com/ethereum/go-ethereum/params" -) - -func u64(val uint64) *uint64 { return &val } - -// Forks table defines supported forks and their chain config. -var Forks = map[string]*params.ChainConfig{ - "Frontier": { - ChainID: big.NewInt(1), - }, - "Homestead": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - }, - "EIP150": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - }, - "EIP158": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - }, - "Byzantium": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - }, - "Constantinople": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(10000000), - }, - "ConstantinopleFix": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - }, - "Istanbul": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - }, - "MuirGlacier": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - }, - "FrontierToHomesteadAt5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(5), - }, - "HomesteadToEIP150At5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(5), - }, - "HomesteadToDaoAt5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(5), - DAOForkSupport: true, - }, - "EIP158ToByzantiumAt5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(5), - }, - "ByzantiumToConstantinopleAt5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(5), - }, - "ByzantiumToConstantinopleFixAt5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(5), - PetersburgBlock: big.NewInt(5), - }, - "ConstantinopleFixToIstanbulAt5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(5), - }, - "Berlin": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - }, - "BerlinToLondonAt5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(5), - }, - "London": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - }, - "ArrowGlacier": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - }, - "ArrowGlacierToMergeAtDiffC0000": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - GrayGlacierBlock: big.NewInt(0), - MergeNetsplitBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0xC0000), - }, - "GrayGlacier": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - GrayGlacierBlock: big.NewInt(0), - }, - "Merge": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - MergeNetsplitBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), - }, - "Shanghai": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - MergeNetsplitBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), - ShanghaiTime: u64(0), - }, - "MergeToShanghaiAtTime15k": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - MergeNetsplitBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), - ShanghaiTime: u64(15_000), - }, - "Cancun": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - MergeNetsplitBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), - ShanghaiTime: u64(0), - CancunTime: u64(0), - }, - "ShanghaiToCancunAtTime15k": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - MergeNetsplitBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), - ShanghaiTime: u64(0), - CancunTime: u64(15_000), - }, -} - -// AvailableForks returns the set of defined fork names -func AvailableForks() []string { - var availableForks []string - for k := range Forks { - availableForks = append(availableForks, k) - } - sort.Strings(availableForks) - return availableForks -} - -// UnsupportedForkError is returned when a test requests a fork that isn't implemented. -type UnsupportedForkError struct { - Name string -} - -func (e UnsupportedForkError) Error() string { - return fmt.Sprintf("unsupported fork %q", e.Name) -} diff --git a/tests/init_test.go b/tests/init_test.go deleted file mode 100644 index 3ab15e7658..0000000000 --- a/tests/init_test.go +++ /dev/null @@ -1,291 +0,0 @@ -// 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 ( - "encoding/json" - "errors" - "fmt" - "io" - "os" - "path/filepath" - "reflect" - "regexp" - "runtime" - "sort" - "strings" - "testing" - - "github.com/ethereum/go-ethereum/params" -) - -var ( - baseDir = filepath.Join(".", "testdata") - blockTestDir = filepath.Join(baseDir, "BlockchainTests") - stateTestDir = filepath.Join(baseDir, "GeneralStateTests") - legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests") - transactionTestDir = filepath.Join(baseDir, "TransactionTests") - rlpTestDir = filepath.Join(baseDir, "RLPTests") - difficultyTestDir = filepath.Join(baseDir, "BasicTests") - executionSpecDir = filepath.Join(".", "spec-tests", "fixtures") - benchmarksDir = filepath.Join(".", "evm-benchmarks", "benchmarks") -) - -func readJSON(reader io.Reader, value interface{}) error { - data, err := io.ReadAll(reader) - if err != nil { - return fmt.Errorf("error reading JSON file: %v", err) - } - if err = json.Unmarshal(data, &value); err != nil { - if syntaxerr, ok := err.(*json.SyntaxError); ok { - line := findLine(data, syntaxerr.Offset) - return fmt.Errorf("JSON syntax error at line %v: %v", line, err) - } - return err - } - return nil -} - -func readJSONFile(fn string, value interface{}) error { - file, err := os.Open(fn) - if err != nil { - return err - } - defer file.Close() - - err = readJSON(file, value) - if err != nil { - return fmt.Errorf("%s in file %s", err.Error(), fn) - } - return nil -} - -// findLine returns the line number for the given offset into data. -func findLine(data []byte, offset int64) (line int) { - line = 1 - for i, r := range string(data) { - if int64(i) >= offset { - return - } - if r == '\n' { - line++ - } - } - return -} - -// testMatcher controls skipping and chain config assignment to tests. -type testMatcher struct { - configpat []testConfig - failpat []testFailure - skiploadpat []*regexp.Regexp - slowpat []*regexp.Regexp - runonlylistpat *regexp.Regexp -} - -type testConfig struct { - p *regexp.Regexp - config params.ChainConfig -} - -type testFailure struct { - p *regexp.Regexp - reason string -} - -// skipShortMode skips tests matching when the -short flag is used. -func (tm *testMatcher) slow(pattern string) { - tm.slowpat = append(tm.slowpat, regexp.MustCompile(pattern)) -} - -// skipLoad skips JSON loading of tests matching the pattern. -func (tm *testMatcher) skipLoad(pattern string) { - tm.skiploadpat = append(tm.skiploadpat, regexp.MustCompile(pattern)) -} - -// fails adds an expected failure for tests matching the pattern. -// -//nolint:unused -func (tm *testMatcher) fails(pattern string, reason string) { - if reason == "" { - panic("empty fail reason") - } - tm.failpat = append(tm.failpat, testFailure{regexp.MustCompile(pattern), reason}) -} - -func (tm *testMatcher) runonly(pattern string) { - tm.runonlylistpat = regexp.MustCompile(pattern) -} - -// config defines chain config for tests matching the pattern. -func (tm *testMatcher) config(pattern string, cfg params.ChainConfig) { - tm.configpat = append(tm.configpat, testConfig{regexp.MustCompile(pattern), cfg}) -} - -// findSkip matches name against test skip patterns. -func (tm *testMatcher) findSkip(name string) (reason string, skipload bool) { - isWin32 := runtime.GOARCH == "386" && runtime.GOOS == "windows" - for _, re := range tm.slowpat { - if re.MatchString(name) { - if testing.Short() { - return "skipped in -short mode", false - } - if isWin32 { - return "skipped on 32bit windows", false - } - } - } - for _, re := range tm.skiploadpat { - if re.MatchString(name) { - return "skipped by skipLoad", true - } - } - return "", false -} - -// findConfig returns the chain config matching defined patterns. -func (tm *testMatcher) findConfig(t *testing.T) *params.ChainConfig { - for _, m := range tm.configpat { - if m.p.MatchString(t.Name()) { - return &m.config - } - } - return new(params.ChainConfig) -} - -// checkFailure checks whether a failure is expected. -func (tm *testMatcher) checkFailure(t *testing.T, err error) error { - failReason := "" - for _, m := range tm.failpat { - if m.p.MatchString(t.Name()) { - failReason = m.reason - break - } - } - if failReason != "" { - t.Logf("expected failure: %s", failReason) - if err != nil { - t.Logf("error: %v", err) - return nil - } - return errors.New("test succeeded unexpectedly") - } - return err -} - -// walk invokes its runTest argument for all subtests in the given directory. -// -// runTest should be a function of type func(t *testing.T, name string, x ), -// where TestType is the type of the test contained in test files. -func (tm *testMatcher) walk(t *testing.T, dir string, runTest interface{}) { - // Walk the directory. - dirinfo, err := os.Stat(dir) - if os.IsNotExist(err) || !dirinfo.IsDir() { - fmt.Fprintf(os.Stderr, "can't find test files in %s, did you clone the tests submodule?\n", dir) - t.Skip("missing test files") - } - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - name := filepath.ToSlash(strings.TrimPrefix(path, dir+string(filepath.Separator))) - if info.IsDir() { - if _, skipload := tm.findSkip(name + "/"); skipload { - return filepath.SkipDir - } - return nil - } - if filepath.Ext(path) == ".json" { - t.Run(name, func(t *testing.T) { tm.runTestFile(t, path, name, runTest) }) - } - return nil - }) - if err != nil { - t.Fatal(err) - } -} - -func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest interface{}) { - if r, _ := tm.findSkip(name); r != "" { - t.Skip(r) - } - if tm.runonlylistpat != nil { - if !tm.runonlylistpat.MatchString(name) { - t.Skip("Skipped by runonly") - } - } - t.Parallel() - - // Load the file as map[string]. - m := makeMapFromTestFunc(runTest) - if err := readJSONFile(path, m.Addr().Interface()); err != nil { - t.Fatal(err) - } - - // Run all tests from the map. Don't wrap in a subtest if there is only one test in the file. - keys := sortedMapKeys(m) - if len(keys) == 1 { - runTestFunc(runTest, t, name, m, keys[0]) - } else { - for _, key := range keys { - name := name + "/" + key - t.Run(key, func(t *testing.T) { - if r, _ := tm.findSkip(name); r != "" { - t.Skip(r) - } - runTestFunc(runTest, t, name, m, key) - }) - } - } -} - -func makeMapFromTestFunc(f interface{}) reflect.Value { - stringT := reflect.TypeOf("") - testingT := reflect.TypeOf((*testing.T)(nil)) - ftyp := reflect.TypeOf(f) - if ftyp.Kind() != reflect.Func || ftyp.NumIn() != 3 || ftyp.NumOut() != 0 || ftyp.In(0) != testingT || ftyp.In(1) != stringT { - panic(fmt.Sprintf("bad test function type: want func(*testing.T, string, ), have %s", ftyp)) - } - testType := ftyp.In(2) - mp := reflect.New(reflect.MapOf(stringT, testType)) - return mp.Elem() -} - -func sortedMapKeys(m reflect.Value) []string { - keys := make([]string, m.Len()) - for i, k := range m.MapKeys() { - keys[i] = k.String() - } - sort.Strings(keys) - return keys -} - -func runTestFunc(runTest interface{}, t *testing.T, name string, m reflect.Value, key string) { - reflect.ValueOf(runTest).Call([]reflect.Value{ - reflect.ValueOf(t), - reflect.ValueOf(name), - m.MapIndex(reflect.ValueOf(key)), - }) -} - -func TestMatcherRunonlylist(t *testing.T) { - t.Parallel() - tm := new(testMatcher) - tm.runonly("invalid*") - tm.walk(t, rlpTestDir, func(t *testing.T, name string, test *RLPTest) { - if name[:len("invalidRLPTest.json")] != "invalidRLPTest.json" { - t.Fatalf("invalid test found: %s != invalidRLPTest.json", name) - } - }) -} diff --git a/tests/rlp_test.go b/tests/rlp_test.go deleted file mode 100644 index 79a1683eb2..0000000000 --- a/tests/rlp_test.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015 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" -) - -func TestRLP(t *testing.T) { - t.Parallel() - tm := new(testMatcher) - tm.walk(t, rlpTestDir, func(t *testing.T, name string, test *RLPTest) { - if err := tm.checkFailure(t, test.Run()); err != nil { - t.Error(err) - } - }) -} diff --git a/tests/rlp_test_util.go b/tests/rlp_test_util.go deleted file mode 100644 index e4bd5450a8..0000000000 --- a/tests/rlp_test_util.go +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2015 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 ( - "bytes" - "encoding/hex" - "errors" - "fmt" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/rlp" -) - -// RLPTest is the JSON structure of a single RLP test. -type RLPTest struct { - // If the value of In is "INVALID" or "VALID", the test - // checks whether Out can be decoded into a value of - // type interface{}. - // - // For other JSON values, In is treated as a driver for - // calls to rlp.Stream. The test also verifies that encoding - // In produces the bytes in Out. - In interface{} - - // Out is a hex-encoded RLP value. - Out string -} - -// FromHex returns the bytes represented by the hexadecimal string s. -// s may be prefixed with "0x". -// This is copy-pasted from bytes.go, which does not return the error -func FromHex(s string) ([]byte, error) { - if len(s) > 1 && (s[0:2] == "0x" || s[0:2] == "0X") { - s = s[2:] - } - if len(s)%2 == 1 { - s = "0" + s - } - return hex.DecodeString(s) -} - -// Run executes the test. -func (t *RLPTest) Run() error { - outb, err := FromHex(t.Out) - if err != nil { - return errors.New("invalid hex in Out") - } - - // Handle simple decoding tests with no actual In value. - if t.In == "VALID" || t.In == "INVALID" { - return checkDecodeInterface(outb, t.In == "VALID") - } - - // Check whether encoding the value produces the same bytes. - in := translateJSON(t.In) - b, err := rlp.EncodeToBytes(in) - if err != nil { - return fmt.Errorf("encode failed: %v", err) - } - if !bytes.Equal(b, outb) { - return fmt.Errorf("encode produced %x, want %x", b, outb) - } - // Test stream decoding. - s := rlp.NewStream(bytes.NewReader(outb), 0) - return checkDecodeFromJSON(s, in) -} - -func checkDecodeInterface(b []byte, isValid bool) error { - err := rlp.DecodeBytes(b, new(interface{})) - switch { - case isValid && err != nil: - return fmt.Errorf("decoding failed: %v", err) - case !isValid && err == nil: - return errors.New("decoding of invalid value succeeded") - } - return nil -} - -// translateJSON makes test json values encodable with RLP. -func translateJSON(v interface{}) interface{} { - switch v := v.(type) { - case float64: - return uint64(v) - case string: - if len(v) > 0 && v[0] == '#' { // # starts a faux big int. - big, ok := new(big.Int).SetString(v[1:], 10) - if !ok { - panic(fmt.Errorf("bad test: bad big int: %q", v)) - } - return big - } - return []byte(v) - case []interface{}: - new := make([]interface{}, len(v)) - for i := range v { - new[i] = translateJSON(v[i]) - } - return new - default: - panic(fmt.Errorf("can't handle %T", v)) - } -} - -// checkDecodeFromJSON decodes from s guided by exp. exp drives the -// Stream by invoking decoding operations (Uint, Big, List, ...) based -// on the type of each value. The value decoded from the RLP stream -// must match the JSON value. -func checkDecodeFromJSON(s *rlp.Stream, exp interface{}) error { - switch exp := exp.(type) { - case uint64: - i, err := s.Uint64() - if err != nil { - return addStack("Uint", exp, err) - } - if i != exp { - return addStack("Uint", exp, fmt.Errorf("result mismatch: got %d", i)) - } - case *big.Int: - big := new(big.Int) - if err := s.Decode(&big); err != nil { - return addStack("Big", exp, err) - } - if big.Cmp(exp) != 0 { - return addStack("Big", exp, fmt.Errorf("result mismatch: got %d", big)) - } - case []byte: - b, err := s.Bytes() - if err != nil { - return addStack("Bytes", exp, err) - } - if !bytes.Equal(b, exp) { - return addStack("Bytes", exp, fmt.Errorf("result mismatch: got %x", b)) - } - case []interface{}: - if _, err := s.List(); err != nil { - return addStack("List", exp, err) - } - for i, v := range exp { - if err := checkDecodeFromJSON(s, v); err != nil { - return addStack(fmt.Sprintf("[%d]", i), exp, err) - } - } - if err := s.ListEnd(); err != nil { - return addStack("ListEnd", exp, err) - } - default: - panic(fmt.Errorf("unhandled type: %T", exp)) - } - return nil -} - -func addStack(op string, val interface{}, err error) error { - lines := strings.Split(err.Error(), "\n") - lines = append(lines, fmt.Sprintf("\t%s: %v", op, val)) - return errors.New(strings.Join(lines, "\n")) -} diff --git a/tests/state_test.go b/tests/state_test.go deleted file mode 100644 index ae78a53a7e..0000000000 --- a/tests/state_test.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2015 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 ( - "bufio" - "bytes" - "fmt" - "math/big" - "math/rand" - "os" - "path/filepath" - "reflect" - "runtime" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/state/snapshot" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/eth/tracers/logger" -) - -func TestState(t *testing.T) { - t.Parallel() - - st := new(testMatcher) - // Long tests: - st.slow(`^stAttackTest/ContractCreationSpam`) - st.slow(`^stBadOpcode/badOpcodes`) - st.slow(`^stPreCompiledContracts/modexp`) - st.slow(`^stQuadraticComplexityTest/`) - st.slow(`^stStaticCall/static_Call50000`) - st.slow(`^stStaticCall/static_Return50000`) - st.slow(`^stSystemOperationsTest/CallRecursiveBomb`) - st.slow(`^stTransactionTest/Opcodes_TransactionInit`) - // Very time consuming - st.skipLoad(`^stTimeConsuming/`) - st.skipLoad(`.*vmPerformance/loop.*`) - // Uses 1GB RAM per tested fork - st.skipLoad(`^stStaticCall/static_Call1MB`) - - // Broken tests: - // EOF is not part of cancun - st.skipLoad(`^stEOF/`) - - // EIP-4844 tests need to be regenerated due to the data-to-blob rename - st.skipLoad(`^stEIP4844-blobtransactions/`) - - // Expected failures: - // These EIP-4844 tests need to be regenerated. - st.fails(`stEIP4844-blobtransactions/opcodeBlobhashOutOfRange.json`, "test has incorrect state root") - st.fails(`stEIP4844-blobtransactions/opcodeBlobhBounds.json`, "test has incorrect state root") - - // For Istanbul, older tests were moved into LegacyTests - for _, dir := range []string{ - filepath.Join(baseDir, "EIPTests", "StateTests"), - stateTestDir, - legacyStateTestDir, - benchmarksDir, - } { - st.walk(t, dir, func(t *testing.T, name string, test *StateTest) { - if runtime.GOARCH == "386" && runtime.GOOS == "windows" && rand.Int63()%2 == 0 { - t.Skip("test (randomly) skipped on 32-bit windows") - return - } - for _, subtest := range test.Subtests() { - subtest := subtest - key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index) - - t.Run(key+"/hash/trie", func(t *testing.T) { - withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { - var result error - test.Run(subtest, vmconfig, false, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) { - result = st.checkFailure(t, err) - }) - return result - }) - }) - t.Run(key+"/hash/snap", func(t *testing.T) { - withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { - var result error - test.Run(subtest, vmconfig, true, rawdb.HashScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) { - if snaps != nil && state != nil { - if _, err := snaps.Journal(state.IntermediateRoot(false)); err != nil { - result = err - return - } - } - result = st.checkFailure(t, err) - }) - return result - }) - }) - t.Run(key+"/path/trie", func(t *testing.T) { - withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { - var result error - test.Run(subtest, vmconfig, false, rawdb.PathScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) { - result = st.checkFailure(t, err) - }) - return result - }) - }) - t.Run(key+"/path/snap", func(t *testing.T) { - withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { - var result error - test.Run(subtest, vmconfig, true, rawdb.PathScheme, func(err error, snaps *snapshot.Tree, state *state.StateDB) { - if snaps != nil && state != nil { - if _, err := snaps.Journal(state.IntermediateRoot(false)); err != nil { - result = err - return - } - } - result = st.checkFailure(t, err) - }) - return result - }) - }) - } - }) - } -} - -// Transactions with gasLimit above this value will not get a VM trace on failure. -const traceErrorLimit = 400000 - -func withTrace(t *testing.T, gasLimit uint64, test func(vm.Config) error) { - // Use config from command line arguments. - config := vm.Config{} - err := test(config) - if err == nil { - return - } - - // Test failed, re-run with tracing enabled. - t.Error(err) - if gasLimit > traceErrorLimit { - t.Log("gas limit too high for EVM trace") - return - } - buf := new(bytes.Buffer) - w := bufio.NewWriter(buf) - config.Tracer = logger.NewJSONLogger(&logger.Config{}, w) - err2 := test(config) - if !reflect.DeepEqual(err, err2) { - t.Errorf("different error for second run: %v", err2) - } - w.Flush() - if buf.Len() == 0 { - t.Log("no EVM operation logs generated") - } else { - t.Log("EVM operation log:\n" + buf.String()) - } - // t.Logf("EVM output: 0x%x", tracer.Output()) - // t.Logf("EVM error: %v", tracer.Error()) -} - -func BenchmarkEVM(b *testing.B) { - // Walk the directory. - dir := benchmarksDir - dirinfo, err := os.Stat(dir) - if os.IsNotExist(err) || !dirinfo.IsDir() { - fmt.Fprintf(os.Stderr, "can't find test files in %s, did you clone the evm-benchmarks submodule?\n", dir) - b.Skip("missing test files") - } - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if info.IsDir() { - return nil - } - if ext := filepath.Ext(path); ext == ".json" { - name := filepath.ToSlash(strings.TrimPrefix(strings.TrimSuffix(path, ext), dir+string(filepath.Separator))) - b.Run(name, func(b *testing.B) { runBenchmarkFile(b, path) }) - } - return nil - }) - if err != nil { - b.Fatal(err) - } -} - -func runBenchmarkFile(b *testing.B, path string) { - m := make(map[string]StateTest) - if err := readJSONFile(path, &m); err != nil { - b.Fatal(err) - return - } - if len(m) != 1 { - b.Fatal("expected single benchmark in a file") - return - } - for _, t := range m { - t := t - runBenchmark(b, &t) - } -} - -func runBenchmark(b *testing.B, t *StateTest) { - for _, subtest := range t.Subtests() { - subtest := subtest - key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index) - - b.Run(key, func(b *testing.B) { - vmconfig := vm.Config{} - - config, eips, err := GetChainConfig(subtest.Fork) - if err != nil { - b.Error(err) - return - } - var rules = config.Rules(new(big.Int), false, 0) - - vmconfig.ExtraEips = eips - block := t.genesis(config).ToBlock() - triedb, _, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, false, rawdb.HashScheme) - defer triedb.Close() - - var baseFee *big.Int - if rules.IsLondon { - baseFee = t.json.Env.BaseFee - if baseFee == nil { - // Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to - // parent - 2 : 0xa as the basefee for 'this' context. - baseFee = big.NewInt(0x0a) - } - } - post := t.json.Post[subtest.Fork][subtest.Index] - msg, err := t.json.Tx.toMessage(post, baseFee) - if err != nil { - b.Error(err) - return - } - - // Try to recover tx with current signer - if len(post.TxBytes) != 0 { - var ttx types.Transaction - err := ttx.UnmarshalBinary(post.TxBytes) - if err != nil { - b.Error(err) - return - } - - if _, err := types.Sender(types.LatestSigner(config), &ttx); err != nil { - b.Error(err) - return - } - } - - // Prepare the EVM. - txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) - context.GetHash = vmTestBlockHash - context.BaseFee = baseFee - evm := vm.NewEVM(context, txContext, statedb, config, vmconfig) - - // Create "contract" for sender to cache code analysis. - sender := vm.NewContract(vm.AccountRef(msg.From), vm.AccountRef(msg.From), - nil, 0) - - var ( - gasUsed uint64 - elapsed uint64 - refund uint64 - ) - b.ResetTimer() - for n := 0; n < b.N; n++ { - snapshot := statedb.Snapshot() - statedb.Prepare(rules, msg.From, context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList) - b.StartTimer() - start := time.Now() - - // Execute the message. - _, leftOverGas, err := evm.Call(sender, *msg.To, msg.Data, msg.GasLimit, msg.Value) - if err != nil { - b.Error(err) - return - } - - b.StopTimer() - elapsed += uint64(time.Since(start)) - refund += statedb.GetRefund() - gasUsed += msg.GasLimit - leftOverGas - - statedb.RevertToSnapshot(snapshot) - } - if elapsed < 1 { - elapsed = 1 - } - // Keep it as uint64, multiply 100 to get two digit float later - mgasps := (100 * 1000 * (gasUsed - refund)) / elapsed - b.ReportMetric(float64(mgasps)/100, "mgas/s") - }) - } -} diff --git a/tests/state_test_util.go b/tests/state_test_util.go deleted file mode 100644 index 19387b5394..0000000000 --- a/tests/state_test_util.go +++ /dev/null @@ -1,468 +0,0 @@ -// Copyright 2015 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 ( - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "math/big" - "strconv" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/consensus/misc/eip4844" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/state/snapshot" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/trie/triedb/hashdb" - "github.com/ethereum/go-ethereum/trie/triedb/pathdb" - "golang.org/x/crypto/sha3" -) - -// StateTest checks transaction processing without block context. -// See https://github.com/ethereum/EIPs/issues/176 for the test format specification. -type StateTest struct { - json stJSON -} - -// StateSubtest selects a specific configuration of a General State Test. -type StateSubtest struct { - Fork string - Index int -} - -func (t *StateTest) UnmarshalJSON(in []byte) error { - return json.Unmarshal(in, &t.json) -} - -type stJSON struct { - Env stEnv `json:"env"` - Pre core.GenesisAlloc `json:"pre"` - Tx stTransaction `json:"transaction"` - Out hexutil.Bytes `json:"out"` - Post map[string][]stPostState `json:"post"` -} - -type stPostState struct { - Root common.UnprefixedHash `json:"hash"` - Logs common.UnprefixedHash `json:"logs"` - TxBytes hexutil.Bytes `json:"txbytes"` - ExpectException string `json:"expectException"` - Indexes struct { - Data int `json:"data"` - Gas int `json:"gas"` - Value int `json:"value"` - } -} - -//go:generate go run github.com/fjl/gencodec -type stEnv -field-override stEnvMarshaling -out gen_stenv.go - -type stEnv struct { - Coinbase common.Address `json:"currentCoinbase" gencodec:"required"` - Difficulty *big.Int `json:"currentDifficulty" gencodec:"optional"` - Random *big.Int `json:"currentRandom" gencodec:"optional"` - GasLimit uint64 `json:"currentGasLimit" gencodec:"required"` - Number uint64 `json:"currentNumber" gencodec:"required"` - Timestamp uint64 `json:"currentTimestamp" gencodec:"required"` - BaseFee *big.Int `json:"currentBaseFee" gencodec:"optional"` - ExcessBlobGas *uint64 `json:"currentExcessBlobGas" gencodec:"optional"` -} - -type stEnvMarshaling struct { - Coinbase common.UnprefixedAddress - Difficulty *math.HexOrDecimal256 - Random *math.HexOrDecimal256 - GasLimit math.HexOrDecimal64 - Number math.HexOrDecimal64 - Timestamp math.HexOrDecimal64 - BaseFee *math.HexOrDecimal256 - ExcessBlobGas *math.HexOrDecimal64 -} - -//go:generate go run github.com/fjl/gencodec -type stTransaction -field-override stTransactionMarshaling -out gen_sttransaction.go - -type stTransaction struct { - GasPrice *big.Int `json:"gasPrice"` - MaxFeePerGas *big.Int `json:"maxFeePerGas"` - MaxPriorityFeePerGas *big.Int `json:"maxPriorityFeePerGas"` - Nonce uint64 `json:"nonce"` - To string `json:"to"` - Data []string `json:"data"` - AccessLists []*types.AccessList `json:"accessLists,omitempty"` - GasLimit []uint64 `json:"gasLimit"` - Value []string `json:"value"` - PrivateKey []byte `json:"secretKey"` - Sender *common.Address `json:"sender"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - BlobGasFeeCap *big.Int `json:"maxFeePerBlobGas,omitempty"` -} - -type stTransactionMarshaling struct { - GasPrice *math.HexOrDecimal256 - MaxFeePerGas *math.HexOrDecimal256 - MaxPriorityFeePerGas *math.HexOrDecimal256 - Nonce math.HexOrDecimal64 - GasLimit []math.HexOrDecimal64 - PrivateKey hexutil.Bytes - BlobGasFeeCap *math.HexOrDecimal256 -} - -// GetChainConfig takes a fork definition and returns a chain config. -// The fork definition can be -// - a plain forkname, e.g. `Byzantium`, -// - a fork basename, and a list of EIPs to enable; e.g. `Byzantium+1884+1283`. -func GetChainConfig(forkString string) (baseConfig *params.ChainConfig, eips []int, err error) { - var ( - splitForks = strings.Split(forkString, "+") - ok bool - baseName, eipsStrings = splitForks[0], splitForks[1:] - ) - if baseConfig, ok = Forks[baseName]; !ok { - return nil, nil, UnsupportedForkError{baseName} - } - for _, eip := range eipsStrings { - if eipNum, err := strconv.Atoi(eip); err != nil { - return nil, nil, fmt.Errorf("syntax error, invalid eip number %v", eipNum) - } else { - if !vm.ValidEip(eipNum) { - return nil, nil, fmt.Errorf("syntax error, invalid eip number %v", eipNum) - } - eips = append(eips, eipNum) - } - } - return baseConfig, eips, nil -} - -// Subtests returns all valid subtests of the test. -func (t *StateTest) Subtests() []StateSubtest { - var sub []StateSubtest - for fork, pss := range t.json.Post { - for i := range pss { - sub = append(sub, StateSubtest{fork, i}) - } - } - return sub -} - -// checkError checks if the error returned by the state transition matches any expected error. -// A failing expectation returns a wrapped version of the original error, if any, -// or a new error detailing the failing expectation. -// This function does not return or modify the original error, it only evaluates and returns expectations for the error. -func (t *StateTest) checkError(subtest StateSubtest, err error) error { - expectedError := t.json.Post[subtest.Fork][subtest.Index].ExpectException - if err == nil && expectedError == "" { - return nil - } - if err == nil && expectedError != "" { - return fmt.Errorf("expected error %q, got no error", expectedError) - } - if err != nil && expectedError == "" { - return fmt.Errorf("unexpected error: %w", err) - } - if err != nil && expectedError != "" { - // Ignore expected errors (TODO MariusVanDerWijden check error string) - return nil - } - return nil -} - -// Run executes a specific subtest and verifies the post-state and logs -func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string, postCheck func(err error, snaps *snapshot.Tree, state *state.StateDB)) (result error) { - triedb, snaps, statedb, root, err := t.RunNoVerify(subtest, vmconfig, snapshotter, scheme) - - // Invoke the callback at the end of function for further analysis. - defer func() { - postCheck(result, snaps, statedb) - - if triedb != nil { - triedb.Close() - } - if snaps != nil { - snaps.Release() - } - }() - checkedErr := t.checkError(subtest, err) - if checkedErr != nil { - return checkedErr - } - // The error has been checked; if it was unexpected, it's already returned. - if err != nil { - // Here, an error exists but it was expected. - // We do not check the post state or logs. - return nil - } - post := t.json.Post[subtest.Fork][subtest.Index] - // N.B: We need to do this in a two-step process, because the first Commit takes care - // of self-destructs, and we need to touch the coinbase _after_ it has potentially self-destructed. - if root != common.Hash(post.Root) { - return fmt.Errorf("post state root mismatch: got %x, want %x", root, post.Root) - } - if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) { - return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs) - } - statedb, _ = state.New(root, statedb.Database(), snaps) - return nil -} - -// RunNoVerify runs a specific subtest and returns the statedb and post-state root -func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapshotter bool, scheme string) (*trie.Database, *snapshot.Tree, *state.StateDB, common.Hash, error) { - config, eips, err := GetChainConfig(subtest.Fork) - if err != nil { - return nil, nil, nil, common.Hash{}, UnsupportedForkError{subtest.Fork} - } - vmconfig.ExtraEips = eips - - block := t.genesis(config).ToBlock() - triedb, snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme) - - var baseFee *big.Int - if config.IsLondon(new(big.Int)) { - baseFee = t.json.Env.BaseFee - if baseFee == nil { - // Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to - // parent - 2 : 0xa as the basefee for 'this' context. - baseFee = big.NewInt(0x0a) - } - } - post := t.json.Post[subtest.Fork][subtest.Index] - msg, err := t.json.Tx.toMessage(post, baseFee) - if err != nil { - triedb.Close() - return nil, nil, nil, common.Hash{}, err - } - - // Try to recover tx with current signer - if len(post.TxBytes) != 0 { - var ttx types.Transaction - err := ttx.UnmarshalBinary(post.TxBytes) - if err != nil { - triedb.Close() - return nil, nil, nil, common.Hash{}, err - } - - if _, err := types.Sender(types.LatestSigner(config), &ttx); err != nil { - triedb.Close() - return nil, nil, nil, common.Hash{}, err - } - } - - // Prepare the EVM. - txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) - context.GetHash = vmTestBlockHash - context.BaseFee = baseFee - context.Random = nil - if t.json.Env.Difficulty != nil { - context.Difficulty = new(big.Int).Set(t.json.Env.Difficulty) - } - if config.IsLondon(new(big.Int)) && t.json.Env.Random != nil { - rnd := common.BigToHash(t.json.Env.Random) - context.Random = &rnd - context.Difficulty = big.NewInt(0) - } - if config.IsCancun(new(big.Int), block.Time()) && t.json.Env.ExcessBlobGas != nil { - context.BlobBaseFee = eip4844.CalcBlobFee(*t.json.Env.ExcessBlobGas) - } - evm := vm.NewEVM(context, txContext, statedb, config, vmconfig) - - // Execute the message. - snapshot := statedb.Snapshot() - gaspool := new(core.GasPool) - gaspool.AddGas(block.GasLimit()) - _, err = core.ApplyMessage(evm, msg, gaspool) - if err != nil { - statedb.RevertToSnapshot(snapshot) - } - // Add 0-value mining reward. This only makes a difference in the cases - // where - // - the coinbase self-destructed, or - // - there are only 'bad' transactions, which aren't executed. In those cases, - // the coinbase gets no txfee, so isn't created, and thus needs to be touched - statedb.AddBalance(block.Coinbase(), new(big.Int)) - - // Commit state mutations into database. - root, _ := statedb.Commit(block.NumberU64(), config.IsEIP158(block.Number())) - return triedb, snaps, statedb, root, err -} - -func (t *StateTest) gasLimit(subtest StateSubtest) uint64 { - return t.json.Tx.GasLimit[t.json.Post[subtest.Fork][subtest.Index].Indexes.Gas] -} - -func MakePreState(db ethdb.Database, accounts core.GenesisAlloc, snapshotter bool, scheme string) (*trie.Database, *snapshot.Tree, *state.StateDB) { - tconf := &trie.Config{Preimages: true} - if scheme == rawdb.HashScheme { - tconf.HashDB = hashdb.Defaults - } else { - tconf.PathDB = pathdb.Defaults - } - triedb := trie.NewDatabase(db, tconf) - sdb := state.NewDatabaseWithNodeDB(db, triedb) - statedb, _ := state.New(types.EmptyRootHash, sdb, nil) - for addr, a := range accounts { - statedb.SetCode(addr, a.Code) - statedb.SetNonce(addr, a.Nonce) - statedb.SetBalance(addr, a.Balance) - for k, v := range a.Storage { - statedb.SetState(addr, k, v) - } - } - // Commit and re-open to start with a clean state. - root, _ := statedb.Commit(0, false) - - var snaps *snapshot.Tree - if snapshotter { - snapconfig := snapshot.Config{ - CacheSize: 1, - Recovery: false, - NoBuild: false, - AsyncBuild: false, - } - snaps, _ = snapshot.New(snapconfig, db, triedb, root) - } - statedb, _ = state.New(root, sdb, snaps) - return triedb, snaps, statedb -} - -func (t *StateTest) genesis(config *params.ChainConfig) *core.Genesis { - genesis := &core.Genesis{ - Config: config, - Coinbase: t.json.Env.Coinbase, - Difficulty: t.json.Env.Difficulty, - GasLimit: t.json.Env.GasLimit, - Number: t.json.Env.Number, - Timestamp: t.json.Env.Timestamp, - Alloc: t.json.Pre, - } - if t.json.Env.Random != nil { - // Post-Merge - genesis.Mixhash = common.BigToHash(t.json.Env.Random) - genesis.Difficulty = big.NewInt(0) - } - return genesis -} - -func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Message, error) { - var from common.Address - // If 'sender' field is present, use that - if tx.Sender != nil { - from = *tx.Sender - } else if len(tx.PrivateKey) > 0 { - // Derive sender from private key if needed. - key, err := crypto.ToECDSA(tx.PrivateKey) - if err != nil { - return nil, fmt.Errorf("invalid private key: %v", err) - } - from = crypto.PubkeyToAddress(key.PublicKey) - } - // Parse recipient if present. - var to *common.Address - if tx.To != "" { - to = new(common.Address) - if err := to.UnmarshalText([]byte(tx.To)); err != nil { - return nil, fmt.Errorf("invalid to address: %v", err) - } - } - - // Get values specific to this post state. - if ps.Indexes.Data > len(tx.Data) { - return nil, fmt.Errorf("tx data index %d out of bounds", ps.Indexes.Data) - } - if ps.Indexes.Value > len(tx.Value) { - return nil, fmt.Errorf("tx value index %d out of bounds", ps.Indexes.Value) - } - if ps.Indexes.Gas > len(tx.GasLimit) { - return nil, fmt.Errorf("tx gas limit index %d out of bounds", ps.Indexes.Gas) - } - dataHex := tx.Data[ps.Indexes.Data] - valueHex := tx.Value[ps.Indexes.Value] - gasLimit := tx.GasLimit[ps.Indexes.Gas] - // Value, Data hex encoding is messy: https://github.com/ethereum/tests/issues/203 - value := new(big.Int) - if valueHex != "0x" { - v, ok := math.ParseBig256(valueHex) - if !ok { - return nil, fmt.Errorf("invalid tx value %q", valueHex) - } - value = v - } - data, err := hex.DecodeString(strings.TrimPrefix(dataHex, "0x")) - if err != nil { - return nil, fmt.Errorf("invalid tx data %q", dataHex) - } - var accessList types.AccessList - if tx.AccessLists != nil && tx.AccessLists[ps.Indexes.Data] != nil { - accessList = *tx.AccessLists[ps.Indexes.Data] - } - // If baseFee provided, set gasPrice to effectiveGasPrice. - gasPrice := tx.GasPrice - if baseFee != nil { - if tx.MaxFeePerGas == nil { - tx.MaxFeePerGas = gasPrice - } - if tx.MaxFeePerGas == nil { - tx.MaxFeePerGas = new(big.Int) - } - if tx.MaxPriorityFeePerGas == nil { - tx.MaxPriorityFeePerGas = tx.MaxFeePerGas - } - gasPrice = math.BigMin(new(big.Int).Add(tx.MaxPriorityFeePerGas, baseFee), - tx.MaxFeePerGas) - } - if gasPrice == nil { - return nil, errors.New("no gas price provided") - } - - msg := &core.Message{ - From: from, - To: to, - Nonce: tx.Nonce, - Value: value, - GasLimit: gasLimit, - GasPrice: gasPrice, - GasFeeCap: tx.MaxFeePerGas, - GasTipCap: tx.MaxPriorityFeePerGas, - Data: data, - AccessList: accessList, - BlobHashes: tx.BlobVersionedHashes, - BlobGasFeeCap: tx.BlobGasFeeCap, - } - return msg, nil -} - -func rlpHash(x interface{}) (h common.Hash) { - hw := sha3.NewLegacyKeccak256() - rlp.Encode(hw, x) - hw.Sum(h[:0]) - return h -} - -func vmTestBlockHash(n uint64) common.Hash { - return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String()))) -} diff --git a/tests/testdata b/tests/testdata deleted file mode 160000 index ee3fa4c86d..0000000000 --- a/tests/testdata +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ee3fa4c86d05f99f2717f83a6ad08008490ddf07 diff --git a/tests/transaction_test.go b/tests/transaction_test.go deleted file mode 100644 index cb0f262318..0000000000 --- a/tests/transaction_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015 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" - - "github.com/ethereum/go-ethereum/params" -) - -func TestTransaction(t *testing.T) { - t.Parallel() - - txt := new(testMatcher) - // These can't be parsed, invalid hex in RLP - txt.skipLoad("^ttWrongRLP/.*") - // We don't allow more than uint64 in gas amount - // This is a pseudo-consensus vulnerability, but not in practice - // because of the gas limit - txt.skipLoad("^ttGasLimit/TransactionWithGasLimitxPriceOverflow.json") - // We _do_ allow more than uint64 in gas price, as opposed to the tests - // This is also not a concern, as long as tx.Cost() uses big.Int for - // calculating the final cozt - txt.skipLoad(".*TransactionWithGasPriceOverflow.*") - - // The nonce is too large for uint64. Not a concern, it means geth won't - // accept transactions at a certain point in the distant future - txt.skipLoad("^ttNonce/TransactionWithHighNonce256.json") - - // The value is larger than uint64, which according to the test is invalid. - // Geth accepts it, which is not a consensus issue since we use big.Int's - // internally to calculate the cost - txt.skipLoad("^ttValue/TransactionWithHighValueOverflow.json") - txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) { - cfg := params.MainnetChainConfig - if err := txt.checkFailure(t, test.Run(cfg)); err != nil { - t.Error(err) - } - }) -} diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go deleted file mode 100644 index 391aa57584..0000000000 --- a/tests/transaction_test_util.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2015 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" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" -) - -// TransactionTest checks RLP decoding and sender derivation of transactions. -type TransactionTest struct { - RLP hexutil.Bytes `json:"rlp"` - Byzantium ttFork - Constantinople ttFork - Istanbul ttFork - EIP150 ttFork - EIP158 ttFork - Frontier ttFork - Homestead ttFork -} - -type ttFork struct { - Sender common.UnprefixedAddress `json:"sender"` - Hash common.UnprefixedHash `json:"hash"` -} - -func (tt *TransactionTest) Run(config *params.ChainConfig) error { - validateTx := func(rlpData hexutil.Bytes, signer types.Signer, isHomestead bool, isIstanbul bool) (*common.Address, *common.Hash, error) { - tx := new(types.Transaction) - if err := rlp.DecodeBytes(rlpData, tx); err != nil { - return nil, nil, err - } - sender, err := types.Sender(signer, tx) - if err != nil { - return nil, nil, err - } - // Intrinsic gas - requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, isHomestead, isIstanbul, false) - if err != nil { - return nil, nil, err - } - if requiredGas > tx.Gas() { - return nil, nil, fmt.Errorf("insufficient gas ( %d < %d )", tx.Gas(), requiredGas) - } - h := tx.Hash() - return &sender, &h, nil - } - - for _, testcase := range []struct { - name string - signer types.Signer - fork ttFork - isHomestead bool - isIstanbul bool - }{ - {"Frontier", types.FrontierSigner{}, tt.Frontier, false, false}, - {"Homestead", types.HomesteadSigner{}, tt.Homestead, true, false}, - {"EIP150", types.HomesteadSigner{}, tt.EIP150, true, false}, - {"EIP158", types.NewEIP155Signer(config.ChainID), tt.EIP158, true, false}, - {"Byzantium", types.NewEIP155Signer(config.ChainID), tt.Byzantium, true, false}, - {"Constantinople", types.NewEIP155Signer(config.ChainID), tt.Constantinople, true, false}, - {"Istanbul", types.NewEIP155Signer(config.ChainID), tt.Istanbul, true, true}, - } { - sender, txhash, err := validateTx(tt.RLP, testcase.signer, testcase.isHomestead, testcase.isIstanbul) - - if testcase.fork.Sender == (common.UnprefixedAddress{}) { - if err == nil { - return fmt.Errorf("expected error, got none (address %v)[%v]", sender.String(), testcase.name) - } - continue - } - // Should resolve the right address - if err != nil { - return fmt.Errorf("got error, expected none: %v", err) - } - if sender == nil { - return fmt.Errorf("sender was nil, should be %x", common.Address(testcase.fork.Sender)) - } - if *sender != common.Address(testcase.fork.Sender) { - return fmt.Errorf("sender mismatch: got %x, want %x", sender, testcase.fork.Sender) - } - if txhash == nil { - return fmt.Errorf("txhash was nil, should be %x", common.Hash(testcase.fork.Hash)) - } - if *txhash != common.Hash(testcase.fork.Hash) { - return fmt.Errorf("hash mismatch: got %x, want %x", *txhash, testcase.fork.Hash) - } - } - return nil -}