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

debug_traceBlockBy{Number,Hash} outputs new opcodes for pre-fork blocks #29464

Open
bearpebble opened this issue Apr 5, 2024 · 4 comments
Open
Labels

Comments

@bearpebble
Copy link

System information

Geth version: geth version 1.13.14-stable-2bd6bd01
CL client & version: none
OS & Version: Linux

Expected behaviour

The output of debug_traceBlockByNumber should contain invalid for cancun opcodes in pre-cancun blocks (or any other fork that introduces new opcodes).

Actual behaviour

The trace contains the new opcodes BLOBHASH, BLOBBASEFEE, TLOAD, TSTORE, MCOPY despite these not being active yet.

Steps to reproduce the behaviour

Make sure cancun is not active

geth --dev dumpgenesis | jq ".config"
{
  "chainId": 1337,
  "homesteadBlock": 0,
  "eip150Block": 0,
  "eip155Block": 0,
  "eip158Block": 0,
  "byzantiumBlock": 0,
  "constantinopleBlock": 0,
  "petersburgBlock": 0,
  "istanbulBlock": 0,
  "muirGlacierBlock": 0,
  "berlinBlock": 0,
  "londonBlock": 0,
  "arrowGlacierBlock": 0,
  "grayGlacierBlock": 0,
  "shanghaiTime": 0,
  "terminalTotalDifficulty": 0,
  "terminalTotalDifficultyPassed": true
}

Start geth and fund the test account

geth --http --http.port 8545 --dev --http.api eth,web3,net,debug --gcmode=archive &
sleep 10
geth attach --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", value: web3.toWei(50, "ether")})' /tmp/geth.ipc

Send a transaction that uses BLOBHASH, specifically PUSH0, PUSH0, BLOBHASH, PUSH0, PUSH0.

cast send --rpc-url http://localhost:8545 --mnemonic "test test test test test test test test test test test junk" --gas-limit 500000 --create 0x5f5f495f5f
cast rpc debug_traceBlockByNumber $(cast block-number | cast to-hex) --rpc-url http://localhost:8545 | jq

Output of the trace will contain BLOBHASH as the last opcode despite the opcode being interpreted as invalid opcode.

[
  {
    "txHash": "0x5c0990c1793ac3bafc8c298766225ad544eb984c53535e004e9f06f01b1c8aae",
    "result": {
      "gas": 500000,
      "failed": true,
      "returnValue": "",
      "structLogs": [
        {
          "pc": 0,
          "op": "PUSH0",
          "gas": 446918,
          "gasCost": 2,
          "depth": 1,
          "stack": []
        },
        {
          "pc": 1,
          "op": "PUSH0",
          "gas": 446916,
          "gasCost": 2,
          "depth": 1,
          "stack": [
            "0x0"
          ]
        },
        {
          "pc": 2,
          "op": "BLOBHASH",
          "gas": 446914,
          "gasCost": 0,
          "depth": 1,
          "stack": [
            "0x0",
            "0x0"
          ]
        }
      ]
    }
  }
]
@c0np4nn4
Copy link

c0np4nn4 commented May 14, 2024

I wonder is this the right way to resolve the issue you left.

I tried to handle it by adding the code below at here

	// for handling issue#29464
	if vmenv.ChainConfig().IsCancun(txctx.BlockNumber, vmenv.Context.Time) != true {
		for _, opcode := range message.Data {
			var opcode = vm.OpCode(opcode)

			// cancun, EIP-4844
			if opcode == vm.StringToOp("BLOBHASH") {
				return nil, fmt.Errorf("invalid cancun opcode: %s", opcode.String())
			}
			// cancun, EIP-7516
			if opcode == vm.StringToOp("BLOBBASEFEE") {
				return nil, fmt.Errorf("invalid cancun opcode: %s", opcode.String())
			}
			// cancun, EIP-1153
			if opcode == vm.StringToOp("TLOAD") || opcode == vm.StringToOp("TSTORE") {
				return nil, fmt.Errorf("invalid cancun opcode: %s", opcode.String())
			}
			// cancun, EIP-5656
			if opcode == vm.StringToOp("MCOPY") {
				return nil, fmt.Errorf("invalid cancun opcode: %s", opcode.String())
			}
			// cancun, EIP-6780 skip
		}
	}

Output is not the trace anymore but an error message.

(code: -32000, message: invalid cancun opcode: BLOBHASH, data: None)

you can also check the log from geth client

image

@bearpebble
Copy link
Author

@c0np4nn4 I don't think that's the correct way of handling this. Tracing should still work and not return an error if there were invalid opcodes in the transaction.

@bearpebble
Copy link
Author

@s1na from looking at other issues it seems you are the most familiar with tracing. Do you believe this can be considered a bug that is worth fixing?

@holiman
Copy link
Contributor

holiman commented May 15, 2024

The old trace format is bad this way (hence why we created a different output-format, standard-tracing, which has opCode as a byte, and opString as a string).

The actual underlying bytecode is non-ambiguous. Translating a byte into a string-representation is context-dependent, e.g DIFFICULTY and RANDAO are two names for the same op-byte, and depends on the fork you're at. In some places, we're not chain-rule-aware, and just output something.

For fuzzing, I never look at the string-name of the operation. That's for human consumption. The debug_traceBlock output-format is inherently flawed, IMO

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