Skip to content
Merged
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions .changeset/slimy-tomatoes-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@eth-optimism/specs": minor
---

Add a new package to contain specs
4 changes: 3 additions & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
l2geth/ @smartcontracts @tynes @karlfloersch
packages/specs/l2geth/ @smartcontracts @tynes @karlfloersch
packages/contracts/ @smartcontracts @ben-chain @maurelian
packages/specs/protocol/ @smartcontracts @ben-chain @maurelian
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved packages/contracts/ up to make the relationship between the specs and the implementation locations more obvious.

ops/ @tynes @karlfloersch
packages/hardhat-ovm/ @smartcontracts
packages/smock/ @smartcontracts @maurelian
packages/core-utils/ @smartcontracts @annieke @maurelian @ben-chain
packages/core-utils/src/watcher.ts @K-Ho
packages/contracts/ @smartcontracts @ben-chain @maurelian
packages/message-relayer/ @K-Ho
packages/batch-submitter/ @annieke @karlfloersch
packages/data-transport-layer/ @annieke
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"workspaces": [
"packages/*",
"l2geth",
"integration-tests"
"integration-tests",
"specs"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gakonst is this change sufficient to "add it to the global yarn workspace" as requested?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

],
"private": true,
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
*********************************/

/**
* @notice Specifies from which L1 rollup queue this transaction originated from.
* @return _queueOrigin Address of the ovmL1QUEUEORIGIN within the current message context.
* @notice Specifies from which source (Sequencer or Queue) this transaction originated from.
* @return _queueOrigin Enum indicating the ovmL1QUEUEORIGIN within the current message context.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a comment I noticed needed improvement while doing this work.

*/
function ovmL1QUEUEORIGIN()
override
Expand Down
1 change: 1 addition & 0 deletions specs/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
15 changes: 15 additions & 0 deletions specs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Optimistic Specs

Welcome to Optimism's specs.

Please refer to the README in each of the subdirectories for a table of contents.

### Usage

We provide some basic yarn scripts to ensure consistent formatting.

After modifying any of the markdown files here, run `yarn format`.

```bash
yarn format
```
7 changes: 7 additions & 0 deletions specs/l2geth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# L2 Geth Specs

## Contents

- [Transaction indexer](./transaction-indexer.md)
- [Transaction ingestor](./transaction-ingestor.md)
- [Transaction types](./transaction-types.md)
109 changes: 109 additions & 0 deletions specs/l2geth/sequencer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Sequencer specs

## Contents

- [Batch Submitter](./batch-submitter.md) (empty file)
- [Fees](./fees.md) (empty file)

### Flow of a tx sent to a Sequencer

