Support state_override in eth_call and eth_estimateGas#629
Merged
lukasz-zimnoch merged 15 commits intomainfrom Mar 30, 2026
Merged
Support state_override in eth_call and eth_estimateGas#629lukasz-zimnoch merged 15 commits intomainfrom
lukasz-zimnoch merged 15 commits intomainfrom
Conversation
state_override is the JSON-encoded state override map for eth_call. It's an optional field.
Wire the state_override parameter through the eth_call RPC path so callers can override account nonce, code, balance, and storage when simulating calls. Add SetBalance and SetStorage methods to StateDB to support the override logic.
When SetStorage replaces an account's storage, reads of non-overridden keys fall through to the keeper and return old values. Add a storageWiped flag on stateObject that makes GetCommittedState return empty for keys not in the new storage, matching geth's behavior of marking the old object as destructed.
Just two basic tests for a valid and invalid state override, consistent with the existing approach in TestEthCall. More thorough tests for individual steps of state overriding will be added in separate commits.
We don't need to represent State and StateDiff as pointers to a map, simple map is enough. Same about a double pointer to Balance's bigint.
Three functions in geth support state_override: eth_call, eth_estimateGas, and eth_createAccessList. The last one is not supported by mezod but from now on the other two both support state_override. For eth_estimateGas it was simple as we use the infrastructure added for eth_call in the previous commits.
Updated documentation to reflect support for state overrides for eth_call and eth_estimateGas.
These two functions are only used in the context of state overriding now, and thinking more about it, setting balance or setting storage for some address to arbitrary values are not usual operations when a transaction is processed.
When storage is overridden via OverrideStorage, cache the empty hash in originStorage for consistency with go-ethereum. This ensures subsequent lookups for the same key hit the cache instead of re-evaluating the storageOverridden branch.
Move state override handling (JSON deserialization + application) out of ApplyMessageWithConfig and into the gRPC handlers where it belongs. Introduce SimulateMessage for read-only simulation (eth_call, eth_estimateGas) with commit hardcoded to false, and extract a private applyMessageWithConfig that takes a pre-built StateDB and has no knowledge of overrides.
lukasz-zimnoch
approved these changes
Mar 30, 2026
Collaborator
lukasz-zimnoch
left a comment
There was a problem hiding this comment.
Tested and works as advertised! ✅
lukasz-zimnoch
approved these changes
Mar 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduction
The pull request adds support for
state_overrideineth_callandeth_estimateGasmethods.Changes
The structure of
stateOverrideis based on the version from go-ethereum. I have also addedSetBalanceandSetStoragetoStateDB, just like go-ethereum does. State overrides are optional and applied inApplyMessageWithConfig, where we make sure state overrides can only be used for calls not committing the state.Testing
Run the node locally with
$ make localnet-bin-startand executeeth_callwithstate_override. Compare the outcome with one returned by RPC providers running themainversion of the code.Where:
0x00000000000000000000000000000000DeaDBeef- fake address for which we are setting balance0x000000000000000000000000000000000000abcd- fake address of ERC20 smart contract0x70a0823100000000000000000000000000000000000000000000000000000000deadbeef-balanceOf(0x...DeaDBeef)0x6080604052348015610010576000...- ERC20 smart contract bytecode0x49361c85...storage slot iskeccak256(abi.encode(0xDeaDBeef, 0))- the balance mapping slot for that addressThe expected result on this branch is
0x...3635c9adc5dea00000 = 1000 * 10^18.Calling
eth_estimateGaswith the same state overrides and calldata fortransfer:should yield gas cost estimated.
Author's checklist
docs/) or specification (x/<module>/spec/)Assigneesfieldmezod-developersin theReviewersfield and notified them on DiscordReviewer's checklist