eth/catalyst, eth/ethconfig, cmd: make engine API max reorg depth configurable#35335
Merged
rjl493456442 merged 2 commits intoJul 14, 2026
Merged
Conversation
…figurable The maximum reorg depth accepted via forkchoiceUpdated was introduced as a hardcoded constant of 32 in ethereum#34767. Test orchestrators (EEST consume- enginex via hive) reuse one client across many tests and rewind the head to genesis between tests; once the head is more than 32 blocks deep, every subsequent rewind is refused with -38006 and the client never recovers. Make the limit configurable via --engine.maxreorgdepth (default 32, 0 disables the check). Like all flags it is also settable through the auto-generated GETH_ENGINE_MAXREORGDEPTH environment variable, which older versions ignore, allowing test runners to set it unconditionally.
Member
|
Sgtm, I guess |
rjl493456442
approved these changes
Jul 14, 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.
TLDR
The
enginexsimulator runs multiple tests against a single client instance, for each test, the simulator FCUs to genesis and then after each payload in the test: This triggers reorgs larger than currently supported by geth. More details in the enginex docs. The simulator's FCU behavior was designed to be consistent with the originalenginesimulator; an alternative would be to change the simulator to only verify payloads without FCU, but I think it's cleaner as it is currently (per docs above).Feel free to close this PR/re-implement as you see fit; whatever's easiest. Thanks!
Motivation
#34767 (implementing execution-apis#786) introduced a hardcoded cap of 32 on the depth of chain rewinds accepted via
engine_forkchoiceUpdatedwhen the target block is an already-canonical ancestor. This breaks systematic testing with EEST'sconsume enginexsimulator (via hive):head = genesisto reset the shared client.-38006 Too deep reorg(e.g.reorg depth 37 exceeds limit 32).Erigon has the same cap but reads it from the
MAX_REORG_DEPTHenvironment variable, which is how hive already works around it for enginex runs (ethereum/hive#1568, raising it to 512). Geth currently offers no knob.Changes
--engine.maxreorgdepth(default: 32,0= no limit), wired throughethconfig.Config.EngineMaxReorgDepthfollowing the--rpc.gascappattern. Since all geth flags are auto-exposed as environment variables, it can also be set viaGETH_ENGINE_MAXREORGDEPTH; older geth versions ignore unknownGETH_*variables with a warning, so test runners can set it unconditionally.catalyst.ConsensusAPIreads the limit from the config at construction instead of the package-level constant. A limit of 0 disables the check, matching the--rpc.gascap"0 disables" convention (and pre-eth/catalyst: allow reorging the head block to a parent #34767 behavior). Default CLI behavior is unchanged (32).TestForkchoiceUpdatedReorgDepthLimitcovering refusal beyond the configured limit, acceptance within it, and unlimited rewind-to-genesis with the check disabled.startEthServicegained optional config-modifier arguments; existing callers are untouched.Notes
core/blockchain.go's reorg path still logsImpossible reorg, please file an issue(error level) for canonical rewinds deeper than its hardcoded 32 heuristic, even when the operator has raised the engine API limit; the rewind itself proceeds correctly. Left as-is to keep this change small — happy to plumb the configured limit intoBlockChainConfigin this PR or a follow-up if preferred.GETH_ENGINE_MAXREORGDEPTH=512inclients/go-ethereum/geth.shwhen the simulator requests deep reorgs, mirroring the erigon fix in erigon: raise MAX_REORG_DEPTH for enginex runs hive#1568.Verification
Verified against EEST's
consume enginexin hive--devmode, using the minimal failing pair: a 37-block test followed by any test on the same shared client (the second test's reset-to-genesis forkchoiceUpdated is a depth-37 canonical rewind).Setup, in a hive checkout: rsync this branch to
clients/go-ethereum/go-ethereum-local/(exclude.git), addexport GETH_ENGINE_MAXREORGDEPTH=512toclients/go-ethereum/geth.sh(this is what ethereum/hive#1572 does, gated on the simulator opting in — that PR is required for enginex runs to pick this fix up), and creategeth-local.yaml:Fastest: run hive in
--devmode and drive it with consume from an execution-specs (EEST) checkout, filling the two fixtures locally instead of downloading the release:Alternatively, run the two tests with a single standalone hive command (the first run builds the simulator image, which downloads the
tests@v20.0.0fixture release):./hive --sim ethereum/eels/consume-enginex \ --sim.buildarg fixtures=tests@v20.0.0 \ --client go-ethereum --client-file geth-local.yaml \ --sim.limit '.*fork_Osaka-blockchain_test_engine_x-test_program_program_(BALANCE|CALLER)-debug.*' \ --docker.outputResults (identical in both modes):
GETH_ENGINE_MAXREORGDEPTHunset, default 32 — identical to current master):BALANCEpasses leaving the head at block 37,CALLERfails its initial forkchoice update with-38006 Too deep reorg: reorg depth 37 exceeds limit 32.GETH_ENGINE_MAXREORGDEPTH=512: client logsSet engine API maximum reorg depth depth=512; both tests pass.