Skip to content

Commit

Permalink
docs: add zk fault dispute game (#22)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* 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 <[email protected]>
Co-authored-by: seolaoh <[email protected]>
  • Loading branch information
3 people authored Sep 4, 2024
1 parent 91c4f92 commit 6721695
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 0 deletions.
1 change: 1 addition & 0 deletions specs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Empty file modified specs/experimental/fault-proof-system-v2/overview.md
100644 → 100755
Empty file.
220 changes: 220 additions & 0 deletions specs/experimental/zk-fault-dipute-game/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# ZK Fault Dispute Game
<!-- All glossary references in this file. -->

[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

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**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)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## 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.

0 comments on commit 6721695

Please sign in to comment.