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

feat(cheatcodes): add vm.meterTxGas cheatcode #6590

Closed
emo-eth opened this issue Dec 12, 2023 · 2 comments
Closed

feat(cheatcodes): add vm.meterTxGas cheatcode #6590

emo-eth opened this issue Dec 12, 2023 · 2 comments
Labels
A-cheatcodes Area: cheatcodes T-feature Type: feature
Milestone

Comments

@emo-eth
Copy link
Contributor

emo-eth commented Dec 12, 2023

Component

Forge

Describe the feature you would like

As suggested by @Vectorized, Forge should have a cheatcode with signatures meterTxGas() and meterTxGas(AccessList[] memory) for accurately measuring how much real-world gas a transaction would use. Currently, gas reporting is misleading for a number of reasons.

Additional context

Real-world gas metering is hard in Forge because tests are executed in the context of a single transaction. Execution of test setup marks accounts and storage slots as "warm," in addition to affecting gas refund logic by changing "starting" storage slot values.

Background

The pause/resumeGasMetering cheatcodes affect reported gas by caching a copy of the interpreter's Gas struct when paused and writing it back to the interpreter with each step.. On resume, the cached copy is deleted and the interpreter's gas member is left to proceed as normal.

After execution, gas_refunded is subtracted from gas, and even farther down the line, an extra "stipend" (the 21000 + calldata costs of invoking the forge test) is subtracted from the reported number.

Approaches

After invoking the cheatcode, the interpreter's Gas struct can be reset. The overall "stipend" can be calculated by adding 21000 + the calldata cost of the next external call seen by the EVM.

After that, I see two obvious ways to account for differences in gas costs and refunds:

  • Add functionality to revm (which Forge can then use) to mark accounts and storage slots in JournaledState as cold, and to override slots' "original" values
    • this may have unintended consequences on the overall state transition
    • as a separate project, changes that benefit Foundry might not be in revm's best interest
  • Track which accounts and storage slots have been accessed + changed since invoking the cheatcode, and do manual gas+refund accounting on the interpreter's Gas struct during execution. Similar to fix(vm.cool) Persist storage changes #5852's approach, but more comprehensive. See also forge-gas-metering for a similar WIP in Solidity.
    • adds a lot of overhead both in complexity and execution

After execution, the test runner should at least report calldata portion of the stipend in addition to execution costs.

Note

Supporting many different EVM execution environments or hard forks may require a lot of extra configuration, which should be considered.

@sam-goldman
Copy link

This would be very useful!

@zerosnacks zerosnacks changed the title feat(forge): meterTxGas cheatcode feat(cheatcodes): add vm.meterTxGas cheatcode Jul 5, 2024
@zerosnacks zerosnacks added the A-cheatcodes Area: cheatcodes label Jul 5, 2024
@zerosnacks zerosnacks added this to the v1.0.0 milestone Jul 26, 2024
@zerosnacks
Copy link
Member

Marking as resolved by the --isolation mode and recent fixes to the pause/resumeGasMetering cheatcodes.

@jenpaff jenpaff moved this from Todo to Completed in Foundry Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cheatcodes Area: cheatcodes T-feature Type: feature
Projects
Archived in project
Development

No branches or pull requests

3 participants