Skip to content

Migrating to permissionless fault proofs on OP Stack #1539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
64bdd4e
initial commit
krofax Mar 27, 2025
08f54cf
fix lint issues
krofax Mar 27, 2025
afce829
fix headers
krofax Mar 27, 2025
8f433da
Auto-fix: Update breadcrumbs, spelling dictionary and other automated…
krofax Mar 27, 2025
5359d94
Mentioned OPCM and prestates
krofax Mar 27, 2025
6bd9fd8
moved to the right section
krofax Mar 27, 2025
70816d5
updated the paths
krofax Mar 27, 2025
8911fef
fix broken link
krofax Mar 27, 2025
3579aee
added breadcrumb nav
krofax Mar 27, 2025
87c2fd2
updated statements
krofax Mar 27, 2025
973b544
update text
krofax Mar 27, 2025
d7162f8
Add new line
krofax Mar 27, 2025
ebc1293
update steps
krofax Mar 27, 2025
6e89dab
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
f8022ba
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
e8d4ef8
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
328fa67
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
23bc0c9
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
9990668
updated the contents
krofax Apr 2, 2025
9180872
pull suggested commits
krofax Apr 2, 2025
7c58e9e
Auto-fix: Update breadcrumbs, spelling dictionary and other automated…
krofax Apr 2, 2025
62a7b8c
remove boilerplate codes
krofax Apr 2, 2025
4c959c7
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
b76bd6c
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
cd25921
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
3849a38
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
dffe511
updated content
krofax Apr 2, 2025
7147bed
pull suggestions
krofax Apr 2, 2025
b374f73
Auto-fix: Update breadcrumbs, spelling dictionary and other automated…
krofax Apr 2, 2025
8fedf6a
add some todos
krofax Apr 2, 2025
685bc04
remove boilerplate code
krofax Apr 2, 2025
b8cdec4
updated the content
krofax Apr 2, 2025
9ca4334
update content
krofax Apr 2, 2025
e60f450
moved a content up
krofax Apr 2, 2025
696e64d
updated the prestate config
krofax Apr 2, 2025
1bb7e4f
add instruction ti use docker
krofax Apr 2, 2025
0517668
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 2, 2025
c750657
remove todo
krofax Apr 2, 2025
bd6e0d8
remove typo
krofax Apr 2, 2025
b44af8d
fix conflict
krofax Apr 2, 2025
741b1e3
remove the version
krofax Apr 2, 2025
2af3aea
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 8, 2025
d90abf7
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 8, 2025
013b0e0
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 8, 2025
35906c1
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 8, 2025
d4eacf6
Update pages/operators/chain-operators/tutorials/migrating-permission…
krofax Apr 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pages/operators/chain-operators/tools/op-challenger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ This guide provides a walkthrough of setting up the configuration and monitoring

