perf(reth): stream authenticated MPT chunks to avoid guest OOM - #45
Merged
Conversation
hero78119
force-pushed
the
feat/resolve_oom
branch
from
July 25, 2026 06:51
fa9cc34 to
fc536cc
Compare
hero78119
force-pushed
the
feat/resolve_oom
branch
from
July 25, 2026 06:56
fc536cc to
453929c
Compare
# Conflicts: # crates/executor/client/src/io.rs # crates/executor/client/src/lib.rs # crates/host-bench/src/lib.rs
hero78119
added a commit
that referenced
this pull request
Jul 27, 2026
… setup phase (#43) * exp preflight * Update Ceno preflight AOT lock * update dep * update dep * update dep * modify default max cell value * update dep * refresh max cell * update ceno dep * remove unused env * exp fused sumcheck kernel * upgrade ceno gpu dep * health check for gpu temp offline * update dep * update cell per shard * add missing parallel feature and aot * add cc for preflight * align ci paramter for ethproofs job * move aot compilation to setup time * fix aot sdk prep mutability warning * fix clippy warning * update ceno and verify feat/bug_fix * fix: move aot outside of reth-block * add s3 block input download path * sync up master and main branch * s3 in https * s3 in https * update ceno branch to master * chore: fix ci error * fix pr ci stack * perf(reth): stream authenticated MPT chunks to avoid guest OOM (#45) * resolve oom * update ceno batched main shard costing * chore: default adaptive shard cap to 5B * Revert "chore: default adaptive shard cap to 5B" This reverts commit a33faa6. * chore: default adaptive shard cap to 4.5B * Revert "chore: default adaptive shard cap to 4.5B" This reverts commit ba89e94. * bench: add execute-mode cycle histograms * update ceno for opt cycle trial * ci: use remote ceno dependencies * executor: avoid rehashing unchanged storage tries * perf: upgrade revm and preallocate execution state * fix: use remote ceno guest dependencies in CI * fix: include executor trim configuration module * ci: pin CUDA architecture for GPU runner * perf: stream authenticated MPT state chunks * update default cell * update ceno dep * chores: remove and clean up debug * perf: allocate streaming state arena lazily
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.
Problem
Large Reth blocks can exhaust the zkVM guest heap during post-execution state-root computation. The previous input format kept the full authenticated state trie, updated storage tries, and post-update witnesses live in one long-lived arena. This makes peak memory scale with the complete modified state and prevents larger shard caps from being used reliably on a 24 GB prover GPU.
Design Rationale
The state update is partitioned at authenticated MPT boundaries instead of weakening state validation or retaining the full mutable trie.
The host records modified accounts and storage-slot counts, then builds a weighted digest frontier around only the affected subtrees. Frontier boundaries are limited by node count, encoded bytes, and update weight. Each extracted subtree carries its absolute nibble prefix and expected root; inline child references conservatively remain in their hash-addressed parent because they cannot be represented safely by a digest-only frontier slot.
The guest authenticates each chunk against the parent frontier, verifies that account and storage witnesses belong to that chunk, applies the sorted bundle updates, rejects duplicate or unused witnesses, and replaces the frontier slot with the updated digest. Each chunk and its storage tries use a short-lived arena and are dropped before the next chunk is decoded. The final block state root is still checked through the existing execution path, so memory lifetime changes without changing the state transition being proven.
REVM state maps receive bounded capacity hints to reduce repeated guest allocations. The bounds remain growth hints rather than correctness limits. The Reth/REVM upgrade is handled through the narrow
CapacityBlockExecutorseam so the upstream execution order, post-execution validation, bundle retention, and block-access-list handling remain explicit.The trade-off is a versioned host/guest witness format and additional host-side frontier construction. This is preferred to global preallocation or an unauthenticated streaming format because chunk memory is bounded while every replacement remains tied to the parent state root.
Change Highlights
crates/mpt: adds weighted frontier construction, nibble-key subtree operations, authenticated frontier replacement, and coverage for multi-chunk, empty-slot, and wrong-digest cases.crates/executor/client: introduces witness format version 2, streams post-state updates by authenticated chunk, allocates chunk/state arenas lazily, and preallocates bounded REVM state maps.crates/host-bench: emits the digest frontier and ordered chunk witnesses; adds native execution and ShardRAM-analysis paths for cycle and memory diagnosis.gkr-backendto v1.0.0-alpha.35.CENO_MAX_CELL_PER_SHARD=4500000000and keeps the value externally overridable.Benchmark / Performance Impact
The primary result is successful proof generation for blocks that exercised the previous OOM path. Blocks 23817600, 25580200, 25586000, and 25586200 completed on a 24 GB RTX 4090 with the 4.5B default shard cap.
The timing comparison below is default-to-default rather than an isolated implementation microbenchmark: the base used
CENO_MAX_CELL_PER_SHARD=1245708288, while this PR used the new4500000000default. The configuration difference is part of this PR and must be considered when interpreting the result.Operation
total_create_proofLayer
Benchmark command(s):
Environment: self-hosted x64 Linux runner, 24 GB RTX 4090, Rust
nightly-2025-11-20(rustc 1.93.0-nightly). Base commit:a70dd56a; measured PR commit:396c3986.Raw data:
Testing
run-benchmark-v2.ymlparsed successfully and the linked end-to-end runs produced root proofs.Risks and Rollout
Follow-ups (optional)
Copilot Reviewer Directive (keep this section)
When Copilot reviews this PR, apply
.github/copilot-instructions.mdstrictly.