Skip to content

Commit

Permalink
Merge pull request ethereum-optimism#31 from ethereum-optimism/feat/f…
Browse files Browse the repository at this point in the history
…raud-proof-writeup

Add fraud proof VM & program writeup
  • Loading branch information
norswap authored Nov 24, 2021
2 parents d71b5cf + 1c383cd commit be35236
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
43 changes: 43 additions & 0 deletions components/fraud-proof-vm/fraud_proof_program.md
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.
50 changes: 50 additions & 0 deletions components/fraud-proof-vm/fraud_proof_vm.md
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.

0 comments on commit be35236

Please sign in to comment.