Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geth/evm raises runtime error when executing opcode prevrandao #29722

Closed
Alleysira opened this issue May 7, 2024 · 9 comments
Closed

Geth/evm raises runtime error when executing opcode prevrandao #29722

Alleysira opened this issue May 7, 2024 · 9 comments
Labels

Comments

@Alleysira
Copy link

Alleysira commented May 7, 2024

System information

Geth version: 1.13.4
CL client & version: Nope
OS & Version: Linux
Commit hash : 3f907d6

Expected behaviour

According to EVM opcodes, when execuing opcode 0X44, EVM should return previous block's RANDAO mix. Comparing with Besu/evmtools, Py-evm and EthereumJS, all other 3 evms are fine, only Geth/evm came to an error.

Actual behaviour

When executing any Ethereum smart contract bytecodes that includes opcode 0X44, the Geth/evm will raise an error and abort its execution, causing Ethereum execution node or other applications built upon Geth/evm fail.

Steps to reproduce the behaviour

  1. Download Geth & Tools 1.13.4-3f907d6a from https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-1.13.4-3f907d6a.tar.gz
  2. Unzip the file and you can see executable evm at geth-alltools-linux-amd64-1.13.4-3f907d6a/evm
  3. Create a new genesis.json file in dir geth-alltools-linux-amd64-1.13.4-3f907d6a/ to let evm support shanghai opcodes.
{
  "config": {
    "chainId": 9599,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "berlinBlock": 0,
    "londonBlock": 0,
    "shanghaiBlock": 0,
    "shanghaiTime":0
  },
  "alloc": {
    "0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f": {
      "balance": "0xffffffffffffffffffffffffffffffffffffffff"
    }
  },
  "coinbase": "0x000000000000000000000000000000000000abcd",
  "difficulty": "0x0",
  "extraData": "",
  "gasLimit": "0xffffff",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}
  1. Run the commands to let geth/evm execute 0x44
$  ./evm --debug --gas 0xffffff --nomemory=false --json --code 6080604052348015600e575f80fd5b50600436106026575f3560e01c80639ceee80c14602a575b5f80fd5b60306044565b604051603b91906061565b60405180910390f35b5f44905090565b5f819050919050565b605b81604b565b82525050565b5f60208201905060725f8301846054565b9291505056fea264697066735822122097f788bd78037d47c3e87ca3ee039171808cf9ea275785553c6ccd08d982424464736f6c63430008170033 --input 9ceee80c --prestate ./genesis.json run  
  1. You can see that terminal outputs error messages.
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0xb7d05b]

goroutine 1 [running]:
github.com/ethereum/go-ethereum/core/vm.opRandom(0x1?, 0x0?, 0xc000534318)
        github.com/ethereum/go-ethereum/core/vm/instructions.go:480 +0x3b
github.com/ethereum/go-ethereum/core/vm.(*EVMInterpreter).Run(0xc000300540, 0xc000172480, {0xc00051dd08, 0x4, 0x8}, 0x0)
        github.com/ethereum/go-ethereum/core/vm/interpreter.go:230 +0x9c7
github.com/ethereum/go-ethereum/core/vm.(*EVM).Call(0xc000176000, {0x12e3640, 0xc000174700}, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...}, ...)
        github.com/ethereum/go-ethereum/core/vm/evm.go:236 +0xbb1
github.com/ethereum/go-ethereum/core/vm/runtime.Call({0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...}, ...)
        github.com/ethereum/go-ethereum/core/vm/runtime/runtime.go:191 +0x2cb
main.runCmd.func2()
        github.com/ethereum/go-ethereum/cmd/evm/runner.go:266 +0x34
main.timedExec(0x0, 0xc0004e6800)
        github.com/ethereum/go-ethereum/cmd/evm/runner.go:99 +0x372
main.runCmd(0xc0004e6f00)
        github.com/ethereum/go-ethereum/cmd/evm/runner.go:271 +0x120e
github.com/ethereum/go-ethereum/internal/flags.MigrateGlobalFlags.func2.1(0x1b50e80?)
        github.com/ethereum/go-ethereum/internal/flags/helpers.go:100 +0x34
github.com/urfave/cli/v2.(*Command).Run(0x1b50e80, 0xc0004e6f00, {0xc0004f45a0, 0x1, 0x1})
        github.com/urfave/cli/v2@v2.25.7/command.go:274 +0x998
