Skip to content
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

Add 1.8.0 permissioned to permissionless runbook. #388

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
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
307 changes: 307 additions & 0 deletions runbooks/1.8.0-permissioned-to-permissionless.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
# [PUBLIC DRAFT] Upgrade Runbook: Enabling permissionless fault proofs on op-contracts/v1.8.0

# Summary

This runbook describes the process of switching from permissioned to permissionless dispute games on
`op-contracts/v1.8.0` ([link](https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv1.8.0)). It
assumes that the chain is either:

* already running `op-contracts/v1.8.0` in permissioned configuration, or
* running `op-contracts/v1.6.0` in permissioned configuration and will upgrade to `v1.8.0` and activate permissionless
games as part of the Holocene hard fork upgrade.

It is further assumed that the respected game is set to the `PermissionedFaultDisputeGame` and infrastructure
including `op-proposer`, `op-challenger` and `op-dispute-mon` are running against the existing `DisputeGameFactory` as
configured by
the [v1.30 to v1.6.0 permissioned upgrade runbook](https://github.com/ethereum-optimism/superchain-ops/blob/main/runbooks/mcp-to-permissioned-fps.md).
The runbook will cover the necessary contract deployment and on-chain configuration changes as well as configuration
changes required for off-chain services.

The `cannon` game type (game type `0`) will be used for permissionless games.

# Deploy `FaultDisputeGame` Contract

## Prerequisites

- The chain configuration must be included in
the [superchain-registry](https://github.com/ethereum-optimism/superchain-registry/)
- An `op-program` release must be available containing the latest chain configuration (including the holocene activation
time)

## Overview

The `FaultDisputeGame` contract and it’s dependencies are deployed to the L1 chain in preparation for activation. This
step can be performed without any special privileges. The new contracts cannot be used to create games until the “Set
Game Implementations” step below is completed.

The deployment will:

1. Build the absolute prestate from `op-program` and calculate the `faultGameAbsolutePrestate`
2. Deploy and initialize a new `DelayedWETHProxy` , transferring its ownership to `ProxyAdminOwner`
3. Deploy new `FaultDisputeGame` and `PermissionedDisputeGame` contracts

- The existing `AnchorStateRegistryProxy`, `PreimageOracle`and `MIPS` contracts will be used.
- The new `faultGameAbsolutePrestate` will be used

## Preparing the Prestate

The absolute prestate is a cannon state snapshot that is the initial state after loading `op-program` into memory. The
commitment hash of this state is set as the `faultGameAbsolutePrestate`. To build the prestate and calculate the
commitment:

1. Checkout the `op-program` release tag:
`git clone https://github.com/ethereum-optimism/optimism -b op-program/<VERSION> --recurse-submodules`
where `<VERSION>` is the op-program version required.
2. Build the prestate:
`cd optimism && make reproducible-prestate`

This will create the prestate in `op-program/bin/prestate.bin.gz` and print the prestate commitment. The build is
performed in a docker container to ensure the result is reproducible. When the build is complete it will print output
like:

```bash
Cannon Absolute prestate hash:
0x0364010a7b2be12b8583c8bc2c610ef5b77bb52161cac1dd4f8cbe47edc05afd
MT-Cannon Absolute prestate hash:
0x03f175dcc65ddc3b5740d67d3cc0d59b6fd8cd748b9bd6c9a7e14341a2386e24
Cannon64 Absolute prestate hash:
0x0318d12b4f68c79bd937d480326031ceffbefad5934e431a3b430c058c1c9e1b
```

The `Cannon Absolute prestate hash` is the version to use. The `MT-Cannon` and `Cannon64` prestates are future
versions of cannon that are not yet production ready. Note that the actual hashes will differ depending on the
release being built.

3. Rename the generated prestate to match the commitment hash:
`cp op-program/bin/prestate.bin.gz op-program/bin/<HASH>.bin.gz`
Keep this prestate file to be used by `op-challenger`

### Verify the Prestate Hash

The expected prestate hashes for each op-program release is recorded in `op-program/prestates/releases.json`. Verify
that the hash printed by the build matches the hash for the same version in `releases.json`.

## Deploy Contracts with Holocene Deployer Tool

The Holocene upgrade deployment tool can be used to deploy the contracts required for Holocene and upgrade to
permissionless fault proofs. The new fault dispute game contracts should be deployed and set as the new implementation (
in the “Set Game Implementations” step) *prior* to the Holocene activation time. The “Switch to Permissionless” step may
be performed either before or after Holocene activates.

Deploy the Holocene upgrade contracts via
the [deployer tool](https://github.com/ethereum-optimism/optimism/tree/op-contracts/v1.8.0-rc.2/packages/contracts-bedrock/scripts/upgrades/holocene)
as usual but set `USE_PERMISSIONLESS_FAULT_PROOFS=true`. Ensure the prestate commitment hash is set as
`faultDisputeGameAbsolutePrestate` in the deploy config specified. Permissionless games will still be completely
disabled until after the “Set Game Implementations” step is completed.

When prompted `Generate safe upgrade bundle for proofs contracts?` answer `N`. The safe upgrade bundle will be generated
in the “Set Game Implementations” section below. The safe upgrade bundle to upgrade the `SystemConfig` from the deployer
can be used as-is after Holocene activates on the chain.

# Update `op-challenger` Configuration

## Description

`op-challenger` is a service that participates in the dispute game process and challenges invalid proposals. With the
move to permissionless fault proofs, `op-challenger` is a security critical service to ensure that any invalid claims
are countered. It will be configured to monitor both permissionless and permissioned games, ensuring it continues to
resolve permissioned games when needed. Refer
to [the Optimism Developer Docs](https://docs.optimism.io/builders/chain-operators/tools/op-challenger) for a detailed
overview of how to run the `op-challenger`.

## Prerequisites

`op-challenger` should already be configured to operate on the network and be resolving permissioned games correctly.

## Configuration

### Upgrade to `op-challenger` v1.2.0 or later

The `op-challenger` v1.2.0 release contains improvements to make the upgrade process simpler, including supporting
`file` URLs to download prestates and allowing the `cannon` trace type to be enabled prior to the game implementation
being set on-chain.

v1.2.0 does not contain any breaking changes.

### Enable `cannon` Trace Type

`op-challenger` needs to be configured to act on both permissioned and permissionless games. This is done by adjusting
the `--trace-type` (env var `OP_CHALLENGER_TRACE_TYPE`) option to be `permissioned,cannon`.

### Replace `--cannon-prestate` with `--prestates-url`

To correctly act on permissionless games, `op-challenger` needs access to the cannon state that the
`faultGameAbsolutePrestate` hash commits to. The absolute prestate used for a game is never changed once the game has
started, however new games may be created with a new prestate to support future hard forks. It is assumed that the
permissioned games were configured to use the op-mainnet absolute prestate commitment of
`0x038512e02c4c3f7bdaec27d00edf55b7155e0905301e1a88083e4e0a6764d54c`. Permissionless games will use the new prestate
commitment selected above so `op-challenger` will need access to multiple different prestates. This can be achieved by
replacing the `cannon-prestate` flag with the `prestates-url` flag that points to a source with all required prestates.
The `prestates-url` option supports `http`, `https` and `file` URLs.

### **Provide Required Prestates**

At minimum, two prestates will be required. The prestate already in use for permissioned games (
`0x038512e02c4c3f7bdaec27d00edf55b7155e0905301e1a88083e4e0a6764d54c`) and the prestate matching the
`faultGameAbsolutePrestate` configuration option used in the contract deployments above. It is safe to have additional
prestates available, `op-challenger` will only download the ones it actually needs based on the on-chain contracts.

The prestate for game created after the upgrades was built as part of the "Preparing the Prestate" section above and can
be reused. The prestate used in the standard permissioned configuration,
`0x038512e02c4c3f7bdaec27d00edf55b7155e0905301e1a88083e4e0a6764d54c`, is built from the `op-program/v1.3.1` tag. It
can be rebuilt with:

```
git clone https://github.com/ethereum-optimism/optimism -b op-program/v1.3.1 --recurse-submodules
cd optimism
make reproducible-prestate
```

The required prestate will be in `op-program/bin/prestate.json`. If existing games use a different prestate hash, it
will need to be built from a different tag using `make reproducible-prestate` as above. Note that later versions may
build the prestate in `op-program/bin/prestate.bin.gz` as cannon state formats are migrating away from using JSON to a
more efficient binary format.

### Ensure Sufficient Funds for Bonds

`op-challenger` needs to post a bond with each claim it makes. The size of the bond increases exponentially as the depth
in the game increases. With `permissioned` games, `op-challenger` would only resolve claims and did not pay any bonds.
With the switch to permissionless games, `op-challenger` may need to counter invalid proposals and claims and post bonds
as it does so. As a result, the funds required by `op-challenger` may be significantly higher than with the permissioned
game. Since `op-challenger` should only perform honest actions, it expects to have its bonds refunded along with the
bonds of invalid claims it challenges, but the bonds remain locked while the game is in progress.

Monitoring should be established to ensure the account used by `op-challenger` has sufficient funds remaining.

# Set Game Implementations

The new `FaultDisputeGame` and `PermissionedDisputeGame` contracts need to be set as the implementation for the `CANNON`
game type (`0`) and `PERMISSIONED` game type (`1`) respectively. Additionally, an initial anchor state must be added for
the `CANNON` game type. This is a privileged action that must be performed by the `ProxyAdminOwner`. This involves:

1. Call `setImplementation` on the `DisputeGameFactoryProxy` to set the implementation for the new permissionless
`FaultDisputeGame` and to upgrade the permissioned game to the new `PermissionedDisputeGameAddress` with the updated
absolute prestate.
2. Upgrade the `AnchorStateRegistryProxy` to point to `StorageSetter` contract and clear the initialized flag.
3. Upgrade `AnchorStateRegistryProxy` back to the `AnchorStateRegistry` implementation and call `initialize` with the
anchor state for the new game type.

The anchor state for permissionless games will be set to the current anchor state for permissioned games at the time the
task is generated.

## Prepare `superchain-ops` Task

A template is provided to generate the required upgrade task.

1. Checkout the https://github.com/ethereum-optimism/superchain-ops repository:
`git clone https://github.com/ethereum-optimism/superchain-ops.git --recurse-submodules`
2. Change directory to the template: `cd superchain-ops/tasks/sep/fp-recovery/005-set-game-implementation`
3. Generate the required transactions:

```bash

just clean \
prep <l1-chain> <l2-chain> \
copy-anchor-state 1 0 \
set-implementation 0 <FaultDisputeGameAddress> \
set-implementation 1 <PermissionedDisputeGameAddress>
```

Where:

- `l1-chain` is the L1 chain name (either `sepolia` or `mainnet`)
- `l2-chain` is the L2 chain name (e.g. `op`, `base`, `unichain` etc)
- `FaultDisputeGameAddress` is the address of the new `FaultDisputeGame`
contract [deployed above](https://www.notion.so/PUBLIC-DRAFT-Upgrade-Runbook-Enabling-permissionless-fault-proofs-on-op-contracts-v1-8-0-11ef153ee16280f299bef3f0c2837e94?pvs=21).

4. Copy the generated task generated in the directory `out` to the appropriate directory for the chain. e.g.
`cp -rf out ../../../tasks/eth/unichain-001-permissionless-proofs`
5. Review the generated task. In particular check any hard coded addresses are correct.
6. Create a PR to the `superchain-ops` repository to be reviewed.
7. Once approved, merge the PR and arrange signing and execution of the task.

## Test Off-Chain Agents

Permissionless dispute games are now enabled but can’t yet be used to perform withdrawals. The off-chain agents,
`op-challenger` and `op-dispute-mon` can now be tested to ensure they are working correctly with permissionless games.
There are a number of useful `op-challenger` subcommands that can be used for testing, particularly `list-games`,
`list-claims` and `create-game`. See
the [README](https://github.com/ethereum-optimism/optimism/tree/develop/op-challenger#subcommands) and
`op-challenger --help` output for further details. The two tests below are basic sanity tests.

**Defending Valid Proposal**

Create a valid proposal using the permissionless game type 0. Ensure that the proposal is from a block at or before the
`safe` head - proposals for the unsafe chain, including the block returned by `cast bn` are invalid as the data required
to support them is not yet available on-chain. `cast block --rpc-url <OP_GETH_ENDPOINT> safe` can be used to retrieve
the current safe head.

The valid output root for a block can be requested from the op-node `optimism_outputAtBlock` RPC - note that this is
only available from op-node, not op-geth. e.g.

```
cast rpc --rpc-url <OP_NODE_ENDPOINT> optimism_outputAtBlock \
$(cast 2h <BLOCK_NUMBER>) | jq -r .outputRoot
```

The `op-challenger create-game` subcommand can be used to create a new game:

```
./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>
```

See the `op-challenger create-game --help` output for available options to specify how to sign the transaction (
replacing `<SIGNER_OPTIONS>` above). This results in a call to `DisputeGameFactory.createGame`

Verify that:

- `op-challenger` logs a message like:
`t=2024-10-21T02:59:31+0000 lvl=info msg="Game info" game=<GAME_ADDR> claims=1 status="In Progress”`
- Note `op-challenger` may initially warn that `Local node not sufficiently up to date`. This is expected until the L2
node used by `op-challenger` has processed the L1 batch data.
- `op-challenger` should not post a counter claim. The claims in the game can be viewed with
`./op-challenger/bin/op-challenger list-claims --l1-eth-rpc <L1_RPC_ENDPOINT> --game-address <GAME_ADDR>`. There
should only be 1 claim in the game.
- `dispute-mon` includes the new game in it’s `op_dispute_mon_games_agreement` metric with `completion="In Progress"`
and `status="agree_defender_ahead"`.

**Counter Invalid Claim**

Post an invalid counter claim to the valid proposal created above. The `op-challenger move` subcommand can be used to do
this.

Verify that `op-challenger` posts a counter-claim to the invalid claim. There should then be 3 claims in the game.

# Switch To Permissionless

## Set Respected Game Type

While permissionless dispute games can now be created, the portal still only allows withdrawals to be performed against
permissioned games. To switch to using permissionless games, the `GUARDIAN` role must call
`OptimismPortal.setRespectedGameType(0)`.


> [!IMPORTANT]
> Changing the respected game type invalidates any user withdrawals that have been proven but not yet finalized. These
> withdrawals will need to be re-proven against a new permissionless dispute game and begin the 7 day withdrawal delay
> again.


The [superchain-ops repository contains a template task](https://github.com/ethereum-optimism/superchain-ops/tree/6668b5301f177a98f354a5619c50af0df81458cb/tasks/sep/fp-recovery/003-enable-permissionless-game)
to call `setRespectedGameType` that can be used as a guide for creating the task to perform the required call.

## Switch `op-proposer --game-type` from 1 to 0

Configure `op-proposer` to create proposals using the permissionless `cannon` game type instead of permissioned games.

- Change the `--game-type` (env var `OP_PROPOSER_GAME_TYPE`) to 0.

# Activate System Config Upgrade

If upgrading from `op-contracts/v1.6.0`, after Holocene has activated, execute the system config upgrade transaction
generated by the Holocene deployment tool.