forked from ethereum-optimism/optimism
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request ethereum-optimism#31 from ethereum-optimism/feat/f…
…raud-proof-writeup Add fraud proof VM & program writeup
- Loading branch information
Showing
2 changed files
with
93 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,43 @@ | ||
# Fraud Proof Program | ||
|
||
The fraud proof program is the specific program which is run on a [fraud proof VM](./fraud_proof_vm.md) during a dispute. This program is designed to evaluate any subset of the Optimistic Ethereum chain. | ||
|
||
## Initialization | ||
|
||
The OE fraud proof program is used to weed out invalid block hash assertions in the `Block Hash Oracle`. The fraud proof program is initialized using values which are recorded at the time of block hash assertions. This is all handled within the `AssertionManager` contract. | ||
|
||
Every time an L2 block hash is asserted using the `AssertionManager`, the following information is hashed together and recorded: | ||
|
||
- Latest L1 block hash at the time of assertion. | ||
- Asserted next L2 block hash. | ||
- The previous assertion this assertion builds upon. | ||
- Epoch number of the L2 block hash. | ||
|
||
The fraud proof program takes in as input the hash of all these values. | ||
|
||
## Execution | ||
|
||
The fraud proof program is designed to execute the full state transition between any two epochs. The epochs used for a dispute are the previous assertion epoch & the new assertion epoch number in the `AssertionManager`. The fraud proof program will execute the state transition between these epochs and determine the final epoch block hash (ie. the one valid assertion). If the asserted L2 block hash is deemed incorrect over the course of a dispute game, the `AssertionManager` will delete the invalid assertion and forfeit the asserter's bond. | ||
|
||
In practice, the fraud proof program is broken up into two separate processes: | ||
|
||
1. Block generation | ||
2. Block processing | ||
|
||
We split the program into these two distinct parts to isolate the complexity of block processing. This way if there is an error which causes a single block to fail (see [this discussion](https://github.com/ethereum-optimism/optimistic-specs/discussions/22) for details), it does not break the entire assertion game. While the block processing may fail, it is critically important that the block generation process never fails. | ||
|
||
### Block Generation | ||
|
||
The fraud proof program starts out running the block generation process. Block generation uses the same algorithm which is laid out in the [block generation document](../rollup_node/block_gen.md). However, it is worth highlighting: | ||
|
||
1. In the FPVM, all chain data is queried using the preimage oracle. The program will use the L1 block hash at the time of assertion to search backwards on L1 to find all information required for block generation. This can be done by recursively calling `get_preimage(block.previous_block_hash)` until all required block information is loaded into the FPVM memory. | ||
2. The block generation document outlines the process to generate a single epoch. For the purposes of this fraud proof program we will need to generate **all** epochs between the previous assertion and the next assertion. | ||
3. The final step in the block generation algorithm where blocks are **processed** is **not** handled in this top level program. Instead a sub-process is spawned to execute that single block. | ||
|
||
### Block Processing | ||
|
||
For every block which needs to be processed in the block generation algorithm, a sub-process is spawned. This process accepts the block inputs and returns the `block hash` computed by executing the block inputs. The specifics of the block processing algorithm is laid out in the [block processing document] [TODO]. | ||
|
||
## Termination | ||
|
||
Once the fraud proof program has generated and processed all blocks between the last asserted L2 block hash and the newly asserted L2 block hash, it will return the **valid** L2 block hash that should have been asserted. In the proposal manager it will compare the value returned by the fraud proof with the value asserted, and if it is incorrect delete the invalid assertion and slash the asserter's bond. |
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,50 @@ | ||
# Fraud Proof VM | ||
|
||
A fraud proof VM (FPVM) is a virtual machine which can be evaluated on-chain to settle a disputed block hash assertion. In this spec we assume the fraud proof VM is evaluated using a multi-round dispute game similar to [Truebit](https://people.cs.uchicago.edu/~teutsch/papers/truebit.pdf). | ||
|
||
## Key Properties | ||
|
||
A Fraud proof VM must satisfy the following properties to be suitable for a multi-round dispute game: | ||
1. Program execution can be split up into deterministic state transitions. | ||
2. Each state transition can be evaluated on-chain with less than or equal to a constant size gas allocation (eg. 10 million L1 gas). | ||
3. The FPVM must be executable off-chain in such a way that state checkpoints (ie. merklized commitments to the VM state) can be generated. | ||
|
||
## Usage | ||
|
||
### Initialization | ||
|
||
The fraud proof VM is initialized with: | ||
1. an executable binary; and | ||
2. an initialization hash for the preimage oracle. | ||
|
||
The executable binary defines the program which is executed during a fraud proof, and the initialization hash is used to load data from the FPVM's database called the `Preimage Oracle`. | ||
|
||
|
||
The fraud proof VM does not have access to a traditional database. Instead, it has access to the "preimage oracle". The preimage oracle is simply a database which exposes the function `get_preimage(hash: bytes)`: | ||
|
||
```python | ||
def get_preimage(hash: bytes) -> bytes: | ||
# The preimage is looked up from a local database held by the fraud prover | ||
preimage = fetch_preimage(hash) | ||
assert keccak256(preimage) == hash | ||
return preimage | ||
``` | ||
|
||
The preimage oracle must be populated with all `hash->preimage` mappings before they are queried by the FPVM. These preimages are committed to in the initialization hash which is supplied as one of the two inputs to the FPVM. During the course of execution, the FPVM must **never** request a preimage which is unavailable as that would result in the FPVM being indeterminate. In this way, a valid executable binary must account for the structure of the initialization hash and only query available preimages. | ||
|
||
### Termination | ||
|
||
The fraud proof VM must terminate with either: | ||
|
||
1. SUCCESS | ||
2. FAIL | ||
3. INDETERMINATE | ||
|
||
If the FPVM returns SUCCESS it may also return a 32 byte value (eg. the valid block hash). If the FPVM returns FAIL it must be handled by the dispute game. | ||
|
||
There are a few conditions under which the FPVM may return FAIL: | ||
|
||
1. Out of memory -- Too much memory was used during execution. | ||
2. Too many instructions -- Too many instructions were consumed (there is a fixed max instructions to prevent DOS attacks on the FPVM). | ||
|
||
The only time in which the FPVM returns INDETERMINATE is when an unavailable preimage is queried. |