Skip to content

Commit

Permalink
refactor: old inbox purge (#5206)
Browse files Browse the repository at this point in the history
Fixes #5263
Fixes #4833
Fixes #5071
\+ did a few random improvements (e.g. not waiting 5 seconds for
archiver to have message available but polling for it instead)
  • Loading branch information
benesjan authored Mar 18, 2024
1 parent 1a5eb69 commit a26d968
Show file tree
Hide file tree
Showing 93 changed files with 1,006 additions and 3,949 deletions.
12 changes: 0 additions & 12 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -892,16 +892,6 @@ jobs:
aztec_manifest_key: end-to-end
<<: *defaults_e2e_test

integration-archiver-l1-to-l2:
steps:
- *checkout
- *setup_env
- run:
name: "Test"
command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=integration_archiver_l1_to_l2.test.ts
aztec_manifest_key: end-to-end
<<: *defaults_e2e_test

integration-l1-publisher:
steps:
- *checkout
Expand Down Expand Up @@ -1421,7 +1411,6 @@ workflows:
- e2e-private-voting: *e2e_test
- uniswap-trade-on-l1-from-l2: *e2e_test
- integration-l1-publisher: *e2e_test
- integration-archiver-l1-to-l2: *e2e_test
- e2e-persistence: *e2e_test
- e2e-browser: *e2e_test
- e2e-card-game: *e2e_test
Expand Down Expand Up @@ -1486,7 +1475,6 @@ workflows:
- e2e-private-voting
- uniswap-trade-on-l1-from-l2
- integration-l1-publisher
- integration-archiver-l1-to-l2
- e2e-persistence
- e2e-browser
- e2e-card-game
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ An entry for the messageboxes multi-sets.

| Name | Type | Description |
| -------------- | ------- | ----------- |
| `fee` | `uint64` | The fee provided to the sequencer for including the message in the inbox. 0 if Outbox (as it is not applicable). |
| `count` | `uint32` | The occurrence of the entry in the dataset |
| `version` | `uint32` | The version of the entry |
| `deadline` | `uint32` | The consumption deadline of the message. |


## `L1Actor`
Expand Down Expand Up @@ -55,8 +53,6 @@ A message that is sent from L1 to L2.
| `recipient` | `L2Actor` | The actor on L2 that is to receive the message. |
| `content` | `field (~254 bits)` | The field element containing the content to be sent to L2. |
| `secretHash` | `field (~254 bits)` | The hash of a secret pre-image that must be known to consume the message on L2. 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. |
| `deadline` | `uint32` | The message consumption-deadline time in seconds. |
| `fee` | `uint64` | The fee that the sequencer will be paid for the inclusion of the message. |

## `L2ToL1Message`

Expand Down
84 changes: 6 additions & 78 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

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

#### 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 consume l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity

#include_code inbox_withdraw_fees l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity
| Name | Type | Description |
| -------------- | ----------- | -------------------------- |
| ReturnValue | `bytes32` | Root of the consumed tree. |

#### 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,22 @@ 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` |
| 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)

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 your 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 +76,7 @@ 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 in a secret.

:::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.

Loading

0 comments on commit a26d968

Please sign in to comment.