Our understanding of the consensus protocol employed by Ethereum, and the assurance of the security it provides, has been progressively established through continuous analysis and critical evaluation of the protocol itself. A concise review of the attack instances identified by researchers during this process, as well as their historical evolution, will facilitate comprehension of the theoretical frameworks designed to provide a unified characterization of these attacks.
Bouncing Attack
Vitalik于2018年7月31日发布了信标链(Beacon Chain)权益证明(Proof-of-Stake)共识机制的原始简要规范(mini-spec),时间恰好是以太坊研究人员放弃先前将以太坊迁移到PoS的设计之后不久。Alistair Stewart指出了这一设计所面临的Bouncing Attack1。这一攻击利用的是Casper FFG存在的缺陷,我们可以在讨论它的时候忽略掉更低一层的区块选择协议2。
Casper FFG 为以太坊引入了 epoch 的概念,它是验证者加入、退出以及履行职责的基本时间单位。每个 epoch 包含 32 个 slot,每个 slot 表示一个区块被提出并验证的时间窗口,长度为 12 秒。因此,一个 epoch 中最多可产生 32 个区块,最低可能一个区块也没有。通常,epoch 中第一个 slot 对应的区块被称为该 epoch 的检查点,其出现标志着一个新 epoch 的开始。若该 slot 未产生区块,则验证者会在前一个 epoch 中选取高度最高的区块,将其作为当前 epoch 的检查点。
我们假设从最后一个 finalized 区块开始,新的 epoch(记为 epoch 0)中出现了两个互相冲突的检查点,分别获得了 70% 和 30% 的投票(其中左侧检查点成为该 epoch 的 last justified checkpoint)。在 epoch 1 中,这两条分支上的检查点分别获得了 30% 和 60% 的投票(攻击者保留了指向右侧分支的 10% 投票)3。进入 epoch 3 后,攻击者等待右侧分支的检查点累计获得 60% 的投票,然后再公布自己在 epoch 1 中支持右侧检查点的投票。
这样,epoch 1 中右侧的检查点将被确认为新的 last justified checkpoint。按照协议规则,原本基于左侧分支构建的链将被抛弃,诚实验证者将转而选择右侧分支作为主链(canonical chain)。然而,由于验证者不能在同一个 epoch 中对多个检查点进行投票,右侧链在 epoch 2 中最多只能获得 30% 的投票,因此将继续推进至 epoch 3。当右侧链在 epoch 3 中的检查点获得 60% 投票后,攻击者再公布其在 epoch 2 中对左侧检查点的 10% 投票。
读者或许会对这种情况是如何产生的感到疑惑,攻击的初始条件也并未如此例子中描述的那么极端(但也不是很容易)。若对此有兴趣,请参考: Analysis of bouncing attack on FFG
该攻击场景的产生,源于 Casper FFG 在分叉选择过程中缺乏“稳定性”。这里的稳定性指的是:一旦分叉选择规则在某一时刻选定了一条链,该选择应在后续合法演化过程中保持方向上的一致性,即继续倾向于同一条链。在比特币协议中,由于算力的集中和积累效应,一条当前最长的链很可能在未来也继续保持最长。而在 Casper FFG 中,当前拥有最高 justified 检查点的链,并不保证在未来仍能维持该地位。
Balancing Attack
First Edition
2020 年 10 月,Jneu 在以太坊研究论坛上发布了他们的 Balancing Attack 的第一版。此时的 Balancing Attack 受到两个重要的限制:
- 攻击者的行为明确违反了共识细则。
- 部分研究人员认为攻击者不具备发动这一攻击所需要的网络控制能力。
在 Jneu 的描述中,攻击者需要先获得某个 epoch 第一个 slot 的出块权。随后,攻击者构建两个互相冲突的区块,并将他们发送给该 slot 中具有投票权的验证者的不同群体。
在理想情况下,这一举动会将该 slot 中的验证者群体划分为两个部分。验证者 A 为上面(原文描述为左边)的区块投票,验证者 B 为下面(原文描述为右边)的区块投票。这一结果成立的条件在于,攻击者知道验证者进行投票的具体时刻4,并择时传递区块信息,以确保验证者在即将投票时只看到其中一个区块。
验证者投完票后会观察到完整的出块形势,并根据分叉选择规则5重新确定主链。
在下一个 slot 的验证者即将开始投票之前,攻击者根据观察到的局势,释放一部分自己隐藏的投票。这一举措让下一个 slot 中的验证者同样在即将开始投票前看到不同的投票情形,并由此继续被分化为两个不同的群体,为两条链投票。
由于这一策略可以在后续的 slot 中持续进行,任何一条链都无法收集到足够的投票以达成 Justified 的状态。我们由此认为链陷入了“停滞”,因为没有新的区块可以被 Finalized。
Second Edition
第二版的 Balancing Attack 对第一版的限制条件进行了修复。
这一攻击的基础条件是验证者有可以投票的不同的链,攻击者在同一个 slot 提出两个区块是一种方式。攻击者也可以隐藏自己的区块,择时发布给验证者,这也能带来视角的分化。
比如,攻击者获得了 slot n + 1 的出块权,他提出自己的区块并对其进行验证。但攻击者保留区块信息和验证信息,直到 slot 结束。
当 slot n + 2 的验证者准备开始出块时,攻击者向一部分验证者发布自己的区块和验证信息。由于两个区块是相互冲突的,看到这一信息的验证者将不会为 slot n + 2 出现的区块投票。 因为刚发布的区块权重低于已有验证的区块 n + 1。
由此,攻击者就实现了验证者群体的视角分化。后续的攻击步骤就和第一版的 Balancing Attack 类似了。
此外,作者(Jneu)补充了对攻击者网络能力的验证,他们通过 AWS 的实验证明攻击者可以具有 Balancing Attack 需要的网络控制能力,并能通过简单的启发式搜索来获得最佳策略。 这一部分的内容不在本博客计划讨论的范畴内,我邀请有兴趣的读者阅读论文(或者论坛上的帖子)以获取详细信息:Three Attacks on Proof-of-Stake Ethereum
Counter Measure
Defense on Bouncing Attack
为应对 Bouncing Attack,以太坊研究人员提出的修复策略是:在分叉选择规则中引入一条额外约束——若节点希望更改其对 last justified checkpoint 的判断,必须在该 epoch 的前 k 个 slot 内完成变更。一旦超过该时间窗口,节点将仅在当前 epoch 结束后才接受新的 last justified checkpoint。
然而,这一修复措施已在 Capella 升级中被移除,原因在于其显著增加了分叉选择规则的复杂性,同时也未能有效解决原问题。
社区并未就解决方案进行进一步的探索,他们认为这一攻击需要极端的网络情况,十分不可能发生。
Defense on Balancing Attack
对 Balancing Attack 解决方案的探索则更加令人放心。即便第一版存在质疑,社区也依然在第二版出现之前就拟定了一些修复方式。
Proposer Boost 的想法十分直接:我们为按照协议履行职责的验证者以额外的奖励,通过加权的方式赋予他们统一网络视角的能力。 这也是现阶段的以太坊采用了的解决方案。但需要明确的是:这一方法并未彻底的关闭这一攻击的窗口,他只是使得这一攻击变得更加复杂和难以出现。 此外,和所有的“药”一样,Proposer Boost 也有自己的“三分毒”。
View Merge 是一个更优雅的方案,他给予诚实验证者统一视角的能力。这并不是通过简单的加权,而是通过帮助传播验证信息来实现的。 遗憾的是,这一方案在当前的版本中尚未实现,因为他需要一些较为苛刻的前提条件。
我无意比较这两种解法的优劣,在我看来他们都代表着科研人员对去中心化更加繁荣的努力,不同的解法适用于不同的版本和基础条件而已。 但私下里来讲,我更喜欢 View Merge,它更像是探索自我中发现的新路,为我们带来新的视角于认识。Proposer Boost则略有一些简单粗暴。
Conclusion
我们不难看到,这两种攻击(Bouncing Attack, Balancing Attack)利用的都是验证者决策时信息难以及时同步的缺点。 固定的执行顺序和规划让攻击者可以知道验证者会在什么时间点执行什么任务,随后择时传递信息,使得所有的验证者在同时做出决策时,对于真实情况无法共识。
在认同了这一想法后,View Merge 才显得比 Proposer Boost 更加对症下药。
-
我并未找到最原始的出处,即Alistair Stewart本人的发言。我想这一部分可能在以太坊基金会的某个内部讨论文件中。 ↩︎
-
以太坊现行的共识协议可以被分为三个部分:1. 确认验证者合法性及权重的Proposer Rule(Proof of Stake)2. 选择链头节点的Fork Choice Rule(LMD-GHOST)3. 为链带来最终确定性的Finality Rule(Casper FFG)。 ↩︎
-
“History doesn’t repeat itself, but it often rhymes.” – Mark Twain. ↩︎
-
我们在前面提到,一个 slot 时间长度为 12 秒。被分配到在该 slot 投票的验证者会在第 4 秒,或者收到了合法区块时开始投票。 ↩︎
-
根据 GHOST 规则选择最重的区块。如果两个区块高度一致且等重,那么选择哈希值较小的区块。 ↩︎