Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

op-proposer: add readme #13160

Merged
merged 1 commit into from
Dec 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions op-proposer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# `op-proposer`

Issues: [monorepo](https://github.com/ethereum-optimism/optimism/issues?q=is%3Aissue%20state%3Aopen%20label%3AA-op-proposer)

Pull requests: [monorepo](https://github.com/ethereum-optimism/optimism/pulls?q=is%3Aopen+is%3Apr+label%3AA-op-proposer)

User docs:
- [Proposer Configuration docs]

[Proposer Configuration docs]: https://docs.optimism.io/builders/chain-operators/configuration/proposer

Specs:
- [`proposals.md`](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/proposals.md)
- [`withdrawals`](https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/withdrawals.md)
- [`fault-proof/stage-one/bridge-integration.md`](https://github.com/ethereum-optimism/specs/blob/main/specs/fault-proof/stage-one/bridge-integration.md)

The `op-proposer` is a light-weight service to automate output-root proposal transactions on regular interval.
Each proposal transaction submits a claim of the L2 state to L1.

Chains with a pre-Fault-Proof deployment make proposal-transactions towards a pre-fault-proofs `OptimismPortal` deployment.

Chains with permissioned or permissionless Fault Proofs make proposal-transactions to the `DisputeGameFactory`,
which instantiates claims (each claim being a new fault-proof "game"),
which can then be resolved for the proposals to persist.

Withdrawals are authenticated against resolved proposals,
with an inclusion-proof of a withdrawn message (as registered in the L2 withdrawal-contract storage).

## Quickstart

```bash
go run ./op-proposer/cmd \
--l1-eth-rpc http://l1:8545 \
--rollup-rpc: http://op-node:8545 \
--game-factory-address=changeme \
--game-type=changeme
```

See [Proposer Configuration docs] for customization of the transaction-managent,
and usage of a remote signer to isolate the proposer secret key.

On test networks, `--allow-non-finalized` may be used to make proposals sooner, to reduce test time.

## Usage

### Build from source

```bash
make op-proposer

./bin/op-proposer --help
```

### Run from source

```bash
# from op-proposer dir:
go run ./cmd --help
```

### Build docker image

See `op-proposer` docker-bake target.

## Overview

<!-- description of *how* this module implements the spec -->

The op-proposer relays subjective `finalized` blocks (irreversible, as locally verified)
to L1 by constructing and submitting proposals.
The proposed claims can then be resolved, and used for withdrawals on L1.

```mermaid
sequenceDiagram
autonumber

participant portal as OptimismPortal (v2)<br/> contract
participant challenger as op-challenger
participant claim as Fault Dispute Game<br/> contract
participant dgf as Dispute Game Factory<br/> contract on L1
participant proposer as op-proposer
participant opnode as op-node
participant el as Execution Engine<br/> (e.g. op-geth)

proposer ->>opnode: query output-root
opnode ->>el: query block and withdrawals-root
el -->> opnode: return block and withdrawals-root
opnode -->> proposer: return output root
proposer ->> dgf: send claim
proposer ->> proposer: repeat with next claim
dgf ->> claim: create game contract
challenger ->> claim: resolve (or counter) claim
portal -->> claim: proveWithdrawalTransaction checks game state
```

The `op-proposer` itself is a light-weight loop to maintain this relay:
schedule when to propose, inspect what to propose, transact on L1 to proposer, and repeat.

## Product

### Optimization target

The `op-proposer` code optimizes for simplicity.

Proposals are few and far-between, commonly only at a 1 hour interval.
Proposal execution speed affects tests more than it does production, and thus not a primary optimization target.

Most costs are made in the proposal contract execution,
not the operation of the op-proposer, and thus not the primary optimization concern.

Proposals are critical to safety however, and simplicity is thus important to this service.

### Vision

The pre-fault-proof proposal functionality is effectively unused code, and may be removed in the near future.
Solutions for alternative proving systems are a work in progress.

With the proposed withdrawals-root feature (see [Isthmus upgrade feature]),
the op-node will soon no longer have to query the storage separately
from the block-header that it constructs an output-root for.
This lowers the requirements to run a proposer,
since no archive-node is required anymore to determine the withdrawals-root.

[Isthmus upgrade feature]: https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/isthmus/exec-engine.md#l2tol1messagepasser-storage-root-in-header

Testing of this service may be further improved by decoupling the scheduling and processing.
Better encapsulated processing would lend itself better to [op-e2e](../op-e2e) action-tests.


## Design principles

<!-- design choices / trade-offs -->

- Reuse the transaction-management: this is the most complicated part of the op-proposer, but is common with other services.
- Keep the proposal flow simple: given that we only expect one transaction per hour,
but the transaction is a critical claim, we have a strong preference for safety over liveness.

## Failure modes

<!-- Risks & error handling -->

While disabled by default, the op-proposer is capable of submitting proposals too eagerly.
A proposal for unfinalized L2 state that does not hold true later may result in an invalid claim on L1,
and thus in dispute-game penalties.

Assuming finality, the op-proposer is only really subject to liveness failures:
- to L1 RPC failure (mitigated with redundancy in L1 RPC)
- local temporary failure, e.g. offline execution engine (mitigated with alerts)
or odd tx-inclusion situations (mitigated with fresh state upon restart).

## Testing

The `op-proposer` integration is covered in system `op-e2e` tests.