这篇文章深入探讨了IBC通道的基本概念,包括通道的类型、握手过程、包的超时机制等。作者通过丰富的实例和图示,清晰地解释了通道在跨链通信中的作用,并对开发者可能遇到的问题进行了解释。文章结构清晰,逻辑严谨,是对IBC通道的优秀介绍。
渠道 是 核心跨链通信(IBC) 协议的重要组成部分。它们充当在一条链上的 模块/应用和另一条链上的模块之间传输数据包的通道。对于应用开发者来说,渠道是 IBC 抽象中最重要的层次。
这篇博客旨在解释渠道,并解答开发者对 IBC Channel的常见问题/误解。涵盖的主要主题包括频道排序、握手、关闭、重新打开、渠道的安全属性以及数据包超时。
内容很多,所以这是一个两部分系列的第一部分。第一部分关注 IBC Channel的基础知识,而第二部分将解答应用开发者对渠道的一些常见问题。
一个渠道是用于在两条不同链上的两个不同模块/应用之间传输数据包的通道。它们确保数据包仅执行一次,并且仅交付给拥有渠道另一端的对应模块。
每个渠道与特定的 连接 相关联,一个连接可以有任意数量的相关渠道。
图 1: 从链 A 上的模块发送到链 B 上模块的数据包的高层次描绘
目前,主要有两种类型的渠道:
渠道排序是通过 数据包 序列 来强制执行的。
每个数据包都有一个数据包序列,表示发送和接收数据包的顺序。序列号为 1 的数据包将在序列号为 2 或更高的数据包之前在目的地被接收和处理。
一个渠道端维护三个不同的序列 — nextSequenceSend
、nextSequenceRecv
和 nextSequenceAck
。每当一个渠道发送、接收或确认一个数据包时,nextSequenceSend
、nextSequenceRecv
和 nextSequenceAck
计数器分别递增。
图 2: 有序渠道中数据包与渠道序列的关系
在 有序渠道中,只有当数据包序列与渠道端预期的 nextSequenceRecv
相符时,数据包才会被接收和处理。如果数据包序列小于 nextSequenceRecv
,意味着数据包已被接收,则核心 IBC 进行无操作,如这里所示。
如果数据包序列大于 nextSequenceRecv
,意味着在当前的数据包之前还有一个较早序列的数据包需要接收,数据包将被拒绝,并且中继者最终会提交正确的数据包。
当数据包在无序渠道上被接收时,核心 IBC 仅确保它尚未被接收(因排序无关紧要),通过查找数据包收据 — 一个指示数据包已经接收的单个位。如果收据已存在,则渠道无操作。如果不存在,则 收据被设置,并处理数据包。
渠道通过四步握手建立。在握手过程的每一步,核心 IBC 执行基本验证和逻辑,同时回调可以执行自定义握手逻辑的应用。
在握手过程中,两个模块之间进行版本协商。这使得应用可以就将通过该渠道发送的数据包数据的结构、与使用中间件相关的逻辑等达成一致。
在 ICS-20 的情况下,渠道握手如下:
chanOpenInit
函数。随后,onChanOpenInit
回调允许链 A 上的应用执行自定义逻辑。这将渠道端状态(在 A 上)设置为 INIT。中继者将此版本传递给链 B,作为第 2 步的 counterpartyVersion
字符串。chanOpenTry
,其中应用执行自定义握手逻辑 onChanOpenTry
,将渠道端状态设置为 TRY。链 B 上的应用确保其版本与对方应用所提议的版本相同, 如这里所示。chanOpenAck
。此步骤中版本协商已经完成,A 上的渠道端状态被设置为 OPEN。chanOpenConfirm
,其中渠道端也设置为 OPEN。图 3: Channel开启握手
¹chanOpenInit 也可以由应用模块(例如 ICA)调用
在握手过程的任何阶段,回调函数都可能返回错误。在这种情况下,渠道握手失败,需要协商新的握手。
一旦在两个模块之间建立了渠道,升级该模块或使用中间件包裹模块是不可行的,除非打开新的渠道或协调整个网络的升级。我们目前关于 渠道可升级性 的工作解决了这一问题,以便模块能够升级以利用新功能,或在两侧添加中间件,同时保持相同的渠道。
一个渠道仅在异常情况下关闭。我们将在系列的第二部分中讨论所有关闭渠道的原因。关闭渠道通过两步渠道关闭握手进行。中继者提交 ChannelCloseInit
,这允许该链上的应用执行自定义逻辑 onChanCloseInit
。ChannelCloseConfirm
在对方链提交,其中调用 onChanCloseConfirm
回调。
图 4: Channel关闭握手
核心 IBC 提供的关键保证之一是 如果超时已过,则数据包不会在目的链上被接收。超时是在 数据包接口 中由 timeoutHeight
和 timoutTimestamp
设置为对方(接收)链的。
func NewPacket(
data []byte,
sequence uint64, sourcePort, sourceChannel,
destinationPort, destinationChannel string,
timeoutHeight clienttypes.Height, timeoutTimestamp uint64,
) Packet {
return Packet{
Data: data,
Sequence: sequence,
SourcePort: sourcePort,
SourceChannel: sourceChannel,
DestinationPort: destinationPort,
DestinationChannel: destinationChannel,
TimeoutHeight: timeoutHeight,
TimeoutTimestamp: timeoutTimestamp,
}
}
注意: 超时需要在发送链上进行证明,基于接收链的超时高度或超时时间戳。
根据接收者的本地时钟指定超时确保不会出现以下情况:发送者认为数据包超时并采取行动,例如在Token转移中释放托管Token,而数据包实际上被对方及时接收,对方继续铸造Token——导致双重支出。
有两个场景可能导致数据包超时:1) 标准情况下接收链上的超时时间戳或超时高度已过,或者 2) Channel关闭,因此所有未接收的数据包将超时。
我们将分别深入探讨这两种情况。首先,让我们看看最常见的场景。
RecvPacket
函数返回错误。ErrPacketTimeout
)并向源链发送 TimeoutPacket
。TimeoutPacket
包含一个 proof
和一个 ProofHeight
。proof
用于证明在这个 特定高度,数据包未被接收。ProofHeight
与特定 ConsensusState
相关联。每个 ConsensusState
都有特定的时间戳。因此,我们使用 GetTimestampAtHeight
函数获取与特定 ProofHeight
相关的时间戳。ProofHeight
证明对方时间戳(与 ProofHeight
相关)大于在数据包中指定的超时时间戳。ProofHeight
大于或等于超时高度。7.a. 在无序渠道的简单情况下,我们证明在此 ProofHeight
上不存在数据包收据。换句话说,这是一个某个键在状态树中不存在的证明。²
7.b. 对于有序渠道,我们验证 nextSequenceReceive
小于或等于数据包序列。这确保目的链未接收该数据包。例如,如果 nextSequenceReceive
为 3,而数据包序列为 4,则渠道期望在接收 4 之前接收序列为 3 的数据包。与第 7.a 不同,这是 nextSequenceReceive
的成员资格证明。³
一旦我们证明了第 5(或 6)和第 7 步,发送模块调用 OnTimeoutPacket
以恢复任何状态更改或执行自定义逻辑。在 ICS-20 代币转账的情况下,托管的代币会被 解托管并退还给用户。
² 也称为 不成员/不存在的证明 。 IBC 模块在 IAVL 树 (与其他 Cosmos SDK 模块类似) 中维护其状态。在 IAVL 树中,子键按字母顺序排列。因此,要证明键 'b' 不存在(即不存在证明),需要证明 'a' 和 'c' 存在,并且在它们之间不存在其他键。
³ _除了超时,IBC 中的所有证明都是 成员资格证明 ,即证明特定键在状态树中存在。
发送模块调用 TimeoutOnClose
函数,以证明发送数据包的渠道已关闭。
在渠道关闭时执行超时逻辑是直接的。与上述提到的超时不同,核心 IBC 证明对方的时间已超过数据包超时,在这种情况下,我们只需证明对方的渠道状态已关闭(如 此处所示)。
在 IBC 中,通过两条不同渠道发送的相同代币并不可替代。这不是一个错误,而是 IBC 安全模型的一个基本方面。
即使存在两条不同的渠道 1 和 2,连接同两条链 A 和 B,通过这些渠道发送的相同代币 $FOO 也不可替代。这是因为每条渠道都有其自己的安全属性。例如,两个不同的渠道可能具有不同的版本。或者这些渠道可能与不同的连接相关联,而不是与同一个连接(可能连接不同的轻客户端)。但最重要的是,模块无法知道对方的渠道端属于哪个链。换句话说,模块只知道它们正在发送数据的渠道,而不知道它们正在与哪个链进行通信。
因此,必须确保每个渠道的安全边界是隔离的,并且不要对渠道及其相关轻客户端做出天真的假设。
如上所述,渠道在 IBC 内的数据包传输和排序中起着重要作用。由于模块和渠道紧密耦合,应用开发者了解 IBC Channel的方方面面是有益的。
在系列的第二部分中,我们将澄清应用开发者关于渠道的一些常见问题。同时,请随时查看我们的 开发者门户,了解更多关于 IBC Channel的信息。
IBC 是保证跨区块链之间以最小信任、安全和可扩展的方式进行任意数据传输的基本范式转变。请查看这里 以了解 IBC 的工作原理的介绍。
关于作者:
Adi Ravi Raj 在 Interchain GmbH 工作,是 IBC 团队的协议分析师。
感谢 Susannah Evans, 和 Thomas Dekeyser 审阅本文草稿。
- 原文链接: medium.com/the-interchai...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!