Skip to content

✨ feat(tests): zkEVM - Add parametrized opcodes and gas limits #1483

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

Conversation

raxhvl
Copy link
Member

@raxhvl raxhvl commented Apr 21, 2025

πŸ—’οΈ Description

The PR extends #1456 to add dynamic gas_limits and opcodes.

πŸ”— Related Issues

#1453

How it works

A series of stress tests that assess the ability of a specific
opcode or precompile to process large proofs in a block.
Large proofs are created by deploying contracts with
maximum allowed bytecode.
Then, a pacman contract (α—§β€’β€’β€’) consumes the maximum possible number of
proofs in a block with a given gas limit using an opcode or precompile.

Configuring gas limits

GAS_LIMITS = [30_000_000, 60_000_000, 100_000_000, 300_000_000]

Configuring opcodes

CONSUMERS = [
Consumer(
opcode=Op.EXTCODEHASH,
gas_cost=2603, # PUSH20[3] + EXTCODEHASH[2600]
generate_bytecode=lambda proof: Op.EXTCODEHASH(proof),
),
Consumer(
opcode=Op.EXTCODESIZE,
gas_cost=2603, # PUSH20[3] + EXTCODESIZE[2600]
generate_bytecode=lambda proof: Op.EXTCODESIZE(proof),
),
]

What's pending

As described in #1456, the pre state size is huge. To solve that, I experimented deploying contracts in the same block, it had the following issues:

  1. The code for deploying large contracts gets messy quickly, and it consumes large amounts gas due to high memory usage.
  2. I adjusted gas limit to offset the contract deployment costs, but I think it skews the benchmark a bit if we do it in the same block.

I was wondering if there is a way to persist data between blocks in the test.

If this approach sounds okay, then I can extend this to include precompiles.

Even after deploying contracts in a separate blocks, communicating the deployed addresses to be consumed would need more work.

cc: @jsign

Output

tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODEHASH-gas_limit_30000000] FILLED                                               [ 1/16]
tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODEHASH-gas_limit_60000000] FILLED                                               [ 2/16]
tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODEHASH-gas_limit_100000000] FILLED                                              [ 3/16]
tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODEHASH-gas_limit_300000000] FILLED                                              [ 4/16]
tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODESIZE-gas_limit_30000000] FILLED                                               [ 5/16]
tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODESIZE-gas_limit_60000000] FILLED                                               [ 6/16]
tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODESIZE-gas_limit_100000000] FILLED                                              [ 7/16]
tests/zkevm/test_proof_size.py::test_via_opcode[fork_Cancun-blockchain_test-EXTCODESIZE-gas_limit_300000000] FILLED                                              [ 8/16]

βœ… Checklist

  • All: Set appropriate labels for the changes.
  • All: Considered squashing commits to improve commit history.

@raxhvl raxhvl force-pushed the jsign-zkvm-bytecode-worstcase branch from 4f6adcf to 858af44 Compare April 21, 2025 05:01
@raxhvl raxhvl force-pushed the jsign-zkvm-bytecode-worstcase branch from 858af44 to 9668583 Compare April 21, 2025 09:02
Comment on lines +2 to +3
A series of stress tests that assess the ability of a specific
opcode or precompile to process large proofs in a block.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opcodes/precompiles wouldn't process proofs.

These tests to be added should be seen as regular blockchain tests that so happen to be edge cases that we want to test in a zkEVM. In that sense, they should not be any different than other blockchain tests

Copy link
Member Author

@raxhvl raxhvl Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. These tests are no different. By "process" I mean making these opcode / precompile to take the bytecode as input, nothing more.

@kevaundray
Copy link
Contributor

kevaundray commented Apr 21, 2025

The code for deploying large contracts gets messy quickly, and it consumes large amounts gas due to high memory usage.

I think we want to just deploy N distinct contracts over as many blocks as needed, where N is the amount of EXTCODEHASH opcodes that I can fit into a block.

Then in the subsequent blocks, we want to call 1 EXTCODEHASH. Then in the next block, we want to call 2 EXTCODEHASH, all the way upto N EXTCODEHASH.

I adjusted gas limit to offset the contract deployment costs, but I think it skews the benchmark a bit if we do it in the same block.

We would be ignoring those blocks that are used to deploy contracts, because we only care about the blocks that are calling the EXTCODEHASH. But from the perspective of the execution spec tests, its just a blockchain test where we deploy N contracts and then call EXTCODEHASH/SIZE in subsequent blocks.

ie nothing to do with proofs should be mentioned here and these tests can be used in a normal client too

@kevaundray
Copy link
Contributor

EXTCODEHASH requires a "setup" phase.

This may not be the case for all opcodes/precompiles we want to test.

For the Add opcode for example, we can have block 1, do as many Adds as possible to fill up the block.

@raxhvl
Copy link
Member Author

raxhvl commented Apr 21, 2025

Makes sense. The code can be tweaked slightly to skip setup phase.

@jsign jsign force-pushed the jsign-zkvm-bytecode-worstcase branch 2 times, most recently from c114004 to afc7f13 Compare April 21, 2025 19:56
@jsign
Copy link
Contributor

jsign commented Apr 21, 2025

Uhm, my take is that we should:

  • Rename the testing file to tests_worst_cases.py
  • Leave the original test_worst_bytecode as it is (maybe generalizing only gas limit and related, but not the opcode generalization)
  • Create a separate new test test_repeated_execution with this new cases of repeated opcodes or precompiles.

My argument on separating tests in the second and third bullets is exactly because the second requires some complicated setup, compared to opcode/precompile repetition being mostly stateless. While you could make that conditional, feels a bit complex and can be confusing (i.e., technically you can create a single test with all the tests in the repo and make it conditional :P ).

To generalize the setup to avoid big pre-alloc @marioevz suggested and idea here.

cc @kevaundray @raxhvl

@raxhvl raxhvl marked this pull request as draft April 22, 2025 03:23
@raxhvl
Copy link
Member Author

raxhvl commented Apr 22, 2025

Thanks @jsign :) I misunderstood bullets (1) and (2) to be the same test.

@marioevz marioevz force-pushed the jsign-zkvm-bytecode-worstcase branch from 55853d2 to a672724 Compare April 30, 2025 22:19
@marioevz marioevz deleted the branch ethereum:jsign-zkvm-bytecode-worstcase April 30, 2025 22:37
@marioevz marioevz closed this Apr 30, 2025
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

Successfully merging this pull request may close these issues.

4 participants