Skip to content

Commit

Permalink
Merge branch 'ethereum-optimism:main' into plasma-tx-version
Browse files Browse the repository at this point in the history
  • Loading branch information
tchardin authored Mar 13, 2024
2 parents aacf693 + d20de8f commit f86bf15
Show file tree
Hide file tree
Showing 17 changed files with 399 additions and 191 deletions.
9 changes: 3 additions & 6 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
@protolambda @tynes @ajsutton @sebastianst @mslipper

batcher.md @sebastianst @trianglesphere
bond-manager.md @ajsutton @clabby
bridges.md @tynes @maurelian
cannon-fault-proof-vm.md @ajsutton @clabby
deposits.md @protolambda @tynes
derivation.md @protolambda @trianglesphere
dispute-game-interface.md @ajsutton @clabby
exec-engine.md @sebastianst @trianglesphere
fault-dispute-game.md @ajsutton @clabby
fault-proof.md @ajsutton @clabby
# glossary.md
guaranteed-gas-market.md @tynes @maurelian
honest-challenger-fdg.md @ajsutton @clabby
# introduction.md
messengers.md @tynes @maurelian
# overview.md
Expand All @@ -26,3 +20,6 @@ superchain-configuration.md @protolambda @tynes
superchain-upgrades.md @protolambda @tynes
system_config.md @sebastianst @trianglesphere
withdrawals.md @tynes @maurelian @clabby

# Fault Proofs
/specs/experimental/fault-proof @ajsutton @clabby @inphi @refcell
27 changes: 23 additions & 4 deletions Justfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,41 @@
set positional-arguments

# default recipe to display help information
default:
@just --list

# Install required dependencies
deps:
pnpm i --frozen-lockfile

# Lint the workspace for all available targets
lint: lint-specs-md-check lint-specs-toc-check lint-links

# Updates all files to fix linting issues
lint-fix: lint-specs-md-fix lint-specs-toc

# Validates markdown file formatting
lint-specs-md-check:
npx markdownlint-cli2 "./specs/**/*.md"

# Updates markdown files formatting to satisfy lints
lint-specs-md-fix:
npx markdownlint-cli2-fix "./specs/**/*.md"
npx markdownlint-cli2 --fix "./specs/**/*.md"

# Validates Table of Content Sections with doctoc
lint-specs-toc-check:
npx doctoc '--title=**Table of Contents**' ./specs && git diff --exit-code .
npx doctoc '--title=**Table of Contents**' ./specs && git diff --exit-code ./specs

# Updates Table of Content Sections with doctoc
lint-specs-toc:
npx doctoc '--title=**Table of Contents**' ./specs

# Validates all hyperlinks respond with status 200
lint-links:
docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback \
--exclude twitter.com --exclude explorer.optimism.io --exclude linux-mips.org --exclude vitalik.ca \
--exclude-mail /input/README.md "/input/specs/**/*.md"

serve:
mdbook serve
# Serves the mdbook locally
serve *args='':
mdbook serve $@
2 changes: 1 addition & 1 deletion specs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
- [Bond Incentives](./experimental/fault-proof/stage-one/bond-incentives.md)
- [Bridge Integration](./experimental/fault-proof/stage-one/bridge-integration.md)
- [Plasma](./experimental/plasma.md)
- [Interoperability](./interop/README.md)
- [Interoperability](./interop/overview.md)
- [Dependency Set](./interop/dependency_set.md)
- [Messaging](./interop/messaging.md)
- [Predeploys](./interop/predeploys.md)
Expand Down
88 changes: 88 additions & 0 deletions specs/experimental/diff-based-attributes-tx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Diff Based L1Attributes Transaction

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**

