Mailbox 信箱模型是什么?跨链消息的两端各发生什么 图 1
Mailbox 信箱模型是什么?跨链消息的两端各发生什么 · 图 1

每条链上都有一个信箱

Hyperlane 的架构文档把它的核心合约说得很简单:在它支持的每条链上各部署一个 Mailbox 合约,发消息调 dispatch,收消息靠接收方实现 handle。除此之外没有中枢——没有一条”消息链”、没有一个必须信任的总路由。跨链动作被拆成两个链上事件加两个链下角色:源链上 dispatch 把消息记进合约,目标链上 process 把消息交付给应用,中间由中继器搬运行、由安全模块把关。

这个”信箱对信箱”的结构决定了后面所有细节。发送方永远只跟自己链上的 Mailbox 打交道,接收方也只认目标链那个 Mailbox 的调用,两边合约之间不发生直接通信。

示意图

dispatch 的签名带着三个核心参数:目标链的域编号、接收者地址、消息体。Mailbox 会在消息体前面拼上头部,字段包括合约版本、nonce、源域、发送者、目标域、接收者。每条消息插入合约维护的一棵递增默克尔树成为一片叶子,消息编号即叶子哈希。这条生命线意味着两件事:其一,任何一条发出的消息都有链上凭据,可以拿编号去查它到没到;其二,默克尔树是后续安全证明的原料,证明类安全模块验证的正是”某条消息确实进了某棵树的某个位置”。

合约还维护一个已交付映射。同一消息编号第二次执行会被拒绝,重放保护因此落在信箱自己身上,不依赖下游逻辑。

中继器:搬运工,但要有凭证

消息不会自己过河。中继器为每条源链跑索引任务、为每条目标链跑提交任务:用 RPC 查 Mailbox 事件找到新消息,确认发送者为投递付过费,再按接收者指定的安全模块准备元数据——可能是验证者签名的聚合、默克尔证明,或零知识证明。准备就绪后,中继器在目标链调 process,附上元数据。它的提交管线分成队列化的几步:检查燃气是否付过、拉取元数据、模拟交付交易,模拟通过才真正上链,失败退回重排队,并用自适应退避持续重试。

这里要注意分工的边界:中继器决定什么时候搬、怎么搬,但不能决定消息成不成立——成立与否由安全模块的验证结果说话。搬运转为付费服务,费用由发送时的报价覆盖目标链的执行成本。

安全模块:收件人有权挑门卫

process 不会直接调应用,而是先把消息和元数据交给安全模块(ISM)验证。ISM 是可插拔的:Mailbox 有默认 ISM,应用也可以自己声明一个,要求更严就多验一层。多签 ISM 要求一组链下验证者对消息树签名;聚合或阈值模块提高签名门槛;路由 ISM 允许按源链分别挂不同门卫。验证通过,Mailbox 才调用接收方的 handle,所以接收合约的标准写法是把调用权限限制为自己的 Mailbox 地址。

这套设计把”消息能不能信”从协议固定项变成了应用选项,但也要诚实地画出边界:安全模块证明的是”这条消息在源链确实被 dispatch 过”,不保证源链本身不会重组,也不审查消息内容是否合理。源链重组可能让”已交付”与”源头存在”分家;接收方还必须自己校验 sender 字段——信箱保证的是谁发的,业务逻辑得自己判断该不该理他。

排障视角:三段各查什么

一条消息卡在途中,定位方式就藏在这个结构里。第一段查源链:Dispatch 事件在不在、消息编号是什么、默克尔树里有没有这片叶子——没有就是根本没发出去。第二段查交付:目标链上同编号的 Process 事件——没有编号映射即未投递,常见原因是付费不足、中继器积压或元数据未就绪。第三段查执行:Process 有但业务状态不对,往往是 handle 内部回滚,问题在应用而不在管道。三段各自有链上凭据,这正是信箱结构给排查带来的最大便利。本文是机制说明,不构成任何投资建议。