同步

介绍

同步,是区块链节点利用节点组成的P2P网络,实现节点数据的可达与一致。

设计概要

同步模块是FISCO BCOS 2.0中负责同步功能的模块,主要的功能分为:

  • 交易同步:让每笔交易尽可能的到达所有的节点。
  • 状态同步:让节点感知到彼此的状态(当前块高,当前块哈希)。
  • 区块同步:某个节点的块高落后于其它节点时,从其它节点下载区块。

详细设计

交易同步

功能

  • 任何一笔交易,发送到链上的任意节点,所有节点都会同步到。

方案

  • RPC来的交易,全量广播
  • P2P来的交易,选择25%的节点广播
  • 一个节点不会重复广播

状态同步

功能

  • 节点间相互告知对方,自己的当前块高等信息,为区块同步提供参考

方案

  • 节点在启动时,其他节点会主动发送块过来
  • 节点在出块时,会主动向其它所有节点广播块高。
  • 间隔一段时间(目前是5s),彼此广播自己的块高。

区块同步

功能

  • 在发现自己的块高落后于别人的块高时,主动向其它节点下载区块,直至所有区块下载完成。

方案

下载请求节点:

  • 分散下载请求,随机选择一些节点请求
  • 超时逻辑,超时后再进入下一次下载请求
  • 设置区块下载优先队列,对收到的区块进行排序,再commit到区块链上
  • 异步处理收到的区块,收到区块时,先放入buffer,同步模块主线程再取出来放到优先队列中

下载响应节点:

  • 异步响应下载请求(请求队列)
  • 回复区块时,将较小的区块组合在一起发送

组成员同步逻辑

同步以组为范围进行,同步只会在组内进行。

组的成员分为

  • 组员:miner,observer
  • 非组员:待加入组的节点(已启动了此组的线程,但未被加入到组中)

全局同步逻辑

  • 组员拒绝一切非组员的同步消息
  • 非组员接收一切同步消息

交易同步逻辑

  • 交易只广播给miner
  • 非组员不广播交易

状态同步逻辑

  • 状态广播只在组员间进行
  • 非组员不广播状态

区块同步限制

  • 当新组员被加入组时,接受新组员的区块下载请求
  • 区块同步时,不收交易,也不发交易
  • 区块同步时,不参与共识

架构与模块

../../../_images/module.png

主要模块如下:

SyncMaster

​ 同步模块主线程,负责同步模块中主动触发的逻辑,包括:广播交易,广播状态,处理下载下来的区块,区块响应下载请求。

SyncMsgEngine

​ 响应其它节点发来发同步包,包括状态包,交易包,下载的区块包,区块请求包。

SyncMasterStatus

​ 管理多个Peer的信息,其中包括多个Peer的SyncStatus。

SyncStatus

​ 管理单个Peer的状态信息。

DownlodingBlockQueue

​ 区块下载的缓冲队列,对下载下来的区块进行排序,等待SyncMaster写入区块链。响应下载的区块包和对下载的区块进行排序,是异步的。

同步场景举例

交易同步

一笔交易被广播到所有节点的过程:

  1. 一笔交易通过channel或RPC发送到某节点上
  2. 收到交易的节点全量广播此节点给其它节点
  3. 其它节点收到交易后,为了保险起见,选择25%的节点再广播一次
  4. 节点收到广播过的交易,不会再次广播

状态同步

节点出块时的广播逻辑

  1. 某个节点出块
  2. 此节点将自己最新的状态(最新块高,最高块哈希,创世块哈希)广播给所有的节点
  3. 其它的节点收到peer的状态后,更新在本地管理的peer数据

组内成员区块同步

组内成员在某时刻意外关闭,但其它成员在出块,当此组员再次启动时,发现区块落后于其它组员:

  1. 组员再次启动
  2. 收到其它组员发来的状态包
  3. 比较发现自己的最高块高落后于其它组员,启动下载流程
  4. 将相差的区块按区间划分成多个下载请求包,发送给多个组员,负载均衡
  5. 等待其它节点回复区块包
  6. 其它节点接受响应,从自己的区块链上查询出区块,回复给启动的节点
  7. 节点收到区块,放入下载队列
  8. 节点从下载队列中将区块拿出,写到区块链上
  9. 若下载未结束,则继续请求,若下载结束,则切换自身状态,开启交易同步,开启共识

新组员区块同步

非组员作为一个新组员加入到某个组中,且此节点第一次启动,从原来的组员中同步区块:

  1. 非组员未被注册到组中,但非组员先启动
  2. 此时发现自己不在组中,不进行状态广播,也不进行交易广播,只等待其它组员发来状态消息
  3. 此时组员中并没有此新组员,不会向新组员广播状态
  4. 管理员将新组员加入到组中
  5. 组员向新组员广播自身状态
  6. 新组员收到组员状态,比较自身快高(为0),启动下载流程
  7. 之后的下载流程,与组内成员区块同步流程相同