Skip to content

Commit

Permalink
feat!: plug-in new outbox and update examples to use api to fetch inc…
Browse files Browse the repository at this point in the history
…lusion proofs #4769 (#5292)

Resolves #4769
  • Loading branch information
sklppy88 authored Mar 21, 2024
1 parent 161c313 commit fec1008
Show file tree
Hide file tree
Showing 24 changed files with 1,452 additions and 987 deletions.
60 changes: 26 additions & 34 deletions docs/docs/developers/contracts/references/portals/outbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ The `Outbox` is a contract deployed on L1 that handles message passing from the

**Links**: [Interface](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol), [Implementation](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/messagebridge/Outbox.sol).

## `sendL1Messages()`
## `insert()`

Inserts multiple messages from the `Rollup`.
Inserts the root of a merkle tree containing all of the L2 to L1 messages in a block specified by _l2BlockNumber.

#include_code outbox_insert l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol solidity

#include_code outbox_send_l1_msg l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol solidity

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_entryKeys` | `bytes32[]` | A list of message hashes to insert into the outbox for later consumption |
| `_l2BlockNumber` | `uint256` | The L2 Block Number in which the L2 to L1 messages reside |
| `_root` | `bytes32` | The merkle root of the tree where all the L2 to L1 messages are leaves |
| `_height` | `uint256` | The height of the merkle tree that the root corresponds to |

#### Edge cases

- Will revert with `Registry__RollupNotRegistered(address rollup)` if `msg.sender` is not registered as a rollup on the [`Registry`](./registry.md)
- Will revert `Outbox__IncompatibleEntryArguments(bytes32 entryKey, uint64 storedFee, uint64 feePassed, uint32 storedVersion, uint32 versionPassed, uint32 storedDeadline, uint32 deadlinePassed)` if insertion is not possible due to invalid entry arguments.
- Will revert with `Outbox__Unauthorized()` if `msg.sender != ROLLUP_CONTRACT`.
- Will revert with `Errors.Outbox__RootAlreadySetAtBlock(uint256 l2BlockNumber)` if the root for the specific block has already been set.
- Will revert with `Errors.Outbox__InsertingInvalidRoot()` if the rollup is trying to insert bytes32(0) as the root.

## `consume()`

Expand All @@ -30,45 +34,33 @@ Allows a recipient to consume a message from the `Outbox`.

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_message` | `L2ToL1Msg` | The message to consume |
| ReturnValue | `bytes32` | The hash of the message |
| `_message` | `L2ToL1Msg` | The L2 to L1 message we want to consume |
| `_l2BlockNumber` | `uint256` | The block number specifying the block that contains the message we want to consume |
| `_leafIndex` | `uint256` | The index inside the merkle tree where the message is located |
| `_path` | `bytes32[]` | The sibling path used to prove inclusion of the message, the _path length directly depends |

#### Edge cases

- Will revert with `Outbox__Unauthorized()` if `msg.sender != _message.recipient.actor`.
- Will revert with `Outbox__InvalidRecipient(address expected, address actual);` if `msg.sender != _message.recipient.actor`.
- Will revert with `Outbox__InvalidChainId()` if `block.chainid != _message.recipient.chainId`.
- Will revert with `Outbox__NothingToConsume(bytes32 entryKey)` if the message does not exist.
- Will revert with `Outbox__InvalidVersion(uint256 entry, uint256 message)` if the version of the entry and message sender don't match (wrong rollup).
- Will revert with `Outbox__NothingToConsumeAtBlock(uint256 l2BlockNumber)` if the root for the block has not been set yet.
- Will revert with `Outbox__AlreadyNullified(uint256 l2BlockNumber, uint256 leafIndex)` if the message at leafIndex for the block has already been consumed.
- Will revert with `Outbox__InvalidPathLength(uint256 expected, uint256 actual)` if the existing height of the L2 to L1 message tree, and the supplied height do not match.
- Will revert with `MerkleLib__InvalidRoot(bytes32 expected, bytes32 actual, bytes32 leaf, uint256 leafIndex)` if unable to verify the message existence in the tree. It returns the message as a leaf, as well as the index of the leaf to expose more info about the error.

