A minimal implementation of generating zero-knowledge proofs of EVM block execution using Reth. Supports both Ethereum and OP Stack.
Caution
This repository is still an active work-in-progress and is not audited or meant for production usage.
To use RSP, you must first have Rust installed and SP1 installed to build the client programs. Then follow the instructions below.
In the root directory of this repository, run:
cargo install --locked --path bin/host
and the command rsp
will be installed.
RSP fetches block and state data from a JSON-RPC node. It's recommended that you use a RPC node that supports the debug_dbGet
endpoint.
This is recommended because in some cases the host needs to recover the preimage of a Merkle Patricia Trie node that's referenced by hash. To do this, the host utilizes the debug_dbGet
endpoint of a Geth node running with options --state.scheme=hash
, which is the default, and --gcmode=archive
. An example command for running the node is:
geth \
--gcmode=archive \
--http \
--http.api=eth,debug
However, in the absence of the debug_dbGet
method, the host is able to fall back to a less efficient process of recovering the preimages via the standard eth_getProof
. The fallback works in most cases but not all, so if you encounter a preimage recovery failure, you can reach out to the Succinct team to access an RPC URL that supports debug_dbGet
.
Tip
Don't have access to such a node but still want to try out RSP? Use rsp-tests
to get quickly set up with an offline cache built for selected blocks.
The host CLI automatically identifies the underlying chain type using the RPC (with the eth_chainId
call). Simply suppply a block number and an RPC URL:
rsp --block-number 18884864 --rpc-url <RPC>
which outputs logs similar to:
2024-07-15T00:49:03.857638Z INFO rsp_host_executor: fetching the current block and the previous block
2024-07-15T00:49:04.547738Z INFO rsp_host_executor: setting up the spec for the block executor
2024-07-15T00:49:04.551198Z INFO rsp_host_executor: setting up the database for the block executor
2024-07-15T00:49:04.551268Z INFO rsp_host_executor: executing the block and with rpc db: block_number=18884864, transaction_count=30
2024-07-15T00:50:51.526624Z INFO rsp_host_executor: verifying the state root
...
The host CLI executes the block while fetching additional data necessary for offline execution. The same execution and verification logic is then run inside the zkVM. No actual proof is generated from this command, but it will print out a detailed execution report and statistics on the # of cycles to a CSV file (can be specified by the --report-path
argument).
You can also run the CLI directly by running the following command:
cargo run --bin rsp --release -- --block-number 18884864 --rpc-url <RPC>
or by providing the RPC URL in the .env
file (or otherwise setting the relevant env vars) and specifying the chain id in the CLI command like this:
cargo run --bin rsp --release -- --block-number 18884864 --chain-id <chain-id>
The client input (witness) generated by executing against RPC can be cached to speed up iteration of the client program by supplying the --cache-dir
option:
cargo run --bin rsp --release -- --block-number 18884864 --chain-id <chain-id> --cache-dir /path/to/cache
Note that even when utilizing a cached input, the host still needs access to the chain ID to identify the network type, either through --rpc-url
or --chain-id
. To run the host completely offline, use --chain-id
for this.
End-to-end integration tests are available. To run these tests, utilize the .env
file (see example) or manually set these environment variables:
export RPC_1="YOUR_ETHEREUM_MAINNET_RPC_URL"
export RPC_10="YOUR_OP_MAINNET_RPC_URL"
export RPC_59144="YOUR_LINEA_MAINNET_RPC_URL"
Note that these JSON-RPC nodes must fulfill the RPC node requirement.
Then execute:
RUST_LOG=info cargo test -p rsp-host-executor --release e2e -- --nocapture
If you want to actually generate proofs, you can run the CLI using the --prove
argument, like this:
cargo run --bin rsp --release -- --block-number 18884864 --chain-id <chain-id> --prove
This will generate proofs locally on your machine. Given how large these programs are, it might take a while for the proof to generate.
Run with prover network
If you want to run proofs using Succinct's prover network, follow the sign-up instructions, and run the command with the following environment variables prefixed:
SP1_PROVER=network SP1_PRIVATE_KEY=
To specify a custom prover network RPC, you can use the PROVER_NETWORK_RPC
environment variable.
Run with GPU
To generate proofs locally on a GPU, you can enable the cuda
feature in the CLI, which will enable it in the SDK. Make sure to read the instructions here to make sure you have all required dependencies installed. You can run it with a command like this:
cargo run --bin rsp --release --features cuda -- --block-number 18884864 --chain-id <chain-id> --prove
Building the client programs manually
By default, the build.rs
in the bin/host
crate will rebuild the client programs every time they are modified. To manually build the client programs, you can run these commands (ake sure you have the SP1 toolchain installed):
cd ./bin/client-eth
cargo prove build --ignore-rust-version
To build the Optimism client ELF program:
cd ./bin/client-op
cargo prove build --ignore-rust-version
What are good testing blocks
A good small block to test on for Ethereum mainnet is: 20526624
.