1. An L2 transaction is submitted to [l2geth](https://github.com/ethereum-optimism/go-ethereum)'s RPC server.
2. The transaction then sent to the [`Sync Service`](https://github.com/ethereum-optimism/specs/blob/main/transaction-ingestor.md)'s (aka `transaction-ingestor`) `applyTransaction(..) function.
3. The raw transaction data is supplied as the input to the [`run(...)`](https://github.com/ethereum-optimism/contracts/blob/master/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol#L155-L158) function in the ExecutionManager.
4. The block including a state root, transaction receipt, and transaction are all stored in Geth's default `EthDB`.
5. The batch submitter periodically queries L1 & L2Geth for unsubmitted transactions & if any are detected queries L2Geth for a range of blocks.
6. The GetBlock endpoint gets the block & transaction data from the EthDB.
7. Blocks are returned to the batch submitter.
8. The batch submitter generates a `appendSequencerBatch` transaction to the CTC on L1 and broadcasts it to its local L1Geth node. From there the transactions makes it into the Eth mainchain for availability & ordering.

<pre>
Ethereum Mainnet
┌──────────────────────────────┐
│┼────────────────────────────┼│
││ Ethereum L1 Mempool/Miners ││
│┼────────────────────────────┼│
└────────────▲─────────────────┘
Sequencer │
┌────────────────────────────────┼─────────────────────────────────────┐
│ │ │
│ ┌───────▼────────┐ 8)AppendBatch (many blocks)│
│ │ L1Geth ◄──────────────┐ │
│ └────────────────┘ │ │
│ L2Geth │ │
│ ┌────────────────────────────────────┐ │ │
│ │ │ │ │
│ │ ┌──────────────────────────┐ 5)Get│Blocks ┌──────┴────────┐ │
│ │ │ <a href="https://github.com/ethereum-optimism/go-ethereum/blob/master/internal/ethapi/api.go">RPC</a> ◄───────┼───────┤ │ │
│ │ │ │ │ 7)│Blocks │ │ │
1)Transaction┌────┼────┼─► SendTx(..) │GetBlock(..) ├───────┼───────►<a href="/sequencer/batch-submitter.md">Batch Submitter</a>│ │
────────────┘ │ │ └──────┬─────┴─────┬──▲────┘ │ └───────────────┘ │
│ │ 2)Tx│ │6)│Get Block │ │
│ │ │ ┌───▼──┴────┐ │ │
│ │ ┌──────▼─────┐ │ │ │ │
│ │ │<a href="/l2-geth/transaction-ingestor.md">Sync Service</a>│ │ <a href="https://github.com/ethereum-optimism/go-ethereum/tree/83593f20c213129f6dceac6321e7cbbad0035a26/core/rawdb">EthDB</a> │ │ │
│ │ └──────┬─────┘ │ │ │ │
│ │ │ └─────▲─────┘ │ │
│ │ 3)Tx│ 4)│Tx, Receipts │ │
│ │ │ │State root │ │
│ │ ┌──────▼─────────────┴───┐ │ │
│ │ │ <a href="/ovm/README.md">OVM</a> │ │ │
│ │ └────────────────────────┘ │ │
│ │ │ │
│ └────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────┘
</pre>

### Verifier Syncing from Mainnet

1. Batches full of L2 transactions are pulled in from an L1Geth node syncing mainnet Ethereum.
2. Each transaction is applied to the Sync Service (AKA the `transaction-ingestor`).
3. The Sync Service pipes the transaction into the OVM (using Geth's Clique Miner).
4. The OVM executes the transaction and stores the resulting state & blocks in the EthDB.
5. The Fraud Prover service pulls all of the recent state roots from L2Geth.
6. The RPC returns state roots stored in the EthDB that were originally stored by the OVM.
7. Now with all of the Verifier computed state roots, the Fraud Prover pulls all of the proposed state roots on L1. It compares the state roots that were computed **locally** against the **proposed** state roots in the State Commitment Chain. _UH OH_ the proposed state root DOES NOT equal the locally computed (and therefore correct) state root! We need to prove fraud!
8. The Fraud Prover requests a full fraud proof from the L2Geth node. This includes the contracts and storage slots that were accessed during the execution of the transaction.
9. The Fraud Prover signs Ethereum transactions and executes a fraud proof on L1! Claiming the bond of the state root proposer.

Yay the chain is secured by L1 and cryptoeconomics!

<pre>
Ethereum Mainnet
┌──────────────────────────────┐
│┼────────────────────────────┼│
││ Ethereum L1 Mempool/Miners ││
│┼────────────────────────────┼│
└────────────▲─────────────────┘
Verifier │
┌─────────────────────────┼───────────────────────────────────┐
│ │ │
│ ┌───────▼────────┐ 9)Execute Fraud proof │
│ │ L1Geth │◄─────────────────────┐ │
│ └─┬────┬─────────┘ │ │
│ │ │7)State Commitment Chain │ │
│ │ └───────────────────────┐ │ │
│ L2Geth │ │ │ │
│ ┌─────────────────┼───────────────────────┐ ┌──▼────────┴─┐ │
│ │ 1)│Batches │ │<a href="/verifier/fraud-prover.md">Fraud Prover</a> │ │
│ │ │ ┌─────────┬┤ └─▲─────────▲─┘ │
│ │ ┌───────▼────────┐ │ <a href="https://github.com/ethereum-optimism/go-ethereum/blob/master/internal/ethapi/api.go">RPC</a> ││ │ │ │
│ │ │<a href="/l2-geth/l1-data-indexer.md">Tx Indexer (DTL)</a>│ │ ◄├───┘ │ │
│ │ └──┬─────────────┘ └▲───────┬─┤5)Get State │ │
│ │ 2)Tx│ 6)│State │ │ roots │ │
│ │ │ │roots, │ │ │ │
│ │ │ │ └─┼─────────────┘ │
│ │ ┌──────▼─────┐ ┌──────────▼┐ │ 8)Fraud │
│ │ │<a href="/l2-geth/transaction-ingestor.md">Sync Service</a>│ │ <a href="https://github.com/ethereum-optimism/go-ethereum/tree/83593f20c213129f6dceac6321e7cbbad0035a26/core/rawdb">EthDB</a> │ │ proof │
│ │ └──────┬─────┘ └─────▲─────┘ │ data │
│ │ 3)Tx│ 4)│Tx, Receipts, │ │
│ │ │ │State roots │ │
│ │ ┌──────▼─────────────┴───┐ │ │
│ │ │ <a href="/ovm/README.md">OVM</a> │ │ │
│ │ └────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
</pre>
Empty file.
68 changes: 68 additions & 0 deletions specs/l2geth/sequencer/fees.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Transaction Fees Spec

