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

evmtool takes opcode BASEFEE as an invalid operation #7433

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

evmtool takes opcode BASEFEE as an invalid operation #7433

Alleysira opened this issue Aug 7, 2024 · 9 comments
Assignees

Comments

@Alleysira
Copy link

Description

Hello developers!

I'm doing fuzzing on EVM implementations, and I'm using besu/evm-tool for testing. I found that when executing the opcode BASEFEE (0X48), besu/evm-tool will return an error Bad instruction and output INVALID_OPERATION.

Steps to Reproduce

  1. I try to reproduce this on the latest develop version of besu/evm-tool with docker image(digest: e79d839a699b). I also compiled the evmtool locally(commit: 7433c8c), got the same result. This the genesis.json file I provided:
{
    "config": {
      "chainId": 9599,
      "shanghaiBlock": 0
    },
    "alloc": {
      "0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      }
    },
    "coinbase": "0x000000000000000000000000000000000000abcd",
    "difficulty": "1",
    "extraData": "",
    "gasLimit": "0xffffff",
    "nonce": "0x0",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp": "0x00"
}
  1. The bytecode to be executed:
# BYTECODE
4860005260406000f3
# MENMONICS
BASEFEE
PUSH1 00
MSTORE
PUSH1 40
PUSH1 00
RETURN
  1. Run the besu/evm-tool with:
docker run --rm -i -v ${PWD}/genesis.json:/opt/data/genesis.json hyperledger/besu-evmtool:develop --code 4860005260406000f3 --json --notime --genesis /opt/data/genesis.json
  1. Result: besu/evm-tool raises an error and charges all gas.
{"pc":0,"op":72,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"BASEFEE","error":"Bad instruction"}
INVALID_OPERATION

{"gasUser":"0x2540be400","gasTotal":"0x2540be400","output":"0x"}

Expected behavior: According to the spec, besu/evmtool should return the base fee of the current block to the stack.

Actual behavior: besu/evmtool raises an error.

Frequency: 100%

Logs

However, if no genesis.json is provided, the evmtool will run successfully.

For example:

docker run --rm -i hyperledger/besu-evmtool:develop --code 4860005260406000f3 --json

The result looks good to me.

