大纲
安全模型
↑ 返回大纲 我们考虑使用基于弱主观性模型的权益证明机制的链, 以加强底层共识引擎所需的假设条件 (例如,Tendermint 要求拜占庭投票权少于三分之一)。背景:区块链中的下一个区块由一组预先确定的全节点进行验证并投票;这些预先确定的全节点也称为验证者。 我们将有资格验证某个区块的验证者称为该区块的验证者集。 要成为验证者集的一部分,验证者需要在一段(最短)时间内绑定(即锁定、质押)一定数量的代币,这段时间称为解绑期。 绑定的代币数量决定验证者的投票权。 当验证者开始解绑其部分代币时,其投票权会立即降低, 但这些代币只有在解绑期结束后才会完成解绑(即解锁)。 如果验证者存在不当行为(例如,在同一高度验证两个不同的区块),那么系统可以惩罚该验证者在不当行为发生期间所对应投票权的已绑定代币。 这可以防止验证者作恶后立即带着代币退出, 也就是说,解绑期使系统能够在不当行为发生后对其进行惩罚。 更多细节可参见 Tendermint 规范 和轻客户端规范。在 CCV 的语境下,消费者链的验证者集是根据验证者在提供者链上绑定的代币来选择的, 也就是说,它们是从提供者链的验证者集中选出的。 当验证者在消费者链上作恶时,会惩罚其在提供者链上绑定的代币。 因此,由提供者链上已绑定代币价值所带来的安全性会与消费者链共享。 与单链方案类似,当验证者开始解绑其部分已绑定代币时,其投票权会在所有链上降低(即提供者链和消费者链); 然而,由于 IBC 协议通信存在延迟(例如,由于数据包中继),消费者链上的投票权不会立即降低。 CCV 的进一步结果是,只有当相应投票权被降低后,所有链上的解绑期都已届满时,代币才会完成解绑。 因此,CCV 可能会延迟验证者在提供者链上所绑定代币的解绑。
动机
↑ 返回大纲 CCV 是一种原语(即构建块),它支持任意共享安全模型:一条链的安全性可以由多个提供者链(包括其自身)的安全性组合而成(消费者链也可以是自己的提供者)。因此,CCV 使链能够从更成熟的链(例如 Cosmos Hub)借用安全性,以提升自身安全性,也就是提高攻击其网络的成本。直觉:例如,对于基于 Tendermint 共识的链,如果攻击者获得全部已绑定代币的 1/3+ 或 2/3+,就可能对网络发起多种攻击。由于新创建链的市值可能相对较低,攻击者现实中可能获得足够的代币以跨过这些阈值。作为解决方案,CCV 允许新创建的链使用那些在市值大得多的链上有质押的验证者,从而提高攻击者必须付出的成本。此外,CCV 还支持枢纽极简主义。简而言之,枢纽极简主义意味着让 Cosmos 网络中的枢纽(例如 Cosmos Hub)尽可能简单,只保留尽可能少的功能,以减少攻击面。CCV 使得可以将不同功能(例如 DEX)迁移到独立链上,而这些链仍由与枢纽相同的一组验证者来验证。
版本说明:请注意,CCV 将逐步开发。 本标准文档规定的是 V1 版本,它要求消费者链的验证者集必须完全由提供者链提供。 换句话说,一旦提供者链同意为消费者链提供安全性,提供者链的整个验证者集也 MUST 在消费者链上进行验证。 有关计划版本的更多细节,请参见跨链安全轻论文。
定义
↑ 返回大纲 本节定义 CCV 引入的新术语和概念。- 提供者链:提供安全性的区块链,即管理消费者链验证者集的区块链。
- 消费者链:消费安全性的区块链,即允许提供者链管理其验证者集的区块链。
注意:在本规范中,消费者链的验证者集完全由提供者链提供。提供者链和消费者链都是应用专用区块链, 也就是说,每条区块链的状态机通常都通过某种区块链接口与底层共识引擎连接,例如 ABCI。 区块链接口 MUST 使状态机能够向底层共识引擎提供一组验证者更新,即授予验证者投票权的变更。 尽管本规范并不依赖 ABCI,但为了便于表述,我们将这些状态机称为 ABCI 应用。 此外,本规范采用模块化范式, 也就是说,每个 ABCI 应用的功能被拆分为多个模块,类似于 Cosmos SDK 所采用的方法。
- CCV 模块:实现 CCV 协议的模块。提供者链和消费者链各自都拥有自己的 CCV 模块。 此外,CCV 模块在提供者链与消费者链上提供的功能有所不同。 为简洁起见,我们分别使用提供者 CCV 模块和消费者 CCV 模块来指代提供者链上的 CCV 模块和消费者链上的 CCV 模块。
- CCV 通道:一个唯一的、有序的 IBC 通道,提供者 CCV 模块使用它与某个消费者 CCV 模块交换 IBC 数据包。 请注意,每条消费者链都有各自独立的 CCV 通道。
- 验证者集变更(VSC):提供者链验证者集的一次变更,必须反映到消费者链的验证者集中。 每个 VSC 都由一批提供给提供者链共识引擎的验证者更新组成。
背景:在单链验证的语境下,验证者集的变更由质押模块触发, 也就是 ABCI 应用中实现安全模型所需权益证明机制的模块。 示例可参见 Cosmos SDK 的质押模块文档。其中一些验证者更新可能会降低授予验证者的投票权。 这些降低可能是提供者链上解绑操作(例如解绑委托)的结果。 这些操作 MUST NOT 在提供者链和所有消费者链上都达到成熟之前完成, 也就是说,提供者链和所有消费者链上的解绑期(记作
UnbondingPeriod)都必须已经届满。
因此,某个 VSC 在消费者链上达到成熟,意味着所有导致该 VSC 中包含验证者更新的解绑操作都已经在该消费者链上成熟。
背景:解绑操作是指对验证者所绑定代币数量进行解绑的任何操作。请注意,已绑定代币对应于验证者的投票权。我们区分三类解绑操作:无论类型如何,解绑操作都包含两个组成部分:
- undelegation - 委托人解绑其此前委托给某个验证者的代币;
- redelegation - 委托人将代币从源验证者立即重新委托给另一个验证者(目标验证者);
- validator unbonding - 验证者被移出验证者集;请注意,尽管验证者解绑并不意味着解绑代币,但其行为与其他解绑操作类似。
更多细节可参见 Cosmos SDK 文档。 注意:时间段以区块时间衡量,也就是
- 发起,例如委托人请求解绑其已委托的代币。对验证者所绑定代币数量进行解绑的操作一旦发起,就会导致该验证者投票权发生变化。
- 完成,例如代币实际完成解绑并返还给委托人。解绑操作要完成,必须达到成熟,也就是说,自操作发起以来必须经过
UnbondingPeriod。currentTimestamp()(定义见 ICS 24)。 因此,消费者链 MAY 在其应用某个区块中的每个 VSC 时,于该区块内任意时点开始计算解绑期。
- 惩罚请求:消费者链发出的请求,用于因某验证者在消费者链上的不当行为而惩罚其在提供者链上绑定的代币。惩罚请求 MAY 还会导致该作恶验证者被监禁一段时间,在此期间它不能成为验证者集的一部分。
背景:在单链验证的语境下,对作恶验证者进行惩罚和监禁由惩罚模块处理, 也就是 ABCI 应用中使应用能够阻止验证者作恶的模块。 示例可参见 Cosmos SDK 的惩罚模块文档。
概述
↑ 返回大纲 CCV 必须处理以下类型的操作:- 通道初始化:在提供者链与每条消费者链之间创建唯一且有序的 IBC 通道。
- 验证者集合更新:这是一个由两部分组成的操作,即:
- 根据从提供者 Staking 模块(即提供者链上的 Staking 模块)获得的、关于提供者链上验证者质押代币数量的信息,更新所有消费者链的验证者集合;
- 并确保解绑操作(即解绑已质押代币的操作)能够及时完成(参见消费者链上的解绑期)。
- 由消费者发起的惩罚:使提供者链能够对在消费者链上执行验证时发生不当行为的已质押验证者进行惩罚和监禁。
- 奖励分配:使消费者链上的区块生产奖励和交易手续费能够分配给提供者链上的验证者。
通道初始化
↑ 返回大纲 CCV 通道初始化区分了两种情况:一种是直接作为消费者链启动的链,另一种是转换为消费者链的现有链。 在这两种情况下,消费者链都通过治理提案创建。关于治理提案如何工作的示例,请参阅 Cosmos SDK 的治理模块文档。通道初始化:新链
下图展示了新链的 CCV 通道初始化概览。
新链的通道初始化由三个阶段组成:
- 创建客户端:当提供者 CCV 模块收到一个用于添加新消费者链且连接 ID 为空的提案后,它会创建该消费者链的客户端(定义见 ICS 2)以及消费者 CCV 模块的创世状态。
然后,提供者链验证者集合中的各验证者运营者都必须向提供者查询 CCV 创世状态,并启动消费者链的验证者节点。
一旦消费者链启动,应用程序将从共识引擎接收到一条
InitChain消息 (更多细节请参阅 ABCI 规范)。InitChain消息会触发对消费者 CCV 模块InitGenesis()方法的调用,从而创建提供者链的客户端。 创建客户端时,同时需要ClientState和ConsensusState(定义见 ICS 2); 这两者都包含在消费者 CCV 模块的创世状态中。 创世状态会分发给所有需要启动消费者链全节点的运营者 (分发创世状态的机制不在本规范的讨论范围内)。 最后,消费者 CCV 模块会同时发起连接握手(定义见 ICS 3)和通道握手(定义见 ICS 4)。注意,在创世时,消费者链的验证者集合与提供者链的验证者集合一致。
- 连接握手:中继器(定义见 ICS 18)负责完成连接握手(定义见 ICS 3)。
- 通道握手:中继器负责完成通道握手(定义见 ICS 4)。
握手由四条消息组成,这些消息需要被接收,以便在预期客户端之上建立通道。
注意,通道握手是在消费者链上发起的。
- OnChanOpenInit:收到
ChanOpenInit消息时,消费者 CCV 模块会验证与该通道关联的底层客户端是否为提供者链的预期客户端(即创世期间创建的客户端)。 - OnChanOpenTry:收到
ChanOpenTry消息时,提供者 CCV 模块会验证与该通道关联的底层客户端是否为消费者链的预期客户端(即在处理治理提案时创建的客户端)。 - OnChanOpenAck:收到第一条
ChanOpenAck消息时,消费者 CCV 模块会认为其 CCV 通道一侧已经建立。 此外,如果治理提案中未提供传输通道 ID,消费者 CCV 模块会发起奖励分配操作所需的代币传输通道的开启握手(参见奖励分配章节)。 - OnChanOpenConfirm:收到第一条
ChanOpenConfirm消息时,提供者 CCV 模块会认为其 CCV 通道一侧已经建立。
- OnChanOpenInit:收到
通道初始化:现有链
下图展示了现有链的 CCV 通道初始化概览。
现有链的通道初始化由三个阶段组成:
- 启动消费者 CCV 模块:当提供者 CCV 模块收到一个用于添加新消费者链且带有有效连接 ID的提案后,它会创建消费者 CCV 模块的创世状态。 然后,该现有链必须通过升级引入消费者 CCV 模块,并使用由提供者创建的 CCV 创世状态对其进行初始化。 一旦消费者 CCV 模块启动,它就会发起通道握手(定义见 ICS 4)。
-
通道握手:中继器负责完成通道握手(定义见 ICS 4)。
握手由四条消息组成,这些消息需要被接收,以便在预期客户端之上建立通道(即治理提案中提供的连接所使用的客户端)。
注意,通道握手是在消费者链上发起的。
- OnChanOpenInit:收到
ChanOpenInit消息时,消费者 CCV 模块会验证与该通道关联的底层客户端是否为提供者链的预期客户端。 - OnChanOpenTry:收到
ChanOpenTry消息时,提供者 CCV 模块会验证与该通道关联的底层客户端是否为消费者链的预期客户端。 - OnChanOpenAck:收到第一条
ChanOpenAck消息时,消费者 CCV 模块会认为其 CCV 通道一侧已经建立。 此外,如果治理提案中未提供传输通道 ID,消费者 CCV 模块会发起奖励分配操作所需的代币传输通道的开启握手(参见奖励分配章节)。 最后,消费者 CCV 模块会向该现有链的 Staking 模块发出请求,用提供者创建的 CCV 创世状态中的初始验证者集合替换其验证者集合。注意,这与处理治理提案时的提供者验证者集合相同。
- OnChanOpenConfirm:收到第一条
ChanOpenConfirm消息时,提供者 CCV 模块会认为其 CCV 通道一侧已经建立。
- OnChanOpenInit:收到
- 转换为消费者链:一旦现有链上的验证者集合被初始验证者集合(来自提供者创建的 CCV 创世状态)替换,该现有链就会成为消费者链。
注意:对于新链和现有链,只要 CCV 所要求的假设成立(例如 Correct Relayer),那么在提供者链上通过的每个用于生成新消费者链的治理提案,最终都会创建出一个 CCV 通道。 此外,上述描述中的“第一条”关键字确保了 CCV 通道的唯一性,即后续任何尝试为同一消费者链再创建另一个 CCV 通道的行为都会失败。 注意:对于新链和现有链,在 CCV 通道建立之前,消费者链的初始验证者集合不能被更新(参见验证者集合更新章节),并且该初始集合中的验证者也不能被惩罚(参见由消费者发起的惩罚章节)。 这意味着消费者链尚未受到提供者链的安全保护。 因此,为了在通道初始化期间减少攻击面,消费者链 SHOULD 仅在 CCV 通道建立之后(即接收到第一个 VSC 之后)才启用用户交易。 因而,恶意的初始验证者集合只能影响 CCV 通道的初始化。有关通道初始化的更详细描述,请参阅技术规范。
验证者集合更新
↑ 返回大纲 在 VSC 的上下文中,CCV 模块支持以下功能:- 在提供者链上,
- 向消费者链提供 VSC,以便它们根据提供者链的验证者集合更新自己的验证者集合;
提供 VSC 意味着向所有消费者链发送
VSCPacket; - 登记来自消费者链的 VSC 成熟通知。
- 向消费者链提供 VSC,以便它们根据提供者链的验证者集合更新自己的验证者集合;
提供 VSC 意味着向所有消费者链发送
- 在每条消费者链上,
- 将提供者链提供的 VSC 应用到消费者链的验证者集合;
- 通知提供者链该消费者链上的已提供 VSC 已经成熟;
通知 VSC 已成熟意味着向提供者链发送
VSCMaturedPacket。
解绑操作的完成
在单链验证的语境下,任何解绑操作的完成都要求自该操作发起以来经过UnbondingPeriod(即,该操作必须达到成熟状态)。
在 CCV 的语境下,为了保持安全模型,完成还必须要求该解绑操作在所有消费者链上都达到成熟状态。
因此,provider 的 Staking 模块需要感知 provider 的 CCV 模块登记的 VSC 成熟通知。
provider 链通过以下方式实现这一点:
- 当任意解绑操作被发起时,Staking 模块会通知 CCV 模块。 因此,CCV 模块会将所有解绑操作映射到对应的 VSC。
- 当 CCV 模块收到来自所有消费者链的某个 VSC 的成熟通知后,它会将映射到该 VSC 的所有解绑操作已成熟这一事实通知 Staking 模块。 这使得 Staking 模块只有在解绑操作同时在 provider 链和所有消费者链上都达到成熟状态时,才会完成这些解绑操作。
- 在
Block 1中,provider 的 Staking 模块发起了两个解绑操作(即undelegate-1和redelegate-1)。 对于每个操作,provider 的 Staking 模块都会通知 provider 的 CCV 模块。 因此,provider 的 CCV 模块会将这些操作映射到vscId,即后续 VSC 的 ID(即VSC1)。 provider 的 CCV 模块会将VSC1提供给所有消费者链。 - 在
Block 2中,对undelegate-2也采用相同的方法。 - 在
Block j中,自Block 1起已经过了UnbondingPeriod。 与此同时,provider 的 CCV 模块已经收到了来自所有消费者链的VSC1成熟通知, 因而通知 provider 的 Staking 模块,undelegate-1和redelegate-1都已成熟。 因此,provider 的 Staking 模块会在Block j中完成这两个解绑操作。 - 在
Block k中,自Block 2起已经过了UnbondingPeriod。 与此同时,provider 的 CCV 模块尚未收到来自所有消费者链的VSC2成熟通知。 因此,provider 的 Staking 模块不能在Block k中完成undelegate-2。 该解绑操作会在 provider 的 CCV 模块收到来自所有消费者链的VSC2成熟通知后,于稍后完成。
消费者发起的惩罚
↑ 返回大纲 为了保持安全模型,行为异常的验证者必须被惩罚(并且可以被监禁,即从验证者集合中移除)。 执行惩罚的前提是收到其不当行为的有效证据。 因此,在惩罚验证者时,我们区分以下三个事件及其发生的高度:infractionHeight,不当行为(或违规)发生的高度;evidenceHeight,收到不当行为证据的高度;slashingHeight,验证者被惩罚(并监禁)的高度。
注意:在单链验证的语境下,通常 evidenceHeight = slashingHeight。
安全模型保证,任何行为异常的验证者在至少一个解绑期内都可以被惩罚,
也就是说,只要该验证者的代币尚未解绑,就仍然可以被惩罚。
但是,如果这些代币在 infractionHeight 之前就开始解绑(即,这些代币并未贡献导致违规的投票权重),那么这些代币就绝不能被惩罚。
在 CCV 的语境下,验证者(其代币绑定在 provider 链上)对于其在消费者链上、且其拥有投票权重的高度所犯下的违规行为,必须被惩罚。
因此,尽管违规发生在消费者链上,且这些违规的证据也是提交到消费者链上的,但实际的惩罚发生在 provider 链上。于是,消费者发起惩罚操作要求对每条消费者链都维护一个从消费者链区块高度到 provider 链区块高度的映射。
下图借助提供的 VSC 展示了这种映射背后的直觉。
四个解绑操作(即取消委托)发生在 provider 链上,因此 provider 链会向消费者链提供 VSC,例如,undelegate-3 会导致提供 VSC3。
四种颜色(即红、蓝、绿、黄)表示消费者链高度到 provider 链高度的映射。
注意,在 provider 链上,每种颜色只对应一个区块。
还要注意,provider 链上绿色区块和黄色区块之间的三个白色区块具有相同的验证者集合。
因此,若某个验证者在消费者链上行为异常,例如发生在两个绿色区块中的任意一个,那么其受到的惩罚与它在 provider 链上行为异常(例如发生在绿色区块)时相同。
这确保了一旦解绑操作被发起,与之对应的解绑代币就不会因后续区块中的违规行为而被惩罚,例如,由 undelegate-3 导致解绑的代币,不会因绿色区块及之后区块中的违规行为而被惩罚。
下图展示了 CCV 如何建立从消费者链高度到 provider 链高度的映射。
为清晰起见,我们分别使用 Hp* 和 Hc* 表示 provider 链和消费者链上的区块高度。
- 对于每个区块,provider 的 CCV 模块都会将它提供给消费者链的 VSC 的 ID 映射到后续区块的高度,即,对于在高度
Hp提供的 VSC,有VSCtoH[VSC.id] = Hp + 1。 直观地说,这意味着某个已提供 VSC 中的验证者更新会在高度VSCtoH[VSC.id]更新投票权重。 - 对于每个区块,每个 consumer 的 CCV 模块都会将后续区块的高度映射到最近收到的 VSC 的 ID,例如,
HtoVSC[Hc2 + 1] = VSC1.id。 直观地说,这意味着消费者链在区块Hc期间的投票权重,是由 ID 为HtoVSC[Hc]的 VSC 更新的。注意:消费者链可能会在同一个区块内收到多个 VSC。更多细节请参见验证者集合、验证者更新与 VSC一节。
- 默认情况下,每个 consumer 的 CCV 模块都会将任意区块高度映射到
0(即,VSC ID 从1开始)。 直观地说,这意味着当HtoVSC(Hc) = 0时,消费者链在高度Hc的投票权重是在通道初始化期间于创世时建立的。 - 对于每条消费者链,provider 的 CCV 模块都会将
VSCtoH[0]设为它与该消费者链建立 CCV 通道时的高度。 注意,provider 链在高度VSCtoH[0]的验证者集合,与向该消费者链提供第一个 VSC 时对应高度的验证者集合是一致的。 这意味着,provider 链上的这个验证者集合,与消费者链上所有满足HtoVSC[Hc] = 0的高度Hc的验证者集合相匹配。
- 在(证据)高度
Hc2,消费者链收到某个验证者V在(违规)高度Hc1发生不当行为的证据。 因此,consumer 的 CCV 模块会向 provider 链发送一个SlashPacket: 它请求惩罚V,但会将违规高度Hc1替换为HtoVSC[Hc1], 即,更新“违规投票权重”的 VSC 的 ID;如果不存在这样的 VSC,则为0。 - provider 的 CCV 模块会在(惩罚)高度
Hp1收到携带vscId = HtoVSC[Hc1]的SlashPacket。 因此,它会请求 provider 的 Slashing 模块惩罚V,但将违规高度设置为VSCtoH[vscId],即:- 如果
vscId != 0,则为 provider 链上由 ID 为vscId的 VSC 更新投票权重的高度; - 否则,则为与该消费者链建立 CCV 通道的高度。
注意:惩罚(以及可能的监禁)
V的结果是,Staking 模块会相应更新V的投票权重。该更新必须在提供给消费者链的下一个 VSC 中可见。 - 如果
奖励分发
↑ 返回大纲 在单链验证的语境下,Distribution 模块,即 ABCI 应用的一个模块,负责根据每个验证者的总投票权重,将奖励(即区块生产奖励和交易手续费)分配到每个验证者账户; 随后,这些奖励会进一步分配给委托者。 一个示例可参见 Cosmos SDK 的Distribution 模块文档。 在每个区块开始时,前一个区块的奖励会被汇总到一个 distribution 模块账户中。 CCV 的奖励分发操作使每条消费者链都能够将其中一部分奖励转移到 provider 链。 该操作由两个步骤组成,如下图所示:
- 在消费者链每个区块开始时,会将一部分奖励转入 consumer 的 CCV 模块上的某个账户。
- 按固定间隔(例如每
1000个区块),consumer 的 CCV 模块会通过 IBC 代币转账包将累计奖励发送到 provider 链上的 distribution 模块账户(定义见 ICS 20)。 注意,该 IBC 转账包是通过一个独立的无序通道发送的。 因此,奖励分发不会与其他 CCV 操作保持同步, 例如,一些验证者可能因为在收到 IBC 转账包之前解绑而错过部分奖励, 而另一些验证者则可能因为在收到 IBC 转账包之前完成绑定而获得额外奖励。
注意:从 provider 链上的 distribution 模块账户视角来看,来自消费者链的奖励与本地收集的奖励无法区分,因此它们会被分配给所有验证者及其委托者。作为这种方法的前提条件,每条消费者链都必须先向 provider 链打开一个代币转账通道,并获知 provider 链上 distribution 模块账户的地址;这两件事都会在通道初始化期间完成。
- 在收到
ChanOpenAck消息后,consumer 的 CCV 模块会使用与 CCV 通道相同的客户端和连接,发起代币转账通道的握手打开流程。 - 在收到
ChanOpenTry消息后,provider 的 CCV 模块会将 distribution 模块账户的地址作为元数据添加到通道版本中(定义见 ICS 4)。
Outline
Security Model
↑ Back to Outline We consider chains that use a proof of stake mechanism based on the model of weak subjectivity in order to strengthen the assumptions required by the underlying consensus engine (e.g., Tendermint requires that less than a third of the voting power is Byzantine).Background: The next block in a blockchain is validated and voted upon by a set of pre-determined full nodes; these pre-determined full nodes are also known as validators. We refer to the validators eligible to validate a block as that block’s validator set. To be part of the validator set, a validator needs to bond (i.e., lock, stake) an amount of tokens for a (minimum) period of time, known as the unbonding period. The amount of tokens bonded gives a validator’s voting power. When a validator starts unbonding some of its tokens, its voting power is reduced immediately, but the tokens are unbonded (i.e., unlocked) only after the unbonding period has elapsed. If a validator misbehaves (e.g., validates two different blocks at the same height), then the system can slash the validator’s bonded tokens that gave its voting power during the misbehavior. This prevents validators from misbehaving and immediately exiting with their tokens, i.e., the unbonding period enables the system to punish misbehaving validators after the misbehaviors are committed. For more details, take a look at the Tendermint Specification and the Light Client Specification.In the context of CCV, the validator sets of the consumer chains are chosen based on the tokens validators bonded on the provider chain, i.e., are chosen from the validator set of the provider chain. When validators misbehave on the consumer chains, their tokens bonded on the provider chain are slashed. As a result, the security gained from the value of the tokens bonded on the provider chain is shared with the consumer chains. Similarly to the single-chain approach, when a validator starts unbonding some of its bonded tokens, its voting power is reduced on all chains (i.e., provider chain and consumer chains); yet, due to delays in the communication over the IBC protocol (e.g., due to relaying packets), the voting power is not reduced immediately on the consumer chains. A further consequence of CCV is that the tokens are unbonded only after the unbonding period has elapsed on all chains starting from the moment the corresponding voting power was reduced. Thus, CCV may delay the unbonding of tokens validators bonded on the provider chain.
Motivation
↑ Back to Outline CCV is a primitive (i.e., a building block) that enables arbitrary shared security models: The security of a chain can be composed of security transferred from multiple provider chains including the chain itself (a consumer chain can be its own provider). As a result, CCV enables chains to borrow security from more established chains (e.g., Cosmos Hub), in order to boost their own security, i.e., increase the cost of attacking their networks.Intuition: For example, for chains based on Tendermint consensus, a variety of attacks against the network are possible if an attacker acquire 1/3+ or 2/3+ of all bonded tokens. Since the market cap of newly created chains could be relatively low, an attacker could realistically acquire sufficient tokens to pass these thresholds. As a solution, CCV allows the newly created chains to use validators that have stake on chains with a much larger market cap and, as a result, increase the cost an attacker would have to pay.Moreover, CCV enables hub minimalism. In a nutshell, hub minimalism entails keeping a hub in the Cosmos network (e.g., the Cosmos Hub) as simple as possible, with as few features as possible in order to decrease the attack surface. CCV enables moving distinct features (e.g., DEX) to independent chains that are validated by the same set of validators as the hub.
Versioning: Note that CCV will be developed progressively. This standard document specifies the V1 release, which will require the validator set of a consumer chain to be entirely provided by the provider chain. In other words, once a provider chain agrees to provide security to a consumer chain, the entire validator set of the provider chain MUST validate also on the consumer chain. For more details on the planned releases, take a look at the Interchain Security light paper.
Definition
↑ Back to Outline This section defines the new terms and concepts introduced by CCV.- Provider Chain: The blockchain that provides security, i.e., manages the validator set of the consumer chain.
- Consumer Chain: The blockchain that consumes security, i.e., enables the provider chain to manage its validator set.
Note: In this specification, the validator set of the consumer chain is entirely provided by the provider chain.Both the provider and the consumer chains are application-specific blockchains, i.e., each blockchain’s state machine is typically connected to the underlying consensus engine via a blockchain interface, such as ABCI. The blockchain interface MUST enable the state machine to provide to the underlying consensus engine a set of validator updates, i.e., changes in the voting power granted to validators. Although this specification is not dependent on ABCI, for ease of presentation, we refer to the state machines as ABCI applications. Also, this specification considers a modular paradigm, i.e., the functionality of each ABCI application is separated into multiple modules, like the approach adopted by Cosmos SDK.
- CCV Module: The module that implements the CCV protocol. Both the provider and the consumer chains have each their own CCV module. Furthermore, the functionalities provided by the CCV module differ between the provider chain and the consumer chains. For brevity, we use provider CCV module and consumer CCV module to refer to the CCV modules on the provider chain and on the consumer chains, respectively.
- CCV Channel: A unique, ordered IBC channel that is used by the provider CCV module to exchange IBC packets with a consumer CCV module. Note that there is a separate CCV channel for every consumer chain.
- Validator Set Change (VSC): A change in the validator set of the provider chain that must be reflected in the validator sets of the consumer chains. Every VSC consists of a batch of validator updates provided to the consensus engine of the provider chain.
Background: In the context of single-chain validation, the changes of the validator set are triggered by the Staking module, i.e., a module of the ABCI application that implements the proof of stake mechanism needed by the security model. For an example, take a look at the Staking module documentation of Cosmos SDK.Some of the validator updates can decrease the voting power granted to validators. These decreases may be a consequence of unbonding operations (e.g., unbonding delegations) on the provider chain. which MUST NOT complete before reaching maturity on both the provider and all the consumer chains, i.e., the unbonding period (denoted as
UnbondingPeriod) has elapsed on both the provider and all the consumer chains.
Thus, a VSC reaching maturity on a consumer chain means that all the unbonding operations that resulted in validator updates included in that VSC have matured on the consumer chain.
Background: An unbonding operation is any operation of unbonding an amount of the tokens a validator bonded. Note that the bonded tokens correspond to the validator’s voting power. We distinguish between three types of unbonding operations:Regardless of the type, unbonding operations have two components:
- undelegation - a delegator unbonds tokens it previously delegated to a validator;
- redelegation - a delegator instantly redelegates tokens from a source validator to a different validator (the destination validator);
- validator unbonding - a validator is removed from the validator set; note that although validator unbondings do not entail unbonding tokens, they behave similarly to other unbonding operations.
For more details, take a look at the Cosmos SDK documentation. Note: Time periods are measured in terms of the block time, i.e.,
- The initiation, e.g., a delegator requests their delegated tokens to be unbonded. The initiation of an operation of unbonding an amount of the tokens a validator bonded results in a change in the voting power of that validator.
- The completion, e.g., the tokens are actually unbonded and transferred back to the delegator. To complete, unbonding operations must reach maturity, i.e.,
UnbondingPeriodmust elapse since the operations were initiated.currentTimestamp()(as defined in ICS 24). As a result, a consumer chain MAY start the unbonding period for every VSC that it applies in a block at any point during that block.
- Slash Request: A request by a consumer chain to slash the tokens bonded by a validator on the provider chain as a consequence of that validator misbehavior on the consumer chain. A slash request MAY also result in the misbehaving validator being jailed for a period of time, during which it cannot be part of the validator set.
Background: In the context of single-chain validation, slashing and jailing misbehaving validators is handled by the Slashing module, i.e., a module of the ABCI application that enables the application to discourage misbehaving validators. For an example, take a look at the Slashing module documentation of Cosmos SDK.
Overview
↑ Back to Outline CCV must handle the following types of operations:- Channel Initialization: Create unique, ordered IBC channels between the provider chain and every consumer chain.
- Validator Set Update: It is a two-part operation, i.e.,
- update the validator sets of all the consumer chains based on the information obtained from the provider Staking module (i.e., the Staking module on the provider chain) on the amount of tokens bonded by validators on the provider chain;
- and enable the timely completion (cf. the unbonding periods on the consumer chains) of unbonding operations (i.e., operations of unbonding bonded tokens).
- Consumer Initiated Slashing: Enable the provider chain to slash and jail bonded validators that misbehave while validating on the consumer chain.
- Reward Distribution: Enable the distribution of block production rewards and transaction fees from the consumer chains to the validators on the provider chain.
Channel Initialization
↑ Back to Outline The CCV Channel initialization differentiates between chains that start directly as consumer chains and existing chains that transition to consumer chains. In both cases, consumer chains are created through governance proposals. For an example of how governance proposals work, take a look at the Governance module documentation of Cosmos SDK.Channel Initialization: New Chains
The following figure shows an overview of the CCV Channel initialization for new chains.
The channel initialization for new chains consists of three phases:
- Create clients: Once the provider CCV module receives a proposal to add a new consumer chain with an empty connection ID, it creates a client of the consumer chain (as defined in ICS 2) and a genesis state of the consumer CCV module.
Then, the operators of validators in the validator set of the provider chain must each query the provider for the CCV genesis state and start a validator node of the consumer chain.
Once the consumer chain starts, the application receives an
InitChainmessage from the consensus engine (for more details, take a look at the ABCI specification). TheInitChainmessage triggers the call to theInitGenesis()method of the consumer CCV module, which creates a client of the provider chain. For client creation, both aClientStateand aConsensusStateare necessary (as defined in ICS 2); both are contained in the genesis state of the consumer CCV module. The genesis state is distributed to all operators that need to start a full node of the consumer chain (the mechanism of distributing the genesis state is outside the scope of this specification). Finally, the consumer CCV module initiates both the connection handshake (as defined in ICS 3) and the channel handshake (as defined in ICS 4).Note that at genesis, the validator set of the consumer chain matches the validator set of the provider chain.
- Connection handshake: A relayer (as defined in ICS 18) is responsible for completing the connection handshake (as defined in ICS 3).
- Channel handshake: A relayer is responsible for completing the channel handshake (as defined in ICS 4).
The handshake consists of four messages that need to be received for a channel built on top of the expected clients.
Note that the channel handshake is initiated on the consumer chain.
- OnChanOpenInit: On receiving a
ChanOpenInitmessage, the consumer CCV module verifies that the underlying client associated with this channel is the expected client of the provider chain (i.e., created during genesis). - OnChanOpenTry: On receiving a
ChanOpenTrymessage, the provider CCV module verifies that the underlying client associated with this channel is the expected client of the consumer chain (i.e., created when handling the governance proposal). - OnChanOpenAck: On receiving the FIRST
ChanOpenAckmessage, the consumer CCV module considers its side of the CCV channel to be established. Also, if a transfer channel ID was not provided in the governance proposal, the consumer CCV module initiates the opening handshake for the token transfer channel required by the Reward Distribution operation (see the Reward Distribution section). - OnChanOpenConfirm: On receiving the FIRST
ChanOpenConfirmmessage, the provider CCV module considers its side of the CCV channel to be established.
- OnChanOpenInit: On receiving a
Channel Initialization: Existing Chains
The following figure shows an overview of the CCV Channel initialization for existing chains.
The channel initialization for existing chains consists of three phases:
- Start consumer CCV module: Once the provider CCV module receives a proposal to add a new consumer chain with a valid connection ID, it creates a genesis state of the consumer CCV module. Then, the existing chain must upgrade by adding the consumer CCV module and initialize it using the CCV genesis state created by the provider. Once the consumer CCV module starts, it initiates the channel handshake (as defined in ICS 4).
-
Channel handshake: A relayer is responsible for completing the channel handshake (as defined in ICS 4).
The handshake consists of four messages that need to be received for a channel built on top of the expected clients (i.e., the clients used by the connection provided in the governance proposal).
Note that the channel handshake is initiated on the consumer chain.
- OnChanOpenInit: On receiving a
ChanOpenInitmessage, the consumer CCV module verifies that the underlying client associated with this channel is the expected client of the provider chain. - OnChanOpenTry: On receiving a
ChanOpenTrymessage, the provider CCV module verifies that the underlying client associated with this channel is the expected client of the consumer chain. - OnChanOpenAck: On receiving the FIRST
ChanOpenAckmessage, the consumer CCV module considers its side of the CCV channel to be established. Also, if a transfer channel ID was not provided in the governance proposal, the consumer CCV module initiates the opening handshake for the token transfer channel required by the Reward Distribution operation (see the Reward Distribution section). Finally, the consumer CCV module makes a requests to the Staking module of the existing chain to replace its validator set with the initial validator set from the CCV genesis state created by the provider.Note that this is the same as the provider validator set when the governance proposal was handled.
- OnChanOpenConfirm: On receiving the FIRST
ChanOpenConfirmmessage, the provider CCV module considers its side of the CCV channel to be established.
- OnChanOpenInit: On receiving a
- Transition to consumer chain: Once the validator set on the existing chain is replace by the initial validator set (from the CCV genesis state created by the provider), the existing chain becomes a consumer chain.
Note: For both new and existing chains, as long as the assumptions required by CCV hold (e.g., Correct Relayer), every governance proposal to spawn a new consumer chain that passes on the provider chain results eventually in a CCV channel being created. Furthermore, the “FIRST” keyword in the above description ensures the uniqueness of the CCV channel, i.e., all subsequent attempts to create another CCV channel to the same consumer chain will fail. Note: For both new and existing chains, until the CCV channel is established, the initial validator set of the consumer chain cannot be updated (see the Validator Set Update section) and the validators from this initial set cannot be slashed (see the Consumer Initiated Slashing section). This means that the consumer chain is not yet secured by the provider chain. Thus, to reduce the attack surface during channel initialization, the consumer chain SHOULD enable user transactions only after the CCV channel is established (i.e., after receiving the first VSC). As a consequence, a malicious initial validator set can only influence the initialization of the CCV channel.For a more detailed description of Channel Initialization, take a look at the technical specification.
Validator Set Update
↑ Back to Outline In the context of VSCs, the CCV module enables the following functionalities:- On the provider chain,
- provide VSCs to the consumer chains, for them to update their validator sets according to the validator set of the provider chain;
providing VSCs entails sending
VSCPackets to all consumer chains; - register VSC maturity notifications from the consumer chain.
- provide VSCs to the consumer chains, for them to update their validator sets according to the validator set of the provider chain;
providing VSCs entails sending
- On every consumer chain,
- apply the VSCs provided by the provider chain to the validator set of the consumer chain;
- notify the provider chain that the provided VSCs have matured on this consumer chain;
notifying of VSCs maturity entails sending
VSCMaturedPackets to the provider chain.
Completion of Unbonding Operations
In the context of single-chain validation, the completion of any unbonding operation requires theUnbondingPeriod to elapse since the operations was initiated (i.e., the operation MUST reach maturity).
In the context of CCV, the completion MUST require also the unbonding operation to reach maturity on all consumer chains (for the Security Model to be preserved).
Therefore, the provider Staking module needs to be aware of the VSC maturity notifications registered by the provider CCV module.
The provider chain achieves this through the following approach:
- The Staking module is notifying the CCV module when any unbonding operation is initiated. As a result, the CCV module maps all the unbonding operations to the corresponding VSCs.
- When the CCV module registers maturity notifications for a VSC from all consumer chains, it notifies the Staking module of the maturity of all unbonding operations mapped to this VSC. This enables the Staking module to complete the unbonding operations only when they reach maturity on both the provider chain and on all the consumer chains.
- In
Block 1, two unbonding operations are initiated (i.e.,undelegate-1andredelegate-1) in the provider Staking module. For each operation, the provider Staking module notifies the provider CCV module. As a result, the provider CCV module maps these to operation tovscId, which is the ID of the following VSC (i.e.,VSC1). The provider CCV module providesVSC1to all consumer chains. - In
Block 2, the same approach is used forundelegate-2. - In
Block j,UnbondingPeriodhas elapsed sinceBlock 1. In the meantime, the provider CCV module registered maturity notifications forVSC1from all consumer chains and, consequently, notified the provider Staking module of the maturity of bothundelegate-1andredelegate-1. As a result, the provider Staking module completes both unbonding operations inBlock j. - In
Block k,UnbondingPeriodhas elapsed sinceBlock 2. In the meantime, the provider CCV module has NOT yet registered maturity notifications forVSC2from all consumer chains. As a result, the provider Staking module CANNOT completeundelegate-2inBlock k. The unbonding operation is completed later once the provider CCV module registered maturity notifications forVSC2from all consumer chains.
Consumer Initiated Slashing
↑ Back to Outline For the Security Model to be preserved, misbehaving validators MUST be slashed (and MAY be jailed, i.e., removed from the validator set). A prerequisite to slashing validators is to receive valid evidence of their misbehavior. Thus, when slashing a validator, we distinguish between three events and the heights when they occur:infractionHeight, the height at which the misbehavior (or infraction) happened;evidenceHeight, the height at which the evidence of misbehavior is received;slashingHeight, the height at which the validator is slashed (and jailed).
Note: In the context of single-chain validation, usually evidenceHeight = slashingHeight.
The Security Model guarantees that any misbehaving validator can be slashed for at least the unbonding period,
i.e., as long as that validator’s tokens are not unbonded yet, they can be slashed.
However, if the tokens start unbonding before infractionHeight (i.e., the tokens did not contribute to the voting power that committed the infraction) then the tokens MUST NOT be slashed.
In the context of CCV, validators (with tokens bonded on the provider chain) MUST be slashed for infractions committed on the consumer chains at heights for which they have voting power.
Thus, although the infractions are committed on the consumer chains and evidence of these infractions is submitted to the consumer chains, the slashing happens on the provider chain. As a result, the Consumer Initiated Slashing operation requires, for every consumer chain, a mapping from consumer chain block heights to provider chain block heights.
The following figure shows the intuition behind such a mapping using the provided VSCs.
The four unbonding operations (i.e., undelegations) occur on the provider chain and, as a consequence, the provider chain provides VSCs to the consumer chain, e.g., undelegate-3 results in VSC3 being provided.
The four colors (i.e., red, blue, green, and yellow) indicate the mapping of consumer chain heights to provider chain heights.
Note that on the provider chain there is only one block of a given color.
Also, note that the three white blocks between the green and the yellow blocks on the provider chain have the same validator set.As a result, a validator misbehaving on the consumer chain, e.g., in either of the two green blocks, is slashed the same as if misbehaving on the provider chain, e.g., in the green block. This ensures that once unbonding operations are initiated, the corresponding unbonding tokens are not slashed for infractions committed in the subsequent blocks, e.g., the tokens unbonding due to
undelegate-3 are not slashed for infractions committed in or after the green blocks.
The following figure shows describes how CCV creates the mapping from consumer chain heights to provider chain heights.
For clarity, we use Hp* and Hc* to denote block heights on the provider chain and consumer chain, respectively.
- For every block, the provider CCV module maps the ID of the VSC it provides to the consumer chains to the height of the subsequent block, i.e.,
VSCtoH[VSC.id] = Hp + 1, for a VSC provided at heightHp. Intuitively, this means that the validator updates in a provided VSC will update the voting power at heightVSCtoH[VSC.id]. - For every block, every consumer CCV module maps the height of the subsequent block to the ID of the latest received VSC, e.g.,
HtoVSC[Hc2 + 1] = VSC1.id. Intuitively, this means that the voting power on the consumer chain during a blockHcwas updated by the VSC with IDHtoVSC[Hc].Note: It is possible for multiple VSCs to be received by the consumer chain within the same block. For more details, take a look at the Validator sets, validator updates and VSCs section.
- By default, every consumer CCV module maps any block height to
0(i.e., VSC IDs start from1). Intuitively, this means that the voting power on the consumer chain at heightHcwithHtoVSC(Hc) = 0was setup at genesis during Channel Initialization. - For every consumer chain, the provider CCV module sets
VSCtoH[0]to the height when it establishes the CCV channel to this consumer chain. Note that the validator set on the provider chain at heightVSCtoH[0]matches the validator set at the height when the first VSC is provided to this consumer chain. This means that this validator set on the provider chain matches the validator set on the consumer chain at all heightsHcwithHtoVSC[Hc] = 0.
- At (evidence) height
Hc2, the consumer chain receives evidence that a validatorVmisbehaved at (infraction) heightHc1. As a result, the consumer CCV module sends aSlashPacketto the provider chain: It makes a request to slashV, but it replaces the infraction heightHc1withHtoVSC[Hc1], i.e., the ID of the VSC that updated the “misbehaving voting power” or0if such a VSC does not exist. - The provider CCV module receives at (slashing) height
Hp1theSlashPacketwithvscId = HtoVSC[Hc1]. As a result, it requests the provider Slashing module to slashV, but it set the infraction height toVSCtoH[vscId], i.e.,- if
vscId != 0, the height on the provider chain where the voting power was updated by the VSC with IDvscId; - otherwise, the height at which the CCV channel to this consumer chain was established.
Note: As a consequence of slashing (and potentially jailing)
V, the Staking module updates accordinglyV’s voting power. This update MUST be visible in the next VSC provided to the consumer chains. - if
Reward Distribution
↑ Back to Outline In the context of single-chain validation, the Distribution module, i.e., a module of the ABCI application, handles the distribution of rewards (i.e., block production rewards and transaction fees) to every validator account based on their total voting power; these rewards are then further distributed to the delegators. For an example, take a look at the Distribution module documentation of Cosmos SDK. At the beginning of every block, the rewards for the previous block are pooled into a distribution module account. The Reward Distribution operation of CCV enables every consumer chain to transfer a fraction of these rewards to the provider chain. The operation consists of two steps that are depicted in the following figure:
- At the beginning of every block on the consumer chain, a fraction of the rewards are transferred to an account on the consumer CCV module.
- At regular intervals (e.g., every
1000blocks), the consumer CCV module sends the accumulated rewards to the distribution module account on the provider chain through an IBC token transfer packet (as defined in ICS 20). Note that the IBC transfer packet is sent over a separate unordered channel. As a result, the reward distribution is not synchronized with the other CCV operations, e.g., some validators may miss out on some rewards by unbonding before an IBC transfer packet is received, while other validators may get some extra rewards by bonding before an IBC transfer packet is received.
Note: From the perspective of the distribution module account on the provider chain, the rewards coming from the consumer chains are indistinguishable from locally collected rewards and thus, are distributed to all the validators and their delegators.As a prerequisite of this approach, every consumer chain must open a token transfer channel to the provider chain and be made aware of the address of the distribution module account on the provider chain, both of which happen during channel initialization.
- On receiving a
ChanOpenAckmessage, the consumer CCV module initiates the opening handshake for the token transfer channel using the same client and connection as for the CCV channel. - On receiving a
ChanOpenTrymessage, the provider CCV module adds the address of the distribution module account to the channel version as metadata (as defined in ICS 4).