Skip to content

execution/commitment: remove the streaming commitment mode - #23191

Open
awskii wants to merge 7 commits into
mainfrom
awskii/cmt-drop-streaming
Open

execution/commitment: remove the streaming commitment mode#23191
awskii wants to merge 7 commits into
mainfrom
awskii/cmt-drop-streaming

Conversation

@awskii

@awskii awskii commented Aug 11, 2026

Copy link
Copy Markdown
Member

The streaming committer's background fold pool was never started in production — every one of the 12 StartScheduler callers is a test, so sc.base was always nil, sc.started always false, and TouchKey's enqueue branch never taken. --experimental.streaming-commitment advertised "overlaps folding with block execution" but folded synchronously, taking the same shape as the mounted parallel path through splits instead of mounts.

Changes

Remove streaming_commitment.go and its tests, the StreamingCommitter wiring in ParallelPatriciaHashed and Updates, VariantStreamingHexPatricia, and the flag with its config plumbing. 2552 deletions.

Kept, each with a live caller on the surviving mounted parallel path:

  • all of streaming_deep_fold.gofoldStorageRoot, dfsSubtreeDeep, unfoldStorageBase, called from processMounted
  • keyArena / keyArenaChunk / touchedKey — declared in the deleted file but needed by collectSubtreeKeys, so moved into streaming_deep_fold.go
  • stitchSplitCells — moved into parallel_mount.go

DeepLocalFolds moves onto ParallelPatriciaHashed rather than disappearing with the committer. TestDeepFold_FreshWhaleFoldsParallel and TestDeepFold_ExistingWhaleStillDemotes use it to assert which fold path ran; without it both degrade to root-parity checks that pass whichever path is taken. Mutation-checked — dropping the counter increment turns FreshWhale red.

Conflicts with the keyArena sizing PR, which edits keyArena in place; that one should land first.

One caveat worth recording: during verification I saw a single unattributed test failure I could not reproduce in four subsequent full runs of execution/commitment/... and db/state/.... Worth watching CI rather than assuming it was noise.

The streaming committer's background fold pool was never started in
production: every StartScheduler caller was a test, so sc.base was always
nil, sc.started always false, and TouchKey's enqueue branch never taken.
--experimental.streaming-commitment advertised "overlaps folding with block
execution" but folded synchronously, taking the same shape as the mounted
parallel path through splits instead of mounts.

Removes streaming_commitment.go, its tests, the StreamingCommitter wiring in
ParallelPatriciaHashed and Updates, VariantStreamingHexPatricia, and the
flag with its config plumbing.

Kept, with live callers on the mounted parallel path: all of
streaming_deep_fold.go (foldStorageRoot, dfsSubtreeDeep, unfoldStorageBase);
keyArena/keyArenaChunk/touchedKey, moved there from streaming_commitment.go
because collectSubtreeKeys needs them; stitchSplitCells, moved into
parallel_mount.go.

DeepLocalFolds moves to ParallelPatriciaHashed rather than disappearing with
the committer. TestDeepFold_FreshWhaleFoldsParallel and
TestDeepFold_ExistingWhaleStillDemotes assert on it to pin which fold path
ran; without it they would degrade to root-parity checks that pass whichever
path is taken. Mutation-checked: dropping the counter increment turns
FreshWhale red.
@AskAlexSharov
AskAlexSharov added this pull request to the merge queue Aug 11, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Aug 11, 2026
# Conflicts:
#	execution/commitment/deepfold_emptystorage_regression_test.go
#	execution/commitment/deepfold_regression_test.go
#	execution/commitment/deepfold_retouch_regression_test.go
#	execution/commitment/deepfold_singleslot_reexpand_regression_test.go
#	execution/commitment/deepfold_subset_regression_test.go
#	execution/commitment/streaming_commitment.go
#	execution/commitment/streaming_commitment_test.go
…ed deepfold tests

The five deepfold_*_regression_test.go files this branch edited were merged into
deepfold_test.go by #23184 (a pure move), so the mode-table and helper changes
had to be reapplied there.

keyArena keeps main's remaining-based sizing: moving the type out of the deleted
streaming_commitment.go dropped the field, but its call site still passes it.
@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Merged main. Seven conflicts, all modify/delete, pointing both ways:

Deleted here, modified on mainstreaming_commitment.go and streaming_commitment_test.go stay deleted; that is what this PR is for.

Deleted on main, modified here — the five deepfold_*_regression_test.go files. #23184 merged them into deepfold_test.go as a pure move (no body changed), so the files are gone but every test still exists. I dropped the old files and reapplied this branch's edits in deepfold_test.go: the four {"streaming", ...} / {"streaming_scheduled", ...} mode rows, and the two parallelBatchDeepFolds rewrites in TestDeepFold_FreshWhaleFoldsParallel and TestDeepFold_ExistingWhaleStillDemotes. The pre-consolidation bodies were byte-identical to the consolidated ones, so the edits transferred exactly.

One semantic break the textual merge hid: moving keyArena out of the deleted streaming_commitment.go into streaming_deep_fold.go dropped its remaining field, but main had meanwhile added remaining-based sizing and its collectSubtreeKeys call site still passes it. Kept main's version — without it a subtree far smaller than a chunk burns a whole 64KB chunk.

Verified on the pushed tree: go build ./... and go vet ./execution/commitment/... clean, execution/commitment/... short suite green, plus db/state/... and execution/stagedsync as the downstream consumers. The six moved tests were also run by name.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the unused “streaming commitment” variant from Erigon’s execution commitment pipeline (flag/config/plumbing, implementation, and tests), consolidating the surviving mounted-parallel commitment path and keeping the deep-fold helpers that are still used in production.