{"pc":0,"op":72,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"BASEFEE"}
{"pc":1,"op":96,"gas":"0x2540be3fe","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":3,"op":82,"gas":"0x2540be3fb","gasCost":"0x6","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"MSTORE"}
{"pc":4,"op":96,"gas":"0x2540be3f5","gasCost":"0x3","memSize":32,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":6,"op":96,"gas":"0x2540be3f2","gasCost":"0x3","memSize":32,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":8,"op":243,"gas":"0x2540be3ef","gasCost":"0x3","memSize":32,"stack":["0x40","0x0"],"depth":1,"refund":0,"opName":"RETURN"}

{"gasUser":"0x14","timens":34254297,"time":34254,"gasTotal":"0x14","output":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}

Versions (Add all that apply)

  • Software version: 24.7
  • Java version: 22.02
  • OS Name & Version: Ubuntu 20.04
  • Virtual Machine software & version: WSL version:2.2.4.0
  • Docker Version: Docker Engine 24.0.7; Docker Desktop 24.0.7

Please let me know if there is something I am not clear about.

Thanks for your time and patience!

@shemnon
Copy link
Contributor

shemnon commented Aug 7, 2024

The genesis file needs to specify a baseFeePerGas for all post london chains, even if it is zero.

{
    "config": {
      "chainId": 9599,
      "shanghaiTime": 0
    },
    "alloc": {
      "0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      }
    },
    "coinbase": "0x000000000000000000000000000000000000abcd",
    "difficulty": "1",
    "extraData": "",
    "gasLimit": "0xffffff",
    "nonce": "0x0",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp": "0x00",
    "baseFeePerGas":"0x0"
}

This is not a problem from the EvmTool harness, but is emergent from Genesis file parsing. A chain that is launched without a baseFeePerGas will see similar behavior with the BASEFEE opcode as it may be configured to not have a fee market (like Ethereum Classic).

@Alleysira
Copy link
Author

Hi @shemnon,

Thank you for your quick reply! The setting in genesis.json works perfectly for me.

I have another question: Should the description of baseFeePerGas be added to the documentation at genesis-items? Currently, there is no explanation that this value should be set after the London upgrade(I also checked concepts and tutorial). While the detailed documentation of Besu is very helpful, I believe it could be further improved by including this information.

Thank you once again for your assistance!

@siladu
Copy link
Contributor

siladu commented Aug 22, 2024

The genesis file needs to specify a baseFeePerGas for all post london chains, even if it is zero.

This isn't strictly true. For example - using the besu client rather than evmtool - this qbft config automatically adds a baseFee to the block headers:

{
    "config": {
      "chainId": 95991,
      "shanghaiTime": 0,
      "qbft" : {
        "blockperiodseconds" : 1,
        "epochlength" : 30000,
        "requesttimeoutseconds" : 2
      }
    },
    "extraData": <encoded node address>
    ...

However, things get a bit weird when I try it with ethash so maybe there's a bug there. I don't think adding baseFeePerGas manually to the genesis was the original intent though.

@siladu
Copy link
Contributor

siladu commented Aug 22, 2024

@Alleysira I think your issue is that shanghaiBlock doesn't exist as a fork name, it's shanghaiTime because it's a timestamp, not a block number. Shanghai fork was the first fork to introduce timestamps for forks, so they all use the ...Time suffix from shanghai onwards.

@Alleysira
Copy link
Author

Alleysira commented Aug 22, 2024

Thanks for your attention @siladu.

I checked locally with Hyperledger Besu evm 24.8-develop-dd64bdf and set shanghaiTime: 0 without setting baseFeePerGas in genesis.json, it returns the baseFee in stack. But the outputs said we are in fork Cancun instead of Shanghai, where opcodes like BLOBBASEFEE are defined.

evmtool --code 484a5f5f --genesis genesis.json --json
{"pc":0,"op":72,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"BASEFEE"}
{"pc":1,"op":74,"gas":"0x2540be3fe","gasCost":"0x2","memSize":0,"stack":["0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"],"depth":1,"refund":0,"opName":"BLOBBASEFEE"}
{"pc":2,"op":95,"gas":"0x2540be3fc","gasCost":"0x2","memSize":0,"stack":["0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","0x0"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":3,"op":95,"gas":"0x2540be3fa","gasCost":"0x2","memSize":0,"stack":["0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH0"}
{"stateRoot":"0x91cfd2502f66e1f512a401ce78779d8b428ca94aab1dbb73b3bbbaebe7b0a6ee","output":"0x","gasUsed":"0x8","pass":true,"fork":"Cancun","timens":2159586,"time":2159}

And if I set baseFeePerGas: 0x7 in genesis.json, it works and overrides the default setting.

evmtool --code 4860005260406000f3 --genesis genesis.json --json
{"pc":0,"op":72,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"BASEFEE"}
{"pc":1,"op":96,"gas":"0x2540be3fe","gasCost":"0x3","memSize":0,"stack":["0x7"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":3,"op":82,"gas":"0x2540be3fb","gasCost":"0x6","memSize":0,"stack":["0x7","0x0"],"depth":1,"refund":0,"opName":"MSTORE"}
{"pc":4,"op":96,"gas":"0x2540be3f5","gasCost":"0x3","memSize":32,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":6,"op":96,"gas":"0x2540be3f2","gasCost":"0x3","memSize":32,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":8,"op":243,"gas":"0x2540be3ef","gasCost":"0x3","memSize":32,"stack":["0x40","0x0"],"depth":1,"refund":0,"opName":"RETURN"}
{"stateRoot":"0xbb7d7bcb5229e387474b0472cee3b70ad746dc53b8d1aea499c096e572ee652b","output":"0x00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000","gasUsed":"0x14","pass":true,"fork":"Cancun","timens":2703133,"time":2703}

Anyway, thanks for your time.

@shemnon
Copy link
Contributor

shemnon commented Aug 22, 2024

can you share the current genesis.json you are using for the last two runs?

@Alleysira
Copy link
Author

Alleysira commented Aug 22, 2024

Of course, for the first run:

{
    "config": {
      "chainId": 9599,
      "shanghaiTime": 0
    },
    "alloc": {
      "0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x0000000000000000000000007265636569766572": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xf7a53ee28e45ac34b9418817c5ca64c870440d9f": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x99ef7574a09cd6f14b82676617487ab57eeb83e5": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x200ec33954e5c259ff8a541c08ffad46fe0d2b8b": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xef35926dccf17894fdadce860646d71ae3bfbf3d": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xebae4db639b2d1ef53f8f7f36a34805b79df92d8": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x8f11937817d0be064d7f13d66175b48dd92eb09c": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xa82da1501a071337b930813e517fe70cce74a057": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x43ed711ac1d57bd3c05842d5d8313e873791d637": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      }
    },
    "coinbase": "0x000000000000000000000000000000000000abcd",
    "difficulty": "1",
    "extraData": "",
    "gasLimit": "0xffffff",
    "nonce": "0x0",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp": "0x00"
}

For the second run:

{
    "config": {
      "chainId": 9599,
      "shanghaiTime": 0
    },
    "alloc": {
      "0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x0000000000000000000000007265636569766572": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xf7a53ee28e45ac34b9418817c5ca64c870440d9f": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x99ef7574a09cd6f14b82676617487ab57eeb83e5": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x200ec33954e5c259ff8a541c08ffad46fe0d2b8b": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xef35926dccf17894fdadce860646d71ae3bfbf3d": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xebae4db639b2d1ef53f8f7f36a34805b79df92d8": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x8f11937817d0be064d7f13d66175b48dd92eb09c": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0xa82da1501a071337b930813e517fe70cce74a057": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      },
      "0x43ed711ac1d57bd3c05842d5d8313e873791d637": {
        "balance": "0xffffffffffffffffffffffffffffffffffffffff"
      }
    },
    "coinbase": "0x000000000000000000000000000000000000abcd",
    "difficulty": "1",
    "extraData": "",
    "gasLimit": "0xffffff",
    "nonce": "0x0",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp": "0x00",
    "baseFeePerGas": "0x7"
}

The only difference is baseFeePerGas.

@shemnon
Copy link
Contributor

shemnon commented Aug 24, 2024

Genesis files were getting skipped, based on a revision I did in June, that has a fix now in #7518. The cancun fork identification was a somewhat related issue. The random basefee was an unrelated serialization issue, that was also included in the fix.

@shemnon
Copy link
Contributor

shemnon commented Aug 24, 2024

fixes #7432

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

No branches or pull requests

3 participants