From 672169527619e9989ef43dd6bc5ce03ba7fbd68d Mon Sep 17 00:00:00 2001 From: Hansol Lee <38912532+0xHansLee@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:45:30 +0900 Subject: [PATCH] docs: add zk fault dispute game (#22) * docs: outline zk fault dispute game spec * docs: add specification of zkvm prover (#19) * docs: add specification of zkvm prover * docs: apply reviews * docs: apply review2 * docs: apply review3 * docs: change l1EndHash to l1Head * chore: apply lint-specs-toc --------- Co-authored-by: seolaoh * docs: remove indent * docs: add overview of zkVM fault proof (#20) * docs: add over view of zkVM fault proof * docs: review applied * docs: use output root instead of root claim * docs: review applied * docs: add proveFault interface (#21) * docs: add proveFault interface * docs: review applied * docs: review applied --------- Co-authored-by: Ethan <44886770+dongchangYoo@users.noreply.github.com> Co-authored-by: seolaoh --- specs/SUMMARY.md | 1 + .../fault-proof-system-v2/overview.md | 0 .../zk-fault-dipute-game/overview.md | 220 ++++++++++++++++++ 3 files changed, 221 insertions(+) mode change 100644 => 100755 specs/experimental/fault-proof-system-v2/overview.md create mode 100644 specs/experimental/zk-fault-dipute-game/overview.md diff --git a/specs/SUMMARY.md b/specs/SUMMARY.md index db60e8f..81c1326 100644 --- a/specs/SUMMARY.md +++ b/specs/SUMMARY.md @@ -29,6 +29,7 @@ - [Challenge](./fault-proof/challenge.md) - [zkEVM Prover](./fault-proof/zkevm-prover.md) - [Experimental]() + - [ZK Fault Dispute Game](./experimental/zk-fault-dipute-game/overview.md) - [Fault Proof System V2](./experimental/fault-proof-system-v2/overview.md) - [Definitions](./experimental/fault-proof-system-v2/definitions.md) - [Transaction Data Commitment](./experimental/fault-proof-system-v2/transaction-data-commitment.md) diff --git a/specs/experimental/fault-proof-system-v2/overview.md b/specs/experimental/fault-proof-system-v2/overview.md old mode 100644 new mode 100755 diff --git a/specs/experimental/zk-fault-dipute-game/overview.md b/specs/experimental/zk-fault-dipute-game/overview.md new file mode 100644 index 0000000..079646c --- /dev/null +++ b/specs/experimental/zk-fault-dipute-game/overview.md @@ -0,0 +1,220 @@ +# ZK Fault Dispute Game + + +[g-zk-fault-proof]: ../../glossary.md#zk-fault-proof +[g-l2-chain-derivation]: ../../glossary.md#l2-chain-derivation +[g-sequencer-batch]: ../../glossary.md#sequencer-batch +[g-withdrawals]: ../../glossary.md#withdrawals + + + +**Table of Contents** + +- [Overview](#overview) +- [ZK Fault Dispute Game Creation](#zk-fault-dispute-game-creation) +- [Challenge Creation](#challenge-creation) +- [Dissection](#dissection) +- [Proving Fault using zkVM](#proving-fault-using-zkvm) + - [ZK Fault Proof](#zk-fault-proof) + - [zkVM Proving System](#zkvm-proving-system) + - [Guest Program](#guest-program) + - [Host Program](#host-program) + - [Public Values of Proof](#public-values-of-proof) + - [Proving Fault](#proving-fault) +- [Resolution of ZK Fault Dispute Game](#resolution-of-zk-fault-dispute-game) + + + +## Overview + +The ZK Fault Dispute Game (ZKFDG) is a new type of dispute game compatible with the OP Stack. In ZKFDG, the first +disagreeing output root between defender and challenger is found by the process called "dissection". Then, both the +derivation of L2 block corresponding to that output root and the execution of the block's transactions are carried out +in zkVM. The validity of the execution is guaranteed by the ZK proof, which can be verified on-chain. + +The main difference from [Kroma's previous ZK Fault Proof System](../../fault-proof/challenge.md) is that ZKFDG uses a +"zkVM" instead of a "zkEVM" to handle the proving fault process. By using zkVM for fault proof, it is possible to verify +the entire processes from derivation to execution without any additional developments of ZK circuit. + +ZKFDG implements the OP Stack's `IDisputeGame`, implying that it is fully compatible as one of the OP Stack's dispute +game type. This also implies that it can be applied to the OP Stack's multi-proof system in the future. + +## ZK Fault Dispute Game Creation + +The ZK Fault Dispute Game is created by a validator selected by the +[`ValidatorManager`](../../protocol/validator-v2/validator-manager.md) at intervals defined as the +`SUBMISSION_INTERVAL` configured in the [`L2OutputOracle`](../../protocol/validation.md#l2-output-oracle-smart-contract) +contract. The validator can create a ZKFDG-type dispute game through the `DisputeGameFactory` with an extra data. The +extra data is composed as follows: + +```text +extra_data = current_l2_block_num ++ prev_game_proxy + +current_l2_block_num = uint256 +prev_game_proxy = bytes32 +``` + +When the ZKFDG is created by the validator, the followings are verified: + +- the validator should be eligible to submit a claim +- The `current_l2_block_num` should be the next block number for submission of root claim (output root) +- The `prev_game_proxy` should be the right previous ZKFDG contract + +If all validations are passed, a new ZKFDG contract is created. The address of this ZKFDG contract is stored with +current L2 block number on the L2OutputOracle contract, which can be used for the creation of the next ZKFDG. The root +claim stored in `prev_game_proxy` is used as the starting output root for the dissection process to find the first +disagreeing block. + +## Challenge Creation + +As with Kroma's [previous Fault Proof System][prev-challenge-creation], a challenge can be initiated by a validator who +disagrees the submitted claim. The challenge process begins by submitting the intermediate segments between starting +output root and disputed output root by challenger. + +[prev-challenge-creation]: ../../../specs/fault-proof/challenge.md#challenge-creation + +```solidity + /** + * @notice Creates a challenge against an invalid claim. + * + * @param _l1BlockHash The block hash of L1 at the time the output L2 block was created. + * @param _l1BlockNumber The block number of L1 with the specified L1 block hash. + * @param _segments Array of the segments. A segment is the first output root of a specific range. + */ + function createChallenge( + bytes32 _l1BlockHash, + uint256 _l1BlockNumber, + bytes32[] calldata _segments + ) external; +``` + +## Dissection + +The dissection process is carried out in the same manner as in Kroma's [previous Fault Proof System][prev-bisection]. +Through interactions between the challenger and the defender (the game creator), the first disagreeing output root can +be specified. + +[prev-bisection]: ../../../specs/fault-proof/challenge.md#bisection + +```solidity + /** + * @notice Selects an invalid section and submits intermediate segments of that section. + * + * @param _challenger Address of the challenger. + * @param _pos Position of the last valid segment. + * @param _segments Array of the segments. A segment is the first output root of a specific range. + */ + function dissect( + address _challenger, + uint256 _pos, + bytes32[] calldata _segments + ) external; +``` + +## Proving Fault using zkVM + +Once the first disagreeing output root is specified, the challenger can prove that the disputed claim is incorrect using +a ZK fault proof. + +### ZK Fault Proof + +A [ZK fault proof][g-zk-fault-proof] demonstrates that a state transition from S to Sā€™ is valid based on the +transactions within the block. While this may seem similar to a validity proof, the key difference lies in its +purpose. The ZK fault proof is used to demonstrate that a state transition from S to Sā€™ā€™ is incorrect by +providing evidence of a valid state transition from S to Sā€™. + +### zkVM Proving System + +The zkVM (Zero-Knowledge Virtual Machine) is a virtual machine that executes guest program compiled with a specified +compiler generating zero-knowledge proofs for their execution. The guest program can be written in standard programming +languages, such as Rust and Go. + +#### Guest Program + +For ZK Fault Dispute Game, the guest program is an extension of [L2 Chain Derivation][g-l2-chain-derivation] that +includes a connectivity check among the blocks from L1 origin block to the specified block `C`. The hash of Block +`C` is determined as the parent hash stored when the ZK Fault Dispute Game is created by calling `create()` of +the [Dispute Game Factory]. + +If the attacker manipulates any data within the extension of L2 Chain Derivation, it will affect the block hash `C`. +This is because all data is ultimately linked to the block hash `C` through the hash chain. Therefore if any data +manipulating attack can be thwarted by checking the block hash `C` value. For example, if an attacker creates a proof +using a transaction that is not included in the [sequencer batch][g-sequencer-batch], the block `C` value will change, +preventing them from winning the challenge. + +[Dispute Game Factory]: https://github.com/ethereum-optimism/specs/blob/46d411bfea922c520a1d43329dbf78a2f6966ae0/specs/fault-proof/stage-one/dispute-game-interface.md#disputegamefactory-interface + +#### Host Program + +The host program is a main part of the prover, responsible for delivering the guest program and its input to the zkVM. +The host program first executes the guest program to gather the necessary data, which is same as the data stored in +[PreImageOracle] during [Optimism's Fault Dispute Game]. For ZKFDG, however, additional data is required, which is the +L1 block data from the origin of target L2 block to block `C`. Finally, the host program delivers the guest program +and the preimages to the zkVM to obtain the zkVM proof. + +[PreImageOracle]: https://github.com/ethereum-optimism/specs/blob/46d411bfea922c520a1d43329dbf78a2f6966ae0/specs/fault-proof/stage-one/fault-dispute-game.md#preimageoracle +[Optimism's Fault Dispute Game]: https://github.com/ethereum-optimism/specs/blob/46d411bfea922c520a1d43329dbf78a2f6966ae0/specs/fault-proof/stage-one/fault-dispute-game.md#fault-dispute-game + +#### Public Values of Proof + +To mark which blocks have been executed, the proof publicly reveals the following data. + +``` plain +1. Output root at the parent block of the target +2. Output root at the target block +3. Hash of the block C +``` + +#### Proving Fault + +The ZK proof generated by a prover can be verified on chain. + +```solidity + /** + * @notice Proves that a specific output is invalid using ZK proof. + * + * @param _pos Position of the last valid segment. + * @param _targetOutput The output root of target block. + * @param _zkProof SP1 proofs composed of points and scalars. + */ + function proveFault( + uint256 _pos, + bytes32 _targetOutput, + uint256[] calldata _zkProof + ) external; +``` + +The verify function of `ZKVerifier` contract, which will be used in `proveFault` for verification of provided ZK proof, +will be implemented following the below interface. + +```solidity +interface ZKVerifier { + /** + * @notice The entrypoint for verifying the ZK fault proof. + * + * @param _publicValues The encoded public values. + * @param _proofBytes The encoded proof. + * + * @return If verification of ZK proof is passed or not. + */ + function verify( + bytes calldata _publicValues, + bytes calldata _proofBytes + ) public view returns (bool); +} +``` + +where the `_publicValues` is concatenated value of public values as described [above](#public-values-of-proof). + +```text +_publicValues = output_root_parent ++ output_root_target ++ l1_head +``` + +## Resolution of ZK Fault Dispute Game + +For the ZKFDG to be resolved, the `FINALIZATION_PERIOD` must pass after it is created. After the `FINALIZATION_PERIOD` +has passed, the status of dispute game can be determined based on the presence of the root claim in the dispute game. If +a non-zero value is stored for the root claim, the dispute game's status will be resolved as `DEFENDER_WINS`. If the +root claim value is stored with zero, it indicates that the challenger succeeded in zk proving for fault, thus the +dispute game will be resolved as `CHALLENGER_WINS`. Only ZKFDG resolved as `DEFENDER_WINS` can be used for proving and +finalizing [withdrawals][g-withdrawals] to L1.