区块回放过程解析

EOS节点为什么需要区块回放,回放的过程是怎样的,回放完毕后结果如何?

这些问题我们将在下面逐一讲述。

区块回放的前提条件

EOS服务节点为什么需要区块回放呢?

EOSIO运行主网中,各个服务节点基于区块保持了状态一致性。当出现某个节点与其他节点的状态不一致,无法持续保证一致性的情况下,这个时候就需要进行区块回放。

那么,服务节点什么时候进行区块回放呢?基本上是两种情况,下面分别讲述:

a.当服务节点运行出错重启服务提示数据库脏数据时,这个时候节点的启动命令中就会带有回放的参数,节点需要根据自身的情况,清除脏数据,从正常主网节点中同步所有不可逆区块到节点本地,并对这些区块按照块序号进行回放,如果本地节点还有可用的可逆块表数据,则再将可逆块按顺序逐个回放。

如下图所示,整个网络上目前是节点B出错或异常重启,所以节点B就需要执行区块同步,然后将创世区块外的所有区块进行回放来对全网节点的区块基线进行追赶:

区块回放过程解析

b.当需要新增服务节点时,这个时候节点启动后加入生产者列表,会从正常主网节点中同步所有不可逆区块到节点本地,并对这些区块按照块序号进行回放。

如下图所示,整个网络上目前存在节点A,B,现在新增节点C,节点C会先执行所有不可逆区块同步,然后将创世区块外的所有区块进行回放来对全网节点的区块基线进行追赶:

区块回放过程解析

区块回放调用的地方

eos节点调用进行replay()的地方只在节点初始化的时候,对应init()函数,如下图所示:

区块回放过程解析

区块回放过程的解析

当一个区块落后节点试图追赶全网节点的区块基线时,主要的步骤是分成三步来执行:

a. 先通过net_plugin网络插件从任何一个正常节点进行区块同步,将这些区块获取到本节点

b. 然后根据区块的块序号顺序,逐个对区块上的交易按照交易顺序进行执行

c. 如果本地缓存了可逆块表数据,则接续不可逆区块,将所有可逆区块上的交易按顺序进行执行

第2,3步循环处理区块交易的步骤就是区块的回放。下图为三个步骤的示意:

区块回放过程解析


我们再来看下区块回放的代码:

区块回放过程解析


其中关键处理函数是replay_push_block(),这个是针对单个区块进行回放的函数,其实现代码如下:

区块回放过程解析


其中的主要功能实现代码是通过maybe_switch_forks()函数实现的,而该函数的处理思想则是:

处理区块链分叉要尽量保证链的可用性和持续运行,因此,当尝试最长链切换失败时,就放弃该分支,继续使用当前分支即可。该函数的具体的实现流程解析请见文章《节点接收区块后的maybe_switch_forks的处理流程解析》。

区块回放的结果

节点区块回放完毕后,此时当前节点应该与全网其他节点的不可逆区块达到一致,即落盘存储的不可逆区块数目和序号都完全一致。全网各个节点当前的唯一差异就在于个节点上的可逆区块表内容及交易队列内容不一致,如下图所示。

区块回放过程解析


此时,新增或重启节点的状态就正常了,可以参与正常的生产流程了。

链接

星河公链

相关文章

文章浏览阅读903次。文章主要介绍了收益聚合器Beefy协议在币...
文章浏览阅读952次。比特币的主要思路是,构建一个无中心、去...
文章浏览阅读2.5k次。虚拟人从最初的不温不火,到现在步入“...
文章浏览阅读1.3k次,点赞25次,收藏13次。通过调查和分析用...
文章浏览阅读1.7k次。这个智能合约安全系列提供了一个广泛的...
文章浏览阅读1.3k次。本文描述了比特币核心的编译与交互方法...