github.com/urfave/cli/v2.(*Command).Run(0xc00045e9a0, 0xc000426e00, {0xc000134270, 0xd, 0xd})
        github.com/urfave/cli/v2@v2.25.7/command.go:267 +0xbe5
github.com/urfave/cli/v2.(*App).RunContext(0xc0003de780, {0x12eaba0?, 0x1bdd400}, {0xc000134270, 0xd, 0xd})
        github.com/urfave/cli/v2@v2.25.7/app.go:332 +0x5b7
github.com/urfave/cli/v2.(*App).Run(...)
        github.com/urfave/cli/v2@v2.25.7/app.go:309
main.main()
        github.com/ethereum/go-ethereum/cmd/evm/main.go:248 +0x45
  1. Comparing with Besu/evmtools Py-evm EthereumJS, all other 3 evms are fine, only Geth/evm came to this error.

Backtrace

{"pc":0,"op":96,"gas":"0xffffff","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":2,"op":96,"gas":"0xfffffc","gasCost":"0x3","memSize":0,"stack":["0x80"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":4,"op":82,"gas":"0xfffff9","gasCost":"0xc","memSize":0,"stack":["0x80","0x40"],"depth":1,"refund":0,"opName":"MSTORE"}
{"pc":5,"op":52,"gas":"0xffffed","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"CALLVALUE"}
{"pc":6,"op":128,"gas":"0xffffeb","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0"],"depth":1,"refund":0,"opName":"DUP1"}
{"pc":7,"op":21,"gas":"0xffffe8","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"ISZERO"}
{"pc":8,"op":96,"gas":"0xffffe5","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0","0x1"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":10,"op":87,"gas":"0xffffe2","gasCost":"0xa","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0","0x1","0xe"],"depth":1,"refund":0,"opName":"JUMPI"}
{"pc":14,"op":91,"gas":"0xffffd8","gasCost":"0x1","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0"],"depth":1,"refund":0,"opName":"JUMPDEST"}
{"pc":15,"op":80,"gas":"0xffffd7","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0"],"depth":1,"refund":0,"opName":"POP"}
{"pc":16,"op":96,"gas":"0xffffd5","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":18,"op":54,"gas":"0xffffd2","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x4"],"depth":1,"refund":0,"opName":"CALLDATASIZE"}
{"pc":19,"op":16,"gas":"0xffffd0","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x4","0x4"],"depth":1,"refund":0,"opName":"LT"}
{"pc":20,"op":96,"gas":"0xffffcd","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":22,"op":87,"gas":"0xffffca","gasCost":"0xa","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0","0x26"],"depth":1,"refund":0,"opName":"JUMPI"}
{"pc":23,"op":95,"gas":"0xffffc0","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":24,"op":53,"gas":"0xffffbe","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x0"],"depth":1,"refund":0,"opName":"CALLDATALOAD"}
{"pc":25,"op":96,"gas":"0xffffbb","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c00000000000000000000000000000000000000000000000000000000"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":27,"op":28,"gas":"0xffffb8","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c00000000000000000000000000000000000000000000000000000000","0xe0"],"depth":1,"refund":0,"opName":"SHR"}
{"pc":28,"op":128,"gas":"0xffffb5","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c"],"depth":1,"refund":0,"opName":"DUP1"}
{"pc":29,"op":99,"gas":"0xffffb2","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x9ceee80c"],"depth":1,"refund":0,"opName":"PUSH4"}
{"pc":34,"op":20,"gas":"0xffffaf","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x9ceee80c","0x9ceee80c"],"depth":1,"refund":0,"opName":"EQ"}
{"pc":35,"op":96,"gas":"0xffffac","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x1"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":37,"op":87,"gas":"0xffffa9","gasCost":"0xa","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x1","0x2a"],"depth":1,"refund":0,"opName":"JUMPI"}
{"pc":42,"op":91,"gas":"0xffff9f","gasCost":"0x1","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c"],"depth":1,"refund":0,"opName":"JUMPDEST"}
{"pc":43,"op":96,"gas":"0xffff9e","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":45,"op":96,"gas":"0xffff9b","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x30"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":47,"op":86,"gas":"0xffff98","gasCost":"0x8","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x30","0x44"],"depth":1,"refund":0,"opName":"JUMP"}
{"pc":68,"op":91,"gas":"0xffff90","gasCost":"0x1","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x30"],"depth":1,"refund":0,"opName":"JUMPDEST"}
{"pc":69,"op":95,"gas":"0xffff8f","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x30"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":70,"op":68,"gas":"0xffff8d","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x9ceee80c","0x30","0x0"],"depth":1,"refund":0,"opName":"DIFFICULTY"}
{"output":"","gasUsed":"0x0"}

Thanks for your attention :)

