Arweave 是一个永久的数据存储网络。本文档描述了 2.6 版本,这是一个为了达成以下目标而做相关的升级。
Web3 正在加速发展,Arweave 作为基础设施将被更多的开发者采用,创造一个全新的、更加丰富多彩的生态系统。 PermaDAO 正是为此而建立起来的共建者社区。所以参与的人都能在这里找到自己的角色来贡献 Arweave 生态,任何关于 Arweave 的提案与任务都可以发布于此,并得到整个社区的支持与回馈。 加入PermaDAO,建设 Web3!
翻译自愿者:ethever @ Contributer of PermaDAO
审校自愿者:Xiaosong HU @ Contributer of PermaDAO
Arweave 是一个永久的数据存储网络。本文档描述了 2.6 版本,这是一个为了达成以下目标而做相关的升级:
<!--StartFragment-->
挖矿元素 | 描述 |
---|---|
Arweave 数据 | 有时又被称为 weave,Arweave 数据被分成统一的 chunk 块集合,这些 chunk 块可以均匀地分布在 Arweave 网络中。此外,这种存储模型支持一种通用的寻址方式,用于定位 weave 中任何地方的 chunk 块。 |
Chunk 块 | chunk 块是连续的区块数据,通常是 256KB 大小。这些 chunk 块的打包和哈希是矿工赢得生产新区块的权利并证明他们在 SPoRA 挖矿过程中确实存储了相关数据副本的方式。 |
Partition 分区 | Partition 分区是 2.6 版本中新引进的,它在 weave 层之上以 3.6TB 的间隔大小描述了一种逻辑分区方案。Partition 从 weave 的 0 位置开始索引,直至覆盖整个 weave(up to the block seeding the hash chain)。 |
Recall 区间 | Recall 区间是从 weave 中特定偏移量开始、长度为 100MiB 的连续 Chunk 块。 |
潜在解 | Recall 区间中每 256KiB 的偏移量就有一个挖矿谜题的潜在解(Potential solutions)。作为挖矿过程的一部分,每个候选的解都会被哈希以测试它是否满足网络的难度要求。如果是,矿工将获得生产新区块并获得挖矿奖励的权力。如果不是,矿工继续在 Recall 区间的下一个 256KiB 间隔挖矿。 |
哈希链 | 哈希链(Hash chain)是将某个哈希函数(这里特指 SHA-256)连续应用于一段数据而产生的。由于该过程无法并行化(并且消费级 CPU 有优化后的 SHA-256 电路),哈希链通过在操作之间要求一定数量的连续哈希来确保发生了延迟。 |
挖矿哈希 | 在足够数量的连续哈希(创建一秒的延迟)后,哈希链生成一个被认为对挖矿有效的哈希。值得注意的是, 挖矿哈希 在所有矿工中都是一致的,并且对所有矿工都是可验证的。 |
Arweave 寻求最大化网络中存储的副本数量。为此,它必须让“赢得挖矿竞争的机会”主要取决于矿工存储的副本数量。
在挖矿游戏中赢得挖矿谜题的解,要求将 recall 区间的 chunk 块打包成指定的格式。打包涉及向 RandomX 提供一个 打包密钥
(packing key),并让它在多次迭代中生成一个 2MiB 的熵暂存器。然后使用熵暂存器的前 256KiB 来加密 chunk 块。解包的工作方式相同,提供 打包密钥
,生成暂存器并使用前 256KiB 解密显示原始 chunk 块。
在 2.5 版本中,打包密钥是 chunk_offset
和 tx_root
串联后的值的 SHA256 哈希值。这确保了每个挖矿得到的解都来自特定区块中 chunk 块的唯一副本。如果一个 chunk 在 weave 的不同位置有多个副本,则每个副本都需要单独打包才能成为候选解(solution candidate)。
在 2.6 版本中,打包密钥被扩展成了 chunk_offset
、 tx_root
和 miner_address
串联后的值的 SHA256 哈希值。这意味着每个副本对于每个挖矿地址也是唯一的。
挖矿算法必须激励矿工构建完整的副本,从而在整个网络中实现统一的数据分布。必须强烈偏好单个完整副本,而不是多次复制的部分副本。
矿工可能采用的一种策略是存储部分数据集的多个副本。
按照这种策略,矿工同步 weave 中前 4 个 Partition 分区
,而不是用唯一的 Partition 分区
填充可用空间;他们复制相同的 4 个 Partition 分区,每个分区都被打包上不同且唯一的 挖矿地址
(mining address)。
<!--StartFragment-->
每次 mining hash
生成的时候,矿工都将它用在硬盘中保存的 Partition 分区的第一个 recall 区间。偶尔第二个 recall 区间落在它们存储的 Partition 分区里,这时他们才会顺便挖它。这保证了他们大概每秒有 400 个潜在解。
给定两个 recall 区间机制的更优策略是尽可能地存储更多唯一的 Partition 分区。下图对比了单个 mining address
有 16 个 Partition 分区和 4 个 Partition 分区复制多次然后用它们自己的 mining address
的情况。
<!--StartFragment-->
通过采用这种策略,矿工大大增加了第二个 recall 区间落在他们存储的 Partition 分区的机会。通常情况下每个 Partition 分区有两个 recall 区间。如果存储了所有 Partition 分区,矿工可以保证每个分区有 800 个潜在的解。
这为矿工们选择存储完整的副本而不是将部分副本复制多次创造了更显著的优势。
注意:每秒读取的数据量被限制为每个 Partition 分区两个 recall 区间。这限制了挖一个 Partition 分区所需的计算量,同时还随着 weave 的大小缩放以确保存储唯一的 Partition 分区始终是最有利可图的挖矿策略。
因为 recall 区间是连续的内存块,因此它们最大限度地减少了机械硬盘(HDDs)上的读取磁头的移动量。这种优化使得机械硬盘的读取性能与昂贵的固态硬盘(SSDs)保持一致,但成本更低。
使用双 recall 区间机制的一个结果是用来挖矿的硬盘的速度和空间之比能够被计算。这带来一个更加平衡的挖矿过程,任何因为更快的硬盘带来的收益都不能覆盖购买和操作这些硬盘的支出。
矿工可以选择每秒能够为每个 Partition 分区传输 4 个 recall 区间的昂贵的固态硬盘。这将使他们在评估潜在的解时较其他的硬盘具有轻微的速度优势,但与使用便宜的机械硬盘矿工相比,它每秒不会提供任何额外的解。更快的硬盘更昂贵,任何闲置时间都会以矿工为代价浪费这种速度的效用。
为了最大限度地减少能源挖矿消耗并确保能源支出用于验证完整副本的存储,挖矿算法必须为其它能源密集型挖矿策略创造递减的收益。
一个可选的挖矿策略是尝试利用计算机资源而不是存储。
为什么矿工要这么做呢?这里有很多原因,一个完全合理的场景是矿工已经在计算硬件上进行了大量投资(可能是为了挖另一个工作量证明的区块链)并且正在寻找最大化投资回报的方法。
矿工更愿意避免存储整个 weave 副本的成本。即使他们确实购买了所需的硬盘。每个 Partition 分区上限的两个 recall 区间也可能使他们的大部分计算资源闲置。为了充分利用他们的计算资源,他们必须存储多个副本并产生与相关的额外存储成本。矿工会尽可能避免资金成本。
矿工如何在不支付存储费用的情况下赢得挖矿竞争呢?
他们将需要访问无限的哈希源,他们可以使用这些哈希来将所有计算资源都放在一个存储分区上。当哈希链每秒只产生一次有效的挖矿哈希时,他们怎么才能这样做到呢?
矿工不会依赖存储尽可能多的分区来最大化潜在解,而是根据需要生成尽可能多的挖矿地址以使他们的计算饱和。但这如何可行?潜在解需要与 miner_address
一起打包才能被视为有效。这是否需要存储为每个挖矿地址打包的分区副本,从而产生额外的存储成本?相反,如果矿工将分区存储为原始的未打包块会怎样。然后,在评估每个挖矿地址时的 recall 区间时,矿工可以使用他们的计算资源按需打包区块。
<!--StartFragment-->
假设存储一个完整的副本并遵循每个分区上限两个 recall 区间,并且每秒产生 100k 个潜在解。如果以计算为中心的矿工能够测试 100k+ 潜在解(仅受可用计算量限制)研磨挖矿地址,他们就可以在挖矿竞争中获得优势。如果有利可图,这可能成为主要的挖矿策略,对数据复制产生负面影响,并破坏 Arweave 永久存储协议。
阻止研磨挖矿地址的关键是确保为挖矿地址按需打包块解决方案所需的成本(时间和精力)远大于为同一地址存储预打包块。
为确保按需打包既耗时又耗能,打包函数包含一个 PACKING_DIFFICULTY
参数。此参数指定生成有效暂存器所需的随机 X 轮数,用作打包密码的熵。
必须在使新 chunk 块的打包速度足够以至于网络的写入吞吐量在不受影响和足够困难之间取得平衡,以至于按需打包的效率明显低于从磁盘读取预先打包的 chunk 块。
2.6 版本将 PACKING_DIFFICULTY
设置为每 chunk 块 45*8 个随机 X 程序,这大约需要 30 个标准随机 X 哈希的时间。这在限制按需打包的速度和矿工一天可以打包的数据量之间取得了合理的平衡。
注意:在 30 次 RandomX 迭代中,16 核 AMD Epyc 7313 在一天内打包大约 20.5TiB。
即使按需打包对于一个 CPU 来说速度较慢,如果跨多个 CPU 按需打包的能源成本与操作充满预打包副本的硬盘的能源成本相近,那么研磨挖矿地址攻击可能你仍然有利可图。
我们制作了一个计算器来探索权衡,建议选择协议参数(recall 区间大小、Partition 分区大小、PACKING_DIFFICULTY 等)以使打包完整副本成为最经济可行的策略。计算器页面链接(源码)
该计算器计算操作按需打包的成本是操作预打包副本的 19.86 倍(在计算器中标记为“On-Demand Cost/Honest Cost”)。
Arweave 上的存储价格的核心是由存储 1GB 数据一小时或 $P_{GBH}$ 的价格决定的,如下式所示: <!--StartFragment-->
其中 $HDD{price}$ 是硬盘在网络上的市场价格,$HDD{size}$ 是以 GB 为单位的硬盘容量,$HDD_{MTBF}$ 是硬盘的平均故障时间。 <!--EndFragment-->
注意:查看 Arweave 黄皮书 获取永久存储价格的详情。
2.5 版本重新引入了基于难度的动态定价,价格每 50 个区块调整一次,幅度在 +/-0.5% 的范围内。
2.5 版本中难以计算的是矿工使用的硬盘的速度。因为更快的硬盘比较慢的硬盘会更贵,所以 $HDD{price}$ 需要估计网络的平均硬盘速度。在 2.6 版本中,协议描述了一个最大的激励硬盘速度,它构成了计算 $HDD{price}$ 的基础。
硬盘需要每秒为每个分区产生两个 recall 区间
的潜在解。每个 recall 区间大小为 100MiB,我们可以声明硬盘必须具有能够每秒为每个存储的 3.6TB 分区传输 200MiB 的带宽。任何超过此目标带宽的硬盘性能都是浪费,会对矿工的盈利能力产生负面影响。部署带宽略低于所需带宽的硬盘意味着矿工的利润也会减少,因为它们没有竞争力。这为计算 $HDD_{price}$ 提供了坚实的基础,并消除了价格计算对平均硬盘速度的依赖。
从这里我们可以检查网络的难度以确定哈希率并从中计算储存的分区数。这是可能的,因为在峰值利用率分区每秒产生 800 个哈希(两个 recall 区间提供的潜在解的数量)。我们可以查看网络的每秒哈希率,并计算必须存储的分区数以产生该哈希数。因为该协议鼓励存储唯一分区,我们可以将(partition_count * 3.6TB)除以 weave_size 并计算副本的近似数量。
为了提供可靠的服务,本协议必须收取足够的价格来资助目标数量的副本,以便在发生灾难性故障时,至少有一个副本可以存活足够长的时间来制作新的副本。
我们对现代硬盘的平均故障时间进行了研究,并得出结论,15 个副本是确保 Arweave 上的数据持久性的保守最小值。有关我们如何得出这些结论的详细信息,请在 此处 查看我们的方法。
因此这些因素构成了计算在网络上充分复制数据以确保其长期生存所需的最低费用的基础。
接受新区块的一部分工作是验证它们是否正确地生成。如果验证器与区块生产者同步,他们将能够从他们自己最近生成的 挖矿哈希
中验证新区块的 挖矿哈希
。
在验证者不在哈希链当前头部的情况下,每个区块包括 25 个 40ms 的检查点(checkpoint)。这些检查点的每一个都是连续哈希 40ms 的结果,并且在组装时代表与先前区块 挖矿哈希
的一秒间隔。
在验证器向其对等方传播新收到的区块之前,它会快速并行验证前 25 个检查点。如果验证了 40ms 检查点,则该区块被传播并且验证了完整的检查点序列。
完整的检查点验证是通过并行哈希剩余的检查点来完成的。前 25 个检查点之后是 500 个一秒检查点,然后是 500 个两秒检查点,对于随后的每组 500 个检查点,检查点间距加倍。
在哈希链的头部产生新的 挖矿哈希
必须按顺序进行,但在此过程中生成的检查点可以并行验证。这允许验证区块的 挖矿哈希
相较于创建该 哈希链
花费更少的时间。
<!--StartFragment-->
注意:虽然对于区块头部可能包含的检查点数量没有协议限制,因为区块通常约 2 分钟生成一次,检查点的数量可能少于 200。
如果某个矿工或矿池有一个稍微更快的 SHA256 实现,则其 哈希链
可能会跑在网络的其余部分之前。随着时间推移,这种微小的速度优势可能会累积成大量的 哈希链
漂移,从而使其产生的 挖矿哈希
与其余验证器不同步。这可能导致许多不必要的分叉和重组场景。
为了减少 哈希链
漂移的可能性,Arweave 以固定间隔将全局 哈希链
与历史区块的熵同步。这每隔一段时间就为 哈希链
提供一个新的种子,其效果是在一个众所周知的和已确认的区块上同步各个矿工的 哈希链
。
<!--StartFragment-->
注意:该 哈希链 从 2.6 硬分叉区块之后的第 50 个区块哈希开始。
哈希链
间隔锚定到哈希链,每 50 * 120 个 挖矿哈希
选择一个新的种子区块。这会将种子区块放置在大约 50 个 Arweave 区块之间,但由于区块时间存在一些差异,种子区块可能会早于或晚于 50 个区块出现。
关于 PermaDAO:Website | Twitter | Telegram | Discord| Medium | Youtube
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!