Skip to content

Commit

Permalink
Merge 7d50548 into 7e8e8e5
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan authored Mar 15, 2024
2 parents 7e8e8e5 + 7d50548 commit 6328d51
Show file tree
Hide file tree
Showing 74 changed files with 693 additions and 3,596 deletions.
80 changes: 4 additions & 76 deletions docs/docs/developers/contracts/references/portals/inbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,98 +16,26 @@ Sends a message from L1 to L2.
| Name | Type | Description |
| -------------- | ------- | ----------- |
| Recipient | `L2Actor` | The recipient of the message. This **MUST** match the rollup version and an Aztec contract that is **attached** to the contract making this call. If the recipient is not attached to the caller, the message cannot be consumed by it. |
| Deadline | `uint256` | The message consumption deadline. If the message have not been removed from the `Inbox` and included in a rollup block by this point, it can be *canceled* by the portal (the portal must implement logic to cancel). |
| Content | `field` (~254 bits) | The content of the message. This is the data that will be passed to the recipient. The content is limited to be a single field for rollup purposes. If the content is small enough it can just be passed along, otherwise it should be hashed and the hash passed along (you can use our [`Hash`](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Hash.sol) utilities with `sha256ToField` functions) |
| Secret Hash | `field` (~254 bits) | A hash of a secret that is used when consuming the message on L2. Keep this preimage a secret to make the consumption private. To consume the message the caller must know the pre-image (the value that was hashed) - so make sure your app keeps track of the pre-images! Use the [`computeMessageSecretHash`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/utils/secrets.ts) to compute it from a secret. |
| Fee (msg.value) | `uint256` | The fee to the sequencer for including the message. This is the amount of ETH that the sequencer will receive for including the message. Note that only values that can fit in `uint64` will be accepted |
| ReturnValue | `bytes32` | The message hash, used as an identifier |

#### Edge cases

- Will revert with `Inbox__ActorTooLarge(bytes32 actor)` if the recipient is larger than the field size (~254 bits).
- Will revert with `Inbox__DeadlineBeforeNow()` if the deadline is before the current block.
- Will revert with `Inbox__ContentTooLarge(bytes32 content)` if the content is larger than the field size (~254 bits).
- Will revert with `Inbox__SecretHashTooLarge(bytes32 secretHash)` if the secret hash is larger than the field size (~254 bits).
- Will revert with `Inbox__FeeTooHigh()` if the fee is larger than `type(uint64).max`.
- Will revert `Inbox__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.

## `cancelL2Message()`
Cancels a message that has not yet been consumed.

#include_code pending_l2_cancel l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_message` | `L1ToL2Msg` | The message to cancel |
| `_feeCollector`| `address` | The address to refund the fee to |
| ReturnValue | `bytes32` | The hash of the message |

#### Edge cases

- Will revert with `Inbox__Unauthorized()` if `msg.sender != _message.sender.actor`.
- Will revert with `Inbox__NotPastDeadline()` if `block.timestamp <= _message.deadline`.
- Will revert with `Inbox__NothingToConsume(bytes32 entryKey)` if the message does not exist.

## `batchConsume()`
## `consume()`

Allows the `Rollup` to consume multiple messages in a single transaction.

#include_code inbox_batch_consume l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity
#include_code consume l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_entryKeys` | `bytes32[]` | The entry keys (message hashes) to consume |
| ReturnValue | `Entry` | The entry for the given key |
| ReturnValue | `bytes32` | Root of the consumed tree. |

#### 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 with `Inbox__InvalidVersion(uint256 entry, uint256 rollup)` if the rollup version does not match the version specified in the message.
- Will revert with `Inbox__PastDeadline()` if the message deadline has passed.
- Will revert with `Inbox__NothingToConsume(bytes32 entryKey)` if the message does not exist.

## `withdrawFees()`

Will claim the fees that has accrued to the `msg.sender` from consuming messages.

Let the sequencer withdraw fees from the inbox.

#include_code inbox_withdraw_fees l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

#### Edge cases

- Will revert with `Inbox__FailedToWithdrawFees()` if the transfer call fails.

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

#include_code inbox_get l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

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

#### Edge cases
- Will revert with `Inbox__NothingToConsume(bytes32 entryKey)` if the message does not exist.


## `contains()`
Returns whether the key exists in the inbox.

#include_code inbox_contains l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_entryKey` | `bytes32` | The entry key (message hash)|
| ReturnValue | `bool` | True if contained, false otherwise|

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

#include_code inbox_compute_entry_key l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `_message` | `L1ToL2Msg` | The message to compute hash for |
| ReturnValue | `bytes32` | The hash of the message |
- Will revert with `Inbox__Unauthorized()` if `msg.sender != ROLLUP` (rollup contract is sometimes referred to as state transitioner in the docs).
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,21 @@ Follow the [token bridge tutorial](../../../tutorials/token_portal/main.md) for

Whether it is tokens or other information being passed to the rollup, the portal should use the `Inbox` to do it.

The `Inbox` can be seen as a mailbox to the rollup, portals put messages into the box, and the sequencers then decide which of these message they want to include in their blocks (each message has a fee attached to it, so there is a fee market here).
The `Inbox` can be seen as a mailbox to the rollup, portals put messages into the box, and the sequencer then consumes a batch of messages from the box and include it in their blocks.

When sending messages, we need to specify quite a bit of information beyond just the content that we are sharing. Namely we need to specify:

| Name | Type | Description |
| ----------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Recipient | `L2Actor` | The message recipient. This **MUST** match the rollup version and an Aztec contract that is **attached** to the contract making this call. If the recipient is not attached to the caller, the message cannot be consumed by it. |
| Deadline | `uint256` | The deadline for the message to be consumed. If the message has not been removed from the `Inbox` and included in a rollup block by this point, it can be _canceled_ by the portal (the portal must implement logic to cancel). |
| Content | `field` (~254 bits) | The content of the message. This is the data that will be passed to the recipient. The content is limited to be a single field. If the content is small enough it can just be passed along, otherwise it should be hashed and the hash passed along (you can use our [`Hash`](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Hash.sol) utilities with `sha256ToField` functions) |
| Secret Hash | `field` (~254 bits) | A hash of a secret that is used when consuming the message on L2. Keep this preimage a secret to make the consumption private. To consume the message the caller must know the pre-image (the value that was hashed) - so make sure your app keeps track of the pre-images! Use the [`computeMessageSecretHash`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/utils/secrets.ts) to compute it from a secret. |
| Fee | `uint64` | The fee to the sequencer for including the message. This is the amount of ETH that the sequencer will receive for including the message. Note that it is not a full `uint256` but only `uint64` |

With all that information at hand, we can call the `sendL2Message` function on the Inbox. The function will return a `field` (inside `bytes32`) that is the hash of the message. This hash can be used as an identifier to spot when your message has been included in a rollup block.

#include_code send_l1_to_l2_message l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

As time passes, a sequencer will see your tx, the juicy fee provided and include it in a rollup block. Upon inclusion, it is removed from L1, and made available to be consumed on L2.
As time passes, a sequencer will consume the message batch you message was included in and include it in a their block.
Upon inclusion, it is made available to be consumed on L2.

To consume the message, we can use the `consume_l1_to_l2_message` function within the `context` struct.

Expand Down Expand Up @@ -77,7 +75,8 @@ To send a message to L1 from your Aztec contract, you must use the `message_port

#include_code context_message_portal /noir-projects/aztec-nr/aztec/src/context/private_context.nr rust

When sending a message from L2 to L1 we don't need to pass recipient, deadline, secret nor fees. Recipient is populated with the attached portal and the remaining values are not needed as the message is inserted into the outbox at the same time as it was included in a block (for the inbox it could be inserted and then only included in rollup block later).
When sending a message from L2 to L1 we don't need to pass recipient nor secret.
Recipient is populated with the attached portal and the remaining values are not needed as the message is inserted into the outbox at the same time as it was included in a block (for the inbox it could be inserted and then only included in rollup block later).

:::danger
Access control on the L1 portal contract is essential to prevent consumption of messages sent from the wrong L2 contract.
Expand Down Expand Up @@ -136,23 +135,6 @@ Generally it is good practice to keep cross-chain calls simple to avoid too many
Error handling for cross chain messages is handled by the application contract and not the protocol. The protocol only delivers the messages, it does not ensure that they are executed successfully.
:::

### Cancellations

A special type of error is an underpriced transaction - it means that a message is inserted on L1, but the attached fee is too low to be included in a rollup block.

For the case of token bridges, this could lead to funds being locked in the bridge forever, as funds are locked but the message never arrives on L2 to mint the tokens. To address this, the `Inbox` supports canceling messages after a deadline. However, this must be called by the portal itself, as it will need to "undo" the state changes is made (for example by sending the tokens back to the user).

As this requires logic on the portal itself, it is not something that the protocol can enforce. It must be supported by the application builder when building the portal.

The portal can call the `cancelL2Message` at the `Inbox` when `block.timestamp > deadline` for the message.

#include_code pending_l2_cancel l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

Building on our token example from earlier, this can be called like:

#include_code token_portal_cancel l1-contracts/test/portals/TokenPortal.sol solidity

The example above ensure that the user can cancel their message if it is underpriced.

### Designated caller

Expand Down
21 changes: 0 additions & 21 deletions docs/docs/developers/tutorials/token_portal/cancelling_deposits.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ Here is an explanation of what it is doing:
2. We construct the “content” of the message we need to send to the recipient on Aztec.
- The content is limited to a single field (~254 bits). So if the content is larger, we have to hash it and the hash can be passed along.
- We use our utility method that creates a sha256 hash but truncates it to fit into a field
- Since we want to mint tokens on Aztec publicly, the content here is the amount to mint and the address on Aztec who will receive the tokens. We also include the L1 address that can cancel the L1->L2 message. Adding this into the content hash makes it so that only the appropriate person can cancel the message and not just any malicious 3rd party.
- More on cancellers can be found in [this upcoming section](./cancelling_deposits.md)
- Since we want to mint tokens on Aztec publicly, the content here is the amount to mint and the address on Aztec who will receive the tokens.
- We encode this message as a mint_public function call, to specify the exact intentions and parameters we want to execute on L2.
- In reality the content can be constructed in any manner as long as the sister contract on L2 can also create it. But for clarity, we are constructing the content like a abi encoded function call.
- It is good practice to include all parameters used by L2 into this content (like the amount and to) so that a malicious actor can’t change the to to themselves when consuming the message.
Expand Down
1 change: 0 additions & 1 deletion docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ const sidebars = {
"developers/tutorials/token_portal/setup",
"developers/tutorials/token_portal/depositing_to_aztec",
"developers/tutorials/token_portal/minting_on_aztec",
"developers/tutorials/token_portal/cancelling_deposits",
"developers/tutorials/token_portal/withdrawing_to_l1",
"developers/tutorials/token_portal/typescript_glue_code",
],
Expand Down
Loading

0 comments on commit 6328d51

Please sign in to comment.