## Goals

- Allow projects to easily query how high of a gasPrice their users need to set to get their transaction approved
- Allow the sequencer to only accept transactions that at least cover their cost to the system (L1 calldata gas costs + L2 gas costs)

## Non-goals

- Minimum possible fees
- Fee calculation that is completely automated
- Congestion Fees

## Why a separate service?

N/A

## Pre-launch timeline

- [ ] getGasPrice endpoint in geth + rejecting underfunded txs 2 weeks before launch
- [ ] Paying fees in Kovan -both Synthetix and Kovan by 1.5 week before launch
- [ ] Paying fees in Mainnet 1 week before launch

## Inputs & dependencies

- OVM_ETH (for fee payment)
- ETH Deposit Withdrawal Dapp
- Seeing your L2 WETH in SNX frontend

### getGasPrice(tx)

- Input is tx calldata

## Outputs

### estimateGasPrice(tx, ?gasLimit)

- returns `gasPrice` in wei to set for a given tx, taking into account the current `dataPrice` and `l2GasPrice` along with the `tx` calldata.

### getDataPrice()

- returns the `dataPrice` in wei (cost per zero byte). This will approximately track 4 \* l1 gasPrice

### getGasPrice()

- returns the gasPrice for L2 execution

### validateTx

- returns error message for eth_sendRawTransaction
- If tx is underfunded, "Error: Inadequate transaction fee. For this transaction to be accepted, set a gasPrice of \_\_ gwei"
- If tx has a gasLimit !== 9m, "Error: Expected a gas limit of 9m. Please set your tx gasLimit to 9m."

## Internals

Geth sets a dataPrice and a gasPrice internally. This can be displayed publicly on an `*.optimism.io` site.

- `dataPrice` in wei is the cost per zero byte of calldata. A non-zero byte of calldata will cost `dataPrice * 4` in wei.
- `gasPrice` in wei is the cost per unit of gas consumed during L2 execution.

```
// estimates the gas price based on a txs size and its gasLimit so gasPrice * gasLimit = intended fee
function estimateGasPrice(tx, ?gasLimit=9000000) {
const dataCost = dataPrice * (tx.zeroBytes + (tx.nonZeroBytes * 4))
const gasCost = gasLimit * gasPrice
return ((gasCost + dataCost) / gasLimit)
}
```
Loading