Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
make rollup node spec consistent with deposit spec
Browse files Browse the repository at this point in the history
  • Loading branch information
norswap committed Jan 9, 2022
1 parent 3fba61b commit 037749a
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 82 deletions.
48 changes: 29 additions & 19 deletions specs/deposits.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
[transaction-type]: /glossary.md#transaction-type
[derivation]: /glossary.md#L2-chain-derivation
[execution-engine]: /glossary.md#execution-engine
[deposits]: /glossary.md#deposits
[L1 attributes deposit]: /glossary.md#l1-attributes-deposit
[transaction deposits]: /glossary.md#transaction-deposits

Deposits are transactions which are initiated on L1, and executed on L2. This document outlines a new
[transaction type][transaction-type] for deposits. It also describes how deposits are initiated on
L1, along with the authorization and validation conditions on L2.
[Deposits] are transactions which are initiated on L1, and executed on L2. This document outlines a
new [transaction type][transaction-type] for deposits. It also describes how deposits are initiated
on L1, along with the authorization and validation conditions on L2.

## The Deposit Transaction Type

Expand All @@ -16,7 +19,8 @@ L1, along with the authorization and validation conditions on L2.
Deposit transactions have the following notable distinctions from existing transaction types:

1. They are derived from Layer 1 blocks, and must be included as part of the protocol.
2. They do not include signature validation (see [L1 transaction deposits][l1-transaction-deposits] for the rationale).
2. They do not include signature validation (see [L1 transaction deposits][l1-transaction-deposits]
for the rationale).

We define a new [EIP-2718] compatible transaction type with the prefix `0x7E`, and the following
fields (rlp encoded in the order they appear here):
Expand Down Expand Up @@ -59,12 +63,13 @@ modifications to L1 client software and complexity in general.
[authorization]: #validation-and-authorization-of-deposit-transaction-types

As noted above, the deposit transaction type does not include a signature for validation. Rather,
authorization is handled by the [L2 chain Derivation][derivation] process, which when
correctly processed will only derive transactions with a `from` address attested to
by the logs of the [L1 deposit feed contract][deposit-feed-contract].
authorization is handled by the [L2 chain Derivation][derivation] process, which when correctly
processed will only derive transactions with a `from` address attested to by the logs of the [L1
deposit feed contract][deposit-feed-contract].

In the event a deposit transaction is included which is not derived by the [execution engine][execution-engine]
using the correct derivation algorithm, the resulting state transition would be invalid.
In the event a deposit transaction is included which is not derived by the [execution
engine][execution-engine] using the correct derivation algorithm, the resulting state transition
would be invalid.

### Execution

Expand Down Expand Up @@ -99,7 +104,8 @@ tooling (such as wallets and block explorers).

[l1-attributes-deposit]: #l1-attributes-deposit

This is a deposit transaction sent to the [L1 attributes predeploy][predeploy] contract.
An [L1 attributes deposit] is a deposit transaction sent to the [L1 attributes predeploy][predeploy]
contract.

This transaction MUST have the following values:

Expand All @@ -110,8 +116,9 @@ This transaction MUST have the following values:
3. `mint` is `0`
4. `value` is `0`
5. `gasLimit` is set to the maximum available.
6. `data` is an [ABI] encoded call to the [L1 attributes predeploy][predeploy] contract's `setL1BlockValues()`
function with correct values associated with the corresponding L1 block.
6. `data` is an [ABI] encoded call to the [L1 attributes predeploy][predeploy] contract's
`setL1BlockValues()` function with correct values associated with the corresponding L1 block (cf.
[reference implementation][l1-attrib-ref-implem]).

<!-- TODO: Define how this account pays gas on these transactions. -->

Expand Down Expand Up @@ -148,6 +155,8 @@ The contract has the following solidity interface, and can be interacted with ac

#### L1 Attributes: Reference Implementation

[l1-attrib-ref-implem]: #l1-attributes--reference-implementation

