EOSIO从开始启动项目,大家就了解到他使用的是DPOS共识,后来BM又做了调整,加入了BFT算法,今天我们来解读一下DPOS+BFT混合共识算法。
我们从以下两部分给大家阐述EOSIO的共识机制:
1、DPOS 的拜占庭容错能力;
2、EOS 的 DPOS 如何提高出块速度和性能。
第一部分:DPOS 的拜占庭容错能力。
DPOS 的特殊性,也是奠定拜占庭容错能力的基础框架,是它的算力节点是固定 21 个人,并且由大型的机构运营节点,其信息也相对透明,例如运营节点的地点、运营的情况等等。并且 DPOS 的算力节点是固定出块顺序的,每个生产节点一般情况下,生产12个block,每隔0.5秒,出一个block,每个block不大于1M,如果在规定的0.5秒出块间隔内,出块时间小于50ms,那么本次时间间隔不再出块,改为下一个时间节点出块。固定地从 A 到 B 到 C ······。
在这种情况下,其实 DPOS 是拜占庭容错的特殊解,如何理解特殊解?原来的拜占庭容错(POW 工作量证明),解决的是不限数量、随机广播同步的算力节点的容错能力,DPOS 解决的拜占庭容错从两个维度降低了难度:
1、节点数量固定只有 21 个。并且节点信息透明。
2、固定出块顺序。每个节点跟接力棒一样,一个个往下接力出块。每个节点不能还没轮到它出块的时候,就出块。都是必须轮到再出块。如果出现出块故障,会跳过这个节点。
在 POW 或者其他的 POS 共识里,节点不限、随机出块顺序的问题,就变成只要解决「固定数量和固定出块顺序情况下的拜占庭问题」,其难度就大大降低。
在这种情况下,DPOS 是如何解决拜占庭错误?
我们假设有三个节点 A、B、C,出块顺序是 A 到B 到 C。实际上 EOS 有 21 个节点,但是举例三个节点足以说明问题了。
1.1 分叉情况
现在,B 决定分叉了。在轮到 B 出块时候,它不再承认 C 和 A 的块,就自己出块。我们在这里假设出块时间为 3s。
那么 B 分叉出去的的链,每 9 秒,才能出一个块,而 C、A 是 6s 出一个块。因为即使分叉,在 DPOS 的机制下,还是只能等到 AC 都出块后,才轮到 B 出块。
在这种情况下,分叉出块的速度永远追不到原来链的速度。而共识只承认最长的链。
以上是少数节点分叉,如果是三分之二的节点决定分叉呢?其实原理也是一样的。如下图。
当三分之二的节点决定分叉的时候,最后一个诚实的少数节点决定了最快、最长的那条链。分叉的 B 和 A 节点,追不上由 C 承认的链的增长速度。
1.2 最后不可逆块
在 DPOS 的共识里,最长的那条链才是真正的链。但是如何确认这条链是最长的?这里就需要「最后不可逆块」的概念。
最后不可逆块,顾名思义,就是最后那块,不能在修改的块。DPOS 规定,这个区块被三分之二的节点确认,就是不可逆块。如果被最新出块的三分之二节点确认,就是最后不可逆块。
如图,蓝色 B 就是最后不可逆块,因为被 C 和 A 确认了。
通过最后不可逆块,就能确认这条链是不是由三分之二节点签名的最长的那条链。
总结:由上文可知 DPOS 可以有效地防范拜占庭作恶,有着稳健的拜占庭容错。本文只列举了主要几种作恶情况,还有许多作恶情况 DPOS 都可以防范,不一一列举。
1.3 交易作为权益证明 TaPOS
交易作为权益证明 TaPOS 的全称是 transaction as proof of stake。有点类似比特币的「区块头」概念,即有每个最后不可逆块有一个哈希值,是来代表前一个块的数据,而前一个块又有前前块的哈希值,环环相扣。
当块数越多后,这条链就很难被替代。因为你修改一个块,所有的 TaPOS 值就对不上了。
1.4 如何确定不可回滚的块。
在生产节点A生产结束,B开始生产区块的时候,B就需要承认A之前生成的所有的区块。也就是B需要确认A生产之前所有的区块。如下图
可以确认A目前确认的所有block的情况,如下图。
当B开始生产的时候,B需要确认一次A之前生产的所有节点,如下图
当确认次数达到21*(2/3)=14,就是当21个节点中,2/3的生产者确认这个block后,最后一个确认这个block的生产者,推荐这个block是不可以回滚的block。
我们可以清晰的看到编号为 661 的block为B生产者推荐的不可以回滚的block。
DPOS共识算法中规定,1/3(21/3=7)的节点确认的不可以回滚的block,才是全网确认的不可回滚的block.我们看看,21个节点确认的不可回滚的block是什么情况,我们假定生产者的顺序为A B C D E F G H I G K ….
如下图
当每个节点收到这个block的时候,节点就可以清晰的计算出,全网不可以回滚的区块位置为666。记住,不是通过通讯得到结果,是通过节点自己计算得到的结果。
第二部分、EOS 的 DPOS 如何提高出块速度和性能
1、EOS是通过定向广播的方式,以500ms的速度出块。
如果不定向广播,那么可能出现如下情况
因为是随机广播,所以会诞生很多同步一轮的区块路径不是最短路径。
而在 EOS 的机制下,节点是定向广播的。21 节点的位置是透明的,会选择最短路径来规定广播顺序。如图:
在最短路径的广播顺序下,生产出最后不可逆块的速度便变快了。
如果其中有一个节点出现故障没有出块,会迅速轮到下一个区块来出产。所以当某些节点出现故障的时候,不会影响其他节点的出块速度。至于跳过节点可能产生的作恶行为的防范,上文已经提到防范的方式了。
2、一般情况下,每次,每个节点发送12个block。让所有节点确认。
2018年8月15日深夜。