跨链消息的可靠性,大家通常只关心封包有没有送到;真正决定「能不能信」的是更早的一步:两条链怎么向彼此认定一条经过授权的管道。Cosmos 的 IBC 标准里,ICS-003 定义的 connection(连接)抽象专门管这件事——与 ICS-002 的轻客户端配合建立授权语义,即每个封包都必须在发送链上可证明地提交过;至于先后次序,则交给 ICS-004 的排序语义。本文按规范原文拆解这场开手协议。
授权与排序:两条正交的担保
规范开篇就把核心 IBC 协议承诺的语义拆成两条:授权与排序。授权保证封包确实已在发送链上提交、对应状态迁移(比如锁住代币)已经执行;排序保证封包被恰好一次、按特定顺序提交,并能按同一顺序交付。连接抽象连同轻客户端抽象负责前者,ICS-004 负责后者。这个分工解释了为什么连接建立的握手看起来与业务消息毫无关系:它做的事情是给未来的每一次封包验证预置参照系——在对方链上,我该用哪个客户端、认哪个连接标识符去查证明。
连接不是通道
先分清楚层次:客户端登记一条链的共识状态,连接站在客户端之上,为两条链上的模块提供一个稳定的「对面那条链」的引用;通道再建在连接之上,才是真正传消息的管道。官方规范强调,开手协议让每条链能验证对面使用的连接标识符,从而让两边的模块可以互相指认;连接提供授权语义,与客户端一起构成交付证明的地基。换句话说,模块验证一笔跨链到账时,链条是「通道证明了封包被提交、连接证明了该用哪个客户端、客户端证明了对方共识状态」,连接是中间那环。
四个数据报,一步不多一步不少
开手协议定义了四个数据报:ConnOpenInit、ConnOpenTry、ConnOpenAck、ConnOpenConfirm。常见的发起方式是一条链先发 Init 建立半开的连接状态,对端回一个 Try 表示「我这儿也想开」,发起方用 Ack 确认,最后对端以 Confirm 收尾。如果双方都已知晓对方的存在,Init 也可以单向发起、直接由 Ack 结束。规范规定:一旦协商开始,只有恰当的数据报能按顺序执行;四步走完,连接才算建立。规范把这四步称为开手子协议,并写明它的作用是在两条链上互相初始化对方的共识状态——握手完成后,连接两端各自持有指向对方的客户端引用,后续封包验证直接复用。

握手每一步在验什么
在原始设计里,Try 与 Ack 两类响应消息携带对方链的客户端状态、客户端证明与共识状态证明:发起方要确认对端确实在用它声称的那条链的客户端,对端也要反向确认发起方的状态真实可信。这正是「防中间人」承诺的来源——规范明确写道,连接握手不可能被第三条链的 IBC handler 冒充:如果对手拿另一条链的客户端状态来套握手,验证会失败。较新的规范文本记录了一处重要改动:ConnOpenTry 与 ConnOpenAck 不再验证对端客户端状态与共识状态对执行链是否合法,clientState、proofClient、proofConsensus、consensusHeight 四个字段被标注为弃用并将最终移除。对工程读者的提醒是:不同 IBC 实现版本对这几个字段的要求不同,排查连接报错时要先确认自己对着哪一版规范。
版本协商与不可逆性
两条链还得谈拢连接协议的版本:实现必须提供 getCompatibleVersions,返回按偏好降序排列的支持版本清单,找不到共同可接受的版本,握手就失败。发起方也可以在消息里钉死一个版本,要么以它完成握手,要么直接失败。开成之后的连接不能关闭,标识符也不能重新分配——规范给出的理由是封堵封包重放与授权混淆:如果连接可以拆了重开、编号可以回收,旧证明就可能被挪用到新连接上。这个一次性设计意味着连接是长期基础设施,参数错配不会给你重来的机会。
排查时怎么想
一条连接开不起来,按规范可以顺序检查三件事:两边引用的客户端状态是否真实存在、状态是否还在信任期内;四个数据报是否按序执行、有没有重复或跳步;版本清单是否谈不拢。中继器在四步之间要分别把消息送到两条链上,任何一步卡住连接就停在半开状态,此时不能删除重建,只能排查后继续补齐剩余步骤。连接一旦成立参数即不再变化,此后的故障通常出在通道与封包层,对应 ICS-004 的超时与回执规则。本文为协议机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。