From 42d3d5da376bd46533f9b1591e2b0e011706a537 Mon Sep 17 00:00:00 2001 From: wildmolasses Date: Thu, 5 Dec 2024 12:21:40 -0500 Subject: [PATCH] wip: more ASR and Portal --- .../stage-one/anchor-state-registry.md | 98 ++++++++++++------- .../stage-one/dispute-game-interface.md | 4 + .../stage-one/fault-dispute-game.md | 16 +-- .../fault-proof/stage-one/optimism-portal.md | 89 +++++++++++++---- 4 files changed, 139 insertions(+), 68 deletions(-) diff --git a/specs/fault-proof/stage-one/anchor-state-registry.md b/specs/fault-proof/stage-one/anchor-state-registry.md index 01509121f..cb835e0ce 100644 --- a/specs/fault-proof/stage-one/anchor-state-registry.md +++ b/specs/fault-proof/stage-one/anchor-state-registry.md @@ -1,6 +1,5 @@ - **Table of Contents** - [Anchor State Registry](#anchor-state-registry) @@ -9,28 +8,32 @@ - [Definitions](#definitions) - [Top-Level Invariants](#top-level-invariants) - [Contract Dependents](#contract-dependents) - - [Contract Dependencies](#contract-dependencies) - [FaultDisputeGame](#faultdisputegame) + - [OptimismPortal](#optimismportal) + - [Contract Dependencies](#contract-dependencies) + - [FaultDisputeGame](#faultdisputegame-1) + - [DisputeGameFactory](#disputegamefactory) + - [SuperchainConfig](#superchainconfig) - [Function-Level Invariants](#function-level-invariants) - [`initialize`](#initialize) - [`getLatestValidGame`](#getlatestvalidgame) - [`updateLatestValidGame`](#updatelatestvalidgame) - [`getLatestAnchorState`](#getlatestanchorstate) - - [`registerGameResult`](#registergameresult) + - [`registerMaybeValidGame`](#registermaybevalidgame) - [`tryUpdateLatestValidGame`](#tryupdatelatestvalidgame) - [`isGameInvalid`](#isgameinvalid) - [`isGameFinalized`](#isgamefinalized) - [`isGameValid`](#isgamevalid) - [`isGameBlacklisted`](#isgameblacklisted) - [`setRespectedGameType`](#setrespectedgametype) - - [`updateValidityTimestamp`](#updatevaliditytimestamp) + - [`invalidateAllExistingGames`](#invalidateallexistinggames) - [`setGameBlacklisted`](#setgameblacklisted) - [`getGameFinalityDelay`](#getgamefinalitydelay) - [Implementation](#implementation) - [`constructor`](#constructor) - [`initialize`](#initialize-1) - [`anchors` / `getLatestAnchorState`](#anchors--getlatestanchorstate) - - [`registerMaybeValidGame`](#registermaybevalidgame) + - [`registerMaybeValidGame`](#registermaybevalidgame-1) - [`updateLatestValidGame`](#updatelatestvalidgame-1) - [`tryUpdateLatestValidGame`](#tryupdatelatestvalidgame-1) - [`setGameBlacklisted`](#setgameblacklisted-1) @@ -48,15 +51,15 @@ ### Perspective -Multiple contracts in the fault proof system have hard dependencies on things outside them: +Multiple contracts in the fault proof system have critical dependencies on things outside them: - The Portal needs to know whether a withdrawal's proof is based on a **valid** dispute game. -- A new dispute game needs to initialize with a **valid** anchor state. +- A new dispute game needs to initialize with the **latest valid anchor state**. - An existing dispute game needs to know whether it is **invalid**, so it can refund its bonds. The AnchorStateRegistry is these contracts' source of truth, managing and exposing dispute game and anchor state validity to moderate dispute games and withdrawals. -Furthermore, the AnchorStateRegistry is a crucial player in incident response. It can invalidate dispute games and withdrawals, effectively mitigating consequences from dispute games that resolve incorrectly. +Furthermore, the AnchorStateRegistry is a crucial player in incident response. It can invalidate dispute games, thereby invalidating withdrawals and dispute games founded on an incorrect root claim. ## Definitions @@ -67,7 +70,7 @@ Furthermore, the AnchorStateRegistry is a crucial player in incident response. I - **Blacklisted game** - A dispute game is blacklisted if it is set as blacklisted via **authorized input**. - **Validity timestamp** - - The validity timestamp is an **authorized input** that partly determines game validity. + - The validity timestamp is a timestamp internal to the contract that partly determines game validity and can only be adjusted via **authorized input**. - **Invalid game** - A dispute game is invalid if any of the following are true: - Game was not created by the dispute game factory. @@ -80,12 +83,17 @@ Furthermore, the AnchorStateRegistry is a crucial player in incident response. I - Game status is `CHALLENGER_WINS` or `DEFENDER_WINS`. - Game `resolvedAt` timestamp is not zero. - Game `resolvedAt` timestamp is more than `dispute game finality delay` seconds ago. +- **Maybe valid game** + - A dispute game that is not an **invalid game** (but not yet a **finalized game**). - **Valid game** - A game is a **Valid game** if it is not an **Invalid game**, and is a **Finalized game**. - **Latest valid game** - The latest valid game is a game whose anchor state is used to initialize new Fault Dispute Games. It was known to be a **valid game** when set. It will continue to be the latest valid game until updated with a more recent valid game, or blacklisted. - **Latest valid anchor state** - The latest valid anchor state is the output root of the latest valid game. +- **Dispute game finality delay** + - The dispute game finality delay is an **authorized input** representing the period of time between a dispute game resolving and a dispute game becoming finalized or valid. + - Also known as "air gap." ## Top-Level Invariants @@ -96,23 +104,41 @@ Furthermore, the AnchorStateRegistry is a crucial player in incident response. I ### Contract Dependents -This contract manages and exposes dispute game validity so that other contracts can do things like validate withdrawals and initialize dispute games correctly. +This contract manages and exposes dispute game validity so that other contracts can do things like correctly initialize dispute games and validate withdrawals. + +#### FaultDisputeGame + +A [FaultDisputeGame](fault-dispute-game.md) depends on this contract for a **latest valid anchor state** against which to resolve a claim and assumes its correct. Additionally, becauase proposers must gather L1 data for the window between the anchor state and the claimed state, FaultDisputeGames depend on this contract to keep a **latest valid anchor state** that's recent, so that proposer software is not overburdened (i.e. runs out of memory). + +#### OptimismPortal + +OptimismPortal depends on this contract to correctly report game validity as the basis for proving and finalizing withdrawals. -- This contract is the source of truth for the validity of an **anchor state**. - - [FaultDisputeGame](fault-dispute-game.md) and PermissionedDisputeGame depend on this contract for a **latest valid anchor state** against which to resolve a claim. These contracts assume the state is valid. -- Optimism Portal depends on this contract for accurate fault dispute game results. - - Can this dispute game can be used to prove a withdrawal? (Is the dispute game not an **invalid game**?) - - Can this dispute game can be used to finalize a withdrawal? (Is the dispute game a **valid game**?) +- Can this dispute game can be used to prove a withdrawal? (Is the dispute game a **maybe valid game**?) +- Can this dispute game can be used to finalize a withdrawal? (Is the dispute game a **valid game**?) ### Contract Dependencies #### FaultDisputeGame -- Only sets that special boolean if it actually is the respected game type. -- And the boolean never changes after it’s been set. -- Reports its game type correctly. -- Reports its l2BlockNumber correctly. -- Reports its createdAt timestamp correctly. +Depends on FaultDisputeGame to correctly report: + +- whether its game type was the respected game type when created (and that it never changes once set). +- its game type. +- its l2BlockNumber. +- its createdAt timestamp. + +#### DisputeGameFactory + +Depends on DisputeGameFactory to correctly report: + +- whether a game was created by the DisputeGameFactory (is "factory-registered"). + +#### SuperchainConfig + +Depends on SuperchainConfig to correctly report: + +- its guardian address. ## Function-Level Invariants @@ -132,9 +158,9 @@ Gets **latest valid game**. ### `updateLatestValidGame` -- Game must be **valid**. -- Block number for latest valid game must be higher than current latest valid game. -- This function is the ONLY way to update the latest valid game (after initialization). +- Game must be a **valid game**. +- Block number for candidate **valid game** must be higher than current **latest valid game**. +- This function is the ONLY way to update the **latest valid game** (after initialization). ### `getLatestAnchorState` @@ -143,17 +169,17 @@ Gets **latest valid game**. - Must maintain the property that the timestamp of the game is not too old. - TODO: How old is too old? -### `registerGameResult` +### `registerMaybeValidGame` -Stores the address of a not invalid dispute game in an array as a candidate for `latestValidGame`. +Stores the address of a **maybe valid game** in an array as a candidate for `latestValidGame`. -- Callable only by a not invalid game. -- Calling game must only register itself. -- TODO: +- Callable only by a **maybe valid game**. +- Calling game must only register itself (and not some other game). + - TODO: determine any invariants around registry ordering. ### `tryUpdateLatestValidGame` -Try update latest valid game based on previous game results. +Try to update **latest valid game** using registry of **maybe valid games**. - Callable by anyone. - Find the latest (comparing on l2BlockNumber) valid game you can find in the register within a fixed amount of gas. @@ -180,23 +206,23 @@ Returns whether the game is a **blacklisted game**. ### `setRespectedGameType` -- Must be **authorized** by . +- Must be **authorized** by _some role_. + +### `invalidateAllExistingGames` -### `updateValidityTimestamp` +Invalidates all games that exist. Note: until updated, the **latest valid game** (now invalidated) will still provide the **latest valid anchor state**. -- Must be **authorized** by . -- Must be greater than previous validity timestamp. -- Cannot be greater than current block timestamp. +- Must be **authorized** by _some role_. ### `setGameBlacklisted` Blacklists a game. -- Must be **authorized** by . +- Must be **authorized** by _some role_. ### `getGameFinalityDelay` -Returns **authorized** finality delay duration in seconds. No external dependent; public getter for convenience. +Returns **authorized** finality delay duration in seconds. No external dependents; public getter for convenience. ## Implementation diff --git a/specs/fault-proof/stage-one/dispute-game-interface.md b/specs/fault-proof/stage-one/dispute-game-interface.md index e4dcaa650..247488db3 100644 --- a/specs/fault-proof/stage-one/dispute-game-interface.md +++ b/specs/fault-proof/stage-one/dispute-game-interface.md @@ -305,5 +305,9 @@ interface IDisputeGame is IInitializable { /// @return rootClaim_ The root claim of the DisputeGame. /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_); + + /// @notice Returns whether this game's game type was the `respectedGameType` when created. + /// @return isRespectedGameType_ Whether this game's game type was the `respectedGameType` when created. + function isRespectedGameTypeWhenCreated() external view returns (bool isRespectedGameType_); } ``` diff --git a/specs/fault-proof/stage-one/fault-dispute-game.md b/specs/fault-proof/stage-one/fault-dispute-game.md index dd50424ef..f30b86392 100644 --- a/specs/fault-proof/stage-one/fault-dispute-game.md +++ b/specs/fault-proof/stage-one/fault-dispute-game.md @@ -11,7 +11,6 @@ - [Execution Trace](#execution-trace) - [Claims](#claims) - [Anchor State](#anchor-state) - - [Anchor State Registry](#anchor-state-registry) - [DAG](#dag) - [Subgame](#subgame) - [Game Tree](#game-tree) @@ -92,20 +91,7 @@ claims, committing to different output roots and FPVM states in the FDG. An anchor state, or anchor output root, is a previous output root that is assumed to be valid. An FDG is always initialized with an anchor state and execution is carried out between this anchor state and the [claimed output root](#claims). FDG contracts pull their anchor state from the -[Anchor State Registry](#anchor-state-registry) contract. The initial anchor state for a FDG is the -genesis state of the L2. - -Clients must currently gather L1 data for the window between the anchor state and the claimed -state. In order to reduce this L1 data requirement, [claims](#claims) about the state of the L2 -become new anchor states when dispute games resolve in their favor. FDG contracts set their anchor -states at initialization time so that these updates do not impact active games. - -### Anchor State Registry - -The Anchor State Registry is a registry that maps FDG types to their current [anchor states](#anchor-state). -The Anchor State Registry is specific to Fault Dispute Game contracts and may not be applicable to -other types of dispute game contracts that do not have the same concept of state that progresses -over time. +[Anchor State Registry](anchor-state-registry.md) contract. ### DAG diff --git a/specs/fault-proof/stage-one/optimism-portal.md b/specs/fault-proof/stage-one/optimism-portal.md index 2865f600d..975f88ab9 100644 --- a/specs/fault-proof/stage-one/optimism-portal.md +++ b/specs/fault-proof/stage-one/optimism-portal.md @@ -1,43 +1,98 @@ - **Table of Contents** - [Optimism Portal](#optimism-portal) - - [Overview (What this contract is actually supposed to do)](#overview-what-this-contract-is-actually-supposed-to-do) + - [Overview](#overview) + - [Perspective](#perspective) + - [Contract Dependencies](#contract-dependencies) + - [AnchorStateRegistry](#anchorstateregistry) + - [SuperchainConfig](#superchainconfig) + - [Contract Dependents](#contract-dependents) - [Definitions](#definitions) - [Top-Level Invariants](#top-level-invariants) - [Function-Level Invariants](#function-level-invariants) - - [Initialize the thing somehow](#initialize-the-thing-somehow) - - [Prove a withdrawal transaction](#prove-a-withdrawal-transaction) - - [Finalize a withdrawal transaction](#finalize-a-withdrawal-transaction) + - [`initialize`](#initialize) + - [`proveWithdrawalTransaction`](#provewithdrawaltransaction) + - [`finalizeWithdrawalTransaction`](#finalizewithdrawaltransaction) # Optimism Portal -## Overview (What this contract is actually supposed to do) +## Overview + +### Perspective + +This contract is responsible for moderating [withdrawals](../../protocol/withdrawals.md). + +### Contract Dependencies + +#### AnchorStateRegistry + +Depends on AnchorStateRegistry to correctly report: + +- Whether a game is an **invalid game**. +- Whether a game is a **valid game**. + +#### SuperchainConfig + +Depends on SuperchainConfig to correctly report: + +- System pause status. +- Guardian address. + +### Contract Dependents + +TODO ## Definitions +- **Authorized input** + - An input for which there is social consensus, i.e. coming from governance. +- **Proven withdrawal** +- **Finalized withdrawal** + ## Top-Level Invariants -- A withdrawal transaction must be proven against a game that is not `invalid`. -- A withdrawal transaction must be finalized against a game that is `valid`. +- A withdrawal transaction must be **proven** against a game that is not `invalid`. +- A withdrawal transaction may only be finalized against a game that is `valid`. + - Implicit in this is that a withdrawal transaction may only be finalized after the proof maturity delay has passed. +- A withdrawal transaction may only be finalized if it has already been **proven**. - A withdrawal transaction must be used only once to finalize a withdrawal. -- A withdrawal can only be finalized if it has been proven. - A withdrawal transaction that is finalized must attempt execution. # Function-Level Invariants -## Initialize the thing somehow +## `initialize` + +- Proof maturity delay seconds must be an **authorized input**. +- Anchor state registry must be an **authorized input**. +- Dispute game factory must be an **authorized input**. +- Superchain config must be an **authorized input**. +- System config must be an **authorized input**. + +## `proveWithdrawalTransaction` + +Proves a withdrawal transaction. + +- Withdrawal game must not be an **invalid game**. +- Withdrawal transaction's target must not be the OptimismPortal address. +- Withdrawal game's root claim must be equal to the hashed outputRootProof input. +- Must verify that the hash of this withdrawal is stored in the L2toL1MessagePasser contract on L2. +- A withdrawal can only be proven once unless the dispute game it proved against resolves against the favor of the root claim. +- Must add proof submitter to the list of proof submitters for this withdrawal hash. -- Need an **authorized** input for proof maturity delay seconds. -- Need an **authorized** reference to the anchor state registry. -- Need an **authorized** reference to the dispute game factory. -- Need an **authorized** input to system config. -- Need an **authorized** reference to superchain config. +## `finalizeWithdrawalTransaction` -## Prove a withdrawal transaction +Finalizes a withdrawal transaction that has already been proven. -## Finalize a withdrawal transaction +- Withdrawal transaction must have already been proven. +- The proof maturity delay duration must have elapsed between the time the withdrawal was proven and this call for its finalization. +- The time the withdrawal was proven must be greater than the time at which the withdrawal's game was created. +- Withdrawal transaction must not have been finalized before. +- The game upon which the withdrawal proof is based must be a **valid game**. +- Function must register the withdrawal as finalized. +- Function must revert when system is paused. +- TODO: withdrawal tx invariants (can't call token contract, exact balance must be transferred, estimator should revert for gas estimation) +- If these invariants are met, function must attempt execution of the withdrawal transaction.