Skip to main content

Canonical message service

The canonical message service passes arbitrary messages (that is, user-specified data and native currency) between a LinethLineth (Formerly the Linea Stack) The open-source ZK-rollup stack, codebase, and technical protocol that's the foundation of Linea Mainnet. Operators can deploy this stack to launch their own Ethereum-compatible L2 or L3 networks. network and its

finalization layerFinalization layer The blockchain where a Lineth deployment submits proofs and state commitments for verification and hard finality. If the finalization layer is Ethereum (an L1), the deployment is an L2. If the finalization layer is Linea (an L2), the deployment is an L3.. It is general-purpose infrastructure: the canonical token bridge is built on it, and any contract or dapp can call it directly.

How it works​

The service is a pair of message service contracts, one deployed on the network and one on the finalization layer. An optional offchain relay, the Postman, watches both contracts and submits claims when a delivery fee was paid. Sending a message from the origin chain to the destination chain works as follows:

  1. A caller invokes sendMessage() on the origin contract with a destination address, a calldata payload, any native value to transfer, and an optional delivery fee. The contract emits the message.
  2. A message commitment is anchored on the destination contract.
  3. Claiming the message executes it: the destination contract checks the claim against that commitment, then calls the destination address with the payload and the value.

Claiming is permissionless: anyone can submit the claim. This gives senders two delivery modes:

  • Push: The sender pays a fee up front, and the Postman claims on their behalf, pushing the message to the recipient without them doing anything.
  • Pull: No fee is paid, so the message sits unclaimed until the recipient, or anyone else, pulls it by submitting the claim and paying the gas.

Push relies on the Postman for convenience, not for correctness. The fee goes to whoever submits the claim, so if the Postman is unavailable, the recipient or a third party can claim the message and collect the fee instead.

Sending and claiming a messageA caller invokes sendMessage on the origin message service, which emits the message. The destination message service anchors a commitment. If a delivery fee was paid, the Postman claims it and collects the fee (push). Otherwise the recipient or anyone else claims it (pull). The destination checks the claim and calls the recipient.Origin message serviceDestination message serviceCallersendMessage()Anchor the commitmentFee paid?Postman claims andcollects the fee (push)Recipient or anyoneelse claims (pull)Check the claim againstthe commitmentCall the recipientEmit the messageYesNo

Message commitments​

Each direction commits to its messages differently, because only one of the two chains sits behind a proof.

Network to finalization layer. Finalizing a range of blocks verifies its

ZK proofZero-knowledge proof A cryptographic method that allows an individual to prove that a statement is true without conveying any additional information. This is useful for scaling blockchain networks through rollups, because it reduces the amount of information you have to provide to lower layers. and anchors the Merkle root of the messages those blocks sent. A claim on the finalization layer's message service carries a Merkle proof. The service accepts the claim only if the proof shows the message is included under that anchored root. Messages are therefore only claimable once the blocks that sent them are finalized.

A message from the network to the finalization layerThe sender calls sendMessage on the network message service. Finalization verifies the ZK proof and anchors the Merkle root on the finalization layer message service. A claim is accepted when its Merkle proof shows the message is included under that root. Any other claim is rejected.Network message serviceFinalization layermessage serviceSender calls sendMessage()Verify the ZK proofAnchor the Merkle rootMerkle proof shows inclusionunder the anchored root?Call the recipientReject the claimYesNo

Finalization layer to network. The coordinatorCoordinator Lineth's coordination module for batching, proof generation, and finality submission. The coordinator monitors block production, manages conflation deadlines, batches blocks, combines batches into blobs, orchestrates execution, compression, and aggregation proofs, and submits proofs and data to the finalization layer. anchors incoming message hashes on the network as a rolling hash. Those messages are claimable once anchored, without waiting for the next finalization. The next finalization checks the network's rolling hash against the hash the finalization layer's message service computed when the messages were sent. If the hashes differ, the network cannot finalize, because it would be finalizing messages the finalization layer never sent.

A message from the finalization layer to the networkThe sender calls sendMessage on the finalization layer message service, which updates the rolling hash. The coordinator anchors that hash on the network message service, and the message can be claimed once anchored. The next finalization reads both rolling hashes and compares them. If they match, finalization continues. If they do not, the network cannot finalize.Finalization layer message serviceNetwork messageserviceNext finalizationSender calls sendMessage()Update the rolling hashCoordinator anchorsthe message hashesClaimable once anchoredCall the recipientCompare therolling hashesHashes match?ContinuefinalizationCannot finalizeYesNo

See also​

Was this page helpful?