From 79337fff94d0f717f5728d27f16d000281d43eae Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 2 Oct 2024 14:11:02 -0700 Subject: [PATCH] specs: migrate holocene dropped features to isthmus (#407) * specs: migrate holocene dropped features to isthmus * isthmus: delete dead spec * more updates * add rationale * lint * lint: fix --- specs/SUMMARY.md | 2 +- specs/experimental/op-contracts-manager.md | 2 +- specs/protocol/configurability.md | 2 +- specs/protocol/holocene/exec-engine.md | 91 +++++-------------- specs/protocol/holocene/overview.md | 7 +- specs/protocol/holocene/system-config.md | 80 ++++++++++++++++ .../{holocene => isthmus}/configurability.md | 64 +++++-------- specs/protocol/isthmus/exec-engine.md | 78 ++++++++++++++++ specs/protocol/isthmus/overview.md | 7 +- .../{holocene => isthmus}/predeploys.md | 20 +++- specs/protocol/isthmus/superchain-config.md | 34 +++++++ 11 files changed, 266 insertions(+), 121 deletions(-) create mode 100644 specs/protocol/holocene/system-config.md rename specs/protocol/{holocene => isthmus}/configurability.md (80%) create mode 100644 specs/protocol/isthmus/exec-engine.md rename specs/protocol/{holocene => isthmus}/predeploys.md (91%) create mode 100644 specs/protocol/isthmus/superchain-config.md diff --git a/specs/SUMMARY.md b/specs/SUMMARY.md index fff23e9b2..b8547733b 100644 --- a/specs/SUMMARY.md +++ b/specs/SUMMARY.md @@ -54,7 +54,7 @@ - [Derivation](./protocol/holocene/derivation.md) - [Execution Engine](./protocol/holocene/exec-engine.md) - [Predeploys](./protocol/holocene/predeploys.md) - - [Configurability](./protocol/holocene/configurability.md) + - [System Config](./protocol/holocene/system-config.md) - [Governance]() - [Governance Token](./governance/gov-token.md) - [Experimental]() diff --git a/specs/experimental/op-contracts-manager.md b/specs/experimental/op-contracts-manager.md index fa80e67ba..405eebb8d 100644 --- a/specs/experimental/op-contracts-manager.md +++ b/specs/experimental/op-contracts-manager.md @@ -45,7 +45,7 @@ TODO. ## Interface -Version 1.0.0 of the OP Contracts Manager deploys the [`op-contracts/v1.6.0`] +Version 1.0.0 of the OP Contracts Manager deploys the `op-contracts/v1.6.0` contracts release. ### `Proxy.sol` diff --git a/specs/protocol/configurability.md b/specs/protocol/configurability.md index 4101c2174..4754c956d 100644 --- a/specs/protocol/configurability.md +++ b/specs/protocol/configurability.md @@ -130,7 +130,7 @@ to finalize withdrawals.
**Requirement:** [`CANNON` ( `0`)](https://github.com/ethereum-optimism/optimism/blob/op-contracts/v1.5.0/packages/contracts-bedrock/src/dispute/lib/Types.sol#L28)
**Notes:** The game type may be changed to [`PERMISSIONED_CANNON` ( -`1`)](https://github.com/ethereum-optimism/optimism/blob/op-contracts/v1.5.0/packages/contracts-bedrock/src/dispute/lib/Types.sol#L31) +`1`)]() as a fallback to permissioned proposals, in the event of a failure in the Fault Proof system.
### Fault Game Max Depth diff --git a/specs/protocol/holocene/exec-engine.md b/specs/protocol/holocene/exec-engine.md index c745deb65..df7a4eb9b 100644 --- a/specs/protocol/holocene/exec-engine.md +++ b/specs/protocol/holocene/exec-engine.md @@ -4,82 +4,33 @@ **Table of Contents** +- [Overview](#overview) - [Timestamp Activation](#timestamp-activation) -- [`L2ToL1MessagePasser` Storage Root in Header](#l2tol1messagepasser-storage-root-in-header) - - [Header Validity Rules](#header-validity-rules) - - [Header Withdrawals Root](#header-withdrawals-root) - - [Rationale](#rationale) - - [Forwards Compatibility Considerations](#forwards-compatibility-considerations) - - [Client Implementation Considerations](#client-implementation-considerations) -- [Extended `PayloadAttributesV3`](#extended-payloadattributesv3) - - [`eip1559Params` encoding](#eip1559params-encoding) +- [Dynamic EIP-1559 Parameters](#dynamic-eip-1559-parameters) + - [Extended `PayloadAttributesV3`](#extended-payloadattributesv3) + - [`eip1559Params` encoding](#eip1559params-encoding) - [Execution](#execution) - - [Rationale](#rationale-1) -- [`eip1559Params` in Header](#eip1559params-in-header) - - [Header Validity Rules](#header-validity-rules-1) - - [Encoding](#encoding) - - [Rationale](#rationale-2) + - [Rationale](#rationale) + - [`eip1559Params` in Header](#eip1559params-in-header) + - [Header Validity Rules](#header-validity-rules) + - [Encoding](#encoding) + - [Rationale](#rationale-1) +## Overview + +The EIP-1559 parameters are encoded in the block header's `nonce` field and can be +configured dynamically through the `SystemConfig`. + ## Timestamp Activation Holocene, like other network upgrades, is activated at a timestamp. Changes to the L2 Block execution rules are applied when the `L2 Timestamp >= activation time`. -## `L2ToL1MessagePasser` Storage Root in Header - -After Holocene's activation, the L2 block header's `withdrawalsRoot` field will consist of the 32-byte -[`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root _after_ the block has been executed, and _after_ the -insertions and deletions have been applied to the trie. In other words, the storage root should be the same root -that is returned by `eth_getProof` at the given block number. - -### Header Validity Rules - -Prior to holocene activation, the L2 block header's `withdrawalsRoot` field must be: - -- `nil` if Canyon has not been activated. -- `keccak256(rlp(empty_string_code))` if Canyon has been activated. +## Dynamic EIP-1559 Parameters -After Holocene activation, an L2 block header's `withdrawalsRoot` field is valid iff: - -1. It is exactly 32 bytes in length. -1. The [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root, as committed to in the `storageRoot` within the block - header, is equal to the header's `withdrawalsRoot` field. - -### Header Withdrawals Root - -| Byte offset | Description | -| ----------- | --------------------------------------------------------- | -| `[0, 32)` | [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root | - -#### Rationale - -Currently, to generate [L2 output roots][output-root] for historical blocks, an archival node is required. This directly -places a burden on users of the system in a post-fault-proofs world, where: - -1. A proposer must have an archive node to propose an output root at the safe head. -1. A user that is proving their withdrawal must have an archive node to verify that the output root they are proving - their withdrawal against is indeed valid and included within the safe chain. - -Placing the [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root in the `withdrawalsRoot` field alleviates this burden -for users and protocol participants alike, allowing them to propose and verify other proposals with lower operating costs. - -#### Forwards Compatibility Considerations - -As it stands, the `withdrawalsRoot` field is unused within the OP Stack's header consensus format, and will never be -used for other reasons that are currently planned. Setting this value to the account storage root of the withdrawal -directly fits with the OP Stack, and makes use of the existing field in the L1 header consensus format. - -#### Client Implementation Considerations - -Varous EL clients store historical state of accounts differently. If, as a contrived case, an OP Stack chain did not have -an outbound withdrawal for a long period of time, the node may not have access to the account storage root of the -[`L2ToL1MessagePasser`][l2-to-l1-mp]. In this case, the client would be unable to keep consensus. However, most modern -clients are able to at the very least reconstruct the account storage root at a given block on the fly if it does not -directly store this information. - -## Extended `PayloadAttributesV3` +### Extended `PayloadAttributesV3` The [`PayloadAttributesV3`](https://github.com/ethereum/execution-apis/blob/cea7eeb642052f4c2e03449dc48296def4aafc24/src/engine/cancun.md#payloadattributesv3) type is extended to: @@ -98,7 +49,7 @@ PayloadAttributesV3: { } ``` -### `eip1559Params` encoding +#### `eip1559Params` encoding | Name | Type | Byte Offset | | ------------- | ------------------ | ----------- | @@ -124,21 +75,21 @@ parameters of the chain. As described in the [derivation - AttributesBuilder](./ section, the derivation pipeline must populate this field from the `SystemConfig` during payload building, similar to how it must reference the `SystemConfig` for the `gasLimit` field. -## `eip1559Params` in Header +### `eip1559Params` in Header Upon Holocene activation, the L2 block header's `nonce` field will consist of the 8-byte `eip1559Params` value. -### Header Validity Rules +#### Header Validity Rules Prior to Holocene activation, the L2 block header's `nonce` field is valid iff it is equal to `u64(0)`. After Holocene activation, The L2 block header's `nonce` field is valid iff it is non-zero. -### Encoding +#### Encoding The encoding of the `eip1559Params` value is described in [`eip1559Params` encoding](#eip1559params-encoding). -### Rationale +#### Rationale By chosing to put the `eip1559Params` in the `PayloadAttributes` rather than in the L1 block info transaction, the EIP-1559 parameters for the chain are not available within history. This would place a burden on performing diff --git a/specs/protocol/holocene/overview.md b/specs/protocol/holocene/overview.md index 095b2a1db..b29019e67 100644 --- a/specs/protocol/holocene/overview.md +++ b/specs/protocol/holocene/overview.md @@ -10,11 +10,9 @@ -This document is not finalized and should be considered experimental. - ## Execution Layer -- [L2ToL1MessagePasser Storage Root in Header](./exec-engine.md##l2tol1messagepasser-storage-root-in-header) +- [Dynamic EIP-1559 Parameters](./exec-engine.md#dynamic-eip-1559-parameters) ## Consensus Layer @@ -22,5 +20,4 @@ This document is not finalized and should be considered experimental. ## Smart Contracts -- [Predeploys](./predeploys.md) -- [Configurability](./configurability.md) +- [System Config](./system-config.md) diff --git a/specs/protocol/holocene/system-config.md b/specs/protocol/holocene/system-config.md new file mode 100644 index 000000000..c94105621 --- /dev/null +++ b/specs/protocol/holocene/system-config.md @@ -0,0 +1,80 @@ +# System Config + + + +**Table of Contents** + +- [Overview](#overview) + - [`ConfigUpdate`](#configupdate) + - [Initialization](#initialization) + - [Modifying EIP-1559 Parameters](#modifying-eip-1559-parameters) + - [Interface](#interface) + - [EIP-1559 Params](#eip-1559-params) + - [`setEIP1559Params`](#seteip1559params) + - [`eip1559Elasticity`](#eip1559elasticity) + - [`eip1559Denominator`](#eip1559denominator) + + + +## Overview + +The `SystemConfig` is updated to allow for dynamic EIP-1559 parameters. + +### `ConfigUpdate` + +The following `ConfigUpdate` event is defined where the `CONFIG_VERSION` is `uint256(0)`: + +| Name | Value | Definition | Usage | +| ---- | ----- | --- | -- | +| `BATCHER` | `uint8(0)` | `abi.encode(address)` | Modifies the account that is authorized to progress the safe chain | +| `FEE_SCALARS` | `uint8(1)` | `(uint256(0x01) << 248) \| (uint256(_blobbasefeeScalar) << 32) \| _basefeeScalar` | Modifies the fee scalars | +| `GAS_LIMIT` | `uint8(2)` | `abi.encode(uint64 _gasLimit)` | Modifies the L2 gas limit | +| `UNSAFE_BLOCK_SIGNER` | `uint8(3)` | `abi.encode(address)` | Modifies the account that is authorized to progress the unsafe chain | +| `EIP_1559_PARAMS` | `uint8(4)` | `uint256(uint64(uint32(_denominator))) << 32 \| uint64(uint32(_elasticity))` | Modifies the EIP-1559 denominator and elasticity | + +### Initialization + +The following actions should happen during the initialization of the `SystemConfig`: + +- `emit ConfigUpdate.BATCHER` +- `emit ConfigUpdate.FEE_SCALARS` +- `emit ConfigUpdate.GAS_LIMIT` +- `emit ConfigUpdate.UNSAFE_BLOCK_SIGNER` +- `emit ConfigUpdate.EIP_1559_PARAMS` + +### Modifying EIP-1559 Parameters + +A new `SystemConfig` `UpdateType` is introduced that enables the modification of +[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) parameters. This allows for the chain +operator to modify the `BASE_FEE_MAX_CHANGE_DENOMINATOR` and the `ELASTICITY_MULTIPLIER`. + +### Interface + +#### EIP-1559 Params + +##### `setEIP1559Params` + +This function MUST only be callable by the chain governor. + +```solidity +function setEIP1559Params(uint32 _denominator, uint32 _elasticity) +``` + +The `_denominator` and `_elasticity` MUST be set to values greater to than 0. +It is possible for the chain operator to set EIP-1559 parameters that result in poor user experience. + +##### `eip1559Elasticity` + +This function returns the currently configured EIP-1559 elasticity. + +```solidity +function eip1559Elasticity()(uint64) +``` + +##### `eip1559Denominator` + +This function returns the currently configured EIP-1559 denominator. + +```solidity +function eip1559Denominator()(uint64) +``` diff --git a/specs/protocol/holocene/configurability.md b/specs/protocol/isthmus/configurability.md similarity index 80% rename from specs/protocol/holocene/configurability.md rename to specs/protocol/isthmus/configurability.md index 3f42ccbe2..7c2792e58 100644 --- a/specs/protocol/holocene/configurability.md +++ b/specs/protocol/isthmus/configurability.md @@ -10,12 +10,7 @@ - [`SystemConfig`](#systemconfig) - [`ConfigUpdate`](#configupdate) - [Initialization](#initialization) - - [Modifying EIP-1559 Parameters](#modifying-eip-1559-parameters) - [Interface](#interface) - - [EIP-1559 Params](#eip-1559-params) - - [`setEIP1559Params`](#seteip1559params) - - [`eip1559Elasticity`](#eip1559elasticity) - - [`eip1559Denominator`](#eip1559denominator) - [Fee Vault Config](#fee-vault-config) - [`setBaseFeeVaultConfig`](#setbasefeevaultconfig) - [`setL1FeeVaultConfig`](#setl1feevaultconfig) @@ -23,6 +18,7 @@ - [`OptimismPortal`](#optimismportal) - [Interface](#interface-1) - [`setConfig`](#setconfig) + - [`upgrade`](#upgrade) @@ -82,43 +78,8 @@ The following actions should happen during the initialization of the `SystemConf These actions MAY only be triggered if there is a diff to the value. -### Modifying EIP-1559 Parameters - -A new `SystemConfig` `UpdateType` is introduced that enables the modification of -[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) parameters. This allows for the chain -operator to modify the `BASE_FEE_MAX_CHANGE_DENOMINATOR` and the `ELASTICITY_MULTIPLIER`. - ### Interface -#### EIP-1559 Params - -##### `setEIP1559Params` - -This function MUST only be callable by the chain governor. - -```solidity -function setEIP1559Params(uint32 _denominator, uint32 _elasticity) -``` - -The `_denominator` and `_elasticity` MUST be set to values greater to than 0. -It is possible for the chain operator to set EIP-1559 parameters that result in poor user experience. - -##### `eip1559Elasticity` - -This function returns the currently configured EIP-1559 elasticity. - -```solidity -function eip1559Elasticity()(uint64) -``` - -##### `eip1559Denominator` - -This function returns the currently configured EIP-1559 denominator. - -```solidity -function eip1559Denominator()(uint64) -``` - #### Fee Vault Config For each `FeeVault`, there is a setter for its config. The arguments to the setter include @@ -173,3 +134,26 @@ The following fields are included: - `version` is `uint256(0)` - `opaqueData` is the tightly packed transaction data where `mint` is `0`, `value` is `0`, the `gasLimit` is `200_000`, `isCreation` is `false` and the `data` is `abi.encodeCall(L1Block.setConfig, (_type, _value))` + +#### `upgrade` + +The `upgrade` function MUST only be callable by the `UPGRADER` role as defined +in the [`SuperchainConfig`](./superchain-config.md). + +```solidity +function upgrade(bytes memory _data) external +``` + +This function emits a `TransactionDeposited` event. + +```solidity +event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); +``` + +The following fields are included: + +- `from` is the `DEPOSITOR_ACCOUNT` +- `to` is `Predeploys.ProxyAdmin` +- `version` is `uint256(0)` +- `opaqueData` is the tightly packed transaction data where `mint` is `0`, `value` is `0`, the `gasLimit` + is `200_000`, `isCreation` is `false` and the `data` is the data passed into `upgrade`. diff --git a/specs/protocol/isthmus/exec-engine.md b/specs/protocol/isthmus/exec-engine.md new file mode 100644 index 000000000..dc4df4752 --- /dev/null +++ b/specs/protocol/isthmus/exec-engine.md @@ -0,0 +1,78 @@ +# L2 Execution Engine + + + +**Table of Contents** + +- [Overview](#overview) +- [Timestamp Activation](#timestamp-activation) +- [`L2ToL1MessagePasser` Storage Root in Header](#l2tol1messagepasser-storage-root-in-header) + - [Header Validity Rules](#header-validity-rules) + - [Header Withdrawals Root](#header-withdrawals-root) + - [Rationale](#rationale) + - [Forwards Compatibility Considerations](#forwards-compatibility-considerations) + - [Client Implementation Considerations](#client-implementation-considerations) + + + +## Overview + +The storage root of the `L2ToL1MessagePasser` is included in the block header's +`withdrawalRoot` field. + +## Timestamp Activation + +Isthmus, like other network upgrades, is activated at a timestamp. +Changes to the L2 Block execution rules are applied when the `L2 Timestamp >= activation time`. + +## `L2ToL1MessagePasser` Storage Root in Header + +After Holocene's activation, the L2 block header's `withdrawalsRoot` field will consist of the 32-byte +[`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root _after_ the block has been executed, and _after_ the +insertions and deletions have been applied to the trie. In other words, the storage root should be the same root +that is returned by `eth_getProof` at the given block number. + +### Header Validity Rules + +Prior to holocene activation, the L2 block header's `withdrawalsRoot` field must be: + +- `nil` if Canyon has not been activated. +- `keccak256(rlp(empty_string_code))` if Canyon has been activated. + +After Holocene activation, an L2 block header's `withdrawalsRoot` field is valid iff: + +1. It is exactly 32 bytes in length. +1. The [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root, as committed to in the `storageRoot` within the block + header, is equal to the header's `withdrawalsRoot` field. + +### Header Withdrawals Root + +| Byte offset | Description | +| ----------- | --------------------------------------------------------- | +| `[0, 32)` | [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root | + +#### Rationale + +Currently, to generate [L2 output roots][output-root] for historical blocks, an archival node is required. This directly +places a burden on users of the system in a post-fault-proofs world, where: + +1. A proposer must have an archive node to propose an output root at the safe head. +1. A user that is proving their withdrawal must have an archive node to verify that the output root they are proving + their withdrawal against is indeed valid and included within the safe chain. + +Placing the [`L2ToL1MessagePasser`][l2-to-l1-mp] account storage root in the `withdrawalsRoot` field alleviates this burden +for users and protocol participants alike, allowing them to propose and verify other proposals with lower operating costs. + +#### Forwards Compatibility Considerations + +As it stands, the `withdrawalsRoot` field is unused within the OP Stack's header consensus format, and will never be +used for other reasons that are currently planned. Setting this value to the account storage root of the withdrawal +directly fits with the OP Stack, and makes use of the existing field in the L1 header consensus format. + +#### Client Implementation Considerations + +Varous EL clients store historical state of accounts differently. If, as a contrived case, an OP Stack chain did not have +an outbound withdrawal for a long period of time, the node may not have access to the account storage root of the +[`L2ToL1MessagePasser`][l2-to-l1-mp]. In this case, the client would be unable to keep consensus. However, most modern +clients are able to at the very least reconstruct the account storage root at a given block on the fly if it does not +directly store this information. diff --git a/specs/protocol/isthmus/overview.md b/specs/protocol/isthmus/overview.md index ec7bf0827..90c286eb2 100644 --- a/specs/protocol/isthmus/overview.md +++ b/specs/protocol/isthmus/overview.md @@ -6,6 +6,7 @@ - [Execution Layer](#execution-layer) - [Consensus Layer](#consensus-layer) +- [Smart Contracts](#smart-contracts) @@ -13,6 +14,10 @@ This document is not finalized and should be considered experimental. ## Execution Layer +- [L2ToL1MessagePasser Storage Root in Header](./exec-engine.md##l2tol1messagepasser-storage-root-in-header) + ## Consensus Layer -- [Interop](../../interop/overview.md) +## Smart Contracts + +- [SuperchainConfig](./superchain-config.md) diff --git a/specs/protocol/holocene/predeploys.md b/specs/protocol/isthmus/predeploys.md similarity index 91% rename from specs/protocol/holocene/predeploys.md rename to specs/protocol/isthmus/predeploys.md index 9b874510f..a6e50868f 100644 --- a/specs/protocol/holocene/predeploys.md +++ b/specs/protocol/isthmus/predeploys.md @@ -6,10 +6,12 @@ - [Constants](#constants) - [Predeploys](#predeploys) + - [ProxyAdmin](#proxyadmin) + - [Rationale](#rationale) - [L1Block](#l1block) - [Storage](#storage) - [Interface](#interface) - - [`setHolocene`](#setholocene) + - [`setIsthmus`](#setisthmus) - [`setConfig`](#setconfig) - [`baseFeeVaultConfig`](#basefeevaultconfig) - [`sequencerFeeVaultConfig`](#sequencerfeevaultconfig) @@ -79,6 +81,20 @@ graph LR OptimismPortal -- "setConfig(uint8,bytes)" --> L1Block ``` +### ProxyAdmin + +The `ProxyAdmin` is updated to have its `owner` be the `DEPOSITOR_ACCOUNT`. +This means that it can be deterministically called by network upgrade transactions +or by special deposit transactions emitted by the `OptimismPortal` that assume +the identity of the `DEPOSITOR_ACCOUNT`. + +#### Rationale + +It is much easier to manage the overall roles of the full system under this model. +The owner of the `ProxyAdmin` can upgrade any of the predeploys, meaning it can +write storage slots that correspond to withdrawals. This ensures that only the +system or a chain governor can issue upgrades to the predeploys. + ### L1Block #### Storage @@ -98,7 +114,7 @@ via a deposit transaction from the `DEPOSITOR_ACCOUNT`. #### Interface -##### `setHolocene` +##### `setIsthmus` This function is meant to be called once on the activation block of the holocene network upgrade. It MUST only be callable by the `DEPOSITOR_ACCOUNT` once. When it is called, it MUST call diff --git a/specs/protocol/isthmus/superchain-config.md b/specs/protocol/isthmus/superchain-config.md new file mode 100644 index 000000000..355614c6a --- /dev/null +++ b/specs/protocol/isthmus/superchain-config.md @@ -0,0 +1,34 @@ +# SuperchainConfig + + + +**Table of Contents** + +- [Overview](#overview) +- [Constants](#constants) +- [Interface](#interface) +- [Initialization](#initialization) + + + +## Overview + +The `SuperchainConfig` contract is updated with a new role that has the ability +to issue deposit transactions from the identity of the `DEPOSITOR_ACCOUNT` +that call the L2 `ProxyAdmin`. + +## Constants + +| Name | Value | Definition | +| --------- | ------------------------- | -- | +| `UPGRADER_SLOT` | `bytes32(uint256(keccak256("superchainConfig.upgrader")) - 1)` | Account that can call the L2 `ProxyAdmin` | + +## Interface + +```solidity +function upgrader() public view returns (address) +``` + +## Initialization + +The `upgrader` can only be set during initialization.