A reference implementation of the L1 Attributes predeploy contract can be found in [L1Block.sol].

[L1Block.sol]: /packages/contracts/contracts/L1Block.sol
Expand All @@ -161,8 +170,8 @@ The bytecode to add to the genesis file will be located in the `deployedBytecode

[l1-transaction-deposits]: #l1-transaction-deposits

L1 transaction deposits are [deposit transactions][deposit-transaction-type] generated by the
[L2 Chain Derivation][derivation] process. The values of each transaction are determined by the
L1 [transaction deposits] are [deposit transactions][deposit-transaction-type] generated by the [L2
Chain Derivation][derivation] process. The values of each transaction are determined by the
corresponding `TransactionDeposited` event emitted by the [deposit feed
contract][deposit-feed-contract] on L1.

Expand All @@ -188,7 +197,8 @@ The deposit feed handles two special cases:

1. A contract creation deposit, which is indicated by setting the `isCreation` flag to `true`.
In the event that the `to` address is non-zero, the contract will revert.
2. A call from a contract account, in which case the `from` value is transformed to its L2 [alias][address-aliasing].
2. A call from a contract account, in which case the `from` value is transformed to its L2
[alias][address-aliasing].

> **TODO** Define if/how ETH withdrawals occur.
Expand All @@ -197,10 +207,10 @@ The deposit feed handles two special cases:
[address-aliasing]: #address-aliasing

If the caller is not a contract, the address will be ed by adding
`0x1111000000000000000000000000000000001111`. This prevents attacks in which a contract on L1
has the same address as a contract on L2 but doesn't have the same code. We can safely ignore
this for EOAs because they're guaranteed to have the same "code" (i.e. no code at all). This also
makes it possible for users to interact with contracts on L2 even when the Sequencer is down.
`0x1111000000000000000000000000000000001111`. This prevents attacks in which a contract on L1 has
the same address as a contract on L2 but doesn't have the same code. We can safely ignore this for
EOAs because they're guaranteed to have the same "code" (i.e. no code at all). This also makes it
possible for users to interact with contracts on L2 even when the Sequencer is down.

#### Deposit Feed: Reference Implementation

Expand Down
70 changes: 47 additions & 23 deletions specs/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
- [L2 Chain Derivation](#l2-chain-derivation)
- [L2 Derivation Inputs](#l2-derivation-inputs)
- [Payload Attributes](#payload-attributes)
- [L1 Attributes Transaction](#l1-attributes-transaction)
- [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract)
- [Deposits](#deposits)
- [L1 Attributes Deposit](#l1-attributes-deposit)
- [Transaction Deposit](#transaction-deposit)
- [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract)
- [Deposit Transaction Type](#deposit-transaction-type)
- [Deposit Feed Contract](#deposit-feed-contract)
- [Execution Engine Concepts](#execution-engine-concepts)
Expand Down Expand Up @@ -186,23 +187,56 @@ cf. [Execution Engine Specification](exec-engine.md)
Payload attributes were historically called "L2 block inputs" in the L2 spec and you might still hear some people using
this term.

## L1 Attributes Transaction
## Deposits

[deposits]: /glossary.md#deposits

A deposit is an L2 transaction derived from an L1 block.

There are two kinds of deposits:

- [L1 Attributes Deposit][l1-attribute-tx], which submit the L1 block's attributes to the [L1 Attributes Predeployed
Contract][l1-attr-predeploy].
- [Transaction Deposits][tx-deposits], which are transaction that have been submitted on L1, via a transaction sent to
the [deposit feed contract][deposit-feed].

While transaction deposits are notably (but not only) used to "deposit" (bridge) ETH and tokens to L2, the word
*deposit* should be understood as "a transaction *deposited* to L2 from L1".

The term *deposit* performs the double duty of referring to both:

1. The transaction information submitted on L1 to the [deposit feed contract][deposit-feed]. This is a kind of [L2
derivation input][deriv-input].
2. The actual L2 transaction derived from this L1 input.

Deposits are specified in the [deposits specification][deposits-spec].

[l1-attributes-tx]: /glossary.md#l1-attributes-transaction
[deposits-spec]: deposits.md

A transaction with an Optimism-specific transaction type, that is used to register the L1 block attributes
(number, timestamp, ...) on L2.
## L1 Attributes Deposit

The L1 attributes for a given L1 block can be read on L2 from the [L1 Attributes Predeployed
Contract][l1-attr-predeploy].
[l1-attributes-deposit]: /glossary.md#l1-attributes-deposit

cf. [L1 attributes transaction format](/rollup-node.md#payload-transaction-format) (in the section on [payload
attributes])
A [deposit][deposits] that is used to register the L1 block attributes (number, timestamp, ...) on L2 via a call to the
[L1 Attributes Predeployed Contract][l1-attr-predeploy]. That contract can then be used to read the the attributes of
the L1 block corresponding to the current L2 block.

> **TODO** We might want to move this the format spec to the execution engine.
L1 attributes deposits are specified in the [L1 Attributes Deposit][l1-attributes-tx-spec] section of the deposits
specification.

> **TODO** We might wish to make this a "normal transaction" if deposits end up
> not carrying a signature.
[l1-attributes-tx-spec]: deposits.md#l1-attributes-deposit

## Transaction Deposits

[tx-deposits]: #transaction-deposits

These [deposits] are transaction that have been submitted on L1, via a transaction sent to the [deposit feed
contract][deposit-feed].

Transaction deposits are specified in the [Transaction Deposits][tx-deposits-spec] section of the deposits
specification.

[tx-deposits-spec]: deposits.md#l1-transaction-deposits

## L1 Attributes Predeployed Contract

Expand All @@ -215,17 +249,7 @@ cf. [L1 Attributes Predeployed Contract Specification](TODO)

> **TODO LINK** L1 attributes predeployed contract spec
## Deposits

[deposits]: /glossary.md#deposits

A deposit is an L2 transaction that has been submitted on L1, via a transaction sent to the [deposit feed
contract][deposit-feed].

While deposits are notably (but not only) used to "deposit" (bridge) ETH and tokens to L2, the word *deposit* should be
understood as "a transaction *deposited* to L2".

Deposits are one kind of [L2 derivation input][deriv-input].

## Deposit Transaction Type

Expand Down
81 changes: 41 additions & 40 deletions specs/rollup-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
[deposit-feed]: /glossary.md#L2-deposit-feed-contract
[L2 chain inception]: /glossary.md#L2-chain-inception
[receipts]: /glossary.md#receipt
[L1 attributes deposit]: /glossary.md#l1-attributes-deposit
[transaction deposits]: /glossary.md#transaction-deposits

The [rollup node] is the component responsible for [deriving the L2 chain][derivation] from L1 blocks (and their
associated [receipts]). This process happens in two steps:
Expand Down Expand Up @@ -41,11 +43,11 @@ concerned with the specification of the rollup driver.

[l2-chain-derivation]: #l2-chain-derivation

This section specifies how the [rollup driver] derives one L2 block per every L1 block. The L2 block will carry the L1
block attributes (as a *[L1 attributes transaction]*) well as all L2 transactions deposited by users in the L1 block
(*[deposits]*).
This section specifies how the [rollup driver] derives one L2 block per every L1 block. The L2 block will carry
*[deposits]*, including a single *[L1 attributes deposit]* (which carries L1 block attributes) and zero or more
*[transaction deposits]* submitted by user on L1.

[L1 attributes transaction]: /glossary.md#l1-attributes-transaction
----

### From L1 blocks to payload attributes

Expand All @@ -59,11 +61,12 @@ The rollup reads the following data from each L1 block:
- timestamp
- basefee
- *random* (the output of the [`RANDOM` opcode][random])
- [deposits]
- L1 log entries emitted for [transaction deposits]

[random]: https://eips.ethereum.org/EIPS/eip-4399

A deposit is an L2 transaction that has been submitted on L1, via a call to the [deposit feed contract][deposit-feed].
A [transaction deposit][transaction deposits] is an L2 transaction that has been submitted on L1, via a call to the
[deposit feed contract][deposit-feed].

While deposits are notably (but not only) used to "deposit" (bridge) ETH and tokens to L2, the word *deposit* should be
understood as "a transaction *deposited* to L2".
Expand Down Expand Up @@ -99,57 +102,53 @@ The object properties must be set as follows:
rounded to the closest multiple of 2 seconds. No two blocks may have the same timestamp.
- `random` is set to the *random* L1 block attribute
- `suggestedFeeRecipient` is set to an address where the sequencer would like to direct the fees
- `transactions` is an array of transactions, encoded in the [EIP-2718] format (i.e. as a single byte defining the
transaction type, concatenated with an opaque byte array whose meaning depends on the type).
- `transactions` is an array containing the [L1 attributes deposit] as well as [transaction deposits], whose format is
specified in the [next section][payload-format].

> **TODO** we need to handle non-EIP-2718 transactions too
[unix type]: https://en.wikipedia.org/wiki/Unix_time
[merge]: https://ethereum.org/en/eth2/merge/
[unix time]: https://en.wikipedia.org/wiki/Unix_time
[yellow paper]: https://github.com/ethereum/yellowpaper
[EIP-155]: https://eips.ethereum.org/EIPS/eip-155
[EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559
[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718
[EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930

[encode-tx]: https://github.com/norswap/nanoeth/blob/cc5d94a349c90627024f3cd629a2d830008fec72/src/com/norswap/nanoeth/transactions/Transaction.java#L84-L130
----

The [EIP-2718] transactions must have a transaction type that is valid on L1, or be an *[L1 attributes transaction]*
(see below).

#### Payload Transaction Format
### Payload Transaction Format

[payload-format]: #payload-transaction-format

The `transactions` array is filled with the deposits, prefixed by the (single) [L1 attributes transaction]. The deposits
are simply copied byte-for-byte — it is the role of the [execution engine] to reject invalidly-formatted transactions.

> **TODO** must offer some precisions on the format of deposits: sender,
> receivers both in-tx-as-encoded, and on-L2-tx. What about the fees?
The `transactions` array is filled with user-submitted deposits, prefixed by the (single) [L1 attributes deposit]. The
format for deposits is described at [the top of the deposit specification][deposit-transaction-type].

The Optimism-specific *[L1 attributes transaction]* has the following [EIP-2718]-compatible format: `0x7E ||
[block_number, timestamp, basefee]` where:
[deposit-transaction-type]: deposits.md#the-deposit-transaction-type

- `0x7E` is the transaction type identifier.
- `block_number` is the L1 block number as a 64-bit integer (4 bytes)
- `timestamp` is the L1 block timestamp as a 64-bit integer (4 bytes)
- `basefee` is the L1 block basefee as a 64-bit integer (4 bytes)
The rollup node is responsible for encoding the L1 attributes deposit based on the attributes (block number, timestamp
and basefee) of the L1 block, as specified in the [L1 Attributes Deposit][l1-attributes-deposit-spec] section of the
deposit specification. It must also encode the transaction deposits based on the `TransactionDeposited` event
emitted by the deposit contract, as specified by the [L1 Transaction Deposits][l1-transaction-deposits] section of the
same document.

When included in the `transactions` array, this transaction should be RLP-encoded in the same way as other transactions.
[l1-attributes-deposit-spec]: deposits.md#l1-attributes-deposit
[l1-transaction-deposits]: deposits.md#l1-transaction-deposits

> **TODO** move this section into a doc specific to the execution-engine
Here is an example valid `PayloadAttributesOPV1` object, which contains an L1 attributes transaction as well as a single
deposit:
Here is an example valid `PayloadAttributesOPV1` object, which contains an L1 attributes deposit as well as a single
transaction deposit:

```js
{
timestamp: "0x61a6336f",
random: "0xde5dff2b0982ecbbd38081eb8f4aed0525140dc1c1d56f995b4fa801a3f2649e",
suggestedFeeRecipient: "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
transactions: [
"TODO specify L1 attribute transaction",
"TODO generate abi-encoded L1 attribute deposit",
"0x02f87101058459682f0085199c82cc0082520894ab5801a7d398351b8be11c439e05c5b3259aec9b8609184e72a00080c080a0a6d217a91ea344fc09f740f104f764d71bb1ca9a8e159117d2d27091ea5fce91a04cf5add5f5b7d791a2c4663ab488cb581df800fe0910aa755099ba466b49fd69"
]
}
```

----

### Building the L2 block with the execution engine

[calling-exec-engine]: #building-the-L2-block-with-the-execution-engine
Expand Down Expand Up @@ -189,15 +188,15 @@ route. This has the same signature, except that:
- `headBlockHash`: block hash of the last block of the L2 chain, according to the rollup driver.
- `safeBlockHash`: same as `headBlockHash`.
- `finalizedBlockHash`: the hash of the block whose number is `number(headBlockHash) - FINALIZATION_DELAY_BLOCKS` if
the number of that block is `>= L2_CHAIN_INCEPTION`, 0 otherwise (where `FINALIZATION_DELAY_BLOCKS == 50400`
(approximately 7 days worth of L1 blocks) and `L2_CHAIN_INCEPTION` is the [L2 chain inception] (the number of the
the number of that block is `>= L2_CHAIN_INCEPTION`, 0 otherwise (where `FINALIZATION_DELAY_BLOCKS` = 50400,
approximately 7 days worth of L1 blocks) and `L2_CHAIN_INCEPTION` is the [L2 chain inception] (the number of the
first L1 block for which an L2 block was produced). See the [Finalization Guarantees][finalization] section for more
details.

[`ForkchoiceStateV1`]: https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#ForkchoiceStateV1

> **Note:** the properties of this `ForkchoiceStateV1` can be used to anchor queries to the regular (non-engine-API)
> JSON-RPC endpoint of the execution engine. [See here for more information.][L2-JSON-RPC-API]
> **Note:** the properties of `ForkchoiceStateV1` can be used to anchor queries to the regular (non-engine-API) JSON-RPC
> endpoint of the execution engine. [See here for more information.][L2-JSON-RPC-API]
[L2-JSON-RPC-API]: TODO

Expand All @@ -216,9 +215,9 @@ requiring manual user intervention).

The following scenarios are assimilated to errors:

- [`engine_forkchoiceUpdateOPV1`] returning a `status` of "`SYNCING`" instead of "`SUCCESS`" whenever passed a
- [`engine_forkchoiceUpdatedOPV1`] returning a `status` of `"SYNCING"` instead of `"SUCCESS"` whenever passed a
`headBlockHash` that it retrieved from a previous call to [`engine_executePayloadV1`].
- [`engine_executePayloadV1`] returning a `status` of "`SYNCING`" or `"INVALID"` whenever passed an execution payload
- [`engine_executePayloadV1`] returning a `status` of `"SYNCING"` or `"INVALID"` whenever passed an execution payload
that was obtained by a previous call to [`engine_getPayloadV1`].

[`engine_getPayloadV1`]: exec-engine.md#engine_executepayloadv1
Expand Down Expand Up @@ -260,6 +259,8 @@ the descendant of an ancestor of the previous head). In those case, the rollup d
> Note that post-[merge], the L1 chain will offer finalization guarantees meaning that it won't be able to re-org more
> than `FINALIZATION_DELAY_BLOCKS == 50400` in the past, hence preserving our finalization guarantees.
[merge]: https://ethereum.org/en/eth2/merge/

Just like before, the meaning of errors returned by RPC calls is unspecified and must be handled at the implementer's
discretion, while remaining compatible with the specification.

Expand Down

0 comments on commit 037749a

Please sign in to comment.