From b31897ac9ee7ef29f0a626cc158a4430e4af2115 Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 10 Mar 2025 13:11:16 +0100 Subject: [PATCH 1/4] interop: access-list spec and RPC --- specs/interop/predeploys.md | 145 +++++++++++++++++++++++++++++++++++- specs/interop/supervisor.md | 32 +++++++- 2 files changed, 172 insertions(+), 5 deletions(-) diff --git a/specs/interop/predeploys.md b/specs/interop/predeploys.md index 817089830..0d6062b08 100644 --- a/specs/interop/predeploys.md +++ b/specs/interop/predeploys.md @@ -6,6 +6,10 @@ - [Overview](#overview) - [CrossL2Inbox](#crossl2inbox) + - [Access-list](#access-list) + - [type 1: Lookup identity](#type-1-lookup-identity) + - [type 2: ChainID extension](#type-2-chainid-extension) + - [type 3: Checksum](#type-3-checksum) - [Functions](#functions) - [validateMessage](#validatemessage) - [`ExecutingMessage` Event](#executingmessage-event) @@ -86,6 +90,142 @@ To ensure safety of the protocol, the [Message Invariants](./messaging.md#messag [`Identifier`]: ./messaging.md#message-identifier +### Access-list + +Execution of messages is statically pre-declared in transactions, +to ensure the cross-chain validity can be verified outside the single-chain EVM environment constraints. + +After pre-verification of the access-list, the `CrossL2Inbox` can allow messages +to execute when there is a matching pre-verified access-list entry. + +Each executing message is declared with 3 typed access-list entries: +- 1: Lookup identity +- 2: ChainID extension +- 3: Checksum + +The type of entry is encoded in the first byte. +Type 0 is reserved, so valid access-list entries are always non-zero. + +Note that the access-list entries may be de-duplicated: +the same message may be executed multiple times. + +The access-list content not always a multiple of 3. + +The access-list content is ordered: +- after type 1, a type 2 or 3 entry is expected. +- after type 2, a type 3 entry is expected. + +Note that type 1 and 2 are only enforced out-of-protocol: +these provide a hint, for viable block-building, +to lookup data to determine the validity of the checksum without prior transaction execution. + +Not every access-list entry may be executed: +access-list content must not be used by applications to interpret results of transactions, +the `ExecutingMessage` event describes in detail what is executed. + +To prevent cross-contamination of access-list contents, +the checksum entry commits to the contents of the other entries. +The checksum will be invalid if the wrong entries are interpreted with it. + +The `CrossL2Inbox` only checks the checksum is present in the access-list: +the presence of other needed entries is enforced during pre-validation. + +#### type 1: Lookup identity + +Packed attributes for message lookup. + +```text +0..1: type byte, always 0x01 +1..4: reserved, zeroed by default +4..12: big-endian uint64 chain ID +12..16: big-endian uint64, block number +16..24: big-endian uint64, timestamp +24..32: big-endian uint32, log index +``` + +Note: chain IDs larger than `uint64` are supported, with additional typed entries. + +In solidity: + +```solidity +// idLogIndex, idTimestamp, idBlockNumber refer to the Identifier attributes. +assembly { + mstore(32, idLogIndex) // 32..64 = big-endian uint32 log index + mstore(28, idTimestamp) // 28..60 = big-endian uint64 timestamp + mstore(20, idBlockNumber) // 20..52 = big-endian uint64 block number + mstore8(32, 1) // 32..33 = type byte, always 0x01 + let lookupID := mload(32) // 32..64 = packed result +} +``` + +#### type 2: ChainID extension + +Large `uint256` Chain IDs are represented with an extension entry, +included right after the lookup ID entry. + +This extension entry does not have to be included for chainIDs that fit in `uint64`. + +```text +0..1: type byte, always 0x02 +8..32: upper 24 bytes of big-endian uint256 chainID +``` + +#### type 3: Checksum + +The checksum is a versioned hash, committing to implied attributes. +These implied attributes are compared against the full version +of the executing message by recomputing the checksum from the full version. +The full version is retrieved based on the preceding lookup entry and optional chainID extension. + +The checksum is iteratively constructed: +this allows services to work with intermediate implied data. +E.g. the supervisor does not persist the `origin` or `msgHash`, +but does store a `logHash`. + +```text +# Syntax: +# H(bytes): keccak256 hash function +# ++: bytes concatenation +logHash = H(bytes20(idOrigin) ++ msgHash) +# This matches the trailing part of the lookupID +idPacked = bytes12(0) ++ idBlockNumber ++ idTimestamp ++ idLogIndex +idLogHash = H(logHash ++ idPacked) +bareChecksum = H(idLogHash ++ idChainID) +typeByte = 0x03 +checksum = typeByte ++ bareChecksum[1:] +``` + +In solidity: + +```solidity +require(idLogIndex < uint256(1 << 32)); +require(idTimestamp < uint256(1 << 64)); +require(idBlockNumber < uint256(1 << 64)); + +assembly { + mstore(0, idOrigin) + mstore(20, msgHash) + let logHash := keccak256(0, add(20, 32)) + + mstore(32, idLogIndex) // 32..64 = big-endian uint32 log index + mstore(28, idTimestamp) // 28..60 = big-endian uint64 timestamp + mstore(20, idBlockNumber) // 20..52 = big-endian uint64 block number + let idPacked := mload(32) + + mstore(0, logHash) + mstore(32, idPacked) + let idLogHash := keccak256(0, 64) + + mstore(0, idLogHash) + mstore(32, idChainID) + let bareChecksum := keccak256(0, 64) + + mstore(0, bareChecksum) + mstore8(0, 3) // type byte + let checksum := mload(0) +} +``` + ### Functions #### validateMessage @@ -131,8 +271,9 @@ A simple implementation of the `validateMessage` function is included below. ```solidity function validateMessage(Identifier calldata _id, bytes32 _msgHash) external { - // We need to know if this is being called on a depositTx - if (IL1BlockInterop(Predeploys.L1_BLOCK_ATTRIBUTES).isDeposit()) revert NoExecutingDeposits(); + // TODO calldata load the inputs + // TODO compute checksum + // TODO check if checksum is known access-list entry emit ExecutingMessage(_msgHash, _id); } diff --git a/specs/interop/supervisor.md b/specs/interop/supervisor.md index d374b0fb2..54faf4ee4 100644 --- a/specs/interop/supervisor.md +++ b/specs/interop/supervisor.md @@ -33,6 +33,7 @@ - [`supervisor_superRootAtTimestamp`](#supervisor_superrootattimestamp) - [`supervisor_syncStatus`](#supervisor_syncstatus) - [`supervisor_allSafeDerivedAt`](#supervisor_allsafederivedat) + - [`supervisor_checkAccessList`](#supervisor_checkaccesslist) @@ -74,6 +75,8 @@ Specifically, this helps apply message-expiry rules on message checks. Object: - `timestamp`: `HexUint64` +- `timeout`: `HexUint64` or `null` - optional, requests verification to still hold at `timestamp+timeout` + (message expiry may drop previously valid messages). #### `HexUint64` @@ -167,7 +170,7 @@ Returns: `SafetyLevel` #### `supervisor_checkMessages` Parameters: -- `messages`: ARRAY of `Message` +- `messages`: `ARRAY` of `Message` - `minSafety`: `SafetyLevel` #### `supervisor_checkMessagesV2` @@ -176,11 +179,11 @@ Next version `supervisor_checkMessage`, additionally verifying the message-expiry, by referencing when the execution happens. Parameters: -- `messages`: ARRAY of `Message` +- `messages`: `ARRAY` of `Message` - `minSafety`: `SafetyLevel` - `executingDescriptor`: `ExecutingDescriptor` - applies as execution-context to all messages -Returns: RPC error the minSafety is not met by one or more of the messages, with +Returns: RPC error if the `minSafety` is not met by one or more of the `messages`. #### `supervisor_crossDerivedToSource` @@ -243,3 +246,26 @@ Parameters: Returns: derived blocks, mapped in a `OBJECT`: - key: `ChainID` - value: `BlockID` + +#### `supervisor_checkAccessList` + +Verifies if an access-list references only valid messages. +Message execution in the [`CrossL2Inbox`] that is statically declared in the access-list will not revert. + +Only the [`CrossL2Inbox`] subset of the access-list in the transaction is required, +storage-access by other addresses is not included. + +The provided execution-context is used to determine validity relative to the provided time constraints, +see [timestamp invariants](./derivation.md#invariants). + +The access-list entries represent messages, and may be incomplete or malformed. +Malformed access-lists result in an RPC error. + +[`CrossL2Inbox`]: ./predeploys.md#crossl2inbox + +Parameters: +- `inboxEntries`: `ARRAY` of `Hash` - statically declared `CrossL2Inbox` access entries. +- `minSafety`: `SafetyLevel` - minimum required safety. +- `executingDescriptor`: `ExecutingDescriptor` - applies as execution-context to all messages. + +Returns: RPC error if the `minSafety` is not met by one or more of the access entries. From fbe0f71b7dcfbe1569cc73445fbbe55ee92358ed Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 12 Mar 2025 13:53:54 +0100 Subject: [PATCH 2/4] interop: update op-supervisor and CrossL2Inbox predeploy specs with updated access-list spec details --- specs/interop/predeploys.md | 94 ++++++++++++------------------------- specs/interop/supervisor.md | 87 +++++++++++++++++----------------- 2 files changed, 76 insertions(+), 105 deletions(-) diff --git a/specs/interop/predeploys.md b/specs/interop/predeploys.md index 0d6062b08..97e79f0a0 100644 --- a/specs/interop/predeploys.md +++ b/specs/interop/predeploys.md @@ -8,7 +8,7 @@ - [CrossL2Inbox](#crossl2inbox) - [Access-list](#access-list) - [type 1: Lookup identity](#type-1-lookup-identity) - - [type 2: ChainID extension](#type-2-chainid-extension) + - [type 2: Chain-ID extension](#type-2-chain-id-extension) - [type 3: Checksum](#type-3-checksum) - [Functions](#functions) - [validateMessage](#validatemessage) @@ -100,7 +100,7 @@ to execute when there is a matching pre-verified access-list entry. Each executing message is declared with 3 typed access-list entries: - 1: Lookup identity -- 2: ChainID extension +- 2: Chain-ID extension - 3: Checksum The type of entry is encoded in the first byte. @@ -133,6 +133,8 @@ the presence of other needed entries is enforced during pre-validation. #### type 1: Lookup identity Packed attributes for message lookup. +This type of entry serves as hint of the message identity, +for verification of the `checksum` and is not verified in the protocol state-transition or fork-choice. ```text 0..1: type byte, always 0x01 @@ -143,31 +145,21 @@ Packed attributes for message lookup. 24..32: big-endian uint32, log index ``` -Note: chain IDs larger than `uint64` are supported, with additional typed entries. +Chain IDs larger than `uint64` are supported, with an additional chain-ID-extension entry. +The lower 64 bits of the chain-ID are always encoded in the lookup entry. -In solidity: - -```solidity -// idLogIndex, idTimestamp, idBlockNumber refer to the Identifier attributes. -assembly { - mstore(32, idLogIndex) // 32..64 = big-endian uint32 log index - mstore(28, idTimestamp) // 28..60 = big-endian uint64 timestamp - mstore(20, idBlockNumber) // 20..52 = big-endian uint64 block number - mstore8(32, 1) // 32..33 = type byte, always 0x01 - let lookupID := mload(32) // 32..64 = packed result -} -``` - -#### type 2: ChainID extension +#### type 2: Chain-ID extension Large `uint256` Chain IDs are represented with an extension entry, -included right after the lookup ID entry. +included right after the lookup identity entry. +Like the lookup identity entry, this entry-type is not verified in the protocol state-transition or fork-choice. -This extension entry does not have to be included for chainIDs that fit in `uint64`. +This extension entry does not have to be included for chain-IDs that fit in `uint64`. ```text 0..1: type byte, always 0x02 -8..32: upper 24 bytes of big-endian uint256 chainID +1..8: zero bytes +8..32: upper 24 bytes of big-endian uint256 chain-ID ``` #### type 3: Checksum @@ -175,7 +167,7 @@ This extension entry does not have to be included for chainIDs that fit in `uint The checksum is a versioned hash, committing to implied attributes. These implied attributes are compared against the full version of the executing message by recomputing the checksum from the full version. -The full version is retrieved based on the preceding lookup entry and optional chainID extension. +The full version is retrieved based on the preceding lookup entry and optional chain-ID extension. The checksum is iteratively constructed: this allows services to work with intermediate implied data. @@ -195,37 +187,6 @@ typeByte = 0x03 checksum = typeByte ++ bareChecksum[1:] ``` -In solidity: - -```solidity -require(idLogIndex < uint256(1 << 32)); -require(idTimestamp < uint256(1 << 64)); -require(idBlockNumber < uint256(1 << 64)); - -assembly { - mstore(0, idOrigin) - mstore(20, msgHash) - let logHash := keccak256(0, add(20, 32)) - - mstore(32, idLogIndex) // 32..64 = big-endian uint32 log index - mstore(28, idTimestamp) // 28..60 = big-endian uint64 timestamp - mstore(20, idBlockNumber) // 20..52 = big-endian uint64 block number - let idPacked := mload(32) - - mstore(0, logHash) - mstore(32, idPacked) - let idLogHash := keccak256(0, 64) - - mstore(0, idLogHash) - mstore(32, idChainID) - let bareChecksum := keccak256(0, 64) - - mstore(0, bareChecksum) - mstore8(0, 3) // type byte - let checksum := mload(0) -} -``` - ### Functions #### validateMessage @@ -235,10 +196,10 @@ Emits the `ExecutingMessage` event to signal the transaction has a cross chain m The following fields are required for validating a cross chain message: -| Name | Type | Description | -| ---------- | ---------- | -------------------------------------------------------------------------- | -| `_id` | Identifier | A [`Identifier`] pointing to the initiating message. | -| `_msgHash` | `bytes32` | The keccak256 hash of the message payload matching the initiating message. | +| Name | Type | Description | +|------------|--------------|----------------------------------------------------------------------------| +| `_id` | `Identifier` | A [`Identifier`] pointing to the initiating message. | +| `_msgHash` | `bytes32` | The keccak256 hash of the message payload matching the initiating message. | ```solidity function validateMessage(Identifier calldata _id, bytes32 _msgHash) @@ -270,16 +231,23 @@ hash comparison. A simple implementation of the `validateMessage` function is included below. ```solidity - function validateMessage(Identifier calldata _id, bytes32 _msgHash) external { - // TODO calldata load the inputs - // TODO compute checksum - // TODO check if checksum is known access-list entry +function validateMessage(Identifier calldata _id, bytes32 _msgHash) external { + bytes32 checksum = calculateChecksum(_id, _msgHash); - emit ExecutingMessage(_msgHash, _id); - } + (bool _isSlotWarm,) = _isWarm(checksum); + + if (!_isSlotWarm) revert NotWarm(); + + emit ExecutingMessage(_msgHash, _id); } ``` +`calculateChecksum` implements the checksum computation (including type-byte) as defined +in the [access-list checksum computation](#type-3-checksum) spec. + +`_isWarm` checks that the access-list prepared the `checksum` storage key to be warm, +no other contract function may warm up this storage without message validation. + An example of a custom entrypoint utilizing `validateMessage` to consume a known event. Note that in this example, the contract is consuming its own event from another chain, however **any** event emitted from **any** contract is consumable! @@ -394,7 +362,7 @@ In both cases, the source chain's chain id is required for security. Executing m assume the identity of an account because `msg.sender` will never be the identity that initiated the message, it will be the `L2ToL2CrossDomainMessenger` and users will need to callback to get the initiator of the message. -The `_destination` MUST NOT be the chainid of the local chain and a locally defined `nonce` MUST increment on +The `_destination` MUST NOT be the chain-ID of the local chain and a locally defined `nonce` MUST increment on every call to `sendMessage`. Note that `sendMessage` is not `payable`. diff --git a/specs/interop/supervisor.md b/specs/interop/supervisor.md index 54faf4ee4..cf560967c 100644 --- a/specs/interop/supervisor.md +++ b/specs/interop/supervisor.md @@ -22,9 +22,6 @@ - [`SuperRootResponse`](#superrootresponse) - [`SafetyLevel`](#safetylevel) - [Methods](#methods) - - [`supervisor_checkMessage`](#supervisor_checkmessage) - - [`supervisor_checkMessages`](#supervisor_checkmessages) - - [`supervisor_checkMessagesV2`](#supervisor_checkmessagesv2) - [`supervisor_crossDerivedToSource`](#supervisor_crossderivedtosource) - [`supervisor_localUnsafe`](#supervisor_localunsafe) - [`supervisor_crossSafe`](#supervisor_crosssafe) @@ -34,6 +31,9 @@ - [`supervisor_syncStatus`](#supervisor_syncstatus) - [`supervisor_allSafeDerivedAt`](#supervisor_allsafederivedat) - [`supervisor_checkAccessList`](#supervisor_checkaccesslist) + - [Access-list joining](#access-list-joining) + - [Access-list execution context](#access-list-execution-context) + - [`supervisor_checkAccessList` contents](#supervisor_checkaccesslist-contents) @@ -74,9 +74,10 @@ Describes the context for message verification. Specifically, this helps apply message-expiry rules on message checks. Object: -- `timestamp`: `HexUint64` -- `timeout`: `HexUint64` or `null` - optional, requests verification to still hold at `timestamp+timeout` - (message expiry may drop previously valid messages). +- `timestamp`: `HexUint64` - expected timestamp during message execution. +- `timeout`: `HexUint64` - optional, requests verification to still hold at `timestamp+timeout` (inclusive). + The message expiry-window may invalidate messages. + Default interpretation is a `0` timeout: what is valid at `timestamp` may not be valid at `timestamp+1`. #### `HexUint64` @@ -147,44 +148,14 @@ Corresponds to a verifier [SafetyLevel](./verifier.md#safety). `STRING`, one of: - `invalid` -- `unsafe` +- `unsafe`: equivalent to safety of the `latest` RPC label. - `cross-unsafe` - `local-safe` -- `safe` +- `safe`: matching cross-safe, named `safe` to match the RPC label. - `finalized` ### Methods -#### `supervisor_checkMessage` - -Checks the safety level of a specific message based on its identifier and message hash. -This RPC is useful for the block builder to determine if a message should be included in a block. - -Parameters: -- `identifier`: `Identifier` -- `payloadHash`: `Hash` -- `executingDescriptor`: `ExecutingDescriptor` - -Returns: `SafetyLevel` - -#### `supervisor_checkMessages` - -Parameters: -- `messages`: `ARRAY` of `Message` -- `minSafety`: `SafetyLevel` - -#### `supervisor_checkMessagesV2` - -Next version `supervisor_checkMessage`, -additionally verifying the message-expiry, by referencing when the execution happens. - -Parameters: -- `messages`: `ARRAY` of `Message` -- `minSafety`: `SafetyLevel` -- `executingDescriptor`: `ExecutingDescriptor` - applies as execution-context to all messages - -Returns: RPC error if the `minSafety` is not met by one or more of the `messages`. - #### `supervisor_crossDerivedToSource` Parameters: @@ -249,23 +220,55 @@ Returns: derived blocks, mapped in a `OBJECT`: #### `supervisor_checkAccessList` -Verifies if an access-list references only valid messages. +Verifies if an access-list, as defined in [EIP-2930], references only valid messages. Message execution in the [`CrossL2Inbox`] that is statically declared in the access-list will not revert. +##### Access-list joining + Only the [`CrossL2Inbox`] subset of the access-list in the transaction is required, storage-access by other addresses is not included. +Note that an access-list can contain multiple different storage key lists for the `CrossL2Inbox` address. +All storage keys applicable to the `CrossL2Inbox` MUST be joined together (preserving ordering), +missing storage-keys breaks inbox safety. + +##### Access-list execution context The provided execution-context is used to determine validity relative to the provided time constraints, see [timestamp invariants](./derivation.md#invariants). -The access-list entries represent messages, and may be incomplete or malformed. -Malformed access-lists result in an RPC error. +Since messages expire, validity is not definitive. +To reserve validity for a longer time range, a non-zero `timeout` value can be used. +See [`ExecutingDescriptor`](#executingdescriptor) documentation. + +As block-builder a `timeout` of `0` should be used. +As transaction pre-verifier, a `timeout` of `86400` (1 day) should be used. +The transaction should be re-verified or dropped after this time duration, +as it can no longer be safely included in the block due to message-expiry. + +The access-list checks are not definite, checks can be extra conservative. +I.e. a message that is uncertain to meet the requested safety level may be denied. +Specifically, no attempt may be made to verify messages that are initiated and executed within the same timestamp, +these are `invalid` by default. +Advanced block-builders may still choose to include these messages by verifying the intra-block constraints. + +[EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 [`CrossL2Inbox`]: ./predeploys.md#crossl2inbox +##### `supervisor_checkAccessList` contents + Parameters: - `inboxEntries`: `ARRAY` of `Hash` - statically declared `CrossL2Inbox` access entries. -- `minSafety`: `SafetyLevel` - minimum required safety. +- `minSafety`: `SafetyLevel` - minimum required safety, one of: + - `unsafe`: the message exists. + - `cross-unsafe`: the message exists in a cross-unsafe block. + - `local-safe`: the message exists in a local-safe block, not yet cross-verified. + - `safe`: the message exists in a derived block that is cross-verified. + - `finalized`: the message exists in a finalized block. + - Other safety levels are invalid and result in an error. - `executingDescriptor`: `ExecutingDescriptor` - applies as execution-context to all messages. Returns: RPC error if the `minSafety` is not met by one or more of the access entries. + +The access-list entries represent messages, and may be incomplete or malformed. +Malformed access-lists result in an RPC error. From 1ee975e223278ca6adbd7f9023f8fdfe4564ac33 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 12 Mar 2025 15:46:37 +0100 Subject: [PATCH 3/4] interop: access-list review fixes Co-authored-by: Skeletor Spaceman <92943766+skeletor-spaceman@users.noreply.github.com> --- specs/interop/predeploys.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specs/interop/predeploys.md b/specs/interop/predeploys.md index 97e79f0a0..e182e59ad 100644 --- a/specs/interop/predeploys.md +++ b/specs/interop/predeploys.md @@ -109,7 +109,7 @@ Type 0 is reserved, so valid access-list entries are always non-zero. Note that the access-list entries may be de-duplicated: the same message may be executed multiple times. -The access-list content not always a multiple of 3. +The access-list content might not always be a multiple of 3. The access-list content is ordered: - after type 1, a type 2 or 3 entry is expected. @@ -236,7 +236,7 @@ function validateMessage(Identifier calldata _id, bytes32 _msgHash) external { (bool _isSlotWarm,) = _isWarm(checksum); - if (!_isSlotWarm) revert NotWarm(); + if (!_isSlotWarm) revert NonDeclaredExecutingMessage(); emit ExecutingMessage(_msgHash, _id); } @@ -245,8 +245,8 @@ function validateMessage(Identifier calldata _id, bytes32 _msgHash) external { `calculateChecksum` implements the checksum computation (including type-byte) as defined in the [access-list checksum computation](#type-3-checksum) spec. -`_isWarm` checks that the access-list prepared the `checksum` storage key to be warm, -no other contract function may warm up this storage without message validation. +`_isWarm` checks that the access-list prepared the `checksum` storage key to be warm. +**No other contract function may warm up this storage without message validation.** An example of a custom entrypoint utilizing `validateMessage` to consume a known event. Note that in this example, the contract is consuming its own event From 40da1c04ceb50173820cf4235c4f663002723ae5 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 12 Mar 2025 15:54:40 +0100 Subject: [PATCH 4/4] interop: access-list rpc spec improvements --- specs/interop/supervisor.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/specs/interop/supervisor.md b/specs/interop/supervisor.md index cf560967c..b3e33f850 100644 --- a/specs/interop/supervisor.md +++ b/specs/interop/supervisor.md @@ -31,8 +31,9 @@ - [`supervisor_syncStatus`](#supervisor_syncstatus) - [`supervisor_allSafeDerivedAt`](#supervisor_allsafederivedat) - [`supervisor_checkAccessList`](#supervisor_checkaccesslist) - - [Access-list joining](#access-list-joining) + - [Access-list contents](#access-list-contents) - [Access-list execution context](#access-list-execution-context) + - [Access-list checks](#access-list-checks) - [`supervisor_checkAccessList` contents](#supervisor_checkaccesslist-contents) @@ -223,14 +224,22 @@ Returns: derived blocks, mapped in a `OBJECT`: Verifies if an access-list, as defined in [EIP-2930], references only valid messages. Message execution in the [`CrossL2Inbox`] that is statically declared in the access-list will not revert. -##### Access-list joining +[EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 + +##### Access-list contents Only the [`CrossL2Inbox`] subset of the access-list in the transaction is required, storage-access by other addresses is not included. + Note that an access-list can contain multiple different storage key lists for the `CrossL2Inbox` address. All storage keys applicable to the `CrossL2Inbox` MUST be joined together (preserving ordering), missing storage-keys breaks inbox safety. +**ALL storage-keys in the access-list for the `CrossL2Inbox` MUST be checked.** +If there is any unrecognized or invalid key, the access-list check MUST fail. + +[`CrossL2Inbox`]: ./predeploys.md#crossl2inbox + ##### Access-list execution context The provided execution-context is used to determine validity relative to the provided time constraints, @@ -246,15 +255,14 @@ As transaction pre-verifier, a `timeout` of `86400` (1 day) should be used. The transaction should be re-verified or dropped after this time duration, as it can no longer be safely included in the block due to message-expiry. -The access-list checks are not definite, checks can be extra conservative. +##### Access-list checks + +The access-list check errors are not definite state-transition blockers, the RPC based checks can be extra conservative. I.e. a message that is uncertain to meet the requested safety level may be denied. Specifically, no attempt may be made to verify messages that are initiated and executed within the same timestamp, these are `invalid` by default. Advanced block-builders may still choose to include these messages by verifying the intra-block constraints. -[EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 -[`CrossL2Inbox`]: ./predeploys.md#crossl2inbox - ##### `supervisor_checkAccessList` contents Parameters: