8.3 EOS两轮共识原因

背景介绍

曾经一篇标题为"震惊!V神和BM竟如此互怼!"的文章在网上热议起来,这是一篇BM和V神在issue上对于DPOS的机制的讨论,接下来我们具体讨论下他们的讨论内容:

先看一下英文版的:

图1
图2

翻译成中文版的:

图3
图4

单轮共识引起不可逆块冲突

我们先来看一下最初EOS的DPOS2.0+BFT的共识机制:当一个特定的区块被(2/3+1)生产者确认的时候,该块成为不可逆块。

假设现在有A,B和C三个块: A 生产了一个区块 N, B 生产区块 N + 1 并且确认了区块 N, C 生产区块 N + 2 并且确认了区块 N, N + 1 , 此时 N 已经有 3 个确认,达到了 2/3 + 1 个确认,则区块 N 成为不可逆。

提出问题:上面所述的共识只经过了一次共识,那么会出现什么问题呢?

V神就在issue上提出一个例子,如下图:

图5

可以看出第一条链 A 生产的 2 经过 B、C 已经达到了 3 个确认数已经成为不可逆了, 但此时 D 因网络不好, 没接收到这些块, 从而产生分叉开始生产区块 2 , 之后 A 生产区块 3 , 因为块高度大于之前的 2 ,所以是可生产的,B同理, 经过 A, B 之后 D 生产的 2 同样达到了三个确认数, 这样就会有 2 个块高度为 2 的区块成为了不可逆,造成冲突。

分析解决不可逆块冲突

为什么会造成这个原因呢?因为区块 2 没有经过所有节点就成为不可逆了, 导致后面的产生的区块 2 可在下一轮被确认成为不可逆块。如果说 A ,B ,C ,D 都确认了区块 2, 那么下一轮谁都没可能生产块高度为 2 的区块。也就不会同时出现 2 个不可逆块了。 但全部节点确认才成为不可逆这就破坏了引入BFT的想法, 而且你没办法保证所有节点都会对他进行确认,毕竟网络延迟一直存在。

那怎么解决不可逆块冲突,但是又不会破坏BFT的想法呢?V神给出的解决方法:经过2轮(2/3+1)的确认,继续使用BFT的思想,破坏掉分叉的区块2成为最终的不可逆区块,因为最终的不可逆块已经是3,小于3的区块都认为是不可逆块了。

这里引进proposed lib的概念, 即可能成为不可逆的区块,简称plib:一个区块经过2/3 + 1共识后,他不会立马成为lib, 会先成为plib, 然后再plib经过 (2/3+1) 共识后才会成为lib。两轮共识的正常流程如下图:

图6

再来看一轮共识,不可逆块产生冲突时,两轮共识的结果:

图7

上图中,当D因网络不好,没接收到之前的块,从而产生分叉开始生产区块2,当一轮共识时,区块2成为不可逆区块时会产生冲突,经过两轮共识后,分叉的链,产生的备选不可逆块为2时,正常的链产生的最终的不可逆块已经是3,此时,小于3的区块都是最终的不可逆区块了。

其实这种方式你可以看成对有多条分叉链的处理,节点对这些链进行(2/3+1)共识来选出哪条plib分叉链作为主链(不可逆序号最大的链),丢弃掉其他plib分叉链。

总结

dpos3.0+BFT由最初的一次共识增加到了两次,避免掉出现conflict(冲突)lib, 但是这也让head_block_num和lib的高度拉到((2/3+1) * 21 - 1)  * 12 * 2 = 336 个块(不考虑漏块的情况)。根据一个区块生产的时间为0.5秒计算,产生最终的不可逆块的用时为:336 * 0.5 = 168

链接

星河公链官网

8.3 EOS两轮共识原因-blog.51cto

8.3 EOS两轮共识原因 - arm_snow的博客 - CSDN博客