- [Implementation](#implementation)
- [Ecotone L1Attributes Example](#ecotone-l1attributes-example)
- [Optimization](#optimization)
- [Node Implementation](#node-implementation)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

The `L1Attributes` transaction is the first transaction included in every L2 block.
It can be thought of as an extension to the L2 block header that is 100% backwards
compatible with L1 Ethereum by not changing the structure of the block header itself.
A major problem with the `L1Attributes` transaction is that it constantly submits the
same information over and over again. This adds chain history that must be preserved
forever. Ideally, the `L1Attributes` transaction only includes diffs to reduce the
growth of the chain history.

## Implementation

The `L1Attributes` transaction already commits to a schema that is ABI encoded.
There is no concept of an `Optional` type in ABI encoding, so instead we can
utilize a custom data structure to indicate the presence of a field in the schema.
A leading bitfield can be used to use presence. Each bit indicates a specific item
in the schema where `1` means it is present and `0` means it is not present. Each
item MUST have at least a fixed size portion so that the decoder knows how far
forward to seek after a read when the item is present.

### Ecotone L1Attributes Example

The following fields are required as part of the `L1Attributes` transaction after
the Ecotone network upgrade.

| Field | Size (bytes) | Bitfield Representation |
| ----------------- | ------------ | ------------------------ |
| baseFeeScalar | 4 | 0b1000\_0000\_0000\_0000 |
| blobBaseFeeScalar | 4 | 0b0100\_0000\_0000\_0000 |
| sequenceNumber | 8 | 0b0010\_0000\_0000\_0000 |
| l1BlockTimestamp | 8 | 0b0001\_0000\_0000\_0000 |
| l1BlockNumber | 8 | 0b0000\_1000\_0000\_0000 |
| basefee | 32 | 0b0000\_0100\_0000\_0000 |
| blobBaseFee | 32 | 0b0000\_0010\_0000\_0000 |
| l1BlockHash | 32 | 0b0000\_0001\_0000\_0000 |
| batcherHash | 32 | 0b0000\_0000\_1000\_0000 |

This is a total of 9 fields, so 9 bits are required to represent all of them.
It cannot fit into a single byte, so 2 bytes should be used to represent the bitfield.
Following the bitfield is the data tightly packed together.
When the value is set to `1` in the location that corresponds to the field, then
it indicates that the value is present and the the `size` number of bytes should
be read from the `calldata` and the offset of the next read from the calldata is
incremented by the `size`. If the value in the bitfield is a `0`, then the data
is not present and any reading/seeking is skipped.

### Optimization

The above example can be optimized by grouping the attributes that always change together
into a single bit. This would be the `l1BlockTimestamp`, the `l1BlockNumber` and `l1BlockHash`.
In the case of a missed L1 slot or L1 reorg, it is possible to have the `l1BlockNumber` not change but
the others may change. This case doesn't happen often and would result in some repeat data being
posted.

It is not safe to omit the `sequenceNumber` due to the fact that it always increases because we need
to guarantee that L1 Attributes Transactions have unique transaction hashes. In this way it acts as a nonce.

## Node Implementation

Previously, the node could read the calldata from the latest `L1Attributes` transaction
to be able to populate it's internal view of the `SystemConfig`. This will not be possible
with a diff based `L1Attributes` transaction implementation, but the problem can be solved
easily with a batch RPC call that reads each value directly from state using `eth_call`.

The RPC receipts are hydrated with the L1 fee parameters such that it is possible to
compute the L1 portion of the fee based on observing the receipt. These fields are not
part of the consensus encoding of the receipt, simply to provide better UX. These fields
are populated by deserializing the L1Attributes transaction's calldata. If the L1Attributes
transaction no longer always contains the latest values, then this approach is no longer feasible.
This means that the values would need to be instead read directly from state.
To prevent the need of an archive node to read the values from state for historical receipts,
an event can be emitted that contains the values required to hydrate this data.
Ideally this event does not need to be emitted for every L1Attributes transaction, but a simple
implementation may do so. It could be emitted everytime that the `sequenceNumber` is `0` and
the rehydration method could observe the L1Attributes transactions from the last L1 origin
update to the block including the receipt being hydrated and apply the diffs against the value
that was emitted from the event.
35 changes: 17 additions & 18 deletions specs/experimental/fault-proof/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
- [Type `3`: Global generic key](#type-3-global-generic-key)
- [Type `4`: Global SHA2-256 key](#type-4-global-sha2-256-key)
- [Type `5`: Global EIP-4844 Point-evaluation key](#type-5-global-eip-4844-point-evaluation-key)
- [Type `6`: Global EIP-4844 Point-evaluation precompile key](#type-6-global-eip-4844-point-evaluation-precompile-key)
- [Type `6`: Global Precompile key](#type-6-global-precompile-key)
- [Type `7-128`: reserved range](#type-7-128-reserved-range)
- [Type `129-255`: application usage](#type-129-255-application-usage)
- [Bootstrapping](#bootstrapping)
Expand All @@ -28,7 +28,7 @@
- [`l1-block-header <blockhash>`](#l1-block-header-blockhash)
- [`l1-transactions <blockhash>`](#l1-transactions-blockhash)
- [`l1-receipts <blockhash>`](#l1-receipts-blockhash)
- [`l1-kzg-point-evaluation <inputbytes>`](#l1-kzg-point-evaluation-inputbytes)
- [`l1-precompile <precompile ++ inputbytes>`](#l1-precompile-precompile--inputbytes)
- [`l2-block-header <blockhash>`](#l2-block-header-blockhash)
- [`l2-transactions <blockhash>`](#l2-transactions-blockhash)
- [`l2-code <codehash>`](#l2-code-codehash)
Expand Down Expand Up @@ -161,24 +161,24 @@ Key: `5 ++ keccak256(commitment ++ z)[1:]`, where:
- `commitment` is a bytes48, representing the KZG commitment.
- `z` is a big-endian `uint256`

#### Type `6`: Global EIP-4844 Point-evaluation precompile key
#### Type `6`: Global Precompile key

An EIP-4844 point-evaluation precompile result. It maps directly to the EIP-4844
point-evaluation precompile introduced in Cancun.
A precompile result. It maps directly to precompiles on Ethereum.

This preimage key can be used to avoid running expensive point-evaluation routine in
a program.
This preimage key can be used to avoid running expensive precompile operations in the program.

Key: `6 ++ keccak256(input)[1:]`, where:
Key: `6 ++ keccak256(precompile ++ input)[1:]`, where:

- `6` is the type byte
- `++` is concatenation
- `input` is the 192 byte input to the KZG point evaluation precompile
- `precompile` is the 20-byte address of the precompile contract
- `input` is the input to the precompile contract

The result has two possible 1-byte values:
The result is identical to that of a call to the precompile contract, prefixed with a revert indicator:

- `0` if the point evaluation precompile fails
- `1` - otherwise
- `reverted ++ precompile_result`.

`reverted` is a 1-byte indicator with a `0` value if the precompile reverts for the given input, otherwise it's `1`.

#### Type `7-128`: reserved range

Expand Down Expand Up @@ -409,11 +409,11 @@ prepare the RLP pre-images of each of them, including transactions-list MPT node
Requests the host to prepare the list of receipts of the L1 block with `<blockhash>`:
prepare the RLP pre-images of each of them, including receipts-list MPT nodes.

#### `l1-kzg-point-evaluation <inputbytes>`
#### `l1-precompile <precompile ++ inputbytes>`

Requests the host to prepare the result of the L1 KZG point evaluation precompile given
Requests the host to prepare the result of an L1 call to the `precompile` address given
`<inputbytes>` as the input. The host also prepares a [global keccak256 preimage](#type-2-global-keccak256-key)
of the input.
of the hint data `<precompile ++ inputbytes>`.

#### `l2-block-header <blockhash>`

Expand Down Expand Up @@ -446,9 +446,8 @@ This approach ensures that the fault proof program can complete a state transiti
amount of time.

During program execution, the precompiles are substituted with interactions with pre-image oracle.
An example of this is the KZG point evaluation precompile, where the program provides
the host with a hint for the point evaluation input. This allows it to subsequently retrieve the result
using a [type `6` pre-image key](#type-6-global-eip-4844-point-evaluation-precompile-key) from the oracle.
The program hints the host for a precompile input. Which it the subsequently retrieves the result of the precompile
opereation using the [type 6 global precompile key](#type-6-global-precompile-key).
All accelerated precompiles must be functionally equivalent to their EVM equivalent.

## Fault Proof VM
Expand Down
Loading

0 comments on commit f86bf15

Please sign in to comment.