## `get()`
Retrieves the `entry` for a given message. The entry contains fee, occurrences, deadline and version information.

#include_code outbox_get l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol solidity
## `hasMessageBeenConsumedAtBlockAndIndex()`

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_entryKey` | `bytes32` | The entry key (message hash) |
| ReturnValue | `Entry` | The entry for the given key |

#### Edge cases
- Will revert with `Outbox__NothingToConsume(bytes32 entryKey)` if the message does not exist.
Checks to see if an index of the L2 to L1 message tree for a specific block has been consumed.

## `contains()`
Returns whether the key is found in the inbox.
#include_code outbox_has_message_been_consumed_at_block_and_index l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol solidity

#include_code outbox_contains l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol solidity

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_entryKey` | `bytes32` | The entry key (message hash)|
| ReturnValue | `bool` | True if contained, false otherwise|
| `_l2BlockNumber` | `uint256` | The block number specifying the block that contains the index of the message we want to check |
| `_leafIndex` | `uint256` | The index of the message inside the merkle tree |

## `computeEntryKey()`
Computes the hash of a message.

#include_code outbox_compute_entry_key l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol solidity
#### Edge cases

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_message` | `L2ToL1Msg` | The message to compute hash for |
| ReturnValue | `bytes32` | The hash of the message |
- This function does not throw. Out-of-bounds access is considered valid, but will always return false.
120 changes: 58 additions & 62 deletions l1-contracts/slither_output.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ Summary
- [pess-unprotected-setter](#pess-unprotected-setter) (1 results) (High)
- [uninitialized-local](#uninitialized-local) (2 results) (Medium)
- [unused-return](#unused-return) (1 results) (Medium)
- [pess-dubious-typecast](#pess-dubious-typecast) (6 results) (Medium)
- [pess-dubious-typecast](#pess-dubious-typecast) (5 results) (Medium)
- [missing-zero-check](#missing-zero-check) (2 results) (Low)
- [reentrancy-events](#reentrancy-events) (2 results) (Low)
- [timestamp](#timestamp) (1 results) (Low)
- [pess-public-vs-external](#pess-public-vs-external) (6 results) (Low)
- [pess-public-vs-external](#pess-public-vs-external) (5 results) (Low)
- [assembly](#assembly) (2 results) (Informational)
- [dead-code](#dead-code) (3 results) (Informational)
- [dead-code](#dead-code) (5 results) (Informational)
- [solc-version](#solc-version) (1 results) (Informational)
- [similar-names](#similar-names) (3 results) (Informational)
- [constable-states](#constable-states) (1 results) (Optimization)
Expand All @@ -17,9 +17,9 @@ Summary
Impact: High
Confidence: Medium
- [ ] ID-0
Function [Rollup.process(bytes,bytes32,bytes,bytes)](src/core/Rollup.sol#L57-L96) is a non-protected setter archive is written
Function [Rollup.process(bytes,bytes32,bytes,bytes)](src/core/Rollup.sol#L60-L104) is a non-protected setter archive is written

src/core/Rollup.sol#L57-L96
src/core/Rollup.sol#L60-L104


## uninitialized-local
Expand All @@ -41,9 +41,9 @@ src/core/libraries/decoders/TxsDecoder.sol#L81
Impact: Medium
Confidence: Medium
- [ ] ID-3
[Rollup.process(bytes,bytes32,bytes,bytes)](src/core/Rollup.sol#L57-L96) ignores return value by [(l2ToL1Msgs) = MessagesDecoder.decode(_body)](src/core/Rollup.sol#L73)
[Rollup.process(bytes,bytes32,bytes,bytes)](src/core/Rollup.sol#L60-L104) ignores return value by [(l2ToL1Msgs) = MessagesDecoder.decode(_body)](src/core/Rollup.sol#L77)

src/core/Rollup.sol#L57-L96
src/core/Rollup.sol#L60-L104


## pess-dubious-typecast
Expand Down Expand Up @@ -71,13 +71,6 @@ src/core/libraries/decoders/MessagesDecoder.sol#L164-L166


- [ ] ID-7
Dubious typecast in [Outbox.sendL1Messages(bytes32[])](src/core/messagebridge/Outbox.sol#L38-L46):
uint256 => uint32 casting occurs in [version = uint32(REGISTRY.getVersionFor(msg.sender))](src/core/messagebridge/Outbox.sol#L40)

src/core/messagebridge/Outbox.sol#L38-L46


- [ ] ID-8
Dubious typecast in [HeaderLib.decode(bytes)](src/core/libraries/HeaderLib.sol#L143-L184):
bytes => bytes32 casting occurs in [header.lastArchive = AppendOnlyTreeSnapshot(bytes32(_header),uint32(bytes4(_header)))](src/core/libraries/HeaderLib.sol#L151-L153)
bytes => bytes4 casting occurs in [header.lastArchive = AppendOnlyTreeSnapshot(bytes32(_header),uint32(bytes4(_header)))](src/core/libraries/HeaderLib.sol#L151-L153)
Expand All @@ -103,7 +96,7 @@ Dubious typecast in [HeaderLib.decode(bytes)](src/core/libraries/HeaderLib.sol#L
src/core/libraries/HeaderLib.sol#L143-L184


- [ ] ID-9
- [ ] ID-8
Dubious typecast in [MessagesDecoder.read1(bytes,uint256)](src/core/libraries/decoders/MessagesDecoder.sol#L154-L156):
bytes => bytes1 casting occurs in [uint256(uint8(bytes1(_data)))](src/core/libraries/decoders/MessagesDecoder.sol#L155)

Expand All @@ -113,24 +106,24 @@ src/core/libraries/decoders/MessagesDecoder.sol#L154-L156
## missing-zero-check
Impact: Low
Confidence: Medium
- [ ] ID-10
- [ ] ID-9
[Inbox.constructor(address,uint256)._rollup](src/core/messagebridge/Inbox.sol#L40) lacks a zero-check on :
- [ROLLUP = _rollup](src/core/messagebridge/Inbox.sol#L41)

src/core/messagebridge/Inbox.sol#L40


- [ ] ID-11
[NewOutbox.constructor(address)._rollup](src/core/messagebridge/NewOutbox.sol#L31) lacks a zero-check on :
- [ROLLUP_CONTRACT = _rollup](src/core/messagebridge/NewOutbox.sol#L32)
- [ ] ID-10
[Outbox.constructor(address)._rollup](src/core/messagebridge/Outbox.sol#L31) lacks a zero-check on :
- [ROLLUP_CONTRACT = _rollup](src/core/messagebridge/Outbox.sol#L32)

src/core/messagebridge/NewOutbox.sol#L31
src/core/messagebridge/Outbox.sol#L31


## reentrancy-events
Impact: Low
Confidence: Medium
- [ ] ID-12
- [ ] ID-11
Reentrancy in [Inbox.sendL2Message(DataStructures.L2Actor,bytes32,bytes32)](src/core/messagebridge/Inbox.sol#L61-L95):
External calls:
- [index = currentTree.insertLeaf(leaf)](src/core/messagebridge/Inbox.sol#L91)
Expand All @@ -140,21 +133,21 @@ Reentrancy in [Inbox.sendL2Message(DataStructures.L2Actor,bytes32,bytes32)](src/
src/core/messagebridge/Inbox.sol#L61-L95


- [ ] ID-13
Reentrancy in [Rollup.process(bytes,bytes32,bytes,bytes)](src/core/Rollup.sol#L57-L96):
- [ ] ID-12
Reentrancy in [Rollup.process(bytes,bytes32,bytes,bytes)](src/core/Rollup.sol#L60-L104):
External calls:
- [inHash = INBOX.consume()](src/core/Rollup.sol#L87)
- [outbox.sendL1Messages(l2ToL1Msgs)](src/core/Rollup.sol#L93)
- [inHash = INBOX.consume()](src/core/Rollup.sol#L91)
- [OUTBOX.insert(header.globalVariables.blockNumber,header.contentCommitment.outHash,l2ToL1TreeHeight)](src/core/Rollup.sol#L99-L101)
Event emitted after the call(s):
- [L2BlockProcessed(header.globalVariables.blockNumber)](src/core/Rollup.sol#L95)
- [L2BlockProcessed(header.globalVariables.blockNumber)](src/core/Rollup.sol#L103)

src/core/Rollup.sol#L57-L96
src/core/Rollup.sol#L60-L104


## timestamp
Impact: Low
Confidence: Medium
- [ ] ID-14
- [ ] ID-13
[HeaderLib.validate(HeaderLib.Header,uint256,uint256,bytes32)](src/core/libraries/HeaderLib.sol#L106-L136) uses timestamp for comparisons
Dangerous comparisons:
- [_header.globalVariables.timestamp > block.timestamp](src/core/libraries/HeaderLib.sol#L120)
Expand All @@ -165,62 +158,53 @@ src/core/libraries/HeaderLib.sol#L106-L136
## pess-public-vs-external
Impact: Low
Confidence: Medium
- [ ] ID-15
- [ ] ID-14
The following public functions could be turned into external in [FrontierMerkle](src/core/messagebridge/frontier_tree/Frontier.sol#L7-L93) contract:
[FrontierMerkle.constructor(uint256)](src/core/messagebridge/frontier_tree/Frontier.sol#L19-L27)

src/core/messagebridge/frontier_tree/Frontier.sol#L7-L93


- [ ] ID-16
- [ ] ID-15
The following public functions could be turned into external in [Registry](src/core/messagebridge/Registry.sol#L22-L129) contract:
[Registry.constructor()](src/core/messagebridge/Registry.sol#L29-L33)

src/core/messagebridge/Registry.sol#L22-L129


- [ ] ID-17
- [ ] ID-16
The following public functions could be turned into external in [Inbox](src/core/messagebridge/Inbox.sol#L24-L124) contract:
[Inbox.constructor(address,uint256)](src/core/messagebridge/Inbox.sol#L40-L51)

src/core/messagebridge/Inbox.sol#L24-L124


- [ ] ID-18
The following public functions could be turned into external in [Rollup](src/core/Rollup.sol#L29-L105) contract:
[Rollup.constructor(IRegistry,IAvailabilityOracle)](src/core/Rollup.sol#L42-L48)

src/core/Rollup.sol#L29-L105


- [ ] ID-19
The following public functions could be turned into external in [Outbox](src/core/messagebridge/Outbox.sol#L21-L148) contract:
[Outbox.constructor(address)](src/core/messagebridge/Outbox.sol#L29-L31)
[Outbox.get(bytes32)](src/core/messagebridge/Outbox.sol#L77-L84)
[Outbox.contains(bytes32)](src/core/messagebridge/Outbox.sol#L91-L93)
- [ ] ID-17
The following public functions could be turned into external in [Rollup](src/core/Rollup.sol#L30-L113) contract:
[Rollup.constructor(IRegistry,IAvailabilityOracle)](src/core/Rollup.sol#L44-L51)

src/core/messagebridge/Outbox.sol#L21-L148
src/core/Rollup.sol#L30-L113


- [ ] ID-20
The following public functions could be turned into external in [NewOutbox](src/core/messagebridge/NewOutbox.sol#L18-L132) contract:
[NewOutbox.constructor(address)](src/core/messagebridge/NewOutbox.sol#L31-L33)
- [ ] ID-18
The following public functions could be turned into external in [Outbox](src/core/messagebridge/Outbox.sol#L18-L132) contract:
[Outbox.constructor(address)](src/core/messagebridge/Outbox.sol#L31-L33)

src/core/messagebridge/NewOutbox.sol#L18-L132
src/core/messagebridge/Outbox.sol#L18-L132


## assembly
Impact: Informational
Confidence: High
- [ ] ID-21
- [ ] ID-19
[MessagesDecoder.decode(bytes)](src/core/libraries/decoders/MessagesDecoder.sol#L61-L146) uses assembly
- [INLINE ASM](src/core/libraries/decoders/MessagesDecoder.sol#L80-L82)
- [INLINE ASM](src/core/libraries/decoders/MessagesDecoder.sol#L116-L122)

src/core/libraries/decoders/MessagesDecoder.sol#L61-L146


- [ ] ID-22
- [ ] ID-20
[TxsDecoder.computeRoot(bytes32[])](src/core/libraries/decoders/TxsDecoder.sol#L265-L284) uses assembly
- [INLINE ASM](src/core/libraries/decoders/TxsDecoder.sol#L272-L274)

Expand All @@ -230,22 +214,34 @@ src/core/libraries/decoders/TxsDecoder.sol#L265-L284
## dead-code
Impact: Informational
Confidence: Medium
- [ ] ID-21
[MessageBox.consume(mapping(bytes32 => DataStructures.Entry),bytes32,function(bytes32))](src/core/libraries/MessageBox.sol#L71-L79) is never used and should be removed

src/core/libraries/MessageBox.sol#L71-L79


- [ ] ID-22
[MessageBox.contains(mapping(bytes32 => DataStructures.Entry),bytes32)](src/core/libraries/MessageBox.sol#L87-L92) is never used and should be removed

src/core/libraries/MessageBox.sol#L87-L92


- [ ] ID-23
[Outbox._errNothingToConsume(bytes32)](src/core/messagebridge/Outbox.sol#L114-L116) is never used and should be removed
[MessageBox.get(mapping(bytes32 => DataStructures.Entry),bytes32,function(bytes32))](src/core/libraries/MessageBox.sol#L104-L112) is never used and should be removed

src/core/messagebridge/Outbox.sol#L114-L116
src/core/libraries/MessageBox.sol#L104-L112


- [ ] ID-24
[Hash.sha256ToField(bytes32)](src/core/libraries/Hash.sol#L52-L54) is never used and should be removed
[MessageBox.insert(mapping(bytes32 => DataStructures.Entry),bytes32,uint64,uint32,uint32,function(bytes32,uint64,uint64,uint32,uint32,uint32,uint32))](src/core/libraries/MessageBox.sol#L30-L60) is never used and should be removed

src/core/libraries/Hash.sol#L52-L54
src/core/libraries/MessageBox.sol#L30-L60


- [ ] ID-25
[Outbox._errIncompatibleEntryArguments(bytes32,uint64,uint64,uint32,uint32,uint32,uint32)](src/core/messagebridge/Outbox.sol#L129-L147) is never used and should be removed
[Hash.sha256ToField(bytes32)](src/core/libraries/Hash.sol#L52-L54) is never used and should be removed

src/core/messagebridge/Outbox.sol#L129-L147
src/core/libraries/Hash.sol#L52-L54


## solc-version
Expand All @@ -270,27 +266,27 @@ src/core/libraries/ConstantsGen.sol#L110


- [ ] ID-29
Variable [Rollup.AVAILABILITY_ORACLE](src/core/Rollup.sol#L32) is too similar to [Rollup.constructor(IRegistry,IAvailabilityOracle)._availabilityOracle](src/core/Rollup.sol#L42)
Variable [Rollup.AVAILABILITY_ORACLE](src/core/Rollup.sol#L33) is too similar to [Rollup.constructor(IRegistry,IAvailabilityOracle)._availabilityOracle](src/core/Rollup.sol#L44)

src/core/Rollup.sol#L32
src/core/Rollup.sol#L33


## constable-states
Impact: Optimization
Confidence: High
- [ ] ID-30
[Rollup.lastWarpedBlockTs](src/core/Rollup.sol#L40) should be constant
[Rollup.lastWarpedBlockTs](src/core/Rollup.sol#L42) should be constant

src/core/Rollup.sol#L40
src/core/Rollup.sol#L42


## pess-multiple-storage-read
Impact: Optimization
Confidence: High
- [ ] ID-31
In a function [NewOutbox.insert(uint256,bytes32,uint256)](src/core/messagebridge/NewOutbox.sol#L44-L64) variable [NewOutbox.roots](src/core/messagebridge/NewOutbox.sol#L29) is read multiple times
In a function [Outbox.insert(uint256,bytes32,uint256)](src/core/messagebridge/Outbox.sol#L44-L64) variable [Outbox.roots](src/core/messagebridge/Outbox.sol#L29) is read multiple times

src/core/messagebridge/NewOutbox.sol#L44-L64
src/core/messagebridge/Outbox.sol#L44-L64


- [ ] ID-32
Expand Down
Loading

0 comments on commit fec1008

Please sign in to comment.