```bash
./op-challenger/bin/op-challenger \
--trace-type cannon \
--trace-type permissioned,cannon \
--l1-eth-rpc http://localhost:8545 \
--rollup-rpc http://localhost:9546 \
--game-factory-address $DISPUTE_GAME_FACTORY \
Expand Down
2 changes: 2 additions & 0 deletions pages/operators/chain-operators/tutorials.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ This section provides information on adding attributes to the derivation functio

<Card title="Integrating a new da layer with alt Da" href="/operators/chain-operators/tutorials/integrating-da-layer" />

<Card title="Migrating to permissionless fault proofs on OP Stack" href="/operators/chain-operators/tutorials/migrating-permissionless" />

<Card title="Modifying predeployed contracts" href="/operators/chain-operators/tutorials/modifying-predeploys" />

<Card title="Using viem" href="/app-developers/get-started" />
Expand Down
1 change: 1 addition & 0 deletions pages/operators/chain-operators/tutorials/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"adding-precompiles": "Adding a precompile",
"modifying-predeploys": "Modifying predeployed contracts",
"integrating-da-layer": "Integrating a new DA layer",
"migrating-permissionless": "Migrating to permissionless fault proofs on OP Stack",
"chain-dev-net": "Running a local network environment"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
---
title: Migrating to permissionless fault proofs on OP Stack
description: A high-level guide for transitioning from permissioned to permissionless fault proofs on an OP Stack.
lang: en-US
content_type: tutorial
topic: migrating to permissionless fault proofs on OP Stack
personas:
- chain-operator
categories:
- fault proofs
- smart contracts upgrades
- Superchain-shared contracts
- proof system
- OPCM upgrade
- OPCM contracts
- dispute game
is_imported_content: 'false'
---

import { Callout } from 'nextra/components'

# Migrating to permissionless fault proofs on OP Stack

This guide provides a high-level overview for chain operators looking to transition their OP Stack from permissioned to permissionless fault proofs. It's designed to be accessible for technical decision makers while providing sufficient detail for implementation teams.

## Overview

The OP Stack architecture uses Fault Proofs to ensure the validity of withdrawals from L2 to L1.
Transitioning from permissioned to permissionless proofs represents a significant security upgrade, allowing any participant to propose and challenge state output roots.
Permissioned games previously relied on a single trusted validator—typically the proposer configured in the `PermissionedDisputeGame`, usually the network's only sequencer.

This migration involves several key components:

* Configuring security-critical dispute [monitoring services](/operators/chain-operators/tools/chain-monitoring)
* Deploying and configuring smart contracts using [op-deployer](/operators/chain-operators/tools/op-deployer)
* Testing the new system before activation
* Setting the respected game type to permissionless fault proofs, specifically using the `FaultDisputeGame`

## Prerequisites

Before beginning this transition, your chain should:

* Be running a standard OP Stack implementation
* Be operating with the recommended infrastructure services including [`op-challenger`](/stack/fault-proofs/challenger) and [`op-dispute-mon`](/operators/chain-operators/tools/chain-monitoring#dispute-mon)

## 1. Configure the dispute components

The `op-challenger` and `op-dispute-mon` services are critical security components that participate in the dispute game process to challenge invalid proposals and monitor active games.

### Upgrade to the latest `op-challenger`

Upgrade to the [latest release](https://github.com/ethereum-optimism/optimism/releases), which contains important improvements to simplify the upgrade process.

We recommend using the official Docker images for reliability and ease of deployment:

```bash
# Pull the latest version
docker pull us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:latest
```
Then run the image, for example:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the example, we should include all of the required variables. Something like this: https://docs.optimism.io/operators/chain-operators/tools/op-challenger#configure-challenger


```bash
docker run -d --name op-challenger \
-e OP_CHALLENGER_TRACE_TYPE=permissioned,cannon \
-e OP_CHALLENGER_PRESTATES_URL=<YOUR_PRESTATES_URL> \
us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:v1.3.3

```
Replace `<YOUR_PRESTATES_URL>` with your actual prestates URL.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will need to be updated with all of the required flags


If your deployment requires building from source, you can alternatively use:

```bash
git clone https://github.com/ethereum-optimism/optimism -b op-challenger/v1.3.3 --recurse-submodules
cd optimism
make op-challenger
```

### Update network configuration

Configure `op-challenger` to load your chain configuration. Even if your chain is not included in the [superchain-registry](/superchain/superchain-registry), you can specify a custom configuration:

```bash
# For chains in the registry
--network <chain-name>

# For chains not in the registry, provide a path to your rollup configuration
* `<chain-id>-rollup.json` - Your rollup configuration
* `<chain-id>-genesis-l2.json` - Your L2 genesis file
```

### Enable cannon trace type

Configure `op-challenger` to support both permissioned and permissionless games by setting:

```bash
--trace-type permissioned,cannon
```

Or by setting the environment variable:

```
OP_CHALLENGER_TRACE_TYPE=permissioned,cannon
```

### Configure prestates access

Replace the `--cannon-prestate` flag with `--prestates-url`, which points to a source containing all required prestates:

```bash
--prestates-url <URL_TO_PRESTATES_DIRECTORY>
```

The URL can use `http`, `https`, or `file` protocols. Each prestate should be named as `<PRESTATE_HASH>.json` or `<PRESTATE_HASH>.bin.gz`.

### Building required prestates for chains not in the Superchain Registry

You'll need to deploy two new dispute game contracts with the new absolute prestate:

1. `FaultDisputeGame`
2. `PermissionedDisputeGame`

<Callout type="info">
The initial prestate used for permissioned games doesn't include the necessary chain configuration for the Fault Proof System. The assumption is that the chain operator, the single permissioned actor, will not challenge their own games. So the absolute prestate on the initial `PermissionedDisputeGame` will never be used.
When deploying a new chain, you must first deploy the L1 contracts and then generate the chain genesis file and rollup configuration files.
These are inputs to the creation of the absolute prestate and this circular dependency is the reason chains cannot be deployed directly to the permissionless Fault Proof System.
</Callout>

For chains not in the Superchain Registry, you need to build custom prestates with your chain's configuration:

```bash
# 1. Clone the repository
git clone https://github.com/ethereum-optimism/optimism --recurse-submodules
cd optimism

# 2. Create a branch from the latest op-program release
git checkout -b op-program/chainconfig op-program/v1.5.0

# 3. Add your chain configuration to the op-program chainconfig directory
# Your rollup config must be named <chain-id>-rollup.json
# Your L2 genesis must be named <chain-id>-genesis-l2.json
mkdir -p op-program/chainconfig/configs
cp /path/to/your/rollup-config.json op-program/chainconfig/configs/<YOUR_L2_CHAIN_ID>-rollup.json
cp /path/to/your/l2-genesis.json op-program/chainconfig/configs/<YOUR_L2_CHAIN_ID>-genesis-l2.json

# 4. Build the reproducible prestate
make reproducible-prestate
```

The prestate will typically be generated at:

* `op-program/bin/prestate.json` (for older versions)
* `op-program/bin/prestate.bin.gz` (for intermediate versions)
* `op-program/bin/prestate-mt64.bin.gz` (for chains upgraded to Cannon MT64, starting from [upgrade 14](/notices/upgrade-14#whats-included-in-upgrade-14))

<Callout type="info">
Post-upgrade 14, chains are expected to use `prestate-mt64.bin.gz` due to the Fault Proof VM contract upgrade to `cannon-mt64`.
The older `prestate.bin.gz` will eventually be deprecated but is temporarily retained until all chains complete the upgrade.
</Callout>

### Ensure sufficient funds for bonds

Bonds are required for both permissioned and permissionless games.
However, with permissioned games, you typically don't post claims regularly, making bond requirements less noticeable.
In contrast, the challenger in permissionless games will frequently need to post bonds with each claim it makes.
Therefore, ensure your challenger has sufficient funds available.

As a general guideline:

* Maintain a minimum balance of 50 ETH
* Have access to a large pool of ETH for potential attack scenarios
* Implement monitoring to ensure sufficient funds are always available

### Set up `op-dispute-mon`

Ensure `op-dispute-mon` is properly configured by following these [steps](/operators/chain-operators/tools/chain-monitoring#dispute-mon)

## 2. Deploy and configure smart contracts using OPCM

This section requires privileged actions by the `ProxyAdminOwner` and may involve the `Guardian` role depending on your security setup.

### Understanding ProxyAdmin Owner and Guardian roles

This migration requires actions by privileged roles in your system:

* The **ProxyAdmin Owner** has the authority to upgrade proxy contracts.

* The **Guardian** has emergency powers like pausing withdrawals and changing the respected game type.

For detailed information about privileged roles and their security implications, refer to the [privileged roles documentation](/superchain/privileged-roles).

### Adding the PermissionlessDisputeGame to a chain

Given that not all chains will support the `PermissionlessDisputeGame` upon deployment, an
`OPCM.addGameType()` method will be added which will orchestrate the actions required to add a
new game type.

This method will:

1. deploy the `FaultDisputeGame` contract
2. setup the `DelayedWethProxy` for the new game
3. Reinitialize the `AnchorStateRegistry` to add the new game type.
Comment on lines +192 to +202
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maurelian Are these the accurate steps?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting! If this is the new way to deploy the permissionless game, we should also include the parameters and an example command on how to deploy it. Because we need to specify the absolute prestate.


See a high‐level implementation from the [spec](https://specs.optimism.io/experimental/op-contracts-manager.html#implementation-2)

### Set game implementations

Execute the following smart contract changes in a single bundled transaction:

1. Call `setImplementation` on the `DisputeGameFactoryProxy` to:

* Set the implementation for the new permissionless `FaultDisputeGame` (game type `0`)
* Upgrade the permissioned game to the new `PermissionedDisputeGameAddress` (game type `1`) with the updated absolute prestate

2. Upgrade the `AnchorStateRegistryProxy` (pre-Upgrade 13 only):

After [upgrade 13](/notices/upgrade-13#whats-included-in-upgrade-13) (FP incident response improvements), this step is *no longer required*, as a single anchor state is shared across all game types. If you have not upgraded, perform the following:

* First upgrade the proxy to point to the `StorageSetter` contract and clear the initialized flag.
* Then upgrade back to the `AnchorStateRegistry` implementation
* Call `initialize` with the anchor state for the new game type
Comment on lines +215 to +221

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose that we:

  1. Declare that this document is only for chains which are on op-contracts/v2.0.0 (upgrade 13).
  2. Then we can just remove steps 2 and 3 from this list. Otherwise we need to support two very different approaches.


<Callout type="info">
Ensure a permissioned game has already resolved with the correct root and updated the anchor state to a valid value.
Initial deployments at genesis always have an invalid anchor state.
</Callout>

Post-upgrade 13, the anchor state for permissionless games automatically matches the current anchor state used by permissioned games, since there's only one shared anchor state.

3. Initialize bond amounts for each game type to exactly 0.08 ETH

## 3. Testing off-chain agents

After you've set the permissionless `FaultDisputeContract` implementations on the `DisputeGameFactory` and before you set the respected game type to it; you can test your off-chain services in the cold path.

### Test defending valid proposals

Create a valid proposal using the permissionless game type `0`:

1. Ensure the proposal is from a block at or before the `safe` head:
```bash
cast block --rpc-url <OP_GETH_ENDPOINT> safe
```

2. Get a valid output root:
```bash
cast rpc --rpc-url <OP_NODE_ENDPOINT> optimism_outputAtBlock \
$(cast 2h <BLOCK_NUMBER>) | jq -r .outputRoot
```

3. Create a test game:
```bash
./op-challenger/bin/op-challenger create-game \
--l1-eth-rpc=<L1_RPC_ENDPOINT> \
--game-factory-address <DISPUTE_GAME_FACTORY_ADDR> \
--l2-block-num <BLOCK_NUMBER> \
--output-root <OUTPUT_ROOT> \
<SIGNER_OPTIONS>
```

4. Verify:
* `op-challenger` logs a message showing the game is in progress
* `op-challenger` doesn't post a counter claim (as this is a valid proposal)
* `dispute-mon` includes the new game with `status="agree_defender_ahead"`

### Test countering invalid claims

Post an invalid counter claim to the valid proposal created above:

```bash
./op-challenger/bin/op-challenger move \
--l1-eth-rpc <L1_RPC_ENDPOINT> \
--game-address <GAME_ADDR> \
--attack \
--parent-index 0 \
--claim 0x0000000000000000000000000000000000000000000000000000000000000000 \
<SIGNER_OPTIONS>
```

Verify that `op-challenger` posts a counter-claim to the invalid claim. You can view claims using:

```bash
./op-challenger/bin/op-challenger list-claims \
--l1-eth-rpc <L1_RPC_ENDPOINT> \
--game-address <GAME_ADDR>
```

There should be 3 claims in the game after this test.

## 4. Switch to permissionless proofs

After completing all previous steps and verifying their successful operation:

1. Set the `respectedGameType` on the `OptimismPortal` to `CANNON` (game type `0`) using OPCM:
```bash
opcm set-respected-game-type \
--game-type 0
```

2. Configure `op-proposer` to create proposals using the permissionless `cannon` game type:

```bash
# Change from game-type 1 to 0
--game-type 0
```

Or via environment variable:

```
OP_PROPOSER_GAME_TYPE=0
```

## Next steps

* [Optimism Fault Proof Documentation](/operators/chain-operators/tools/op-challenger)
* [Privileged Roles Documentation](/superchain/privileged-roles)
* [L2Beat OP Mainnet Upgrades](https://l2beat.com/scaling/projects/op-mainnet#upgrades-and-governance)
* [op-challenger GitHub](https://github.com/ethereum-optimism/optimism/tree/develop/op-challenger)
* [op-dispute-mon GitHub](https://github.com/ethereum-optimism/optimism/tree/develop/op-dispute-mon)

## Conclusion

Transitioning to permissionless proofs represents a significant security improvement for your OP Stack chain. This transition decentralizes the validation process, allowing any participant to challenge invalid withdrawal claims rather than relying on a limited set of trusted validators.

By following this guide, you'll be able to safely configure and test your system before making the switch to permissionless proofs. Remember to thoroughly test each service before proceeding to the next step, and ensure that your security monitoring is properly configured to track the health of the system after the transition.
1 change: 0 additions & 1 deletion words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ offchain
opchaina
opchainb
OPCM
opcm
Openfort
oplabs
opnode's
Expand Down