背景
在多节点的区块链网络中,通常节点是来自多个不同的组织。在区块链网络升级时,会出现无法将所有共识节点同时升级的情况。 因此,需要共识模块支持部分节点升级,不同版本的共识节点可以同时存在,不会影响链的运行。
现状
部分节点升级后,就会导致升级后的节点共识版本
与未升级的节点共识版本
不一致。共识版本不一致的情况下,节点间共识数据通信无法相互解析和逻辑处理,就会导致以下情况。
情况一: 升级大部分节点
- Raft共识:会以升级后的大部分节点之间可以正常通信,从而在这些节点中产生Leader,继续完成共识。未升级的节点会直接无法参与共识。
- BFT类的共识:当升级超过2/3的节点情况下,于Raft类似。
情况一: 升级小部分节点
- Raft共识:原先未升级的大部分节点会继续共识,新升级的小部分节点,因无法与大部分节点共识通信,无法参与共识。
- BFT类:
- 小于1/3的节点升级,与Raft类似,原先未升级的2/3节点,将继续完成共识。
- 大于1/3节点小于2/3节点时,升级后的节点与未升级的节点群,都因为无法收集到足够的投票,都无法完成共识。
需求
共识模块版本之间兼容,支持不同版本的节点之间通信,不影响链的运行。
方案设计
版本号
共识节点之间的通信,需要带有版本号,用于识别节点之间的共识版本。
版本号设计
在网络层增加版本号的消息。
- 网络层修改*netpb.NetMsg的Type,第一个字节涉及到符号位丢弃不用,第二个字节预留,第三个字节保存共识内部版本号,最后一个字节是网络模块的.
- 共识内部可以通过message.Payload.(*netpb.NetMsg)解析版本号
流程设计
- 共识模块将版本号添加到*netpb.NetMsg的Type中
- 网络模块通过位运算解析出原始的Type,依照原来网络模块逻辑发送消息
- 网络模块接受消息时,将*netpb.NetMsg的Type恢复成包含共识版本号的Type
- 共识模块通过解析包含共识版本号的Type,获取共识消息来源的共识版本号