协议升级概览
因为区块链去中心化的特性,节点之间并不确定相互使用的是同一个软件版本,甚至是同一个实现(比如以太坊的 geth 和 parity)。
因此区块链并不代表某一特定实现,而是一个协议。
CITA 采用类似公链分叉的方式进行协议升级。
对于公链来说,其维持唯一的一条链,通常使用指定的区块高度作为分叉开关,链达到这个区块高度即触发协议升级。
CITA 作为许可链平台,服务于多条链,区块高度并不唯一,无法采用区块高度做为分叉开关。
CITA 采用的升级方案是增加一个专门的 version_manager 合约,存放一个单调递增的协议版本号。通过发送交易变更版本号来触发协议升级。
另外许可链节点数较少,相对可控,因此要求所有节点统一升级至新版本,然后再实施协议升级。
CITA 会针对每个协议版本有一个文档,说明支持该协议版本的最小 release 版本号,该版本协议相对上一个版本的变化,以及实施协议升级需要的详细操作。
协议升级的公共流程如下:
- CITA 开发团队完成新版本协议的开发工作,发布支持新版本协议的 CITA 版本,并附带相关的文档。
- 已有链的运营方讨论之后决定升级到新版本协议。
- 所有的节点都升级至支持新版本协议的 CITA 版本。升级 CITA 版本,只需要停掉节点,替换发布件中的文件(节点文件夹不动),然后再启动节点即可。如果有额外的操作,会在 release notes 中说明。升级 CITA 版本之后,使用的依然是老的协议。因此可以预留一个比较长的时间,让各个节点错开时间分别升级 CITA 版本,可以避免中断业务。
- 待所有节点升级 CITA 版本完成后,链的超级管理员根据文档中的描述发送交易,实施协议升级。
- 普通用户需要将使用的工具以及 SDK 升级至支持新版本协议的版本。这些内容也会在相关文档中详细描述。
注意:
- 超级管理员实施协议升级过程中,最好暂停一下业务。老的交易如果在协议升级生效之前进入交易池,协议升级生效之后才打包上链,将会在打包交易阶段报错,此时错误已经无法反馈给用户,会给用户制造一些困扰。可以参考紧急制动。
- 如果节点没有及时升级 CITA 版本,超级管理员实施协议升级之后,节点将停止工作,并可能会出现各种异常情况。
- 如果链实施完协议升级,但是普通用户没有及时升级工具和 SDK 版本。发送交易将会得到 InvalidVersion 错误。
- 使用支持新版本协议的 CITA 版本重新创建一条链,除非在生成链配置的时候指定协议版本号,否则默认都直接使用该 CITA 版本支持的最新版本的协议。
完整 CITA 版本升级及协议升级流程示例:
- 假设现在有一条正在运营中的,使用 CITA V0.19 的链,当前使用的协议版本为 v0。有 4 个共识节点,对应的有 4 名运维人员,另外有一个超级管理员。
- CITA V0.20 开发完成并正式发布。V0.20 支持 v0/v1 两个版本的协议。
- 链的超级管理员通知 4 个节点的运维人员,可以开始升级 CITA V0.20 了,限期 10 天。
- 4 个节点管理员,可以在这 10 天里面任何时间对自己维护的节点进行升级 CITA V0.20 的操作。所以这段时间 4 个共识节点会存在 V0.19 和 V0.20 混用的情况。这种情况没有任何问题,过程中业务也不会中断。此时使用的依然是 v0 协议。
- 10 天的期限结束。4 个节点都升级到 CITA V0.20 了。
- 超级管理员开启紧急制动功能。链的业务暂停,只有超级管理员可以发交易上链。
- 超级管理员发交易,升级系统合约。我们提供了脚本 scripts/amend_sys_cont_to_v0-20.sh 辅助完成这项工作。
- 超级管理员发送交易,将 VersionManager 系统合约中的 version 从 0 改为 1,完成协议升级。
- 超级管理员关闭紧急制动功能,链的业务恢复。
- 至此,只有使用 v1 协议的交易才能发送上链,依然使用 v0 协议的交易,发送时将会返回错误。