以太坊2.0中有两个时间概念:时隙槽slot 和 时段(周期)epoch。其中一个slot为12秒,而每个 epoch 由 32 个 slots 组成,所以每个epoch共384秒,也就是 6.4 分钟。
对于每个epoch,使用RANDAO伪随机算法将全部的验证节点分成多个委员会(committee),这些委员会的职责主要包括出块、LMD GHOST(以太坊的分叉选择规则)投票和Casper FFG投票(有时候把这两种投票合称Gasper)。
每个委员会至少包括128个验证节点(一个验证节点在一个 epoch 中只能参与一个委员会),它的职责是负责验证一个slot(这里我看不同的资料有不同的说法,资料[1]的说法是全部验证者被随机分成32个委员会,正好对应一个epoch里的32个slot;而资料[2]的说法是由于网络中的验证者总数大于32*128*2=8192,所以可以保证每个slot至少有两个委员会;资料[3]的说法是由一个或多个单独的委员会负责验证每个slot。这个估计要看最新的资料,据说关于ETH2.0出块机制这方面一直在变化,貌似两年前的文章已经没有太多参考价值)。
在这至少128个验证者组成的委员会中,会随机选择(还有种说法是根据有效余额权重,有效余额定义见资料[4])一个验证者作为区块提议者(propose),其余验证者负责LMD GHOST投票和Casper FFG投票,其中LMD GHOST投票需要所有验证者在自己所在的 slot 中投票选出信标链的head。
这两种投票的区别就像地方选举和全国选举,因为只有分配给某个slot的验证者才会对该slot进行LMD GHOST 投票,而Casper FFG需要所有验证者为epoch的检查点(checkpoints)进行投票,投票的权重由验证者节点的的余额决定。在每个Epoch之后,各委员会的验证者被混合并合并到新的委员会。
区块提议者会根据LMD-GHOST 分叉选择规则,在他认为拥有最多验证者证明的链构建下一个区块。提议者有4秒的时间去提议一个新区块,如果提议者完成了它的任务,一个有效的区块(在4秒内)将会填充slot;如果未完成任务(比如提议者离线),slot将传递为空(skipped),如下图中的slot4。
在区块提议的过程中,有可能因为网络延迟或者恶意行为(例如区块提议者同时发布两个不同的区块)等原因出现分叉(这里我在网上其他地方查了资料好像很多人都说ETH2.0不会存在叔块/孤块,但这里的分叉难道不会产生叔块么??),比如下图在slot5/6出现了分叉:验证者(5)提议了一个区块,但是验证者(6)没有收到相关信息(例如,该区块到达该验证者的速度不够快)。所以验证者(6)根据从验证者(3)那里看到的最新信息提议了一个区块。
当出现分叉时,要根据LMD GHOST投票结果确定主链。相比于POW选择最长链为主链,LMD GHOST规则的思路为根据验证者最近一次的投票(Latest Message Driven)确定每个区块的weight,每当遇到分叉时选择weight最大的区块作为主链,一直重复该操作直至找到leaf block即链头。而对于某一个区块的weight,它等于投给该区块以及该区块所有子孙后代区块的票数总和。
(但是这里我不太理解的是到底什么叫做最近一次的投票?我是觉得在一个epoch当中,一个验证者本来就是只在他所在的slot投一次票吧,这样的话就不存在第二次投票也就不存在什么最近不最近这个概念了,那照这样理解的话应该下图中的每个区块都有与它直接连接的笑脸才对,但显然不是这样的,下面这张图只有 2 1 4 1这几个区块有投票,有懂行的朋友能解释下嘛?)
以上图为例,笑脸表示验证者的最近一次投票证明(每个笑脸的weight这里都取1),数字表示每个区块的weight,尽管最上面一条链才是最长链,但由于绿色这条链获得了最多的验证者证明,所以绿色这条链才是权威链。
检查点(checkpoints)与区块的最终确认(finalized)
前面讲的都是以太坊2.0的出块机制,那么区块又是怎么确认的呢?
首先,我们需要明确检查点的定义。检查点是一个epoch中第一个slot的区块。第一个slot中若是没有区块,则检查点是前一个最近的区块。每个epoch必定有一个检查点块,且一个区块可以是被归属于多个epoch的检查点。
以上图为例,slot 64 处的区块是 epoch 1的检查点,epoch 2 的检查点本来应该是位于 slot 128 处产生的区块,但由于从 slot 65 到 slot 128 之间都没有区块,所以 epoch 2 的检查点是从 slot 128 往前的第一个区块,即 slot 64 处的区块。
当进行 LMD GHOST 投票时,验证者也会投票给当前周期中的检查点target checkpoint以及先前的检查点 source checkpoint,此投票即为 Casper FFG 投票。
当一个周期结束时,如果某检查点获得了所有活跃验证者总有效余额 2/3 的投票支持,则该检查点被认为是justified状态。如果检查点A被证明是justified,并且紧接的下一个epoch中的检查点B也被证明是 justified 的,那么A将被最终确认,变为finalized状态。通常,一个检查点会在两个时期内得到最终确认,即 12.8 分钟。
上图的英语逐句翻译如下:
1. slot 96处产生一个新的区块,标志着epoch 2结束。该区块内存储了关于epoch 2检查点(即slot 64处区块)的投票;(这句没太懂,为啥slot96会存储slot64的投票)
2. 信标链检查epoch 2检查点(即slot 64处区块)是否获得验证人超过2/3的证明;如果超过,则epoch 2检查点(即slot 64处区块)及epoch 1中的所有区块都被证明(justified);
3. 如果epoch 2检查点(即slot 64处区块)被证明,那么epoch 1检查点(即slot 32处区块)及之前被证明的所有区块都最终确定(finalized)。
所有最终确认(finalized)的检查点都成为规范链(区块链历史的一部分),所有忠诚节点都默认接收规范链,即「最终检查点」之后的区块可以随意分叉,但之前的区块不允许分叉。但如果节点主动选择作恶,则需要承担高昂的攻击成本。所以,通过Casper FFG保证了ETH2.0的安全性。
信标链浏览器:https://beaconscan.com/
让我们在信标链浏览器上查看一下epoch191896,可以看到该epoch的slot6140674为forked,slot6140676为skipped
对应的,在ETH区块链浏览器上,可以看到16967454区块在slot6140673被提议,16967455区块在slot6140675被提议,中间正好隔了一个slot6140674,因为该slot产生的区块是一个分叉块,且没有在LMD Ghost获得更多的投票weight。
可以看到16967456区块在slot6140677被提议,与上一个区块中间正好隔了一个slot6140676,因为该slot没有提议区块,可能因为提议者离线了。