为了解决“存活性攻击”的问题,Conflux 设计了 GHAST 机制。
GHAST 机制的核心可以概括为以下几点:
1.同样采取最重链规则,但是区块有三种不同的权重:0, 1, X。其中 X 是一个比较大的数,例如 X=1000(先不讨论涉及挖矿难度调整的情形)。
2.网络中有两种区块:普通区块和特殊区块。普通区块的权重永远为1;特殊区块的权重根据区块的难度值(Difficulty)确定——有 1/X 的特殊区块权重为 X, 其余为 0。挖出一个普通区块和挖出一个特殊区块的难度是一样的。
3.区块的类型由区块的“历史树图结构”决定, 区块的生成者不能随意指定区块类型。
4.在没有攻击的情况下,所有新生成的诚实区块都应当是普通区块;在攻击者进行任何一种“存活性攻击”,并且持续足够长的时间后,所有新生成的诚实区块都应当是特殊区块。
下面我们详细介绍一下这几条规则:
l 三种权重的最重链规则
在最重链规则选主链的过程中,初始步骤是将创世块加入主链,之后的每一轮操作中,选择当前最后一个主链区块的所有孩子,计算每一个孩子的子树权重,然后选择子树权重最大的孩子。
当区块权重由一种变化为三种时,我们依然可以使用相同的规则,只是在计算子树权重时不再是简单地数区块的个数,而是把子树上所有区块的权重加起来。
此处我们还加了一条额外的限制:一个权重为 0 的区块不能成为主链(pivot chain)的一部分,也能成为另一个区块的父亲区块。这个条件保证了每一个权重为 0 区块的子树权重一定是 0。
l 普通区块与特殊区块
三种不同的权重来自于两种区块,普通区块与特殊区块。所有权重为 1 的区块都来自于普通区块,而权重为 0 和 X 的区块都来自于特殊区块。
普通区块很好理解,它和比特币、以太坊,以及 Conflux 引入“GHAST”之前共识机制中的区块没有什么不同。
特殊区块更复杂一些,它的生成难度和普通区块一样,但区块权重由难度值决定。
这样说可能比较抽象,我们来举一个例子。
假如当前的网络参数中,一个区块的区块头哈希有 32 字节,也就是 256 比特,前 60 个比特为 0 的区块视为合法区块,X 的取值为 1024。那么当一个矿工在挖一个普通区块时,找到了一个区块头哈希前 60 比特为 0,那这就是一个合法的普通区块,权重为1. 当一个矿工在挖一个特殊区块时,找到了一个区块头哈希前 60 比特为 0,那这就是一个合法的特殊区块。如果这个区块头哈希的第 61 比特至第 70 比特都是 0,那么特殊区块的权重为 1024. 否则,特殊区块虽然合法,但是权重是 0. 也就是说,每次矿工生成一个合法的特殊区块,有 1/1024 的概率区块权重为 1024, 另外 1023/1024 的概率权重为 0,最终权重的期望值还是1。
让矿工生成特殊区块,在共识机制中类似于将区块难度调高 X 倍,将出块速度放慢 X 倍。出块速度放慢后,是有利于解决“存活性攻击”的问题的。关于这部分的细节,我们稍后再详细分析。
l “历史树图结构”决定普通区块或特殊区块
在我们的设计中,矿工是不能自主决定挖一个普通区块还是特殊区块的。一个区块是普通还是特殊,由这个区块的“历史树图结构”决定的。
一个区块(记为区块 b)的历史树图结构是指:从这个区块开始,沿父边和引用边往前回溯,直到创世块,这些区块(不包括区块 b 自己)所构成的树图结构就是区块 b 的历史树图结构。
对于一个诚实节点来说,生成的区块 b 的历史树图结构就是节点生成这个区块 b 时所看到的树图结构(因为树图结构要求矿工引用所有看到的、未被引用的区块)。
一个区块是普通区块还是特殊区块,完全由历史树图结构确定。
由历史树图结构确定特殊区块的好处是,每个人都可以独立地判断一个区块应该是普通区块还是特殊区块,并且达成一致不会出现分歧——因为区块自己的父边和引用边都是不可修改的。
只要所有人对每个区块是普通区块还是特殊区块都达成一致,自然也就对相应区块的权重达成了一致,从而避免在选择主链时产生分歧。
l 决定普通区块或特殊区块的规则
如何根据一个给定区块的“历史树图结构”,决定这个区块应该是普通区块还是特殊区块呢?这个规则的设计是需要仔细斟酌的。
在没有观测到攻击行为时,所有新生成的诚实区块都应当是普通区块;在发现攻击者进行任何一种“存活性攻击”,并且持续足够长的一段时间后,所有新生成的诚实区块都应当是特殊区块;
对于两者的中间状态,即观测到持续时间不长的攻击行为时,按照上一期文章中提到的“让诚实节点求同存异”的思想,我们允许一部分诚实节点生成普通区块,另一部分诚实节点生成特殊区块的状态存在。
实际上,活跃的攻击行为是可以从一个区块的历史树图结构中反映出来的。
如果一个区块的历史树图结构中有两棵大小相近且权重都很大的子树,则可以推测有一个攻击者正在进行平衡攻击。此时诚实的节点都应该产生特殊区块。
另一方面,如果历史树图结构中每个区块都可以根据确认规则很快地被确认,就说明没有什么问题(至少暂时没有可以被诚实节点观测到的问题)。此时诚实的节点都应该产生普通区块。
至于如何根据历史树图结构确定当前应该挖的到底是普通区块还是特殊区块,由于其具体设计方案稍微有一点点复杂,我们将留在下一期为大家详细介绍。