execution/vm: add --use-gevm flag to opt-in to GEVM as the EVM#21070
Closed
Giulio2002 wants to merge 2 commits intoerigontech:mainfrom
Closed
execution/vm: add --use-gevm flag to opt-in to GEVM as the EVM#21070Giulio2002 wants to merge 2 commits intoerigontech:mainfrom
Giulio2002 wants to merge 2 commits intoerigontech:mainfrom
Conversation
Adds an opt-in `--use-gevm` flag on both `cmd/erigon` and
`cmd/integration` that selects GEVM (github.com/Giulio2002/gevm)
as the EVM driving block execution. Default unset — legacy
interpreter unchanged.
Wiring
- node/cli, node/ethconfig, node/eth/backend, cmd/utils:
--use-gevm flag plumbed into ethconfig and through into the
staged-sync executor's vm.Config.
- cmd/integration/commands/{flags,stages}.go: --use-gevm on
every stage subcommand (stage_exec is what V03/V05 measure).
- execution/vm/interpreter.go: vm.Config gains a UseGevm bool.
Adapter
- execution/vm/gevm/ (new): BlockExecutor wrapping
gevmhost.Evm. Per-block lifecycle: NewBlockExecutor in
InitializeBlock; ExecuteTx per tx; FinalizeBlock once.
Reads via state.NewReaderV3(domains.AsGetter(tx)) — exact
same path legacy IBS uses, no adapter cache. Writes through
Erigon's existing stateWriter; GEVM's journal flushes once
per block at FinalizeBlock.
- execution/stagedsync/exec3_gevm.go (new): per-block dispatch
shim used by exec3_serial.go's executeBlockGevm path.
- execution/tests/testutil/gevm.go (new): plumbs USE_GEVM=1
through the EEST + state-test harness so the GEVM path is
exercised in tests.
Staged-sync
- execution/stagedsync/exec3_serial.go: executeBlockGevm
branch — when cfg.vmConfig.UseGevm, route to BlockExecutor;
otherwise legacy TxnExecutor unchanged.
- execution/stagedsync/{exec3,stage_execute,stageloop}.go:
force parallel=false on the GEVM path (BlockExecutor is
serial-only by design, races on block-scoped state if
EXEC3_PARALLEL=true).
- execution/state/{rw_v3,history_reader_v3}.go: minor
per-block-scoped helpers used by the adapter; legacy paths
unchanged.
Tests
- execution/execmodule/execmoduletester/exec_module_tester.go,
execution/tests/testutil/{block,state}_test_util.go:
testutil reads USE_GEVM env var and propagates UseGevm into
vm.Config so EEST + state-tests run on either interpreter.
- execution/builder/exec.go, execution/exec/block_assembler.go,
execution/tracing/calltracer/calltracer.go,
execution/commitment/commitmentdb/commitment_context.go,
cl/spectest/spectest/suite.go: minor signature plumbing.
Module
- go.mod / go.sum: require github.com/Giulio2002/gevm pinned
at commit 92fa74d (companion PR
Giulio2002/gevm#2).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GEVM dropped the parallel ReaderOps callback surface and unified on the state.Database interface. Update the Erigon adapter: - New gevmDatabase struct wraps erigonstate.StateReader (with the *Raw fast-path when the reader exposes it) and implements all six gevmstate.Database methods directly. - NewEvm replaces NewEvmWithReaderOps in the construction site. - readerOps() helper removed. CodeByHash and BlockHash on the wrapper return zero/nil — neither is exercised on the Erigon path: Code(address) is the loadCode read shape, and BlockEnv.GetHash is the BLOCKHASH source. go.mod re-pinned to the matching GEVM commit (5376a47e22e4eb29b2a3231131a1cc1a4e1b678e). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Collaborator
Author
|
will make a new one |
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.
Summary
Adds an opt-in
--use-gevmCLI flag on bothcmd/erigonandcmd/integrationthat routes block execution through GEVM instead of the legacy go-ethereum-derived interpreter underexecution/vm/. Default unset — legacy interpreter and all existing code paths unchanged.GEVM is brought in as a regular Go module (
require github.com/Giulio2002/gevm, noreplaceto a local path). The companion GEVM PR is Giulio2002/gevm#2; this PR pins commit92fa74d.Why
GEVM is a separately-maintained EVM that's faster than the legacy interpreter on real workloads. This wiring lets Erigon optionally drive state transitions through it without taking on a hard dependency: legacy stays the default, the binary still ships, every existing test still runs.
What's wired
--use-gevmoncmd/erigonandcmd/integration(every stage subcommand). Plumbed vianode/cli/flags.go→node/ethconfig→vm.Config.UseGevm.execution/vm/gevm/adapter.go, new):BlockExecutorwrapsgevmhost.Evmfor the block lifecycle —NewBlockExecutorinInitializeBlock,ExecuteTxper tx,FinalizeBlockonce. Reads route throughstate.NewReaderV3(domains.AsGetter(tx))— the same thin reader legacy IBS uses; no adapter-side cache. Writes go through Erigon's existingstateWriter; GEVM's journal flushes once per block.execution/stagedsync/exec3_serial.go,exec3_gevm.go):executeBlockGevmbranch whencfg.vmConfig.UseGevm.parallel = falseis forced when GEVM is on (theBlockExecutoris serial-only by design — races on block-scoped state if the parallel executor runs).execution/tests/testutil/,execution/execmodule/execmoduletester/):USE_GEVM=1env var routes the EEST and state-test harness through the GEVM path so both interpreters are exercised bymake test-short.What's NOT in scope
rpc/jsonrpc/,rpc/transactions/,rpc/rpchelper/,cmd/rpcdaemon/) continue to use the legacy interpreter regardless of--use-gevm. The flag only swaps the execution-path interpreter, not the RPC-side trace/sim helpers.execution/vm/legacy interpreter source — it stays as upstream ships it.Test plan
go build ./...cleanmake test-shortpasses with--use-gevmUNSET (no regression to legacy path)make test-shortpasses withUSE_GEVM=1for the in-scope packages (execution/vm/...,execution/exec/...,execution/stagedsync/...,execution/runtime/...,execution/tests/...)execution/tests/eest_*) passes on both pathsintegration stage_exec --reset --chain mainnet --datadir <pre-synced>followed byBATCH_COMMITMENTS=false integration stage_exec --no-commit --chain mainnet --datadir <pre-synced>(legacy serial replay) andBATCH_COMMITMENTS=false integration stage_exec --no-commit --use-gevm --chain mainnet --datadir <pre-synced>(GEVM serial replay) both complete with per-block state-root match against canonical mainnet over block range 24,978,234–24,980,902 (2,668 Fusaka blocks); zeroWrong trie rooton either runPerformance (Fusaka mainnet,
stage_exec --no-commit, serial executor for both)EXEC3_PARALLEL=false BATCH_COMMITMENTS=false)BATCH_COMMITMENTS=false --use-gevm)Both runs verified correct end-to-end on the same 2,668-block window with per-block
[commitment] processedstate-root checks active.Origin
Generated by an automated worker→verifier loop (gpt-5.5 worker + gpt-5.5 verifier) over ~30 attempts. The verifier framework gates on six independent checks: no cheating diffs, GEVM module wired,
--use-gevmflag wired, stage_exec correctness + ≥1.19× perf, full Go test suite passes on both paths, and EEST fixtures pass on both paths. All six green on attempt 30.🤖 Generated by an automated worker→verifier loop.