diff --git a/runbooks/1.8.0-permissioned-to-permissionless.md b/runbooks/1.8.0-permissioned-to-permissionless.md new file mode 100644 index 000000000..56899140d --- /dev/null +++ b/runbooks/1.8.0-permissioned-to-permissionless.md @@ -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/ --recurse-submodules` + where `` 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/.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 \ + copy-anchor-state 1 0 \ + set-implementation 0 \ + set-implementation 1 + ``` + + 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 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 optimism_outputAtBlock \ + $(cast 2h ) | 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= \ + --game-factory-address \ + --l2-block-num \ + --output-root \ + +``` + +See the `op-challenger create-game --help` output for available options to specify how to sign the transaction ( +replacing `` 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= 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 --game-address `. 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.