Commit ca854129 authored by Andreas Bigger's avatar Andreas Bigger

merge proposer spec into proposals

parent f01bd973
......@@ -25,8 +25,8 @@
After processing one or more blocks the outputs will need to be synchronized with the settlement layer (L1)
for trustless execution of L2-to-L1 messaging, such as withdrawals.
These output proposals act as the bridge's view into the L2 state.
[Proposers](./proposer.md) submit the output roots to the settlement layer (L1) and can be contested with a fault proof,
with a bond at stake if the proof is wrong.
Actors called "Proposers" submit the output roots to the settlement layer (L1) and can be contested with a fault proof,
with a bond at stake if the proof is wrong. The [op-proposer](../op-proposer/) in one such implementation of a proposer.
_Note_: Fault proofs on Optimism are not fully specified at this time. Although fault proof
construction and verification [is implemented in Cannon][cannon],
......@@ -39,7 +39,6 @@ are part of later specification milestones.
The proposer's role is to construct and submit output roots, which are commitments to the L2's state,
to the `L2OutputOracle` contract on L1 (the settlement layer).
The proposer is further detailed in [proposer.md](./proposer.md).
### L2OutputOracle v1.0.0
......@@ -68,8 +67,8 @@ while True:
time.sleep(poll_interval)
```
A `CHALLENGER` account can delete multiple output roots by calling the `deleteL2Outputs()` function and specifying the
index of the first output to delete, this will also delete all subsequent outputs.
A `CHALLENGER` account can delete multiple output roots by calling the `deleteL2Outputs()` function
and specifying the index of the first output to delete, this will also delete all subsequent outputs.
### L2OutputOracle v2.0.0
......@@ -81,10 +80,49 @@ either via fault proof or by an attestation proof, then the bond can be slashed
payment to the users who paid for gas to remove the malicious output.
The `op-proposer` can still be used to submit output proposals. A naive implementation of the
`op-proposer` will still submit output proposals on an interval. A more ideal implementation
`op-proposer` will submit output proposals on an interval. However, this is not required, and other
proposer implementations may submit valid outputs at any time. A more ideal implementation
will use heuristics such as time of last submission or number of pending withdrawals that have
yet to be included in an output proposal.
In order to post outputs to the `L2OutputOracle`, the proposer needs to periodically query the
[rollup node](./rollup-node.md)'s [`optimism_outputAtBlock` rpc method](./rollup-node.md#l2-output-rpc-method)
for the latest output root derived from the latest [finalized](rollup-node.md#finalization-guarantees)
L1 block.
It then takes the output root and submits it to the `L2OutputOracle` contract on the settlement layer (L1).
A single iteration of the proposer (posting one output root to L1) is depicted below:
```mermaid
sequenceDiagram
participant L1
participant Rollup Node
participant Proposer
L1->>L1: L1 block finalized
L1->>Rollup Node: L1 block finalized
Proposer->>Rollup Node: optimism_syncStatus
Rollup Node->>Proposer: sync status { finalized L1 block num }
Proposer->>Rollup Node: optimism_outputAtBlock
Rollup Node->>Proposer: output root
Proposer->>L1: Query L2OutputOracle for this output root
L1->>Proposer: output root or nil
Proposer->>Proposer: stop if the current output is already proposed
Proposer->>L1: L2OutputOracle.proposeOutputRoot
```
Since there may be multiple proposers running simultaneously when permissionless output proposals are enabled,
the [op-proposer](../op-proposer/) will check that it's output root has not been posted for the given L2 block
number before sending the proposal transaction. This is shown in the sequence diagram above when the `Proposer`
queries the `L2OutputOracle` for the output root. If it receives an output root that is equal to the one it
received from the rollup node, it will **not** send this output root in a transaction to the `L2OutputOracle`.
Also note, while the [op-proposer](../op-proposer/) implementation submits outputs _only_ based on finalized
or safe L2 blocks, other proposer implementations may submit outputs corresponding to unsafe (non-finalized)
L2 blocks. This comes with risk as it will be possible for [batchers](./batcher.md) to submit L2 blocks that
do not correspond to the output that have already been made available (implying those outputs are now _invalid_).
Version `v2.0.0` includes breaking changes to the `L2OutputOracle` ABI.
## L2 Output Commitment Construction
......
<!-- DOCTOC SKIP -->
# Proposer
The proposer, or output proposer, is an actor that is responsible for submitting L2 output roots
to the settlement layer (L1 in bedrock's case).
## Background
Initially, the v1 settlement layer smart contract that received these output roots, `L2OutputOracle`,
specified a single, permissioned proposer. In this version, output roots were required to be
submitted by said proposer once every `SUBMISSION_INTERVAL` blocks.
In the next iteration of the `L2OutputOracle`, [v2.0.0](./proposals.md#-L2OutputOracle-v2.0.0), the proposer is
no longer permissioned. Anyone can submit an output root to the `L2OutputOracle` contract.
This is coined _Permissionless Output Proposals_.
## Permissionless Architecture
The [op-proposer](../op-proposer/) is an implementation of an output proposer. In order to post
outputs to the `L2OutputOracle`, the proposer needs to periodically query the [rollup node](./rollup-node.md)'s
[`optimism_outputAtBlock` rpc method](./rollup-node.md#l2-output-rpc-method) for the latest output root derived
from the latest [finalized](rollup-node.md#finalization-guarantees) L1 block.
It then takes the output root and submits it to the `L2OutputOracle` contract on the settlement layer (L1).
A single iteration of the proposer (posting one output root to L1) is depicted below:
```mermaid
sequenceDiagram
participant L1
participant Rollup Node
participant Proposer
L1->>L1: L1 block finalized
L1->>Rollup Node: L1 block finalized
Proposer->>Rollup Node: optimism_syncStatus
Rollup Node->>Proposer: sync status { finalized L1 block num }
Proposer->>Rollup Node: optimism_outputAtBlock
Rollup Node->>Proposer: output root
Proposer->>L1: Query L2OutputOracle for this output root
L1->>Proposer: output root or nil
Proposer->>Proposer: stop if the current output is already proposed
Proposer->>L1: L2OutputOracle.proposeOutputRoot
```
Since there may be multiple proposers running simultaneously when permissionless output proposals are enabled,
the [op-proposer](../op-proposer/) will check that it's output root has not been posted for the given L2 block
number before sending the proposal transaction. This is shown in the sequence diagram above when the `Proposer`
queries the `L2OutputOracle` for the output root. If it receives an output root that is equal to the one it
received from the rollup node, it will **not** send this output root in a transaction to the `L2OutputOracle`.
Note that the [op-proposer](../op-proposer/) implementation by default will submit output roots at the
`SUBMISSION_INTERVAL` from v1 of the `L2OutputOracle` contract. This is to allow for backwards compatibility
in the UX of outputs being posted to the settlement layer. However, this is not a requirement and other proposer
implementations may choose to submit output roots at any time.
Additionally, a proposer implementation may submit output commitments that correspond to unsafe (non-finalized)
L2 blocks but this comes with risk as it will be possible to submit L2 blocks that do not correspond to the
output commitments that have already been made available.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment