You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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:
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.
The text was updated successfully, but these errors were encountered:
Component
Forge
Describe the feature you would like
As suggested by @Vectorized, Forge should have a cheatcode with signatures
meterTxGas()
andmeterTxGas(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'sGas
struct when paused and writing it back to the interpreter with each step.. On resume, the cached copy is deleted and the interpreter'sgas
member is left to proceed as normal.After execution,
gas_refunded
is subtracted fromgas
, 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:
revm
(which Forge can then use) to mark accounts and storage slots inJournaledState
as cold, and to override slots' "original" valuesGas
struct during execution. Similar to fix(vm.cool) Persist storage changes #5852's approach, but more comprehensive. See alsoforge-gas-metering
for a similar WIP in Solidity.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.
The text was updated successfully, but these errors were encountered: