同步¶
介绍¶
同步,是区块链节点利用节点组成的P2P网络,实现节点数据的可达与一致。
设计概要¶
同步模块是FISCO BCOS 2.0中负责同步功能的模块,主要的功能分为:
- 交易同步:让每笔交易尽可能的到达所有的节点。
- 状态同步:让节点感知到彼此的状态(当前块高,当前块哈希)。
- 区块同步:某个节点的块高落后于其它节点时,从其它节点下载区块。
详细设计¶
状态同步¶
功能
- 节点间相互告知对方,自己的当前块高等信息,为区块同步提供参考
方案
- 节点在启动时,其他节点会主动发送块过来
- 节点在出块时,会主动向其它所有节点广播块高。
- 间隔一段时间(目前是5s),彼此广播自己的块高。
区块同步¶
功能
- 在发现自己的块高落后于别人的块高时,主动向其它节点下载区块,直至所有区块下载完成。
方案
下载请求节点:
- 分散下载请求,随机选择一些节点请求
- 超时逻辑,超时后再进入下一次下载请求
- 设置区块下载优先队列,对收到的区块进行排序,再commit到区块链上
- 异步处理收到的区块,收到区块时,先放入buffer,同步模块主线程再取出来放到优先队列中
下载响应节点:
- 异步响应下载请求(请求队列)
- 回复区块时,将较小的区块组合在一起发送
组成员同步逻辑¶
同步以组为范围进行,同步只会在组内进行。
组的成员分为
- 组员:miner,observer
- 非组员:待加入组的节点(已启动了此组的线程,但未被加入到组中)
全局同步逻辑
- 组员拒绝一切非组员的同步消息
- 非组员接收一切同步消息
交易同步逻辑
- 交易只广播给miner
- 非组员不广播交易
状态同步逻辑
- 状态广播只在组员间进行
- 非组员不广播状态
区块同步限制
- 当新组员被加入组时,接受新组员的区块下载请求
- 区块同步时,不收交易,也不发交易
- 区块同步时,不参与共识
架构与模块¶

主要模块如下:
SyncMaster
同步模块主线程,负责同步模块中主动触发的逻辑,包括:广播交易,广播状态,处理下载下来的区块,区块响应下载请求。
SyncMsgEngine
响应其它节点发来发同步包,包括状态包,交易包,下载的区块包,区块请求包。
SyncMasterStatus
管理多个Peer的信息,其中包括多个Peer的SyncStatus。
SyncStatus
管理单个Peer的状态信息。
DownlodingBlockQueue
区块下载的缓冲队列,对下载下来的区块进行排序,等待SyncMaster写入区块链。响应下载的区块包和对下载的区块进行排序,是异步的。
同步场景举例¶
交易同步¶
一笔交易被广播到所有节点的过程:
- 一笔交易通过channel或RPC发送到某节点上
- 收到交易的节点全量广播此节点给其它节点
- 其它节点收到交易后,为了保险起见,选择25%的节点再广播一次
- 节点收到广播过的交易,不会再次广播
组内成员区块同步¶
组内成员在某时刻意外关闭,但其它成员在出块,当此组员再次启动时,发现区块落后于其它组员:
- 组员再次启动
- 收到其它组员发来的状态包
- 比较发现自己的最高块高落后于其它组员,启动下载流程
- 将相差的区块按区间划分成多个下载请求包,发送给多个组员,负载均衡
- 等待其它节点回复区块包
- 其它节点接受响应,从自己的区块链上查询出区块,回复给启动的节点
- 节点收到区块,放入下载队列
- 节点从下载队列中将区块拿出,写到区块链上
- 若下载未结束,则继续请求,若下载结束,则切换自身状态,开启交易同步,开启共识
新组员区块同步¶
非组员作为一个新组员加入到某个组中,且此节点第一次启动,从原来的组员中同步区块:
- 非组员未被注册到组中,但非组员先启动
- 此时发现自己不在组中,不进行状态广播,也不进行交易广播,只等待其它组员发来状态消息
- 此时组员中并没有此新组员,不会向新组员广播状态
- 管理员将新组员加入到组中
- 组员向新组员广播自身状态
- 新组员收到组员状态,比较自身快高(为0),启动下载流程
- 之后的下载流程,与组内成员区块同步流程相同