-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add 1.8.0 permissioned to permissionless runbook.
- Loading branch information
Showing
1 changed file
with
311 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,311 @@ | ||
# [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 is running | ||
`op-contracts/v1.6.0` 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](https://github.com/ethereum-optimism/optimism) -b op-program/<VERSION> —init-submodules —recursive` | ||
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. | ||
|
||
**Build All Tagged Versions** | ||
|
||
The prestate for every tagged release of op-program can be built using the [ | ||
`bulid-prestates.sh` script in the monorepo](https://github.com/ethereum-optimism/optimism/blob/develop/op-program/scripts/build-prestates.sh): | ||
|
||
``` | ||
git clone https://github.com/ethereum-optimism/optimism --recurse-submodules | ||
cd optimism | ||
./op-program/scripts/build-prestates.sh | ||
``` | ||
|
||
The resulting states will be built in `./op-program/temp/states` and named correctly to be used with the `prestates-url` | ||
option. | ||
|
||
**Build a Specific Version** | ||
|
||
To build the prestate for a specific commit or tag, check out the commit to be built and run | ||
`make reproducible-prestate`. The prestate with commitment hash | ||
`0x038512e02c4c3f7bdaec27d00edf55b7155e0905301e1a88083e4e0a6764d54c` is built from the `op-program/v1.3.1` tag: | ||
|
||
``` | ||
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`. 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](https://github.com/ethereum-optimism/superchain-ops.git) --init-submodules --recursive` | ||
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. |