3. 同步

同步是共识的重要组成部分,所有的共识消息都是基于最新的区块进行的,保证区块链网络的安全性和健壮性。主要是区块和交易的同步。

3.1. 握手消息

区块链网络中两个节点建立连接,首先发送的就是握手消息,分别告知对方本地节点的状态信息,主要有

  • 区块高度
  • 创世hash
  • 最新区块Hash
  • 网络ID

节点双方分别维护对方的节点信息,如果对方的高度比本地的高,对方可能是有用节点,节点会作为同步的备用节点

3.2. 节点标记

在节点数据的转发过程中,对方节点的信息在本地会有记录,这可以减少网络负载和数据泛洪攻击。 如果你从网络上收到了节点A的交易,在本地验证通过需要转发交易,此时你和4个节点连接,有了节点标记,只需要转发给除了A的3个节点。

3.3. 交易同步

交易同步分为两个部分

  • 交易同步
  • 交易转发

节点首次连接的时候,会将本地TxPool中的交易,分批发送给对方。 交易的两种来源

  • SDK RPC
  • 网络

当用户通过RPC或是收到网络上的交易,都需要在TxPool中做验证,验证通过会转发给其他节点,当交易堵塞时,会将10个交易打成一个数据包发出去。 一般区块同步未完成的时候,会拒绝接收交易,Dapp通过RPC发送的交易,为交易的源头。

3.4. 区块同步

当一个新节点加入网络,或是一个节点停机维护再重启时就需要区块同步。区块同步需要先查找有用的Peer,必须是难度或是高度比自己高的节点。 同步的几个要素

  • 合适的节点请求数据
  • 双方公共区块
  • 长距离请求区块
  • 闲置Peer

节点同步分为全同步和快速同步,快速同步在最新块之前的64个块是不需要执行交易的,最近的64个区块需要执行交易。节点和对方节点会先查找祖先区块,如果本地节点是新节点,则双方祖先区块必是创世区块。不管是全同步和快速同步都需要长距离查询区块,同步起点是祖先区块,每次可连续同步一批区块,这被封装被一次区块请求,请求可以找多个节点来完成,节点并发的执行请求任务,被请求的节点会做评级,会和往返延时rtt有关,如果节点请求一直超时,则和这个节点断开,每次请求都会查找闲置节点。

3.5. 区块转发

新区块的转发是区块链的重中之重,会有DOS攻击的风险。这里有两个重要概念,

  • 区块通知
  • 区块广播

一个是发生区块Hash,一个发生完整区块,由于新区块的大小相较于Hash的大小很大,如果对于连接的每个节点转发新区块,会造成网络风暴,解决这个问题引入了小范围发区块,大范围发区块Hash,即区块通知,

区块Hash的作用是告诉对方节点这个区块我本地已经有了,你不需要给我转发了

一般是节点的开根号节点发区块,如果少于4个则向4个节点发送区块,其他的节点发送区块Hash。 这样做的原因是,有部分节点已收到了新区块,不需要接收网络中的同一区块,如果节点收到Hash后发现本地没有,则向节点主动获取。 此措施将网络的被动接收区块,改为主动请求区块,大大降低了网络的负载,和Gossip方式基本相同。

3.5.1. 举个例子:网络中有8个节点分别相连,有一个节点为出块节点,产生出块后,向4个节点广播区块区块,7个节点广播区块Hash,收到区块的4个节点向自己连接的7个节点中的6个转发区块Hash,3个发生区块,假设最后3个节点分别是ABC,A向5个中的一个请求完整区块,本地验证通过了只需向AB两个转发完整区块,其他5个本地已标记为拥有此Hash的节点。