Skip to content

execution/commitment: streaming commitment trie (--experimental.streaming-commitment) - #21709

Merged
AskAlexSharov merged 138 commits into
mainfrom
awskii/parallel_prepare_fold
Jun 21, 2026
Merged

AskAlexSharov merged 138 commits into
mainfrom
awskii/parallel_prepare_fold

Conversation

@awskii

@awskii awskii commented Jun 9, 2026

Copy link
Copy Markdown
Member

Draft / checkpoint — streaming + parallel commitment trie, with main merged in and the parallel-path stability bugs fixed and validated on mainnet.

What

Adds StreamingCommitter, a commitment engine that overlaps trie folding with block execution (touched keys folded into per-top-nibble splits during execution; root stitched at block end). Selected via --experimental.streaming-commitment (precedence: streaming > parallel > concurrent). The branch stacks concurrent → parallel → streaming; streaming reuses the parallel engine's prefix-trie / split machinery and delegates Process to the committer.

Stability fixes (parallel/streaming)

Live mainnet validation surfaced a deterministic wrong root and two .kv mmap use-after-munmap SIGSEGVs, all now fixed:

  • Wrong root (deep storage-fold path) — the mount-only fold is the correct parallel trie; the unsound deep storage split is off by default.
  • Mem-batch alias — root cause of both crashes. TemporalMemBatch.putLatest stored values without copying; under parallel commitment they alias a .kv mmap of the foreground exec tx's file generation, which a background merge munmaps mid-fold. sd.mem is read first by every worker's TrieContext (shared SharedDomains), so a concurrent worker (TrieContext.Branch) or the commit flush (SharedDomains.Commit) reads the freed pointer → fault. Fix: copy-on-put so sd.mem owns heap bytes (8196bac851). (Copy-on-get under latestStateLock can't fix this — the source is already munmapped before the copy runs.)
  • Supporting: a fold-scoped file-view pin across the parallel fold (6fadc5d9aa), and gating main's State Cache Consolidation (PR #1 of the perf stack) #21380 BranchCache off under parallel/streaming (1fc7e2a605) — it gives ~nothing under parallel (which warms itself) and complicates shared-context lifetimes.

Status

  • Mainnet (live node): parallel & streaming cross the historically-failing blocks — 25320897 (prior deterministic wrong root) and 25346499 (prior mmap fault) — with no state-root divergence and no crash; validation ongoing toward tip.
  • Parity: streaming root + stored branches match ModeDirect / ModeParallel across multi-depth, incremental storage collapse (partial + full delete), and whale corpora; -race -count clean.
  • make lint clean; make erigon integration builds.

Perf (1M-whale benchmark, 18 cores)

engine time/op vs sequential
sequential (ModeDirect) 1.465 s 1.0×
parallel 0.410 s 3.6×
streaming 0.420 s 3.5×

Known follow-ups

  • Correct deep storage-interior split (depth > 64); current flat 16-way per-nibble fold already recovers the win.
  • Fold is sync-bound (goroutine coordination), not compute-bound — optimization opportunity.
  • Re-evaluate whether the fold-scoped pin is still needed now that copy-on-put owns the mem-batch bytes; and whether State Cache Consolidation (PR #1 of the perf stack) #21380's BranchCache can be made parallel-safe rather than gated.
  • copy-on-put adds one alloc per DomainPut on the exec hot path (bounded; same order as what the state/branch caches already pay).

awskii added 30 commits May 16, 2026 19:41
Plan for parallelizing hph.Process via a new ParallelPatriciaHashed
sibling type. Builds on the existing depth-1 ConcurrentPatriciaHashed
PoC and pushes split-points to arbitrary depths using a path-compressed
prefix trie built during TouchPlainKey, a maphash.NonConcurrentMap of
split-points consulted at fold time, and a last-finisher-continues
barrier protocol over atomic.Int32 arrival counters.
First building block for ParallelPatriciaHashed. The trie tracks touched
hashed keys during TouchPlainKey and exposes a subtreeCount on every node
so the future Prepare pass can identify split-point candidates in O(1).
Introduces the per-batch data carrier that drives parallel commitment.
parallelUpdate wraps the prefix trie from the prior commit and adds a
NonConcurrentMap of split-points, a leaf-task queue, and a mutex-guarded
deferred-update slice. splitPoint holds the per-prefix barrier state
(atomic arrival counter + 16-cell deposit grid laid out to match
DeferredBranchUpdate.cells). leafTask carries the work-unit metadata.

newParallelUpdate / Insert / Reset / Close / appendDeferred are wired up;
Prepare and the worker fold-time barrier follow in later tasks.

Race-detector tests cover construction, Insert delegation, full Reset
state-clear, appendDeferred under 16-way concurrent contention, and
splitPoint.arrived correctness.
Implements the freeze-time DFS that partitions touched-key prefix trie
into split-points (fanout >= 2 && subtree >= 32 keys) and leaf-tasks for
the parallel commitment worker pool. For each split-point, fetches the
on-disk branch via ctx.Branch and pre-populates sp.cells for untouched
nibble siblings so the last-finisher fold produces a correct branch hash.

leafQueue is sorted by keyCount descending for better worker utilisation.
Add the ModeParallel mode constant and integrate the parallelUpdate
prefix-trie state into the Updates struct lifecycle. TouchPlainKey,
TouchPlainKeyDirect, and TouchHashedKey route through the per-nibble
ETL collectors and into the parallel trie; NewUpdates/SetMode/Reset/
Close/Size handle the new mode symmetrically. IsConcurrentCommitment
now returns true for either ModeParallel or legacy sortPerNibble so
the ConcurrentPatriciaHashed PoC stays functional.
Introduce ParallelPatriciaHashed: a configuration-and-lifecycle wrapper
around a template HexPatriciaHashed plus a worker sync.Pool. The
skeleton implements Reset, Release, ResetContext, SetTrace,
SetTraceDomain, EnableWarmupCache, GetCapture, SetCapture,
EnableCsvMetrics, RootTrie, Variant, and a RootHash that publishes the
last-finisher's atomic value (falling back to the template for the
no-updates path).

Adds VariantParallelHexPatricia and a "parallel" key in
ParseTrieVariant. Process and the worker fold-time barrier are added in
Tasks 6 and 7.
Task 6: orchestration without the worker fold-time barrier. Adds
ParallelPatriciaHashed.Process, the per-nibble ETL dispatcher, the
warmupSplitAncestors helper, and the assertEquivalentRoot test helper
that drives both ModeDirect and ModeParallel through the same update
set and asserts byte-equal roots.

The barrier protocol (Task 7) is required to merge multiple worker
roots; Process explicitly rejects multi-leafTask-per-nibble inputs
until then.
…atriciaHashed

Workers under a shared split-point now converge via cellEncodeData deposits
into sp.cells with sp.arrived atomic coordination. The last-finisher
rebuilds the split-point's grid row from every deposit and folds upward,
either depositing again at a further-enclosing split-point or — at the
topmost — publishing the root hash via p.rootHash CAS.

Design diverges from the original plan in two places, both documented in
docs/plans/20260516-parallel-hph.md:
- the per-fold-step splitMap query doesn't fire reliably on empty-DB tries
  whose row depths don't match split-point depths, so the loop folds fully
  first and then walks the enclosing-split-point chain via the leafTask's
  prefix
- sp.arrived initialises to fanout (not fanout-1) so the truly-last Add(-1)
  returns 0, eliminating the race where fanout=2 left both workers as
  last-finishers
Add a ModeParallel arm to verify_test.go that drives random update
batches through sequential HexPatriciaHashed (ModeDirect) and
ParallelPatriciaHashed (ModeParallel) and asserts byte-equal root
hashes. The cardinal correctness rule: same-root-as-sequential.

Covers five batch shapes: accounts-only, storage-heavy single account,
storage spread across accounts, mix of inserts and deletes, and empty
batches. TestVerifyParallel_AllShapes runs one of each as a subtest;
TestVerifyParallel_RandomBatches sweeps 1100 randomized batches across
shapes; FuzzParallelEquivalence exposes the harness to go test -fuzz.

The harness exposed an indexing bug in depositRootIntoSplitPoint when a
leafTask covers a single account's deep storage subtree: fold produces
a cell whose extLen exceeds the 64-byte extension array, panicking on
slice. Documented as a Task 9 follow-up; the affected shape is gated
behind shapeRequiresStorageDeepBarrierFix and t.Skip'd until fixed.
Task 9 of the parallel HPH plan: nine end-to-end edge-case tests
covering deletions, bloatnet shape, single-account-many-storage, empty
batches, single-touched-key, mixed account/storage, and same-account
multi-field updates. All run through the cardinal-correctness
assertEquivalentRoot helper.

Three underlying barrier-protocol gaps surfaced and were fixed:

- foldDrainWithBarrier: in multi-phase scenarios the worker's
  followAndUpdate unfolds the shared root branch from DB into its row
  stack; folding past the split-point's child depth then absorbs that
  shared branch into the worker's deposit, overwriting siblings via
  deferred updates. Identify the first enclosing split-point up front,
  stop folding while depths[deepest] > len(sp.prefix)+1, and deposit
  grid[deepest][childNibble] directly when a row remains at deposit
  depth. Fresh-DB workers (every existing test) still collapse to
  activeRows==0 and use the original hph.root path.

- Prepare: a split-point at a node where a key terminates (e.g. an
  account at depth 64 alongside its storage subtree) silently drops the
  terminating key — splitPoint.cells has no terminator slot. Detect via
  subtreeCount > sum(child.subtreeCount) and collapse the subtree to a
  single leafTask instead.

- depositRootIntoSplitPoint: hph.root.extLen can exceed 64 when the
  worker folds a deep storage subtree (cell.extension is [64]byte and
  fold silently truncates). Snapshot currentKey + depths[0] before the
  final row-0 fold; on overflow, reconstruct the trimmed extension from
  the snapshot and skip computeCellHash (the cell's hash is already the
  branch hash from foldBranch's keccak2.Read).

These fixes unblock the fuzz harness's shapeStorageHeavySingle, which
is re-enabled in TestVerifyParallel_RandomBatches and FuzzParallelEquivalence.
…l-commitment

Adds a runtime feature flag (default off) that routes NewSharedDomains to
construct a ParallelPatriciaHashed trie + ModeParallel Updates buffer.

InitializeTrieAndUpdates forces ModeParallel for VariantParallelHexPatricia
so the Updates buffer always allocates parallelUpdate state Prepare reads.

commitmentdb/commitment_context.go gains a switch arm for the parallel trie:
each Process spins up a concurrent TrieContextFactory (per-worker collectors)
and injects it via SetTrieContextFactory. LatestCommitmentState/encode/restore
state paths now also accept VariantParallelHexPatricia via RootTrie().

Integration tests in db/state/execctx/parallel_commitment_flag_test.go cover
both flag positions and assert root-hash equivalence between the sequential
and parallel paths on a basic commit.
ParallelPatriciaHashed workers concurrently access PatriciaContext.Branch
and PutBranch via the deferred-update path. MockState guards its
branchData/accountData/storageData maps with a mutex only when
SetConcurrentCommitment(true) is set, but the new parallel helpers
omitted the toggle, so `go test -race ./execution/commitment/...`
flagged map races on every multi-worker test. Production callers use
the commitmentdb context which is naturally serialized; this is purely
a test-side fix.

Closes Task 11 (acceptance verification) in
docs/plans/20260516-parallel-hph.md.
Adds execution/commitment/agents.md describing the three trie variants
(HexPatriciaHashed, ConcurrentPatriciaHashed, ParallelPatriciaHashed),
when to use ModeParallel, and the --experimental.parallel-commitment CLI
flag. Moves the completed parallel-hph plan into docs/plans/completed/.
- Drop unused produceCellForBarrier and its test; barrier deposits use
  depositRootIntoSplitPoint / depositGridCellIntoSplitPoint.
- Remove workerSlot.used field (write-only, never read).
- Document --experimental.parallel-commitment in the gitbook reference
  and note its precedence over --experimental.concurrent-commitment.
ParallelPatriciaHashed was returning workers to its pool via hph.Reset(),
which only clears root state — activeRows, depths, branchBefore, touchMap,
afterMap, currentKey, and the warmup cache all survived. Across Process
calls without an explicit ParallelPatriciaHashed.Reset(), a recycled worker
would start its next followAndUpdate with stale grid state. Switch to
resetForReuse() at all three pool-return sites (cleanupAll, the per-task
Get, and foldDrainWithBarrier's defer).

The warmuper was started but its cache pointer was never propagated to the
workers — workers inherited trace/traceDomain/enableWarmupCache only and
re-read every branch from the DB. Expose warmuper.Cache() on the template
when EnableWarmupCache is set, and have each worker pick it up alongside
its branchEncoder before runNibbleBucket dispatches keys.
Fail loudly when ParallelPatriciaHashed is combined with deferred
commitment updates (fork validation + parallel block apply paths).
Previously the parallel trie applied worker-accumulated deferred branch
updates inline at the end of Process, bypassing the deferred-flush
mechanism and silently breaking per-block changeset attribution.
- commitmentdb: handle *ParallelPatriciaHashed in trace state capture so
  trie-trace recordings include the pre-Process internal state for replay
  instead of starting from empty.
- db/state/squeeze: rebuildCommitmentShard selects VariantParallelHexPatricia
  and enables ParaTrieDB when ExperimentalParallelCommitment is set, mirroring
  the concurrent path so the flag is honored during snapshot rebuild.
- commitment: clear pu.deferredCombined and pendingRoot on the errgroup-wait
  failure path so a retry on the same Updates buffer cannot re-apply stale
  worker deferred branches or surface a never-persisted root via RootHash().
- commitment: thread logPrefix into Process error wrapping so staged-sync
  callers can correlate parallel-commitment failures with stage logs.
New benchmark file `parallel_patricia_hashed_bench_test.go` defines two
deterministic corpus builders (100K accounts-only, 500K storage-heavy),
two bench helpers that bracket measured Process() with StopTimer/StartTimer,
and a top-level `Benchmark_Commitment_DirectVsParallel` driver that
sub-benches by corpus and worker count. Smoke run + lint deferred to Task 2.
Smoke-run executed successfully on Apple M2 Max:
- All 10 sub-benches passed with non-zero ns/op
- Package tests pass (go test ./execution/commitment/...)
- make lint clean (2 runs)
Append measured ratios from Benchmark_Commitment_DirectVsParallel
to execution/commitment/agents.md (Apple M2 Max, Go 1.25.7):
500K-StorageHeavy peaks at ~2x with 4 workers and plateaus;
100K-AccountsOnly does not benefit from ModeParallel.
…Timer

- add b.ReportAllocs() to both bench helpers so B/op and allocs/op are
  visible; convention across other benches in this package.
- drop b.ResetTimer() from the outer per-corpus b.Run dispatchers; they
  don't time anything themselves (the inner sub-benches manage their own
  timers via b.Loop()), so the calls were no-ops.
Benchmark sweep across {8, 32, 64, 128, 256} shows m64 strictly dominates
the previous default (32):

  100K-AccountsOnly @ NumCPU=8:  m32 1.06x -> m64 1.46x faster than Direct
  500K-StorageHeavy @ NumCPU=8:  m32 1.96x -> m64 1.92x (within noise)
  100K-AccountsOnly memory @w12: 5.87 GB -> 3.07 GB (48% less)

m32 was leaving meaningful headroom on flat workloads by emitting too
many fine-grained split-points; barrier coordination overhead exceeded
the parallelism gain. m64 produces fewer, larger leafTasks so per-worker
setup cost amortizes over more useful work. Storage-heavy workloads are
unaffected because storage hash distribution produces a small fixed
number of useful splits per account regardless of threshold.

Tests that hardcoded the previous 32-key threshold are updated to scale
from MinSplitKeys (matching the pattern already used by
TestParallelBarrier_ChainedSplitPoints).
The bench was creating a fresh *ParallelPatriciaHashed per loop iteration
and calling Release() at the end. Release() calls resetPool() which
drops the entire sync.Pool of HexPatriciaHashed workers. The pool that
takes ~1000 hph allocations to fill (16 buckets × ~62 tasks each,
running 8 in parallel under NumCPU=8) was being thrown away every
iteration, so iter 2-10 paid the same allocation cost as iter 1.

Production usage is one long-lived *ParallelPatriciaHashed servicing
many blocks — the pool stays warm. The bench should mirror that.

After this change, on 500K-StorageHeavy/w8: alloc bytes drop 59% (859MB
-> 354MB), time improves ~4%. On 100K-AccountsOnly the wins are larger:
w8 alloc bytes -64% and time -7%, w12 alloc -65% and time -14%. The
storage-heavy time floor is dominated by something else (CPU profile
points at runtime.usleep / scheduler thrashing — separate concern,
noted in agents.md).
Resolve conflicts after main's TrieConfig-threading + SharedDomains options refactor:
- domain_shared.go: fold ExperimentalParallelCommitment precedence into PickTrieVariant (keep main's options-pattern NewSharedDomains)
- commitment_context.go: keep main's warmupBase template; re-add ParallelPatriciaHashed warmup case
- adapt NewHexPatriciaHashed / NewParallelPatriciaHashed call sites to the new TrieConfig parameter
- InitializeTrieAndUpdates(mode, tmpdir, cfg) signature; branchEncoder.setDeferUpdates now unexported
- drop generated docs/gitbook README (removed on main); flag stays self-documenting via its Usage string
Replace "Task N" plan references in parallel-hph doc comments and a runtime
error string with descriptions of the actual behavior, per the repo
comment-style guidance.

Delete the empty, skipped TestParallelProcessSkeleton_MultipleNibblesNoSplit:
a leftover skeleton whose multi-bucket-no-split rejection is already covered by
TestParallelBarrier_ProcessRejectsMultiBucketWithoutSplit.
@awskii

awskii commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

branch now broken after recent merge from main or after simplification effort.

awskii added 3 commits June 18, 2026 13:37
- adopt #21380 aggregator-scope BranchCache; drop per-trie WarmupCache plumbing
  (warmup_cache.go + obsolete tests removed; Warmuper page-cache prefetch kept)
- adopt main's GenerateWitness(produceExclusionProofs) signature + witness tests
- drop removed VariantBinPatriciaTrie; keep parallel/streaming trie variants
…ent-read SIGSEGV)

Hold one BeginTemporalRo on paraTrieDB for the whole parallel/concurrent fold so a
background merge cannot reclaim+munmap a .kv that an in-flight worker's TrieContext.Branch
read still aliases. common.Copy at the Branch boundary stays (#21630).
The aggregator-scope BranchCache (#21380) is shared across the parallel commitment
workers' patriciaContexts and caches values aliasing freed .kv mmap; the mem-batch
flush (SharedDomains.Commit memmove) then faults reading an unmapped region. Gate
its creation off when parallel/streaming commitment is active. The fold-scoped
file-view pin handles the fold-read path separately.
@awskii

awskii commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

Parallel-commitment crash root cause (validated on mainnet)

Correction of the earlier version of this comment. Validating --experimental.parallel-commitment against a mainnet datadir (~block 25320897) surfaced two .kv mmap use-after-munmap SIGSEGVs — a fold-read fault (TrieContext.Branch in the parallel mount-fold workers) and a flush fault (SharedDomains.CommitTemporalMemBatch memmove). Both have the same root cause, and a single fix covers both.

Root cause. The shared mem-batch (TemporalMemBatch / sd.mem) stored values that alias a CommitmentDomain .kv mmap. A background merge munmaps that file while a concurrent commitment worker still reads sd.mem — the fold-read path reads it via Branch, the flush via memmove. Same dangling mmap, two readers.

Fix 8196bac851 — copy the value on insert in TemporalMemBatch.putLatest (common.Copy). The batch owns its bytes while the source mmap is still mapped, so nothing downstream can alias a file that later gets reclaimed. Single choke point for every DomainPut/DomainDel, so it closes both faults at once. Cost is ~1 GB cumulative alloc over a multi-hour run (≈1% of total) — negligible.

Two earlier partial mitigations, both superseded by the fix above:

  • Fold-scoped file-view pin (6fadc5d9aa): held one BeginTemporalRo across the whole parallel fold. Dropped in dba2efc852 — redundant once the bytes are owned. No-pin run validated clean (2h52m, 0 SIGSEGV, 0 wrong root).
  • BranchCache (State Cache Consolidation (PR #1 of the perf stack) #21380) disabled under parallel/streaming (1fc7e2a605): the cache was suspected of the flush fault, but it only shifted timing — it was never the root cause. Reverted in 7c2dcdf72. With copy-on-put the cache is safe under parallel, so there is now a single state cache gated only by USE_STATE_CACHE — same path for sequential / parallel / streaming, no commitment-mode special-casing.

Validation. Copy-on-put crosses mainnet block 25320897 and runs on past 25.35M with 0 SIGSEGV and 0 wrong root, now with the BranchCache enabled under --experimental.parallel-commitment. The awskii/parallel_hph_dfs correctness baseline carries no BranchCache (unmerged) and is consistent — the cache was never the cause.

awskii added 4 commits June 19, 2026 08:49
…se-after-munmap)

TemporalMemBatch.putLatest stored the caller's val slice without copying. Under
parallel commitment, val can alias a .kv mmap of the foreground exec tx's file
generation; sd.mem is read first by every worker's TrieContext (shared SharedDomains),
so a concurrent worker (or the commitment flush) reads that pointer while a background
merge munmaps the generation -> SIGSEGV in TrieContext.Branch / SharedDomains.Commit.
Copy at put time (mmap still mapped) so every later reader gets heap-owned bytes.
Copy-on-get under latestStateLock could not fix this (the source was already freed).
Copy-on-put (mem-batch owns its bytes) is the actual fix for the parallel-commitment
mmap use-after-munmap; the umbrella file-view pin only covered the fold-start generation
and was already proven insufficient (crash recurred with it). Worker file reads are
covered by each worker's own roTx. Removing the pin; verified on the mainnet repro.
@awskii

awskii commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

race-tests execution-other failure is a pre-existing data race in main (#21075), not this PR.

PresetNonChainTipConcurrencysetCompressWorkers/setBuildAccessorsWorkers write d.CompressCfg.Workers / d.BuildAccessorsWorkers under workersCfg.trySet's lock, while a background mergeFiles reads the same fields unlocked (merge.go:423, domain.go:1079). Write-locked, read-unlocked.

This PR's net diff to all involved files (aggregator.go, aggregator2.go, merge.go, domain.go, exec3.go) is empty — the race code is entirely main's. The failing test (TestHistoryVerification_SimpleBlocks) uses neither parallel/streaming commitment nor the branch cache, so the last commit can't have caused it. Re-ran the job; will flag upstream.

@awskii
awskii marked this pull request as ready for review June 19, 2026 09:48
ParallelPatriciaHashed.Process (non-streaming) now calls flushTrieStateRates(),
matching the sequential and streaming paths. The load/skip atomics are bumped by
the worker fold/unfold hot path but were never published on a pure-parallel node,
so trie_state_load_rate / trie_state_skip_rate stalled.

Also correct the subtreeCount doc (it counts distinct keys; re-inserting an
existing key merges without bumping) and fix a "seralized" test-message typo.

Addresses Copilot review nits on #21709.

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

Copilot reviewed 61 out of 61 changed files in this pull request and generated 2 comments.

// trie root and a concurrent-read SIGSEGV on mainnet block 25142734. The
// top-level per-account-nibble mount fold stays parallel; only the second-tier
// storage split is off until its correctness + file-view pinning is fixed.
var deepStorageFold = true
Comment on lines +1785 to +1794
case ModeParallel:
if len(hashedKey) == 0 {
return
}
dedupKey := string(hashedKey)
if _, ok := t.keys[dedupKey]; !ok {
// Hashed-only touch has no plainKey; the parallel fold rejects such a terminator.
t.parallel.Insert(hashedKey, nil, nil)
t.keys[dedupKey] = struct{}{}
}
@AskAlexSharov
AskAlexSharov added this pull request to the merge queue Jun 21, 2026
Merged via the queue into main with commit b521c4e Jun 21, 2026
94 checks passed
@AskAlexSharov
AskAlexSharov deleted the awskii/parallel_prepare_fold branch June 21, 2026 10:42
AskAlexSharov added a commit that referenced this pull request Jul 1, 2026
…-fold fix #21945) (#22129)

Refreshes `bal-devnet-7_warmup` onto `bal-devnet-7`, pulling in the
parallel deep-storage-fold trie-root fix #21945 (and its feature line
#21709, #21941).

### `sstore_bloated` MGas/s

| variant | base (par-kvi, BAL) | ethrex | now (+#21945) |
|---|--:|--:|--:|
| `sstore_bloated` (F) — new slots | 92 | 461 | 399 |
| `sstore_bloated` (T) — existing slots | 7 | 82 | 30 |

### Notes

Rendered as a merge, so review the conflict resolutions rather than the
upstream commits:

- `commitment_convert.go` / `_blackbox_test.go`: took bal-devnet-7's
merged form (#21933) over the pre-merge draft.
- `db/seg/decompress.go`: comment-only, took bal-devnet-7 (#21927).
- `rawdbreset/reset_stages.go`: combined out-of-tx `ClearTables` with
bal-devnet-7's branchCache invalidation.
- `stage_execute.go`: kept warmup's `PruneExecutionStage` (`haveMore`
signature, required by callers). bal-devnet-7's #20860 prune-timeout
budget-sharing is **not** carried into this function.
- `cmd/integration/commands/stages.go`: took bal-devnet-7's `stageExec`
(drops the removed `--no-commit` flag), adapted its prune calls to the
`haveMore` signature.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: lystopad <oleksandr.lystopad@erigon.tech>
Co-authored-by: kewei <kewei.train@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com>
Co-authored-by: Alex Sharov <AskAlexSharov@gmail.com>
Co-authored-by: lupin012 <58134934+lupin012@users.noreply.github.com>
Co-authored-by: Mark Holt <135143369+mh0lt@users.noreply.github.com>
Co-authored-by: Mark Holt <erigon@dev-bm-e3-ethmainnet-n4.erigon.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: awskii <awskii@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: erigon-copilot[bot] <265817861+erigon-copilot[bot]@users.noreply.github.com>
Co-authored-by: erigon-copilot[bot] <erigon-copilot[bot]@users.noreply.github.com>
Co-authored-by: Giulio Rebuffo <giulio.rebuffo@gmail.com>
Co-authored-by: Ilya Mikheev <54912776+JkLondon@users.noreply.github.com>
Co-authored-by: JkLondon <me@ilyamikheev.com>
Co-authored-by: bloxster <bloxster@proton.me>
Co-authored-by: Bloxster <gianni.morselli@erigon.tech>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: yperbasis <andrey.ashikhmin@gmail.com>
Co-authored-by: noop <noop@noop>
Co-authored-by: Sudeep Kumar <sudeep.kumar@erigon.tech>
Co-authored-by: bloxster <bloxster@users.noreply.github.com>
Co-authored-by: info@weblogix.biz <admin@10gbps.weblogix.it>
Co-authored-by: Sahil Sojitra <88416181+Sahil-4555@users.noreply.github.com>
Co-authored-by: awskii <artem.tsskiy@gmail.com>
Co-authored-by: Michelangelo Riccobene <michelangelo.riccobene@gmail.com>
Co-authored-by: Matt Joiner <anacrolix@gmail.com>
Co-authored-by: milen <94537774+taratorio@users.noreply.github.com>
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