Changes:

  • Removed the StreamingCommitter implementation, its variant (VariantStreamingHexPatricia), CLI/config flags, and related scheduled/streaming test modes.
  • Kept and refactored shared deep-fold logic for whale storage folding (moving keyArena/touchedKey and relocating stitchSplitCells).
  • Added a DeepLocalFolds counter to ParallelPatriciaHashed and updated tests to assert which fold path ran without relying on the deleted streaming engine.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
node/ethconfig/config.go Removes the ExperimentalStreamingCommitment config field.
node/eth/backend.go Drops propagation of the streaming commitment toggle into statecfg.
node/cli/default_flags.go Removes the streaming-commitment CLI flag from defaults.
execution/commitment/streaming_deep_fold.go Moves touchedKey/keyArena into the deep-fold helper file for continued use by the mounted path.
execution/commitment/streaming_commitment.go Deletes the streaming committer implementation.
execution/commitment/streaming_commitment_test.go Deletes streaming-committer tests.
execution/commitment/state_roundtrip_regression_test.go Removes streaming variants from restart/state round-trip coverage.
execution/commitment/parallel_trace_test.go Updates wording to remove streaming references.
execution/commitment/parallel_testkit_test.go Removes streaming run modes; adds parallelBatchDeepFolds helper for fold-path assertions.
execution/commitment/parallel_streaming_bench_test.go Removes streaming overlap benchmark code and related helpers.
execution/commitment/parallel_patricia_hashed.go Removes streaming wiring; adds DeepLocalFolds counter to the parallel trie.
execution/commitment/parallel_patricia_hashed_test.go Drops streaming variant from reuse-across-reset parity test.
execution/commitment/parallel_mount.go Moves stitchSplitCells here; increments DeepLocalFolds on successful deep storage fold.
execution/commitment/mode_parallel_lifecycle_test.go Removes streaming lifecycle assertions and variants.
execution/commitment/deepfold_test.go Switches deep-fold assertions from streaming committer to parallel deep-fold counter.
execution/commitment/commitmentdb/commitment_context.go Removes streaming references in variant selection comments and restore paths.
execution/commitment/commitment.go Removes streaming variant and Updates→streaming funnel plumbing.
execution/commitment/additive_updates_test.go Drops streaming additive-touch test case.
db/state/statecfg/state_schema.go Removes the ExperimentalStreamingCommitment statecfg toggle.
db/state/squeeze.go Removes streaming variant selection from commitment file rebuild path.
db/state/execctx/domain_shared.go Simplifies trie variant selection to sequential vs parallel only.
db/state/execctx/commitment_flag_test.go Removes streaming-flag tests and associated global-flag plumbing.
cmd/utils/flags.go Removes --experimental.streaming-commitment flag and config wiring.
cmd/integration/commands/flags.go Removes integration flag binding for streaming commitment.
cmd/evm/staterunner_test.go Removes streaming flag handling in state runner test setup.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +33 to +34
// touchedKey is a snapshotted touch a background fold replays; hk is copied off
// the walk path while pk/upd reference the caller's stable backing.
Comment on lines +189 to +196
for i, k := range keys {
ks := string(k)
ut.TouchPlainKey(ks, nil, func(c *KeyUpdate, _ []byte) {
c.plainKey = ks
c.hashedKey = KeyToHexNibbleHash(k)
c.update = &upds[i]
})
}
Comment on lines 99 to 106
// Reset clears the published root hash and resets the template so the instance
// can be reused; pooled workers stay cached for the next Process call.
func (p *ParallelPatriciaHashed) Reset() {
if p.template != nil {
p.template.Reset()
}
p.rootHash.Store(nil)
if p.streaming != nil {
p.streaming.Reset()
}
}
keyArena outlived streaming_commitment.go — collectSubtreeKeys still uses it —
but its two tests were in streaming_commitment_test.go and went with the file.
They move to deepfold_test.go, next to the deep fold that drives them.
@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Correction to my merge: it dropped two live tests, now restored in cc290e94b5.

keyArena outlives this PR — collectSubtreeKeys in streaming_deep_fold.go still uses it — but TestKeyArena_PointerStability and TestKeyArena_ChunkSizedFromRemaining lived in streaming_commitment_test.go and went with the file when I deleted it. Keeping the type while dropping its tests was wrong; both move to deepfold_test.go, next to the deep fold that drives them.

Found by diffing the sorted Test/Fuzz/Benchmark name sets across main, this branch, and the merge — the same check #23184 used. After the restore, the only names in main and not here are the streaming tests plus TestModeParallel_RetouchReachesStreamer and the two TestStateRoundTrip_*, all three of which this branch had already deleted before the merge. Nothing in this branch's set is missing from the merge.

On the arena itself, since the merge kept main's remaining sizing over the older copy this branch moved:

  • subtreeCount is an exact count, not an estimate. dfsSubtree calls back once per node with a non-nil plainKey, which is what subtreeCount counts, so remaining reaches 0 on the last key. I checked it rather than trusting the doc — a temporary len(out) != subtreeCount panic in collectSubtreeKeys survives the full (non-short) execution/commitment/... suite without firing.
  • A wrong hint would degrade, not corrupt: max(a.remaining, 1) floors it, min(want, keyArenaChunk) caps it, and max(..., len(hk)) guarantees the key always fits.
  • The explicit len(hk) > cap-len check means append never reallocates mid-chunk, so a chunk's backing never moves while slices point into it. Returned slices are full-cap three-index ([start:end:end]), so a caller's append allocates instead of overwriting the next key.
  • No sharing across goroutines: collectSubtreeKeys runs on the loop goroutine before g.Go, and each call starts a fresh arena with a nil buf, so per-child groups never share a chunk.

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.

3 participants