Skip to content

commitment: catch cases when parallel commitment not enabled - #23596

Draft
AskAlexSharov wants to merge 10 commits into
mainfrom
alex/paracommit_enforce_37
Draft

commitment: catch cases when parallel commitment not enabled#23596
AskAlexSharov wants to merge 10 commits into
mainfrom
alex/paracommit_enforce_37

Conversation

@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Based on #23544.

NewSharedDomainsCommitmentContext starts on the sequential trie and upgrades only once EnableParaTrieDB arrives. That fallback is deliberate for the DB-less RPC and integrity contexts, but nothing separated it from a caller that simply forgot — which is how cmd/evm t8n, stage_custom_trace, GenerateChain, the state-test harness and MakePreState all ended up computing state roots on the sequential trie with the flag on, silently (fixed in #23544).

Two layers:

  1. WithParaTrieDB(db) folds the wiring into construction, so selecting the trie and supplying its DB are one expression with no second call to forget.
  2. ComputeCommitment stops being quiet about the rest: a context still holding a pending parallel selection fails under ERIGON_ASSERT and logs a one-shot warning otherwise. Assertions are on in CI, so a new site that forgets the DB goes red instead of testing the wrong trie.

An error rather than a panic — the calculator drives ComputeCommitment from a goroutine the exec loop waits on, where a panic parks the loop instead of failing it. That is not hypothetical: the first draft panicked and turned a committer test into a 10-minute hang.

The guard immediately caught one more unwired site, setupStepTest, wired here.

…ode review

--limit could push block past the real stages.Senders ceiling when
sendersProgress==0 or execProgress>=sendersProgress, causing the exec
loop to spin forever waiting for an unreachable target. Clamp --limit
to sendersProgress instead. Also restores the execProgress==0-only
gate around the SeekCommitment fallback (was running unconditionally
on every invocation) and closes SharedDomains on its error path.
# Conflicts:
#	cmd/integration/commands/flags.go
#	cmd/integration/commands/stages.go
…p mode

The chain-tip loop ran execBlocksBatch(bn) for bn in [execProgress, block), so
the first iteration re-targeted a block already executed and the resolved target
was never reached: progress 100 with --limit=1 resolves to 101 and executed
nothing. Iterate (execProgress, block] instead.

Also from review:
- profiling starts before ApplyMigrations, so its failure path still produces
  the profiles the flag promises.
- StopCPUProfile only runs when this helper started one; --pprof.cpuprofile
  already holds it otherwise, and stopping it closed it out from under its
  owner. The mutex rate is restored to its previous value rather than 0 for the
  same reason.
- target resolution moves into resolveExecTarget with table-driven coverage of
  the --limit/--block/progress boundaries.
… trie

stage_exec, state_stages and loop_exec all compute commitment but never
registered --experimental.parallel-commitment, so the flag was unknown there and
only ERIGON_COMMITMENT_PARALLEL could reach statecfg. A stage_exec profile on n5
shows the cost: the sequential trie saturates one core for the whole exec window
while the executor's workers sit 96% idle on a 16-core box.

The flag default now ORs erigon's own flag default with the env-derived value, so
flipping the default in one binary cannot leave the other on a different trie.
…8n and custom_trace

Both compute commitment against a SharedDomains that never called
EnableParaTrieDB. NewSharedDomainsCommitmentContext starts on the sequential trie
and only upgrades once a DB arrives, so these two ran the sequential trie
whatever the flag or ERIGON_COMMITMENT_PARALLEL said -- silently, since the
fallback is the design's escape hatch for RPC and integrity contexts that have no
DB to give.

t8n is the sharper case: cmd/evm statetest already wires it, so one binary
computed state roots two different ways.

Construction moves into a named helper per site so a test can assert the wiring
rather than the whole command.
…e test harnesses

GenerateChain, the state-test harness and MakePreState all compute a state root
on a SharedDomains that never called EnableParaTrieDB, so the CI shards that set
ERIGON_COMMITMENT_PARALLEL were exercising the sequential trie in those paths.

MakePreState has no DB of its own, so it takes one; every caller already holds
m.DB.

InitPraguePreDeploys is left alone: it only flushes, and Commit does no trie
work.
… loud

NewSharedDomainsCommitmentContext starts on the sequential trie and upgrades only
once EnableParaTrieDB arrives. That fallback is deliberate for the DB-less RPC and
integrity contexts, but nothing separated it from a caller that simply forgot, so
several sites computed state roots on the sequential trie with the flag on and no
sign of it.

WithParaTrieDB folds the wiring into construction, so selecting the trie and
supplying its DB are one expression with no second call to forget.

ComputeCommitment now refuses to be quiet about the remaining case: a context that
still holds a pending parallel selection fails under ERIGON_ASSERT and logs a
one-shot warning otherwise. Assertions are on in CI, so a new site that forgets
the DB goes red instead of testing the wrong trie. It returns an error rather than
panicking because the calculator drives ComputeCommitment from a goroutine the
exec loop waits on, where a panic parks the loop instead of failing it.

The guard immediately caught setupStepTest, which is wired here.
@AskAlexSharov AskAlexSharov changed the title db/state/execctx, execution/commitment: make an unwired parallel commitment trie loud commitment: catch cases when parallel commitment not enabled Aug 27, 2026
Base automatically changed from alex/integr_fix_37 to main August 27, 2026 05:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant