主子链¶
1. 引言¶
1.1 背景¶
在
ChainSQL 3.0
之前的版本中,所有节点都属于一个链,所有的业务都在这条链上进行,所有的节点都会同步相同的数据,这会存在以下问题:
数据冗余:随着业务量的增加,数据会越来越大,每个节点都会同步和存储一些不必要的数据,这增加了数据同步的压力、数据存储的压力和数据处理的压力
安全隐患:网络中所有的节点都能读取到所有的数据,一些敏感数据可能分发给其他不应该访问这些数据的节点,这会带来数据安全隐患
1.2 目标¶
通过实现ChainSQL主子链功能,实现以下目标:
单个ChainSQL中节点可支持多条子链同时运行
子链之间数据隔离(包括存储,网络通讯等)
子链创建时可选择是否继承主链状态
通过主链实现对子链共识节点的去中心化管理
在ChainSQL主子链的设计中,主链负责对多条子链共享的数据进行初始化,子链负责实现具体业务
2. 总体设计¶
ChainSQL主子链有以下3个特性:
子链可选择继承主链账户状态
通过主链对子链的共识节点进行治理
可通过多方签名方式发送子链相关交易,子链节点执行建链操作时不需要再进行加入子链的确认
2.1 主子链关系图¶
2.2 子链数据隔离¶
2.3 子链继承主链状态¶
3.结构定义¶
3.1 新增Schema链上数据结构¶
字段名 |
类型 |
描述 |
---|---|---|
Account |
String |
建子链的账户ID |
SchemaName |
String |
子链名称 |
SchemaStrategy |
Int |
建链策略(1,2) |
SchemaAdmin |
String |
子链管理员(可选) |
AnchorLedgerHash |
String |
要锚定的主链区块Hash(依赖chain_strategy=2) |
Validators |
Array |
子链的信任列表(all) |
PeerList |
Array |
邻接节点连接方式 |
其中,ChainStrategy取值意义如下:
1 :创建全新子链
2 :子链继承主链状态
Validator的元素结构为:
字段名 |
类型 |
描述 |
---|---|---|
PublicKey |
String |
建子链的账户ID |
Signed |
BOOL |
是否参与了建链交易多方签名 |
Signed字段值是由交易推断出来的:只有SchemaCreate交易是多方签名交易且交易中Validators字段某一公钥对交易进行了签名,Signed值才会置为1,否则置为0
如果选择子链继承主链状态,则子链继承主链所有状态,并且子链创世区块的父区块hash为锚定的主链区块hash
3.2.新增交易类型¶
3.2.1 子链创建交易¶
SchemaCreate
字段名 |
类型 |
描述 |
---|---|---|
Account |
String |
建子链的账户ID |
TransactionType |
String |
交易类型:SchemaCreate |
SchemaName |
String |
子链名称 |
SchemaStrategy |
Int |
建链策略(1,2) |
SchemaAdmin |
String |
子链管理员(可选) |
AnchorLedgerHash |
String |
要锚定的主链区块Hash(依赖chain_strategy=2) |
Validators |
Array |
子链的信任列表(all) |
PeerList |
Array |
邻接节点连接方式 |
3.2.2.子链修改共识列表交易¶
SchemaModify
字段名 |
类型 |
描述 |
---|---|---|
Account |
String |
管理员账户/建链账户(多方签名中使用) |
TransactionType |
String |
交易类型:SchemaModify |
OpType |
Int |
操作码(1为增加节点,2为删除节点) |
SchemaID |
String |
子链ID |
Validators |
Array |
子链的信任列表(all) |
PeerList |
Array |
邻接节点连接方式 |
4.详细流程¶
4.1子链的创建¶
4.1.1节点确认加入¶
在 ChainSQL 3.0
中,任何账户都可以创建子链,那就存在一个问题,子链中的节点如果不想加入某条子链,而被某个账户建子链时加入到共识列表中,怎么办?
ChainSQL中通过下面三种方案来解决这一问题:
对子链创建交易直接使用多方签名
节点可配置自动加入子链
节点不配置自动加入子链,通过命令主动加入
4.1.1.1 多方签名交易建链¶
交易发送方设置多方签名列表(签名列表中每个地址用子链参与节点的validation_seed生成)
构造建链交易JSON
子持有者对建链交易签名
构造多方签名交易,并发送
节点收链节点私钥到建链交易,检查交易中validators数组中哪些公钥参与了多方签名,并在新建的SLE结构中将对应项的Signed字段置为true
4.1.2 新建存储¶
这里分两种情况:
不继承主链状态,子链创世块与主链创世块生成规则相同
继承主链状态,子链创世块的父区块hash为继承的主链区块hash,子链创世块中有与主链中锚定的区块相同的全局世界状态
4.2子链的修改¶
4.2.1 有管理员¶
在建链时,如果指定了管理员账户,那么只有管理员账户可直接发送增删节点的交易
对于节点增加
新增节点仍需要配置自动加入子链或者在命令行发送命令加入子链
其它已存在节点在交易共识成功后直接执行增加validator的操作
对于节点删除
被删除节点在监测到修改后停止参与子链
其它节点在交易共识成功后执行删除validator的操作
4.2.2 无管理员¶
未指定管理员的情况下,只有子链创建账户可以通过多方签名交易发送增删节点的交易。任意一个收集到当前unl_list中多数签名的 SchemaModify 交易都可实现节点增删
新增节点仍需要配置自动加入子链或者在命令行发送命令加入子链
5. 架构调整¶
6.子链日志输出¶
所有子链日志都在同一个文件中,为了避免混淆,用16进制的SchemaId取前4位作为子链的标识,如:
SchemaId= 001814BCCB1B1D0598366F033091DE9D7CC41419583A4F5CD04ABC36BE210163
日志中会有 [0018] 作为子链的标识:
2020-Oct-26 03:46:04.4880969 [0018]OrderBookDB:DBG Advancing from 0 to 2
而主链的日志以 [0000] 作为标识