From 5157d4540a58a660a914e5cc1eac6f2e281e35d7 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 2 May 2022 16:26:30 +0200 Subject: [PATCH] cmd/evm: make evm t8n handle post-merge transitions (#24546) This adds the ability to run --state.fork=Merged, and have post-merge rules apply. When doing so, it also requires the input env to contain currentRandom, and enforces the currentDifficulty to be omitted or zero. --- cmd/evm/internal/t8ntool/flags.go | 2 +- cmd/evm/internal/t8ntool/transition.go | 20 ++++++-- cmd/evm/t8n_test.go | 16 +++++++ cmd/evm/testdata/24/alloc.json | 14 ++++++ cmd/evm/testdata/24/env-missingrandom.json | 9 ++++ cmd/evm/testdata/24/env.json | 9 ++++ cmd/evm/testdata/24/exp.json | 53 ++++++++++++++++++++++ cmd/evm/testdata/24/txs.json | 28 ++++++++++++ tests/init.go | 17 +++++++ 9 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 cmd/evm/testdata/24/alloc.json create mode 100644 cmd/evm/testdata/24/env-missingrandom.json create mode 100644 cmd/evm/testdata/24/env.json create mode 100644 cmd/evm/testdata/24/exp.json create mode 100644 cmd/evm/testdata/24/txs.json diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index b6054ea562..595ff327b0 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -152,7 +152,7 @@ var ( "\n\tSyntax (+ExtraEip)", strings.Join(tests.AvailableForks(), "\n\t "), strings.Join(vm.ActivateableEips(), ", ")), - Value: "Istanbul", + Value: "ArrowGlacier", } VerbosityFlag = cli.IntFlag{ Name: "verbosity", diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 097f9ce65c..6406ccf6a4 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -252,11 +252,21 @@ func Transition(ctx *cli.Context) error { return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section")) } } - // Sanity check, to not `panic` in state_transition - if prestate.Env.Random != nil && !chainConfig.IsLondon(big.NewInt(int64(prestate.Env.Number))) { - return NewError(ErrorConfig, errors.New("can only apply RANDOM on top of London chainrules")) - } - if env := prestate.Env; env.Difficulty == nil { + isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0 + env := prestate.Env + if isMerged { + // post-merge: + // - random must be supplied + // - difficulty must be zero + switch { + case env.Random == nil: + return NewError(ErrorConfig, errors.New("post-merge requires currentRandom to be defined in env")) + case env.Difficulty != nil && env.Difficulty.BitLen() != 0: + return NewError(ErrorConfig, errors.New("post-merge difficulty must be zero (or omitted) in env")) + } + prestate.Env.Difficulty = nil + } else if env.Difficulty == nil { + // pre-merge: // If difficulty was not provided by caller, we need to calculate it. switch { case env.ParentDifficulty == nil: diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 3f0bd3185f..352633811c 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -203,6 +203,22 @@ func TestT8n(t *testing.T) { output: t8nOutput{result: true}, expOut: "exp.json", }, + { // Test post-merge transition + base: "./testdata/24", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Merged", "", + }, + output: t8nOutput{alloc: true, result: true}, + expOut: "exp.json", + }, + { // Test post-merge transition where input is missing random + base: "./testdata/24", + input: t8nInput{ + "alloc.json", "txs.json", "env-missingrandom.json", "Merged", "", + }, + output: t8nOutput{alloc: false, result: false}, + expExitCode: 3, + }, } { args := []string{"t8n"} diff --git a/cmd/evm/testdata/24/alloc.json b/cmd/evm/testdata/24/alloc.json new file mode 100644 index 0000000000..73a9a03c0b --- /dev/null +++ b/cmd/evm/testdata/24/alloc.json @@ -0,0 +1,14 @@ +{ + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x5ffd4878be161d74", + "code": "0x", + "nonce": "0xac", + "storage": {} + }, + "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192":{ + "balance": "0xfeedbead", + "nonce" : "0x00", + "code" : "0x44600055", + "_comment": "The code is 'sstore(0, random)'" + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/24/env-missingrandom.json b/cmd/evm/testdata/24/env-missingrandom.json new file mode 100644 index 0000000000..db49fd3fce --- /dev/null +++ b/cmd/evm/testdata/24/env-missingrandom.json @@ -0,0 +1,9 @@ +{ + "currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty": null, + "currentRandom": null, + "currentGasLimit": "0x750a163df65e8a", + "currentBaseFee": "0x500", + "currentNumber": "1", + "currentTimestamp": "1000" +} diff --git a/cmd/evm/testdata/24/env.json b/cmd/evm/testdata/24/env.json new file mode 100644 index 0000000000..262cc2528c --- /dev/null +++ b/cmd/evm/testdata/24/env.json @@ -0,0 +1,9 @@ +{ + "currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty": null, + "currentRandom": "0xdeadc0de", + "currentGasLimit": "0x750a163df65e8a", + "currentBaseFee": "0x500", + "currentNumber": "1", + "currentTimestamp": "1000" +} diff --git a/cmd/evm/testdata/24/exp.json b/cmd/evm/testdata/24/exp.json new file mode 100644 index 0000000000..05d8c7a03b --- /dev/null +++ b/cmd/evm/testdata/24/exp.json @@ -0,0 +1,53 @@ +{ + "alloc": { + "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192": { + "code": "0x44600055", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000000000000000000000000000000000000deadc0de" + }, + "balance": "0xfeedbeaf" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x5ffd4878b803f972", + "nonce": "0xae" + }, + "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x1030600" + } + }, + "result": { + "stateRoot": "0x9e4224c6bba343d5b0fdbe9200cc66a7ef2068240d901ae516e634c45a043c15", + "txRoot": "0x16cd3a7daa6686ceebadf53b7af2bc6919eccb730907f0e74a95a4423c209593", + "receiptsRoot": "0x22b85cda738345a9880260b2a71e144aab1ca9485f5db4fd251008350fc124c8", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": [ + { + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0xa861", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0x92ea4a28224d033afb20e0cc2b290d4c7c2d61f6a4800a680e4e19ac962ee941", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0xa861", + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x0" + }, + { + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0x10306", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0x16b1d912f1d664f3f60f4e1b5f296f3c82a64a1a253117b4851d18bc03c4f1da", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x5aa5", + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x1" + } + ], + "currentDifficulty": null, + "gasUsed": "0x10306" + } +} diff --git a/cmd/evm/testdata/24/txs.json b/cmd/evm/testdata/24/txs.json new file mode 100644 index 0000000000..99c2068f1a --- /dev/null +++ b/cmd/evm/testdata/24/txs.json @@ -0,0 +1,28 @@ +[ + { + "gas": "0x186a0", + "gasPrice": "0x600", + "hash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673", + "input": "0x", + "nonce": "0xac", + "to": "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192", + "value": "0x1", + "v" : "0x0", + "r" : "0x0", + "s" : "0x0", + "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + }, + { + "gas": "0x186a0", + "gasPrice": "0x600", + "hash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673", + "input": "0x", + "nonce": "0xad", + "to": "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192", + "value": "0x1", + "v" : "0x0", + "r" : "0x0", + "s" : "0x0", + "secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" + } +] diff --git a/tests/init.go b/tests/init.go index d6b5b3043d..52277e8416 100644 --- a/tests/init.go +++ b/tests/init.go @@ -197,6 +197,23 @@ var Forks = map[string]*params.ChainConfig{ LondonBlock: big.NewInt(0), ArrowGlacierBlock: big.NewInt(0), }, + "Merged": { + 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), + MergeForkBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + }, } // Returns the set of defined fork names