Demo of Integrating the MPT from RSP with Reth's ExecutionWitness #17416
+1,319
−2
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.
Let me provide some context to avoid confusion.
Ethereum Block Proving
For proving Ethereum blocks, most zkVM teams are using SuccintLabs's RSP. There is also Risc0 Zeth, but it is not widely adopted.
Both RSP and Zeth are built upon Reth crates, with additional optimizations to make them zkVM-friendly.
However, they both suffer from a long input preparation times - several minutes - due to thousands calls to RPC:
eth_getProof
eth_getStorageAt
Manually building the state and storage tries is just too slow.
Execution Witness
The Reth team introduced a dedicated endpoint:
debug_getExecutionWitness
. It provides all relevant state and storage data in a single RPC request. Fetching the witness is fast for the recent blocks:That is not all! Reth also provides
reth-stateless
crate, which is the state-of-the-art for stateless execution and block validation. Naturally, it usesExecutionWitness
, allowing input preparation time to take only seconds.One might now wonder: why not just replace RSP with
reth-stateless
?Well, there is a trade-off. For block 22830000 and SP1 zkVM, we got:
Input preparation time got reduced almost to zero, but we doubled the proving time.
This difference is understandable - Reth was not designed for zkVM efficiency. Its trie implementation is one of the bottlenecks.
Witness in Action
I currently work at ZkCloud, where I have build a prototype primarily based on
reth-stateless
logic, incorporating MPT/state implementation from RSP.By constructing RSP's trie using
ExecutionWitness
, we drastically reduced total time to proof:At this point I got many questions like: "How did you build this low-latency data fetcher? Can you open source the integration?"
The truth is, there is no custom data fetcher. Fetching the
ExecutionWitness
is simply a call to Reth node.So for everyone interested: this PR open-sources the integration of RSP's state with ExecutionWitness format.
Updating RSP / RPC
I imagine most people just want to plug updated RSP code and run it. While I am not using the original RSP, you should be able to adapt your code with minimal effort. Essentially,
SP1ZkvmTrie
replaces RSP’sEthereumState
.Also, you will need to run your own Reth node that exposes the execution witness endpoint. Public RPC providers will not work here.
Upstreaming Changes to Reth
By using RSP-style trie, instead of default
SparseStateTrie
:It helped to reduce ~60M cycles when executing block 22830000.
However, I do not plan to polish this PR for merging, since I am now experimenting with replacing RSP's MPT with Zeth's version (see
risc0-ethereum-trie
), or even writing custom implementation.@kevaundray Currently,
reth-stateless
validation takesExecutionWitness
and builds the tries from it , which is not optimal for zkVM use. It would be great to have an API that builds a serializable NotValidatedTrie, which can then be deserialized and validated separately usingreth-stateless
.