Skip to main content

Message expiration

Messages referenced between OP Stack chains have a limited validity period called the expiry window. Once this window elapses, the referenced message becomes invalid and can no longer be referenced. For messages using L2ToL2CrossDomainMessenger, a message that expires before being relayed can never be relayed. Its source chain can learn this and report it, so applications can undo the send.

The expiry window

The expiry window is an offchain constant that defines how long a cross-chain message or event emitted remains valid. For any chain in the Superchain interop cluster, messages must be referenced within 7 days (604,800 seconds) of the log being created.

Undoing an expired message

A message that its destination never relays can be marked expired on its source chain, so the application can undo the send:
  1. Export. Anyone calls exportUndeliveredMessage on the destination chain’s UndeliveredMessageExporter predeploy (0x4200000000000000000000000000000000000030), naming the message and the source chain’s L1CrossDomainMessenger. The exporter checks that the message was not relayed on the destination. The call can also be forced in as a deposit if the destination’s sequencer refuses it.
  2. Withdrawal. The export is an L2-to-L1 withdrawal to the source chain’s L1CrossDomainMessenger. After the destination’s withdrawal delay, someone proves and finalizes it on L1, and the source chain’s L1CrossDomainMessenger passes it to the source chain as a deposit.
  3. Expiry. The source chain’s L2ToL2CrossDomainMessenger sets expiredMessages(messageHash) and emits MessageExpired(messageHash, undeliveredAt), but only if the export happened more than 8 days after the message was sent (the expiry window plus a day of margin). An earlier export never becomes valid: it ends up as a failed message on the source chain, and the message can be exported again later.
The SuperchainETHBridge undoes an expired send with refundETH: the address that called sendETH calls it and gets its ETH back. Another application can undo its own sends the same way: check expiredMessages(messageHash) on the source chain’s L2ToL2CrossDomainMessenger, or watch for MessageExpired, and record that it undid the send, so the undo happens only once. The flag stays set.

Next steps