@Alleysira
Copy link
Author

Using paris version bytecodes with same genesis.json to avoid PUSH0 error in #29782, the run time error didn't occur in geth/evm 1.14.4, 1.14.3, 1.14.2. The specific input is as follows:

./evm --debug --gas 0xffffff --nomemory=false --json --code 6080604052348015600f57600080fd5b506004361060285760003560e01c806332a2c5d014602d575b600080fd5b60336047565b604051603e91906066565b60405180910390f35b600044905090565b6000819050919050565b606081604f565b82525050565b6000602082019050607960008301846059565b9291505056fea26469706673582212207ff40fb39a7b5e0a9ae6ee8422a04abe9e81eb8ba50c1e71c214eba304e7b67464736f6c63430008170033 --input 32a2c5d0 --prestate ./genesis.json run 

@holiman
Copy link
Contributor

holiman commented May 15, 2024

Same as the other one, evm doesn't have any random, so it doesn't enable merge. Problem is here: https://github.com/ethereum/go-ethereum/blob/master/core/vm/runtime/runtime.go#L191 .

The evm run functionality isn't that well specified. The evm statetest is better specified, and evm t8n is best specified of them all.

@Alleysira
Copy link
Author

Okay, I'll try to learn how to use evm statetest or t8n for fuzzing, but I think maybe the problem is not in https://github.com/ethereum/go-ethereum/blob/master/core/vm/runtime/runtime.go#L191.
Because3 the corresonding line 157 in release/1.13 is the same as 1.14.x

rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)

And I can successfully run PUSH0 in geth/evm 1.13.4, like

$ ./evm --debug  --code 5f --json --prestate ./genesis.json run 
INFO [05-15|21:52:17.758] Persisted trie from memory database      nodes=1 size=144.00B time="6.216µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B
{"pc":0,"op":95,"gas":"0xffffff","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":1,"op":0,"gas":"0xfffffd","gasCost":"0x0","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"STOP"}
{"output":"","gasUsed":"0x2"}
#### LOGS ####
$ ./evm --version
evm version 1.13.4-stable-3f907d6a

Maybe somewhere else is wrong? Thanks for your time.

@holiman
Copy link
Contributor

holiman commented May 15, 2024

Well yes, the input IsMerge is untouched, but the difference is that the new code actually cares about it: https://github.com/ethereum/go-ethereum/blame/master/params/config.go#L947 .

Changed in ac0ff04

But actually, that commit is included in all of v1.14.3 v1.14.2 v1.14.0 v1.13.15 v1.13.14 v1.13.13, so the same thing should happen in 1.13 -- but not 1.13.4, which is too old.

@Alleysira
Copy link
Author

Alleysira commented May 16, 2024

Thanks for your reply!
But I think that evm v1.14.x and later versions should support opcodes after the Merge for testing and it will be convenient for developers to test the new features. And I understand that you guys already have evm statetest for testing, but evm run seems to be easy to use without extra charges of signature or transactions.
Maybe we can improve this by setting IsMerge=True directly in --prestate genesis.json or supporting random value as part of evm input like evm --code --gas --input run.
What do you think of this? Thanks again.

@holiman
Copy link
Contributor

holiman commented May 16, 2024

But I think that evm v1.14.x and later versions should support opcodes after the Merge for testing

Please don't misunderstand me -- this is a legit bug. I just meant that this bug is not high-priority, but sure we should fix it. Preferrably not by hardcoding IsMerge, but somehow making a better detector/indicator.

@Alleysira
Copy link
Author

Okay, thanks. Should I close this issue for now or what?

@namiloh
Copy link

namiloh commented May 16, 2024

Let's keep it open until we fix it

@Alleysira
Copy link
Author

Fixed in #29799.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants