本文提出了一种新颖的数据可用性采样 (DAS) 和分片 Blob 内存池设计,旨在增强可扩展性的同时保持去中心化。传统的 Danksharding 策略假设一个区块构建者/提议者创建区块,对其进行纠删码处理,然后将完整数据分发到整个对等 (P2P) 网络。这对网络带宽的要求非常高,尤其是对于The Block构建者和提议者是同一节点的小型家庭权益质押者 (home-staker) 而言。本文中的提案通过实现分布式区块构建 (DBB) 解决了这个问题,并采用了两个新思路:i) 分片 Blob 内存池,以及 ii) 部分列传播。
本文的其余部分安排如下。首先,阐明作为此新设计基础的基本假设。然后,介绍当前的 DAS 和 blob 内存池设计。最后,阐述拟议的设计及其带来的优势。
假设
以下是我们在这项工作中采用的主要假设。
网络规模:目前以太坊的网络规模估计约为 10,000 个节点。本文假设网络规模将保持在 5,000 到 50,000 个节点之间,但未来几年可能会有所变化。
块结构:我们假设所有数据块都由 512 字节元素组成,称为“单元”,然后使用擦除编码(Reed Solomon)进行分组和扩展以创建二维矩阵。
槽位吞吐量:我们的目标吞吐量为256 个 128KB 的 blob ,在使用纠删码扩展之前,每个槽位总计 32 MB。因此,在二维纠删码扩展之后,大小为 128MB。
数据传播:Gossipsub 用于在 P2P 网络内的多个通道上传播共识层 (CL) 的数据。我们假设 Gossipsub 可以扩展到一千个主题甚至更多。
DAS 和内存池的旧设计
槽周期
一个块及其 blob 的整个时隙周期可以用以下四个步骤来描述。
1. 内存池
在以太坊网络中,blob 通过类型 3 ( 0x03 ) 交易提交。该交易可以包含一个或多个 blob,自 Pectra 以来最多可包含 9 个。类型 3 交易通过 devP2P 网络进行传播。这意味着,首先将交易的哈希值推送到所有对等点,然后节点可以决定提取交易和相关的 blob 数据,这些数据在BlobTxSidecar中传输。如果节点不需要,则无需下载类型 3 交易或 blob 数据。想要构建和提议区块的验证者节点应监视网络交易(包括类型 3),并将所有 blob 下载到其内存池中。Blob 数据进入执行层 (EL) blob 内存池,等待被纳入区块。当选择节点提议区块时,它将包含其内存池中的一些 blob,前提是它们的可用性已经过验证。任何节点都可以选择下载所有 blob 数据用于其他目的(例如监控、研究)。
2. 建筑
一个区块由两部分组成:执行有效载荷和 blob 数据。执行有效载荷不包含 blob 数据,它仅通过 type3 交易引用 blob。The Block构建者/提议者选择要包含在The Block中的 blob 及其顺序。在满负荷情况下,它每个 slot 最多选择 256 个 blob(每个 128KB),因此在纠删码之前,总共约有 32MB 的 blob 数据。The Block构建者通过 Reed-Solomon 编码水平和垂直扩展这些数据,最终生成一个 128MB 的区块。
3.传播
The Block构建者 / 提议者将执行负载广播到网络进行验证,并通过 Gossipsub 通道传播整行和整列。CL 节点仅保管(即存储)The Block中所有行和列的一小部分。保管的行数和列数由每个节点决定,但每个节点都必须保管最少数量的行和列。一些节点可以决定保管所有行和列,使它们成为超级节点。CL 节点通过 Gossipsub 接收执行负载以及它们保管的整行和整列。CL 节点在其以太坊名称记录(ENS)中告知其他节点其保管的大小。行和列是从节点 ID 确定得出的,因此任何节点都可以知道其对等节点保管哪些行和列。
4. 采样
CL 节点共同确保所有 blob 均可检索,而无需每个节点都存储完整区块 (128MB)。由于 blob 使用纠删码进行扩展,因此,如果数据足够,即使是部分 blob 数据也可以完全重建。CL 节点执行随机采样以验证数据可用性。每个节点都会从其对等节点中选择一定数量的随机单元进行采样。它知道哪些对等节点保管哪些列/单元,因此可以向这些对等节点发出请求。或者,它可以将请求发送给多个对等节点,并让任何节点响应。
这种设计的缺点
- 想要构建/提议区块的验证器节点必须将所有 blob 下载到其内存池中。
- The Block构建者/提议者在生成区块时需要传播(即上传)所有擦除编码的 blob 数据(128MB)。
- Blob 在 EL 和 CL 上传播(作为行),导致冗余和带宽浪费。
- 整行和整列都通过网络传播
新设计
想法和理由
这一新设计的主要目标有三方面:
- 减少 EL 节点需要在 blob 内存池中下载的数据量,
- 消除 EL 和 CL 之间存在的网络冗余
- 减少需要上传并由 CL 节点保管的数据量。
在本节中,我们介绍此新设计中引入的新概念。
水平分片的 Blob 内存池
每隔几秒下载几十MB的blob数据会对互联网带宽有限的家庭权益持有者造成压力。因此,我们提出了一种水平分片的内存池设计,以便EL节点只需下载部分blob。主要思想是根据节点ID和它们将存储的blob的类型3交易的哈希值对节点进行分片:当且仅当类型3交易哈希值的最后4位与其节点ID的最后4位匹配时,节点才应该下载类型3交易及其相关blob。这将创建16个不同的分片,其中所有类型3交易和blob都是不相交的。EL节点下载到其内存池中的相同blob是CL节点必须保管的相同行,因此无需通过CL网络下载行;可以通过从EL到CL的getBlobs获取它们。这意味着,对于每个时隙,节点将根据类型 3 交易的哈希值保管不同的行。尽管如此,根据对等节点的节点 ID 和时隙的执行有效负载,计算出对等节点在给定时隙保管的行 ID 应该相当简单。在本例中,我们使用了 4 个比特(16 个分片),但不一定非得是 4 个;它可以是任意数量的比特B ,用于对我们希望每个区块拥有的 256 个 blob 进行分片。这减少了网络带宽,同时加速了The Block创建后 CL 层的数据传播。
需要强调几点。由于行托管基于类型 3 交易哈希,因此节点需要存储的 blob/行数在不同时隙之间并不相同,因为它取决于哈希值和每个交易的 blob 数量。但是,平均而言,所有节点在统计上存储的数据量相同。相反,对于给定的时隙,并非所有节点都存储相同数量的行。尽管如此,所有 blob 都会在节点之间平均分布并进行稳健复制。此策略通过消除 CL 处的 blob/行传播来避免 EL 和 CL 冗余。另一个可用的策略是验证者托管:要存储的 blob/行数可以与节点中的验证者数量成正比。例如,对节点的最低要求可以是匹配节点 ID 的最后B位,而对于具有验证者的节点,则可以匹配最后B-1位。具有更多验证者的节点可能会更频繁地提议区块;因此,在 Blob 内存池中拥有更多 Blob 有助于他们更快地构建区块。此外,从经济角度来看,拥有多个验证者的节点可能拥有足够的硬件和网络资源来保管更多 Blob/行。
部分专栏传播
列与 blob 的不同之处在于,它们仅在The Block构建后才为人所知。因此,只有在The Block构建者/提议者决定包含哪些 blob 及其顺序后,才能传播列,即使是部分传播。在本提案中,CL 节点需要保管多个列,并且这些列的确切索引由节点 ID 确定,与之前的设计相同。这些列索引在节点的整个生命周期内保持不变。这意味着,**与行相反,节点在每个 slot 始终存储相同数量的列,并且始终是相同的列。行和列之间的这种差异对于优化网络带宽利用率至关重要。同时,它能够实现稳健的数据保管和快速采样。
与整列传输相反,部分列传输是此新设计的关键部分,因为在水平分片的内存池中,大多数节点在收到执行负载时将无法传播整列。因此,部分列传输对于传播部分数据和加速区块扩散至关重要。例如,如果 blob 内存池被分成 16 个分片,那么为了获得整列,节点需要通过该列的 gossipsub 主题接收 16 条部分列消息。通过在每个节点收到执行负载后立即传播部分列,网络无需依赖The Block构建者/提议者的上传速度来获取其各自的列。当The Block提议者是上传带宽有限的本地抵押者时,这一点尤为重要。此外,即使所有 EL 节点都拥有其内存池中的所有 blob 并共享整列以避免The Block提议者的瓶颈,它们仍然需要上传整列。相比之下,这种设计允许每个节点仅发送 1/16 列,从而减少带宽消耗。
新设计老虎机周期
1. 内存池
此设计与现有设计之间的主要区别在于引入了分片内存池。在此设计中,节点仅下载一定数量的类型 3 交易和相关的 Blob Sidecar(即 Blob 数据) 。每个节点必须保管的 Blob 是根据节点 ID 以确定性方式计算出来的,这样每个节点都可以知道自己要下载哪些 Blob,还可以知道其对等节点保管哪些 Blob。每个节点都应该下载并存储在其 Blob 内存池中的类型 3 交易的最小数量。具有验证器的节点可以在其 Blob 内存池中保管更多 Blob,类似于验证器保管。节点可以选择将每个 Blob 下载到其 Blob 内存池中,因为它们有许多验证器,或者因为它们需要它来完成其任务(例如,区块构建器、汇总器、浏览器)。
2. 建筑
目标是在每个 slot 中引入 256 个 128 KB 的 Blob,总计 32 MB 的 Blob 数据,在纠删码之前。在这种新设计下,The Block构建者/提议者拥有一个有限的(即分片的)类型 3 交易列表,可以将其附加到其区块中。它可以决定只附加来自其受限列表的 Blob。然而,还有另一种策略。由于区块提议者是预先已知的,因此需要在下一个周期提议区块的节点可以暂时更改其 Blob 内存池的行为,开始下载所有类型 3 交易和 Blob,直到The Block被提议,届时它们可以恢复到标准的 Blob 内存池行为。
3.传播
The Block构建者/提议者应该传播的第一件事是执行有效负载,其中包括附加到The Block的3 类交易和 blob 的列表。
CL 节点需要保管(即存储)EC 扩展区块中的若干行和列。在此设计中,我们建议 CL 需要保管的行应该与 EL 节点下载到其内存池中的 Blob 相同。这样一来,我们确保无论The Block中包含哪些 Blob,每个遵循协议的 CL 节点都无需通过网络接收任何水平行,因为它们的 Blob 内存池中已经拥有这些行。相反,它们可以通过纠删码技术进行水平扩展,并将其从 EL 节点的 Blob 内存池转移到 CL 保管存储。在这种情况下,任何节点(即使是The Block构建者)都不应通过 CL 网络推送水平行,因为水平传播发生在 EL 节点,因此没有必要这样做。如果由于某种原因(例如网络或硬件故障),某个节点的 Blob 内存池中没有应有的 Blob,它可以通过拉取操作向其他节点请求这些 Blob。
关于列传播,当 CL 节点接收到The Block的执行有效载荷时,它知道哪些 blob 要包含在The Block中。由于该节点拥有The Block的部分行,因此它也拥有节点负责的列的部分单元格,但不是全部。因此,节点不会发送整个列(除非它是超级节点),而是通过 Gossipsub 主题传播部分列。这应该能够从列主题中的所有对等节点快速检索列。一旦节点从非扩展列中接收到所有单元格,它就会使用纠删码垂直扩展该列。此时,网络中的所有节点都应将其相应的行和列分配给托管。
4. 采样
新设计中采样没有显著变化。一切与之前的设计相同。
一些数字
假设在任何给定时间,大约有 1000 个类型 3 的交易可供区块构建者选择在下一个区块中引入哪些交易。对于希望将所有 Blob 都放入其 Blob 内存池中的区块构建者来说,这将导致 Blob 内存池的大小约为 128MB。假设没有验证者的节点保管以与其节点 ID 相同的 4 位结尾的 Blob,那么它们将持有这些 Blob 的 1/16。也就是说,平均 1024 个 Blob 中,有 64 个 Blob(约 8MB)。假设一个网络包含 8,000 个节点,并且节点 ID 均匀分布,那么每个 Blob 将存储在大约 500 个节点上,从而提供足够的冗余和稳健性。借助我们的爬虫,我们获取了当前网络中的 EL 节点列表,并按照此设计对它们进行了分片。上图显示了每个分片中存在的节点数量。
我们还分析了从 Pectra(5 月 22 日)到 6 月 3 日(6107 个 epoch)的所有类型 3 交易,并根据它们各自的分片绘制了图表,以检查它们的分布均匀性。总共有 254,097 笔类型 3 交易分布在 16 个分片上,如下所示。
类似地,我们验证了 707,923 个 blob 也均匀分布在各个分片中。
这不包括多验证器节点和超级节点。
实施这一新设计
为了实现本文提出的水平分片 blob 内存池设计, EL 节点在拉取类型 3 交易之前只需要进行一次额外检查,即验证匹配的哈希值。
对于列传播,我们需要实现部分列传输,以便传播部分列。这可以简单到发送一个较短的(1/16)列以及单元格在该列中的位置列表。
讨论
其他一些策略可以补充这一建议:
我们可以添加一个Blob 内存池票据,用于将 Blob 引入 Blob 内存池。该票据可以通过拍卖获得。Blob 内存池票据的目的是限制注入内存池的 Blob 数量,从而防止 DoS 攻击。然而,在本设计中,Blob 内存池是水平分片的,因此 Blob 内存池票据的需求并不大。
The Block构建者/提议者可以“尽力而为”地传播所有数据(行和列)。虽然大多数数据列将通过部分传播从其他对等节点到达,但来自The Block构建者的列可以作为备份策略。
节点应使用 IDONTWANT 消息来减少接收单元时的带宽。请注意,部分传播将始终传播完全相同的部分消息,因为分片是不相交的且具有确定性。因此,IDONTWANT 消息在部分传播的环境下仍然有效。
由于列传播从所有节点同时开始,我们可以实施推拉相变策略,同时最大限度地减少匿名性问题。
致谢
这项研究由Codex 团队完成。我们感谢@dankrad和其他 DAS 研究人员的反馈和贡献。









