Skip to content

Commit

Permalink
Merge pull request #1268 from qbzzt/250120-msg-passing
Browse files Browse the repository at this point in the history
Interop message passing explainer
  • Loading branch information
krofax authored Jan 22, 2025
2 parents 3a4e633 + 95310e0 commit 3cff469
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 37 deletions.
110 changes: 75 additions & 35 deletions pages/stack/interop/message-passing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,101 @@ description: Learn about cross-chain message passing in the Superchain.

import { Callout, Steps } from 'nextra/components'

# Interop message passing overview
import { InteropCallout } from '@/components/WipCallout'

<Callout>
Interop is currently in active development and not yet ready for production use. The information provided here may change. Check back regularly for the most up-to-date information.
</Callout>
<InteropCallout />

This guide provides an overview of cross-chain message passing in the Superchain.
# Interop message passing overview

## Overview
The low-level [`CrossL2Inbox`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol) contract handles basic message execution. It verifies whether an initiating message exists but does not check the message's destination, processing status, or other attributes.

The Superchain uses a pull-based event system for cross-chain communication. Messages are sent through the `L2ToL2CrossDomainMessenger` contract, which provides a secure and standardized way to pass information between chains.
The [`L2ToL2CrossDomainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol) contract extends `CrossL2Inbox` by providing complete cross-domain messaging functionality.

## How it works
For high-level interoperability, both messages use the `L2ToL2CrossDomainMessenger` contract on their respective chains.

The following diagram illustrates how messages flow between chains through the `L2ToL2CrossDomainMessenger` contract, which acts as a bridge for cross-chain communication. When a contract on the source chain initiates a message, it's processed through several stages before reaching its destination, ensuring secure and reliable message delivery.
## Initiating message

```mermaid
sequenceDiagram
participant Source as Source Chain
participant Messenger as L2ToL2CrossDomainMessenger
participant Dest as Destination Chain
participant app as Application
box rgba(0,0,0,0.1) Source Chain
participant srcContract as Source Contract
participant srcXdom as L2ToL2CrossDomainMessenger
participant log as Event Log
end
app->>srcContract: 1. Send a message
srcContract->>srcXdom: 2. Call contract A<br/>in chainId B<br/>with calldata C
note over srcXdom: 3. Sanity checks
srcXdom->>log: 4. Log event SentMessage
Note over Source,Dest: Message Creation
Source->>Messenger: Emit message event
Note over Source,Dest: Message Serialization
Messenger-->>Messenger: Convert to standard format
Note over Source,Dest: Identifier Creation
Messenger-->>Messenger: Generate unique ID
Note over Source,Dest: Message Execution
Messenger->>Dest: Process message
```

Cross-chain messaging involves four main phases:
1. The application sends a transaction to a contract on the source chain.

2. The contract calls [`L2ToL2CrossDomainMessenger.SendMessage`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol#L127-L154).
The call requires these parameters:

* `_destination`: The chain ID of the destination blockchain.
* `_target`: The address of the contract on that blockchain.
* `_message`: The actual message.
This message is provided to `_target` as calldata, which means it includes a function selector and the parameters for that function call.

3. `L2ToL2CrossDomainMessenger` on the source chain verifies the message is legitimate:
* The destination chain is one to which this chain can send messages.
* The destination chain is *not* the source chain.
* The target is neither `CrossL2Inbox` nor `L2ToL2CrossDomainMessenger`.

4. `L2ToL2CrossDomainMessenger` emits a log entry.
In addition to the parameters, the log entry also includes:

1. **Message Creation**: The source chain contract emits an event containing the message data and destination information. This event serves as the initiating message that will be relayed across chains.
* `_nonce`: A [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) value to ensure the message is only executed once.

2. **Message Serialization**: The messenger contract converts the event data into a standardized format that can be consistently processed across different chains in the Superchain.
* `_sender`: The contract that sent the cross domain message.

3. **Identifier Creation**: A unique identifier is generated for the message, containing information about its `origin`, `timestamp`, and other `metadata`. This identifier helps track and verify the message.
## Executing message

4. **Message Execution**: The destination chain receives and processes the message, executing any associated actions or state changes specified in the original message.
```mermaid
sequenceDiagram
participant app as Application
box rgba(0,0,0,0.1) Source Chain
participant log as Event Log
end
participant super as OP-Supervisor<br/>(destination chain<br/>node)
box rgba(0,0,0,0.1) Destination Chain
participant dstXdom as L2ToL2CrossDomainMessenger
participant Xinbox as CrossL2Inbox
participant dstContract as Destination Contract
end
log->>super: 1. Initiating message log event
app->>dstXdom: 2. Send an executing message
dstXdom->>Xinbox: 3. Verify the initiating message is real
note over dstXdom: 4. Sanity checks
dstXdom->>dstContract: 5. Call with provided calldata
```

For detailed implementation steps and code examples, see our [message passing implementation guide](https://supersim.pages.dev/guides/interop/viem).
1. Before the executing message is processed, the log event of the initiating message has to get to `op-proposer` on the destination chain.

## Common Use Cases
2. The application (or a contract calling on the application's behalf) calls [`L2ToL2CrossDomainMessenger.SendMessage.relayMessage`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol#L156-L216).
This call includes the message that was sent (`_sendMessage`), as well as the [fields required to find that message (`_id`)](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/interfaces/L2/ICrossL2Inbox.sol#L4-L10).

* Simple messages between identical contracts
* Complex multi-contract interactions
* Cross-chain state synchronization
* Token transfers and bridging
3. The `L2ToL2CrossDomainMessenger` uses `CrossL2Inbox` to verify the message was sent from the source.

For a practical example, see our [cross-chain ping pong tutorial](https://supersim.pages.dev/guides/interop/cross-chain-contract-calls-pingpong).
4. `L2ToL2CrossDomainMessenger` on the destination chain verifies the message is legitimate:

* The origin (of the log entry) is `L2ToL2CrossDomainMessenger` on the other side.
* The destination chain ID is correct.
* The target is neither `CrossL2Inbox` nor `L2ToL2CrossDomainMessenger`.
* This message has not been relayed before.
This is the reason we need the nonce value, to enable us to send multiple messages that would be otherwise identical.

5. If everything checks out, `L2ToL2CrossDomainMessenger` calls the destination contract with the calldata provided in the message.

## Next steps

* Read about the [anatomy of a cross-chain message](/stack/interop/explainer#how-messages-get-from-one-chain-to-the-other)
* Try [Supersim](supersim) for testing cross-chain messages locally
* Learn about [manually relaying messages](https://supersim.pages.dev/guides/interop/viem?#viem-to-send-and-relay-interop-messages)
* Read how [messages get from one blockchain to another (`CrossL2Inbox`)](explainer#how-messages-get-from-one-chain-to-the-other).
* Try [Supersim](tools/supersim) for testing cross-chain messages locally.
* Learn about [manually relaying messages](https://supersim.pages.dev/guides/interop/viem?#viem-to-send-and-relay-interop-messages).

{/* After the tutorial for L2ToL2CrossDomainMessenger is written, need to add a link here */}
5 changes: 3 additions & 2 deletions words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Inator
inator
INFLUXDBV
influxdbv
interchain
intiating
IPCDISABLE
ipcdisable
ipcfile
Expand Down Expand Up @@ -195,6 +195,7 @@ MEMPROFILERATE
memprofilerate
Merkle
merkle
mesage
MFHI
MFLO
Minato
Expand Down Expand Up @@ -299,6 +300,7 @@ pricelimit
productionize
productionized
Protip
providng
Proxied
Proxyd
proxyd
Expand Down Expand Up @@ -370,7 +372,6 @@ Superchain
superchain
Superchain's
Superchainerc
superchainerc
Superchains
Superscan
Supersim
Expand Down

0 comments on commit 3cff469

Please sign in to comment.