本文介绍了以太坊2.0设计中的数据分片(Data Sharding)方案,该方案是rollup-centric roadmap的核心组成部分。
除了权益证明之外,eth2 设计中的另一个核心特征是分片。这个提案引入了一种有限形式的分片,称为“数据分片”,根据以 Rollup 为中心的路线图:分片将存储数据,并证明大小约为 250 kB 的数据 blob 的可用性。这种可用性验证为 rollup 等 layer-2 协议提供了一个安全且高吞吐量的数据层。
为了验证大量数据的可用性,而不需要任何单个节点亲自下载所有数据,两种技术相互叠加:(i)由随机抽样的委员会进行证明,以及(ii)数据可用性抽样 (DAS)。
假设你有大量数据(想想:16 MB,这是 eth2 链每个 slot 实际处理的平均数量,至少在最初是这样)。你将这些数据表示为 64 个“blob”,每个 256 kB。你有一个约 6400 个验证者的权益证明系统。你如何在不(i)要求任何人下载整个内容,或(ii)为仅控制少量验证者的攻击者打开后门以偷偷通过无效区块的情况下检查所有数据?
我们可以通过拆分工作来解决第一个问题:验证者 1…100 必须下载并检查第一个 blob,验证者 101…200 必须下载并检查第二个 blob,依此类推。每个子组(或“委员会”)中的验证者只需创建一个签名,证明他们已验证了该 blob,并且整个网络只有在看到来自相应委员会的大部分签名后才会接受该 blob。但这会导致一个问题:如果攻击者控制了验证者的某些连续子集(例如 1971…2070)怎么办?如果是这种情况,那么即使攻击者仅控制整个验证者集合的约 1.5%,他们也会主导一个委员会(在这种情况下,他们将拥有委员会 20 的约 70%,其中包含验证者 2001…2100),因此他们将能够控制委员会并将甚至无效/不可用的 blob 推入链中。
随机抽样通过使用随机洗牌算法来选择委员会来解决这个问题。我们使用一些哈希作为随机数生成器的种子,然后使用它来随机洗牌列表 [1..6400]。洗牌列表中的前 100 个值是第一个委员会,接下来的 100 个值是第二个委员会,依此类推。
RNG 种子是在验证者存入资金之后选择的,并且每个验证者的索引都是固定的,因此攻击者无法尝试将“所有验证者放入”单个委员会中。他们可能会偶尔因为随机的机会而幸运一次,但前提是他们控制了所有验证者的很大一部分(> 1/3)。
数据可用性抽样在某些方面是随机抽样委员会的镜像。仍然有抽样在进行,因为每个节点最终只下载了总数据的一小部分,但抽样是在客户端完成的,并且是在每个 blob内部而不是在 blob 之间完成的。每个节点(包括未参与 staking 的客户端节点)都会检查每个 blob,但它们不是下载整个 blob,而是在 blob 中私下选择 N 个随机索引(例如 N = 20),并尝试仅下载这些位置的数据。
此任务的目标是验证每个 blob 中至少有一半的数据可用。如果少于一半的数据可用,那么几乎可以肯定的是,任何给定客户端抽样的至少一个索引将不可用,因此客户端将拒绝该 blob。请注意,这种机制是(i)高效的,因为客户端只需要下载每个 blob 的一小部分即可验证其可用性,并且也是(ii)高度安全的,因为即使是 51% 的攻击者也无法诱骗客户端接受不可用的 blob。
为了涵盖攻击者提供 50-99% 的数据的情况(这很容易导致一些客户端起初接受而其他客户端拒绝该 blob),我们使用一种称为纠删码的技术。纠删码允许我们以这样一种方式编码 blob:如果 blob 中至少一半的数据已发布,则网络中的任何人都可以重建并重新发布其余数据;一旦重新发布的数据传播开来,最初拒绝该 blob 的客户端将收敛为接受它(注意:接受 blob 没有时间限制;只要它收到了对其所有样本索引的响应,客户端就会认为该 blob 可用)。
理解纠删码最简单的数学类比是“两点总是足以恢复一条线”的想法:如果我构造一个包含四个点的“文件” ((1, 4), (2, 7), (3, 10), (4, 13))
,所有这些点都在一条线上,那么如果你有其中任意两个点,你就可以重建这条线,并计算剩下的两个点(我们假设 x 坐标 1, 2, 3, 4
是系统的固定参数,而不是文件创建者的选择)。对于更高次的多项式,我们可以扩展这个想法来创建 6 个中的 3 个文件、8 个中的 4 个文件,通常对于任何任意的 n
,创建 2n
中的 n
个文件,其属性是:如果你有文件的任何 n
个点,你就可以计算出 2n
中缺失的剩余点。
攻击者也可能默认情况下不提供任何区块,并且仅选择性地发布块以响应它看到的样本查询,但这只会愚弄少数客户端,然后攻击者需要发布超过一半的区块才能回答所有查询(我们假设客户端公开重新广播他们收到的所有响应)。
我们使用多项式承诺(特别是 Kate 承诺)而不是 Merkle 根作为指向这些数据 blob 的指针,因为多项式承诺可以让我们轻松地证明给定的值实际上是在所需坐标处特定度数 n
多项式的正确评估。否则,我们必须要么证明(例如,使用 SNARK)Merkle 根编码了一个低次多项式(一旦我们需要后量子技术,这可能是最终的解决方案,但目前成本太高),要么依赖于在编码不正确的情况下可以广播的欺诈证明(增加了高复杂性和更多的同步性假设)。
仅使用委员会具有以下缺点:
仅使用 DAS 具有以下缺点:
这已经在其他材料中进行了详细讨论,这里无法复制;我推荐:
一个关键的结论是 BitTorrent、IPFS 和类似的系统不能解决数据可用性问题。虽然 BitTorrent 是一个良好的可扩展数据发布来源,但它不提供关于一块数据是否可用的共识保证,从而为节点在数据发布时间上存在分歧的难以解决的“边缘情况”攻击留下了可能性,从而阻止了混合 layer 2 协议的工作。为了在数据可用性上达成共识,需要本文档中描述的更强大的技术。
为了实现分片的可扩展性增益,我们需要一个 P2P 系统,以避免每个节点都下载所有数据。幸运的是,我们在 phase 0 中已经有一种 P2P 层分片形式!具体来说,有 64 个子网正在用于证明聚合。每个验证者只需要在 (i) 主要的“全局子网”和 (ii) 他们自己的证明聚合子网上;他们不会从其他 63 个证明聚合子网接收任何数据。
在委员会 + DAS 分片中,我们将此扩展到“网格”结构,其中包含 2048 个水平子网(每个 epoch 中每个(分片,slot)对一个),以及 2048 个垂直子网(每个 blob 中的每个索引一个)。
在每个 slot 期间,我们为每个分片选择一个提议者。每个提议者都有权提议一个 blob:一个高达 512 kB 的任意数据块(我们将其解释为每个约 512 字节的“样本”的集合),以及纠删码扩展和额外的证明,以允许独立验证 blob 的每个部分。
blob 的完整“主体”由原始数据、扩展数据和证明组成(尽管如果需要,为了数据效率,可以省略扩展数据,因为每个收到 blob 的节点相对较快地重建它)。
blob 的“标头”是对 blob 的 Kate 承诺,以及一些其他杂项数据(slot、分片、长度证明)以及来自提议者的签名。
当发布 blob 时,标头将在全局子网上发布,blob 将在对应于 slot 号和分片 ID 的水平子网上发布。对于每个
i 在 [0 ... SAMPLES_PER_BLOCK - 1]
中,第 i 个样本在垂直子网上发布
i,以及第 i 个样本实际上是在第 i 个 x 坐标处在标头中承诺的多项式评估的证明。
在实践中,将有 2048 个水平子网,以允许每个 epoch 中每个(分片,slot)组合一个水平子网。这样做是为了确保每个验证者都可以加入一个水平子网,在该子网上他们将仅接收对应于分配给他们的委员会的 blob(除了他们加入以参与抽样的少量垂直子网)。
每个验证者必须加入以下子网:
有一个程序,blob 提议者可以通过该程序将样本分发到所有子网,而无需提议者成为子网本身的一部分。此过程如下:
例如,如果块大小为 512 字节,并且最大数据 blob 大小(不带纠删码扩展)为 512 kB,那么使用纠删码扩展它为 1 MB,因此将有 2048 个垂直子网。如果每个节点有 15 个私有垂直子网和 5 个公共垂直子网,以及 50 个对等方,并且假设最坏的情况是每个水平子网中有 128 个成员(仅委员会),那么仅子网成员将直接发布到 128 * 20 = 2560 个子网(考虑到冗余发布后约为 1461 个),并且包括对等方,这将增加到 128 * 4 * 50 = 25600 个子网(考虑到冗余发布后,所有 2048 个子网占 99.2% 的时间)。
请注意,恶意区块提议者在不发布完整区块的情况下将样本发布到垂直子网在理论上是可能的。为了涵盖这种情况,我们添加了一个程序,通过该程序可以“自我修复”部分发布的(意味着 >= 50% 可用但不是 100% 可用)区块。自我修复程序有三个基本步骤:
在每个 slot 中,我们随机为 64 个分片中的每一个选择一个提议者。提议者有权创建一个分片 blob,并使用上述程序广播它,以及将 blob 的 ShardHeader
广播到全局子网。ShardHeader
可以包含在该 slot 或同一 epoch 或下一个 epoch 中的任何后续 slot 中的信标链中。
信标链跟踪 PendingShardHeader
对象的列表。PendingShardHeader
存储 (i) ShardHeader
中的关键信息(分片和 slot,对 blob 的承诺及其长度),以及 (ii) 一个位域,跟踪从随机选择的委员会(实际上,与 phase 0 中已经引入的委员会相同)中哪些验证者签署了该 blob。扩展了 AttestationData
结构,以包括 shard_header_root
,这是给定证明者投票支持的 ShardHeader
的根哈希。如果证明者没有看到他们被分配的(分片,slot)对的有效和可用的分片 blob,他们也可以投票支持一个空根。
如果 ShardHeader
获得了委员会 2/3 的支持,则会立即确认。如果在下一个 epoch 结束时,ShardHeader
比任何其他 ShardHeader
(包括默认的空 ShardHeader
)获得了委员会的更大份额的支持,则在下一个 epoch 结束时确认。
更改了分叉选择规则,以便只有当在该区块或其祖先中确认的所有 blob 都通过了可用性检查时,该区块才有资格被考虑。这被称为紧密耦合:如果一个链指向(意味着,已确认)甚至一个无效的 blob,则整个链都被认为是无效的。这是与“侧链”架构的一个关键区别,在“侧链”架构中,侧链可能会失败,而中心链仍然有效。
有关紧密耦合及其价值的进一步探讨,请参见 此处。
如果验证者少于 262144 个(32 个 slot * 64 个分片 * 128 个最小委员会规模),那么我们不会为所有分片选择提议者,而是为分片的有限子集选择提议者,循环通过分片(例如,如果 slot N 的开始分片为 0,则有 32 * 128 * 50 个验证者,则 slot N 将为分片 0…49 分配一个提议者,slot N+1 将为分片 50…63 和 0…35 分配一个提议者,slot N+2 将为分片 36…63 和 0…21 分配一个提议者,等等)。这样做是为了确保即使在参与度低的情况下,委员会规模也保持充足。
添加了一个类似于 EIP-1559 的机制,其中分片数据按字节收费,并且会调整此价格:如果区块平均超过 50% 满,则会增加价格,如果区块平均少于 50% 满,则会降低价格。因此,目标是平均区块大小为 50%。
与其他分片方案相比,仅数据 blob 分片设计功能强大,因为它在安全假设方面出奇地轻。特别是,它避免了诚实多数假设(因为 DAS 可以检测到多数推送的不可用 blob)和时间假设(因为与早期 DAS 方案 不同,此方案使用 Kate 承诺而不是欺诈证明,因此不依赖于任何欺诈证明将被足够快地广播的假设)。
恶意的 51% 联盟可以审查 blob,但 51% 的审查在非分片链中也是可能的。
添加的主要新假设是“诚实少数 DAS 假设”:有足够的节点进行抽样,以至于攻击者无法在不发布超过一半的区块的情况下满足它们。如果一个 blob 中有 2048 个样本,需要 1024 个样本才能恢复(2048 * ln(2) ~= 1419,考虑到某些客户端会采样相同的点),并且每个客户端需要 20 个样本,那么如果每个分片有超过约 70 个客户端进行抽样,则系统是安全的。
如果以后需要,仅数据 blob 分片设计与许多在分片中添加执行的方法向前兼容。特别是,可以修改该方案以要求 blob 包含先验状态根和后验状态根,并且我们可以使用欺诈证明或 ZK-SNARK 来验证 blob 中的状态转换是否正确。请注意,在任一选项中,确保分片中执行的正确性将不依赖于任何诚实多数假设。
尽情享受!
https://github.com/ethereum/eth2.0-specs/pull/2146/ 艰难攀越
- 原文链接: hackmd.io/@vbuterin/shar...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!