Overview
Permissionless fault proofs are a critical component of the OP Stack's security model. They allow anyone to challenge invalid state proposals, ensuring the correctness of L2 to L1 withdrawals without relying on trusted third parties. To enable this functionality, chain operators must generate and maintain the necessary absolute prestate and preimage files. The absolute prestate is a commitment to the initial state of the fault proof program, and the preimage is the serialized binary representation of this program state. These files are essential for the op-challenger tool to participate in dispute games when challenging invalid claims.
Prerequisites
Before starting, ensure you have:
- Docker (opens in a new tab) running
- Have sufficient disk space and memory
Using the latest absolute prestate and multi-threaded Cannon
As of the latest releases, OP Stack chains should utilize the 64-bit
MIPS multi-threaded version of Cannon.
This upgrade offers several advantages:
- Improved performance through parallelized execution
- Enhanced fault proof VM capabilities
- Support for the latest network upgrades
Beginning with Upgrade 14, all chains should use the 64-bit
multi-threaded version of Cannon.
The absolute prestate files for this version typically have the format prestate-mt64.bin.gz
.
Generating the absolute prestate
Clone and checkout the tagged version
First, clone the Optimism monorepo and check out the appropriate release tag (opens in a new tab) for op-program:
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
# For production chains, use the latest finalized release (not an rc)
git checkout op-program/v1.6.1 # Use the latest stable version
# For testnets and devnets, you might use:
git checkout op-program/v1.6.1-rc.1
git submodule update --init --recursive # Initialize submodules
Generate the absolute prestate
After placing your configuration files in the proper location, run the following command from the root of the monorepo:
make reproducible-prestate
The command will automatically detect and use the configuration files you placed in the op-program/chainconfig/configs
directory.
The output should look like this:
-------------------- Production Prestates --------------------
Cannon64 Absolute prestate hash:
0x03eb07101fbdeaf3f04d9fb76526362c1eea2824e4c6e970bdb19675b72e4fc8
-------------------- Experimental Prestates --------------------
CannonInterop Absolute prestate hash:
0x03fc3b4d091527d53f1ff369ea8ed65e5e17cc7fc98ebf75380238151cdc949c
Cannon64Next Absolute prestate hash:
0x03eb07101fbdeaf3f04d9fb76526362c1eea2824e4c6e970bdb19675b72e4fc8
The output will display production and experimental prestate hashes:
-
Production prestates: Contains the
Cannon64
prestate, which is the current production absolute prestate hash for the 64-bit version of Cannon. This is the hash you should use for permissionless fault proofs. -
Experimental prestates: These contain prestates for versions that are in development and not yet ready for production use.
Prepare the preimage file
After generating the prestate, the preimage file will be located in op-program/bin/prestate-mt64.bin.gz
. The exact name might vary based on the version.
Rename this file to include the prestate hash:
cd op-program/bin
mv prestate-mt64.bin.gz 0x[CANNON64_PRESTATE_HASH].bin.gz
Replace [CANNON64_PRESTATE_HASH]
with the actual Cannon64
absolute prestate hash value from the output.
This file needs to be uploaded to a location that's accessible by your op-challenger instances.
Official prestate hashes for Superchain registry chains
The Superchain registry maintains official absolute prestate hashes for chains that are part of the registry. These prestates include the configurations of chains that were in the Superchain registry at the time the prestate was created.
Important: A prestate listed in the Superchain registry may not be suitable for your chain if:
- Your chain was added to the registry after the prestate was created
- The configuration for your chain has been updated since the prestate was created
Before using a prestate from the registry, verify that it contains the latest configuration for your chain.
When in doubt, generating your own prestate with your specific chain configuration is the safest approach.
You can find the latest prestate tags in the Superchain registry (opens in a new tab).
Handling unannounced chain configurations
If your chain is not included in the Superchain registry, you'll need to generate a custom prestate with your specific chain configuration. This applies to:
- New chains
- Chains with custom configurations
For these cases, follow these additional steps:
Verify the chain configuration directory exists
The directory for custom chain configurations already exists in a valid checkout of the monorepo:
# Verify the directory exists
ls -la op-program/chainconfig/configs
If this directory doesn't exist, you may be using a version of the monorepo that doesn't support custom configs.
Copy your chain configuration files to this directory
First, you need to obtain your chain's configuration files. These are typically generated when you deploy your L2 chain with op-deployer:
- rollup.json: The rollup configuration file
- genesis.json: The L2 genesis file
Name them according to the required format:
# Replace 67865 with your actual chain ID
cp /path/to/rollup.json op-program/chainconfig/configs/67865-rollup.json
cp /path/to/genesis.json op-program/chainconfig/configs/67865-genesis-l2.json
Note: The naming format is critical - the files must be named as:
<L2-chain-id>-rollup.json
<L2-chain-id>-genesis-l2.json
These files are outputs from your L2 chain deployment process using op-deployer.
For long-term preservation and reproducibility, commit these configuration files to a git branch in your own fork of the monorepo.
This ensures you can always rebuild the prestate in the future by checking out that branch and running make reproducible-prestate
, even if your original files are lost.
Generate the prestate
After placing your configuration files in the proper location, run the following command from the root of the monorepo:
make reproducible-prestate
The command will automatically detect and use the configuration files you placed in the op-program/chainconfig/configs
directory.
This should generate output containing three prestate hashes:
-------------------- Production Prestates --------------------
Cannon64 Absolute prestate hash:
0x03eb07101fbdeaf3f04d9fb76526362c1eea2824e4c6e970bdb19675b72e4fc8
-------------------- Experimental Prestates --------------------
CannonInterop Absolute prestate hash:
0x03fc3b4d091527d53f1ff369ea8ed65e5e17cc7fc98ebf75380238151cdc949c
Cannon64Next Absolute prestate hash:
0x03eb07101fbdeaf3f04d9fb76526362c1eea2824e4c6e970bdb19675b72e4fc8
For current production use, you should use the Cannon64
Absolute prestate hash.
Locate and prepare the preimage File
Follow this step
Deploying and configuring with the absolute prestate
After generating the absolute prestate and preimage files, you'll need to:
Upload preimage file
Upload the preimage file to a location accessible by your op-challenger instances
Configure op-challenger
Configure the op-challenger to use the generated prestate. There are two ways to provide prestates:
Option 1: Using HTTP URL (Recommended for production)
If your prestate files are hosted on a web server, you can simply provide the URL to the directory containing those files:
docker run -d --name op-challenger \
-e OP_CHALLENGER_TRACE_TYPE=permissioned,cannon \
-e OP_CHALLENGER_PRESTATES_URL=<HTTP_URL_PATH_TO_PRESTATE> \
-e OP_CHALLENGER_L1_ETH_RPC=<YOUR_L1_RPC_URL> \
-e OP_CHALLENGER_GAME_FACTORY_ADDRESS=<YOUR_DISPUTE_GAME_FACTORY> \
-e OP_CHALLENGER_PRIVATE_KEY=<YOUR_PRIVATE_KEY_OR_USE_WALLET_SIGNER> \
-e OP_CHALLENGER_NETWORK=<YOUR_NETWORK> \
-e OP_CHALLENGER_CANNON_ROLLUP_CONFIG=<PATH_TO_ROLLUP_CONFIG> \
-e OP_CHALLENGER_CANNON_L2_GENESIS=<PATH_TO_GENESIS_CONFIG> \
us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:latest
When using an HTTP URL, no volume mount is required. The challenger will download the prestate files as needed.
Option 2: Using local files
If you have prestate files stored locally, you'll need to mount them as a volume and use the file://
protocol:
docker run -d --name op-challenger \
-e OP_CHALLENGER_TRACE_TYPE=permissioned,cannon \
-e OP_CHALLENGER_PRESTATES_URL=file:///prestates \
-e OP_CHALLENGER_L1_ETH_RPC=<YOUR_L1_RPC_URL> \
-e OP_CHALLENGER_GAME_FACTORY_ADDRESS=<YOUR_DISPUTE_GAME_FACTORY> \
-e OP_CHALLENGER_PRIVATE_KEY=<YOUR_PRIVATE_KEY_OR_USE_WALLET_SIGNER> \
-e OP_CHALLENGER_NETWORK=<YOUR_NETWORK> \
-e OP_CHALLENGER_CANNON_ROLLUP_CONFIG=<PATH_TO_ROLLUP_CONFIG> \
-e OP_CHALLENGER_CANNON_L2_GENESIS=<PATH_TO_GENESIS_CONFIG> \
-v /path/to/local/prestates:/prestates \
us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:latest
When using local files, ensure your prestate files are in the mounted directory and properly named with their hash (e.g., 0x03eb07101fbdeaf3f04d9fb76526362c1eea2824e4c6e970bdb19675b72e4fc8.bin.gz
).
- Ensure you're using the latest op-challenger version, see the release page (opens in a new tab).
- If your chain uses interoperability features, you'll need to add a
depsets.json
file to theop-program/chainconfig/configs
directory. - This file contains dependency set configurations in the same format as the op-supervisor's configs. You can extract this from your existing op-supervisor setup.