Skip to content
This repository was archived by the owner on Apr 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1367722
Add message expiration doc
bradleycamacho May 12, 2025
4b1224e
Auto-fix: Update breadcrumbs, spelling dictionary and other automated…
bradleycamacho May 15, 2025
c24ec58
Implement review
bradleycamacho May 15, 2025
c64be26
Add missing link
bradleycamacho May 15, 2025
7490333
Auto-fix: Update breadcrumbs, spelling dictionary and other automated…
bradleycamacho May 15, 2025
aefdf2e
Merge branch 'main' into Message-expiration
bradleycamacho May 15, 2025
dd0209d
Fix flipflopped info
bradleycamacho May 15, 2025
070d225
Merge branch 'Message-expiration' of https://github.com/ethereum-opti…
bradleycamacho May 15, 2025
ac54be7
Auto-fix: Update breadcrumbs, spelling dictionary and other automated…
bradleycamacho May 15, 2025
fc712c4
Next steps and logs reference
bradleycamacho May 15, 2025
97bd758
fix link
bradleycamacho May 15, 2025
ee8b461
Lint
bradleycamacho May 15, 2025
51b3e80
Auto-fix: Update breadcrumbs, spelling dictionary and other automated…
bradleycamacho May 15, 2025
2bd4e3e
Add reviews
bradleycamacho May 15, 2025
43b0411
Fix callout
bradleycamacho May 15, 2025
375f96e
Fix callout
bradleycamacho May 15, 2025
198805c
Update reading-logs.mdx
zainbacchus May 15, 2025
65dd836
Update message-expiration.mdx
zainbacchus May 15, 2025
b1ee830
Update message-expiration.mdx
zainbacchus May 15, 2025
825519b
Update message-expiration.mdx
zainbacchus May 15, 2025
4e1ae12
Update message-expiration.mdx
zainbacchus May 15, 2025
cafff0f
Spelling fix
bradleycamacho May 15, 2025
fc29281
Update message-expiration.mdx
zainbacchus May 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pages/interop/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"explainer": "Superchain interop explainer",
"predeploy": "Superchain interop predeploys",
"message-passing": "Superchain interop message passing",
"message-expiration": "Message expiration",
"reading-logs": "Reading logs",
"op-supervisor": "OP Supervisor",
"superchain-eth-bridge": "Superchain ETH bridge",
Expand Down
52 changes: 52 additions & 0 deletions pages/interop/message-expiration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Message expiration
description: What message expiration is, why it exists, and how to reemit a previously sent message if it has expired and was never relayed.
lang: en-US
content_type: guide
topic: message-expiration
personas:
- protocol-developer
- chain-operator
- app-developer
categories:
- protocol
- interoperability
- cross-chain-messaging
- security
- block-safety
- message-passing
- reorgs
- superchain
is_imported_content: 'false'
---

# Message expiration

[Initiating messages](/interop/message-passing) sent between OP Stack chains have a limited validity period called the expiry window. Once this window elapses, the initiating message becomes invalid and can no longer be referenced on the destination chain.

If a message expires before being relayed, developers can reemit the message on the source chain. This triggers a fresh `SentMessage` event, allowing offchain infrastructure to pick it up and relay it again ensuring successful delivery.

## The expiry window

The expiry window is an offchain constant, defined by op-supervisor, that defines how long a cross-chain message or event emmitted by a chain remains valid. For any chain in the [interop set](/interop/explainer), messages must be executed within 7 days (604,800 seconds) of the initiating message being sent.
Comment thread
bradleycamacho marked this conversation as resolved.
Outdated
Comment thread
bradleycamacho marked this conversation as resolved.
Outdated

After this period, a message can no longer be executed on the destination chain unless the event is remitted on the source chain.
Comment thread
bradleycamacho marked this conversation as resolved.
Outdated

## Reemitting an expired message

The `resendMessage` function on the [`L2ToL2CrossDomainMessenger`](/interop/message-passing) contract allows developers to reemit a message that was sent but not yet relayed.
Comment thread
bradleycamacho marked this conversation as resolved.

This emits a new `SentMessage` log with the same content as the original message, enabling offchain relayers to pick it up again.

The process to reemit an expired message:

1. Call [`resendMessage`](https://github.com/ethereum-optimism/optimism/blob/a979a9444dbb482843f2a42f437ced54a8ac1053/packages/contracts-bedrock/interfaces/L2/IL2ToL2CrossDomainMessenger.sol#L110-L128) on the origin chain to reemit the message event. The contract verifies the message hash was originally sent. The call required the following parameters:

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

2. [Relay the new message](/interop/message-passing#executing-message) as normal.
14 changes: 7 additions & 7 deletions pages/interop/message-passing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ sequenceDiagram
dstXdom->>dstContract: 5. Call with provided calldata
```

1. Before the executing message is processed, the log event of the initiating message has to get to `op-supervisor` on the destination chain.
1. Before the executing message is processed, the log event of the initiating message has to get to `op-supervisor` on the destination chain before the [expiry window](/interop/message-expiration) of 7 days.

2. The autorelayer, the application, or a contract calling on the application's behalf calls [`L2ToL2CrossDomainMessenger.relayMessage`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol#L150-L203).
This call includes the message that was sent (`_sentMessage`), 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).
Expand All @@ -110,12 +110,12 @@ sequenceDiagram

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.
* `_destination`: Chain ID of the destination chain.
* `_nonce`: Nonce of the message sent
* `_sender`: Address that sent the message
* `_target`: Target contract or wallet address.
* `message`: Message payload to call target with.


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

Expand Down
Loading