新型PeerDAS方案 (Fulu)

本文介绍了PeerDAS方案,它通过分片blob数据责任的方式,旨在提高以太坊每个区块的blob数量,同时避免线性增加带宽和存储需求。该方案通过纠删码、数据列划分、节点数据列管理、数据列抽样和数据恢复等技术,确保blob数据的可用性,并对比了PeerDAS与Proto-Danksharding在数据存储和带宽方面的差异。

*查克·诺里斯不需要对数据可用性进行抽样;当他决定是时候的时候,数据就会变得可用。*

全新的 PeerDAS 方法 (Fulu)

引言

我们提出了一种系统,该系统允许节点分担 blob 的保管责任,而不是要求所有信标节点从超过 `4096` 个 epoch 的所有区块中获取和存储每个 blob。这种方法旨在增加每个区块的 blob 数量,而无需线性增加所需的带宽和存储容量。

然而,必须确保所有 blob 在整个 `4096` 个 epoch 中始终保持有效可用。一种简单但资源密集的方式来验证 blob 可用性是下载每个 blob,这在 EIP-4844 (Proto-Danksharding) 中使用。不幸的是,即使下载 blob 而不存储它们也会消耗网络带宽。

PeerDAS 的概念通过确保 blob 的可用性来应对这一挑战,而无需下载所有 blob

协议

第一步是对每个 blob 应用纠删码。如果你不熟悉纠删码,请参阅本书末尾关于 [多项式](https://hackmd.io/XyUFRKB1RGSiMEWlypw9hw#Polynomials) 的章节。就我们的目的而言,我们将使用 `2` 的纠删码比率。这意味着经过纠删码的 blob 将需要是非纠删码 blob 两倍的存储空间。

在应用纠删码之前,blob 可以表示如下: ![image](https://hackmd.io/_uploads/S1arLcZgA.png)

使用纠删码,blob 可以表示如下: ![image](https://hackmd.io/_uploads/r1ed89beA.png)

现在,让我们将所有行(即 blob)划分为 128 列,称为 数据列 。 ![image](https://hackmd.io/_uploads/ryUrfqzeC.png)

  • 有 `128` 个数据列,每个单元格代表 `256 kB / 128 = 2 kB`。
  • 有 `6` 个 blob,每列代表 `2 kB * 6 = 12 kB`。

节点保管

节点不再需要下载和存储完整的 blob(即整行)。相反,他们只需要处理数据列的一个子集。

![image](https://hackmd.io/_uploads/r1xQB2YGyx.png)

在这个例子中:

  • 有 128 列 `NUM_COLUMNS = 128`。
  • 节点保管 `4` 个数据列。

修改后的主题结构

随着 peerDAS 的引入,之前的 `blob_sidecar_<n> topics`(其中 `n=0..5`)已被 `data_column_sidecar_<n>` 主题(其中 `n=0..127`)取代。

Prysm 日志示例:

...
INFO sync: Subscribed to topic=/eth2/153249ea/data_column_sidecar_36/ssz_snappy
INFO sync: Subscribed to topic=/eth2/153249ea/data_column_sidecar_105/ssz_snappy
INFO sync: Subscribed to topic=/eth2/153249ea/data_column_sidecar_124/ssz_snappy
INFO sync: Subscribed to topic=/eth2/153249ea/data_column_sidecar_23/ssz_snappy
...

:::info 注意

在规范的早期版本中,单个主题可以包含多个数据列。但是,在当前版本中,每个主题仅限于一个数据列,因此总共有 `128` 个主题。 :::

保管要求

没有附加验证器

没有 附加验证器,一个全节点需要下载、存储 和服务 至少 `4` 个数据列,但如果需要,可以选择下载、存储 和服务 更多数据列。

[来源](https://github.com/ethereum/consensus-specs/blob/dev/specs/fulu/das-core.md#custody-requirement)。

默认情况下,Prysm 信标节点将下载、存储 和服务 `4` 个数据列。但是,使用 `--subscribe-all-subnets` 选项运行 Prysm 信标节点可以使其下载、存储 和服务 所有 `128` 个数据列。在这种配置中,该节点被认为是 超级节点

使用托管验证器(验证器保管)

使用 至少一个附加验证器,一个全节点需要下载、存储 和服务 至少 `8` 个数据列。 对于每个新的附加的 `32 ETH`,全节点需要下载、存储 和服务 一个额外的数据列。

  • 如果附加了 `3872 ETH` 或更多(`121` 个验证器,每个验证器有 `32 ETH`),则该节点需要下载、存储 和服务 至少所有 `128` 个数据列。
  • 如果附加了 `1824 ETH` 或更多(`57` 个验证器,每个验证器有 `32 ETH`),则该节点需要下载、存储 和服务 至少所有的 `64` 个数据列,现在能够重建 `64` 个缺失的数据列。

![image](https://hackmd.io/_uploads/r13i_o79Jg.png)

[来源](https://github.com/ethereum/consensus-specs/pull/3871/files)。

确定保管数据列

信标节点使用私钥运行,数据列的保管通过以下步骤确定:

  1. 从私钥确定性地派生出一个唯一的公钥。
  2. 从公钥确定性地派生出一个唯一的节点 ID。
  3. 从节点 ID 确定性地派生出一个 `128` 个数据列索引的唯一序列。
  4. 如果节点需要保管 `n` 个数据列,则这些数据列必须对应于步骤 3 中计算的序列的前 `n` 个索引。

示例: 如果在步骤 `3` 中,从节点 ID 派生出以下 128 个索引的唯一序列:`[14, 86, 45, 54, 66, 78, 127, 103, 2, ...]`,并且该节点被分配了保管 `4` 列的任务,则相应的索引必须为 `[14, 86, 45, 54]`。

如果在稍后的时间,同一节点(使用相同的私钥)被分配了保管 `6` 列的任务,则相应的索引必须为 `[14, 86, 45, 54, 66, 78]`。

[来源](https://github.com/ethereum/consensus-specs/blob/dev/specs/_features/eip7594/das-core.md#get_data_column_sidecars)。

广播保管列

保管组的数量(对应于当前规范中保管数据列的数量)通过节点的 ENR 记录和 Metadata P2P 消息进行广播。

在 ENR 记录中,引入了一个新字段 `cgc`(保管组计数的缩写)来指示此信息。

使用以下示例:

enr:-Me4QGw9qjlhPjQ9Q-yoi_ju4-6aXLtvjeS2V2U0BveqIkeVGNObDR8pTRZCUVQW48yd81ch6SndZTzd6w6Ha1tqtDaGAZNDJl6sh2F0dG5ldHOIAAAAAAAAGACDY3NjBIRldGgykBUySepgAAA4AOH1BQAAAACCaWSCdjSCaXCErBAAFYlzZWNwMjU2azGhAnhJ7EpX-jrAq3cBimdLfhcXmUwMiZyxylTUjCrr00Y1iHN5bmNuZXRzAIN0Y3CCMsiDdWRwgjLI

![image](https://hackmd.io/_uploads/Sy_ZfRYMkx.png)

新的元数据结构:

seq_number: uint64
attnets: Bitvector[ATTESTATION_SUBNET_COUNT]
syncnets: Bitvector[SYNC_COMMITTEE_SUBNET_COUNT]
custody_subnet_count: uint64 # csc

节点 ID 和保管子网计数都是公开可访问的,允许任何人确定网络上任何节点的保管数据列。

新引入的 Req/Resp

PeerDAS 带有两个新的 Req/Resp 消息:`DataColumnSidecarsByRoot` 和 `DataColumnSidecarsByRange`。

([来源](https://github.com/ethereum/consensus-specs/blob/dev/specs/_features/eip7594/p2p-interface.md#the-reqresp-domain))

`DataColumnSidecarsByRoot` 允许通过指定以下内容从节点检索数据列 Sidecar 列表:

  • 一个块根,以及
  • 一个数据列索引。

在 Prysm 中,`DataColumnSidecarsByRoot` 用于:

  • 在节点采样期间,以及
  • 在重组后检索数据列时(如果重组足够小,不会切换回初始同步)。

`DataColumnSidecarsByRange` 允许通过指定以下内容从节点检索一系列数据列 Sidecar:

  • 一个起始插槽,
  • 一个计数,以及
  • 一个数据列索引列表。

在 Prysm 中,`DataColumnSidecarsByRange` 在初始同步期间使用。

数据列采样

两种采样类型

除了管理保管列之外,节点还必须执行数据列采样,以统计方式验证所有数据列的可用性。可以使用两种主要方法:保管采样节点采样

Prysm 实现了这两种方法,但目前只有保管采样可用。虽然保管采样更容易实现,但它需要更多的带宽。

客户端可以在子网采样和节点采样之间切换(或反之亦然),而无需协调的硬分叉。

保管采样

[来源](https://github.com/ethereum/consensus-specs/blob/dev/specs/fulu/das-core.md#custody-sampling)。

使用保管采样,节点需要通过 gossip 下载并验证每个区块至少 `8` 个数据列的有效性。

如果节点已经保管了至少 `8` 个数据列,则子网采样什么也不做(无操作)。

示例 1: 如果一个节点保管了 `5` 个数据列,那么对于每个包含 blob 的区块,它必须通过 gossip 获取和验证另外 `3` 个数据列,总共 `5 + 3 = 8` 个数据列。

  • 注意 1: 节点继续仅广播保管 `5` 个数据列(其 ENR 中的 `csc` 值保持为 `5`)。
  • 注意 2: 节点不需要存储或服务为子网采样获取的 `3` 个额外数据列。

在这种情况下,节点总共订阅 `8` 个 `data_column_sidecar_<n>` 主题:对应于其保管数据列的 `5` 个主题和子网采样所需的 `3` 个额外主题。

要将一个区块标记为可用,必须成功检索和验证所有保管和子网采样列。

![image](https://hackmd.io/_uploads/B1avLy5GJg.png)

示例 2: 如果一个节点保管 `12` 个数据列,那么对于每个包含 blob 的区块,它不需要获取或验证任何额外的数据列。总数仍然是 `12 + 0 = 12` 个数据列,并且子网采样是一个无操作。

![image](https://hackmd.io/_uploads/Bk-UvkqMkg.png)

下图显示保管采样仅对不管理任何验证器的完整节点有效。

![image](https://hackmd.io/_uploads/B13fKsm5yl.png)

节点采样

[来源](https://github.com/ethereum/consensus-specs/blob/dev/specs/fulu/peer-sampling.md)

子网采样 中,一个节点将订阅 `8` 个数据列主题,同时仅通过其 ENR 和元数据保管和广播,例如,`4` 个数据列。

节点采样 中,节点订阅的确切数据列主题数与其广播的数据列主题数相同。

当节点收到一个包含 blob 的区块时,它会随机选择 `8` 个数据列,并使用 `DataColumnSidecarsByRoot` Req/Resp 消息从其直接节点采样这些数据列。

因此,节点实现了以下目标:

  • 保管某些列,这些列通过 gossip 获取和存储。
  • 通过 Req/Resp 协议检索某些数据列(尽管节点不需要服务这些列)。

![image](https://hackmd.io/_uploads/H1cWmM9fkg.png)

要将一个区块标记为可用,必须成功检索和验证所有保管和节点采样列。

数据列如何存储?

在 Prysm 中,数据列直接存储在文件系统中,使用的模式为 `blobs/<blockRoot>/<columnIndex>.ssz`。

节点保管列 `3`、`5`、`13` 和 `120` 的示例:

blobs
├── 0x00022463ed9299403b70d78cd0ab5049fc03eefdd0bf87108ee387587eadd06b
│   ├── 3.ssz
│   ├── 5.ssz
│   ├── 13.ssz
│   └── 120.ssz
├── 0x00026f77d57e29089085edf99bc79a37f67cdb844f01aa5f85435e77de3c5d2b
│   ├── 3.ssz
│   ├── 5.ssz
│   ├── 13.ssz
│   └── 120.ssz
├── 0x0002fd2893c692ac508b502ba31fbfe351738280af8e92acc397e456af888c7a
│   ├── 3.ssz
│   ├── 5.ssz
│   ├── 13.ssz
│   └── 120.ssz
├── 0x0003be159d8a3d04ccbc288dfb19b39eba35dfb9eba1788a966cd90d23426c21
│   ├── 3.ssz
│   ├── 5.ssz
│   ├── 13.ssz
│   └── 120.ssz
├── 0x0004d2a59f6ae7996a87a5b6e928b2fad0b864171dcf3bf609f74b8584f44722
│   ├── 3.ssz
│   ├── 5.ssz
│   ├── 13.ssz
│   └── 120.ssz
├── 0x000537721bdc9fb0de40e0f14220155eb9cb94dd46e9b73f0a0e6fd852fa5539
│   ├── 3.ssz
│   ├── 5.ssz
│   ├── 13.ssz
│   └── 120.ssz
...

重建

如果 Prysm 信标节点收到 `50%` 或更多的数据列(即 `64` 个或更多数据列),它会立即开始重建缺失的 `50%`。

插槽的 `3 秒` 后,节点会将它应该理论上收到的数据列(基于它对相应主题的订阅)与它实际收到的数据列进行比较。然后,信标节点会发送差值。

我们真的需要所有这些复杂性吗?

保持使用带有行子网的 EIP-4844 并要求每个节点仅保管 blob 的子集是否就足够了?

考虑以下场景:每个区块最多有 6 个 blob。与当前 EIP-4844 设计(其中所有节点都保管所有 blob)不同,在这个提议的(且有缺陷的)系统中,每个节点只需要保管 2 个子网。

现在,想象一下攻击者发起 DDoS 攻击,目标是负责保管给定子集 blob 的所有节点。在这种情况下,这些节点将完全无法服务相应的 blob。

因此,一些 blob——尽管已提交到区块——将不再可用。

![image](https://hackmd.io/_uploads/HJCIw2fgR.png)

:::warning

这正是我们想要防止的情况。 :::

现在使用列子网 纠删码:

示例:

![image](https://hackmd.io/_uploads/HyudqmN_Jg.png)

提取一个(扩展的)blob: ![image](https://hackmd.io/_uploads/ByAYq7Ndkg.png)

由于扩展的 blob 是 [纠删码](https://learnblockchain.cn/article/17626) 的,只要缺失的扩展 blob 不超过 50%,仍然可以重建扩展的 `256 kB` blob。

![image](https://hackmd.io/_uploads/HJQGoXVuyl.png)

最后,检索原始的、非扩展的 `128 kB` blob。

![image](https://hackmd.io/_uploads/BkPqUnGg0.png)

原始比较:没有 vs. 使用 PeerDAS

没有 PeerDAS(仅 Proto-Danksharding)

当仅考虑 blob 数据负载(不包括[Blob Sidecar](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/p2p-interface.md#blobsidecar) 中的附加数据,例如 `kzg_commitment` 或 `kzg_proof`)时:

  • 每个 blob 由 64 个单元格 组成。
  • 每个区块最多可以包含 6 个 blob
  • 每个单元格包含 2 kB 的数据。

这意味着一个节点负责存储多达: 64 × 6 × 2 kB = 768 kB 的 blob 数据(每个块)。

![image](https://hackmd.io/_uploads/ry8za7VdJe.png)

使用 PeerDAS

使用 PeerDAS,具有 4 个保管数据列和 4 个通过子网采样获取的额外数据列,并且仅考虑 blob 数据负载(不包括[Data Column Sidecar](https://github.com/ethereum/consensus-specs/blob/dev/specs/fulu/das-core.md#datacolumnsidecar) 中的其他数据,例如 `kzg_commitments` 或 `kzg_proofs`),同时保持总共 768 kB 的 blob 数据,我们可以定义以下内容:

  • 每个节点保管和采样 8 个数据列(每个块)。
  • 每个区块最多可以包含 48 个 blob
  • 每个单元格包含 2 kB 的数据。

这导致每个节点保管和采样多达: 8 × 48 × 2 kB = 768 kB 的 blob 数据(每个块)。

![image](https://hackmd.io/_uploads/B1mo144u1g.png)

仅关注 blob 数据并 忽略所有其他约束和潜在挑战,PeerDAS 使 Ethereum 网络能够实现 blob 数量的 8 倍 增长。

然而:

... 使用 PeerDAS 将 blob 吞吐量提高 8 倍可能“比我们想象的要困难一些”,并且在开发人员能够确定如何最好地推出与采样相关的代码更改之前,需要更多的研究和测试。 来源: [Galaxy.com (Terence Tsao)](https://www.galaxy.com/insights/research/ethereum-all-core-developers-consensus-call-149/)

  • 原文链接: hackmd.io/e3UGeZ7cS92uk8...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
e3UGeZ7cS92uk8b1SeVSyw
e3UGeZ7cS92uk8b1SeVSyw
江湖只有他的大名,没有他的介绍。