本文总结了Base链对OP Stack中的Fault Proof组件进行的基准测试,以确保其在扩展过程中保持稳定。
Base 最近在主网上启动了故障证明,这标志着我们在逐步去中心化道路上的一个重要里程碑。故障证明允许任何人参与保护 Base,创建一个更值得信赖和开放的经济体。故障证明的一个核心属性是,如果至少有一个诚实的参与者,或“挑战者”参与故障证明游戏,那么游戏应该正确解决。它们是 Base 堆栈的关键组件,并且随着我们不断提高 Base 的吞吐量,我们需要确保我们的扩展工作不会引入与故障证明的任何不兼容性。因此,我们启动了一项专门的计划,旨在分析 OP Stack 中的故障证明系统将如何受到我们的扩展工作的影响,并确保我们能够继续安全地扩展故障证明。如今,Base 的故障证明系统利用了 Cannon 故障证明虚拟机 (FPVM)。你可以在此处阅读更多关于 OP Stack 中故障证明的信息。
Cannon 是 OP Stack 支持的第一个故障证明 VM (FPVM)。它结合了链上和链下组件,以便在 EVM 内部有效地运行 EVM,确保任何状态转换都可以被审计,并被无需许可地挑战。与仅确保交易具有确定性输出(例如,余额和代币转账)的典型以太坊实现不同,Cannon FPVM 模拟了一台以确定性方式运行的计算机——精确到单个 MIPS 指令——同时运行其自身的 EVM 实例。
鉴于与故障证明相关的复杂性,今天的 Cannon 实现包含某些简化。Cannon 实现了一组最少的 unix 系统调用——刚好足够分配内存、读取和写入 preimage oracle,并优雅退出。值得注意的是,这不包括与创建和管理线程或其他并发原语相关的 syscall。由于 Cannon 是用 Go 编写的,Go 是一种为并发代码优化的垃圾回收语言,因此存在一些缺点。最重要的是,Cannon 一旦不再需要就无法清理内存,导致 footprint 不断增长,直到程序完成或达到 32 位 MIPS 架构施加的硬性限制。这意味着每次 Cannon 执行都对可用内存有硬性约束。由于执行行为完全是确定性的(故障证明系统的一个基本属性),任何导致 Cannon 耗尽内存的输入都将始终导致其失败。
Cannon 不仅在与其内存限制赛跑,而且还在与时间赛跑。Base 提供了一个设定的时间窗口,供任何人验证或挑战发布回 L1 的状态。在有两名玩家的故障证明争议游戏中,每个玩家只有 3 天多的时间从头到尾运行 Cannon 才能参与。由于 Cannon 提供了多个虚拟机抽象层,并针对确定性进行了优化,因此在 Cannon 上执行 block 的速度比在标准 Base 节点上慢很多个数量级。
为了在这些限制下安全地将故障证明发布到主网,我们需要确保所有 block 始终都是可证明的——尤其是在提高我们的 gas 目标时。换句话说,任何 block 组合都不能通过占用过多时间和内存来“破坏”Cannon。这当然意味着我们需要尽可能多地对系统进行压力测试。
为了应对这一挑战,我们构建了一个开源工具,用于在本地 devnet 中生成可重复的故障证明测试用例。我们首先在 Cannon 之外生成和执行这些测试,以更快地开发和迭代,然后将它们在较慢的 Cannon 环境中运行,以进行比较和指标收集。
每个测试场景都包含一个配置了给定 gas 目标的单个交易。此交易将部署一个合约,该合约将重复执行特定的操作模式,直到达到或超过 gas 目标。每个合约和相关的 forge 脚本都在上面链接的测试存储库中定义。这些测试场景以 4 个 gas 目标执行:1Mgas、2Mgas、3Mgas 和 20Mgas,以便生成和验证线性缩放模型,然后该模型使我们能够预测包含具有相同特征的 100Mgas 的 block 的影响。测试覆盖范围包括 ETH 转移、ERC20 转移、存储写入、存储读取、合约部署以及大多数预编译合约。我们省略了对 Cannon 中的资源约束没有风险的预编译,例如那些可以卸载到 L1 EVM 的预编译。
对于每个测试用例,我们专门评估了 Cannon MIPS 指令计数、内存使用情况和实际运行时间。我们在一个性能低于我们的生产挑战者的运行时环境中执行了这些测试。从这个基线开始,我们再次向下取整到一个非常保守的每秒 10M 指令的执行速度,以便预测每个测试装置的最坏情况挑战者证明时间。
从这些测试中,我们确定了两种在使用模式方面最突出的资源约束,即 p256Verify 和 ECAdd 预编译,如下详述。重要的是,我们验证了这些约束不会将我们的扩展工作限制在 60Mgas/秒以下。
p256Verify 预编译(在 RIP-7212 中引入)消耗每个 gas 单位最多的 Cannon 指令,并且不能简单地使用现有的 L1 预编译 preimage 执行模式在链上 MIPS.sol 合约中加速,因为它尚未部署在 L1 上。以每个 gas 大约 10,000 条 Cannon 指令,并使用极其保守的每秒 10,000,000 条指令的执行估计值,p256Verify 预编译可能消耗每个 gas 约 1 毫秒。在更高的 block gas 限制 100Mgas 下,以这些性能特征执行可能需要长达 28 小时。幸运的是,这仍然远低于约 3.5 天的挑战超时,并且对挑战者设置的 minor 改进,例如更快的硬件或软件优化,可以大大缩短此持续时间。
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 17,049,500,014 | 131.29 MB | 1,277,339 |
2Mgas | 2,000,000 | 27,803,520,661 | 129.99 MB | 1,878,936 |
3Mgas | 3,000,000 | 38,780,421,364 | 133.84 MB | 2,585,735 |
20Mgas | 20,000,000 | 210,254,748,805 | 155.70 MB | 13,078,063 |
估计值 | ||||
20Mgas | 20,000,000 | 223,456,106,163 | 154.60 MB | 13,689,567 |
100Mgas | 100,000,000 | 1,224,139,467,745 | 288.95 MB | 75,132,093 |
p256Verify:给定实际和估计 gas 使用量的内存使用量和运行时(毫秒)
ECAdd 预编译显示了相对于 gas 使用量的最大内存消耗率,约为每 gas 7 字节。验证一个主要由 ECAdd 预编译组成的 20Mgas block 需要大约 250MB 的 Cannon 内存(包括大约 135MB 的 L1 block 开销),这表明遵循此模式的 100Mgas block 可能会使用大约 690MB 的内存。这仍然远低于 32 位 MIPS Cannon 堆限制(约 1.1GB),并且允许在真实 L1 block 的典型消耗之上有高达 2 倍的误差裕度。
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 7,018,067,400 | 143.96 MB | 549,523 |
2Mgas | 2,000,000 | 7,614,519,602 | 150.25 MB | 584,388 |
3Mgas | 3,000,000 | 8,483,630,982 | 162.28 MB | 643,260 |
20Mgas | 20,000,000 | 15,553,134,512 | 250.38 MB | 1,241,447 |
估计值 | ||||
20Mgas | 20,000,000 | 20,895,478,233 | 317.06 MB | 1,436,023 |
100Mgas | 100,000,000 | 50,658,462,679 | 689.75 MB | 4,134,394 |
ECAdd:给定实际和估计 gas 使用量的内存使用量和运行时(毫秒)
由于加速的预编译、存储读取/写入、合约部署或 ETH 或简单 ERC-20 代币的转移导致 gas 消耗的 modest 增加,指令计数、内存使用量和实际运行时间没有实质性增加。与其他简单的 EVM 字节码相比,其他非加速预编译(如 SHA256 和 ECMul)消耗了相对大量的指令和内存,但即使在大大增加的 block gas 限制下,也不足以对故障争议游戏的完整性构成任何风险。
另一个重要的发现是,Cannon 的资源使用量不仅受正在验证的单个 L2 block 内容的影响,还受同一 span batch 中包含的所有 L2 block 内容的影响。这意味着,即使单个 block 可能需要包含约 200Mgas 的 ECAdd 预编译才能破坏 Cannon(远远超过今天的 gas 限制),但包含 10 个 block 的 span batch 也可以轻松超过这个限制,并且还有剩余空间。为了降低这种风险,我们将 Base 主网的 span batch gas 限制设置为非常保守的 120Mgas,并根据每个 block 的 gas 限制限制每个 batch 的 L2 block 数量。
随着 Base 每 2 秒构建一个 block,并且每个 block 的限制为 120Mgas,我们可以在当前版本的 Cannon 上扩展到大约 60Mgas/秒。这比我们今天的水平大约增加了 3 倍,但远低于我们的 1Gigagas/秒的 north star 目标。幸运的是,目前正在进行许多工作流程,这将有助于与我们的目标一起扩展故障证明。
OP Stack 贡献者目前正在开发对 Cannon 的两项重大升级,这将解决内存限制,并在许多较小的改进和优化的基础上:多线程 (MT) 和 64 位 Cannon。MT Cannon 将引入运行时垃圾回收,防止内存使用量以无限的方式增长。此外,将 Cannon 从 32 位 MIPS 架构迁移到 64 位架构将允许堆增长许多数量级,从而有效地为运行时提供无限内存。多线程和 64 位 Cannon 目前正在接受审计,应该可以在未来几个月内上线测试网。
此外,Base 工程团队正在与其他 OP Stack 核心贡献者合作开发即将推出的 Holocene OP Stack 硬分叉。此升级增加了 partial span batch 验证,通过消除故障证明程序执行 batch 中所有 L2 block 的需求来减少资源约束
既然我们已经开发了一套基本的故障证明测试、工具和参考数据,我们计划对 OP Stack 的所有未来更改进行基准测试,以确保我们能够继续安全地扩展 Base 和更广泛的 Superchain,并将世界带入链上。
为了透明起见,我们在下面包含了我们每次测试的原始数据。所有测试均使用从 v1.9.1 op-stack 版本 构建的 Cannon 和 op-program 二进制文件,使用 go 1.21。
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 5,623,138,719 | 111.39 MB | 381,827 |
2Mgas | 2,000,000 | 6,928,151,521 | 132.27 MB | 492,737 |
3Mgas | 3,000,000 | 6,767,001,159 | 129.62 MB | 463,468 |
20Mgas | 20,000,000 | 6,785,483,671 | 129.92 MB | 448,499 |
估计值 | ||||
20Mgas | 20,000,000 | 16,734,192,426 | 288.43 MB | 1,180,780 |
100Mgas | 100,000,000 | 8,745,359,260 | 161.04 MB | 490,610 |
观察到的错误 | ||||
20Mgas | 20,000,000 | -146.62% | -122.01% | -163.27% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 6,204,271,686 | 131.99 MB | 452,159 |
2Mgas | 2,000,000 | 6,310,449,198 | 131.40 MB | 413,534 |
3Mgas | 3,000,000 | 6,589,280,079 | 133.50 MB | 482,149 |
20Mgas | 20,000,000 | 11,317,368,094 | 170.07 MB | 791,432 |
估计值 | ||||
20Mgas | 20,000,000 | 9,833,075,858 | 145.90 MB | 719,191 |
100Mgas | 100,000,000 | 33,251,618,820 | 336.95 MB | 2,309,041 |
观察到的错误 | ||||
20Mgas | 20,000,000 | 13.12% | 14.21% | 9.13% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 5,765,573,364 | 127.43 MB | 523,396 |
2Mgas | 2,000,000 | 5,779,242,866 | 127.70 MB | 564,251 |
3Mgas | 3,000,000 | 5,794,625,704 | 128.22 MB | 554,143 |
20Mgas | 20,000,000 | 6,258,738,250 | 138.29 MB | 669,946 |
估计值 | ||||
20Mgas | 20,000,000 | 6,041,285,038 | 134.86 MB | 823,986 |
100Mgas | 100,000,000 | 8,378,069,765 | 184.85 MB | 1,221,734 |
观察到的错误 | ||||
20Mgas | 20,000,000 | 3.47% | 2.48% | -22.99% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 5,933,015,834 | 127.08 MB | 513,891 |
2Mgas | 2,000,000 | 6,290,868,310 | 129.71 MB | 540,739 |
3Mgas | 3,000,000 | 6,300,316,628 | 127.04 MB | 559,180 |
20Mgas | 20,000,000 | 9,431,852,148 | 126.98 MB | 805,725 |
估计值 | ||||
20Mgas | 20,000,000 | 9,480,440,737 | 127.57 MB | 945,538 |
100Mgas | 100,000,000 | 23,909,994,957 | 122.71 MB | 2,001,824 |
观察到的错误 | ||||
20Mgas | 20,000,000 | -0.52% | -0.47% | -17.35% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 5,777,467,988 | 127.69 MB | 524,860 |
2Mgas | 2,000,000 | 5,973,143,239 | 130.88 MB | 555,883 |
3Mgas | 3,000,000 | 5,998,996,944 | 131.45 MB | 536,078 |
20Mgas | 20,000,000 | 6,164,316,368 | 137.03 MB | 564,437 |
估计值 | ||||
20Mgas | 20,000,000 | 7,910,296,661 | 163.85 MB | 639,902 |
100Mgas | 100,000,000 | 7,339,598,094 | 169.39 MB | 680,956 |
观察到的错误 | ||||
20Mgas | 20,000,000 | -28.32% | -19.57% | -13.37% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 5,983,226,628 | 128.70 MB | 473,537 |
2Mgas | 2,000,000 | 6,201,949,185 | 130.35 MB | 498,090 |
3Mgas | 3,000,000 | 6,232,516,126 | 128.73 MB | 485,517 |
20Mgas | 20,000,000 | 9,330,323,559 | 153.91 MB | 683,860 |
估计值 | ||||
20Mgas | 20,000,000 | 8,382,836,128 | 129.52 MB | 593,535 |
100Mgas | 100,000,000 | 23,472,781,822 | 262.44 MB | 1,560,676 |
观察到的错误 | ||||
20Mgas | 20,000,000 | 10.15% | 15.85% | 13.21% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 6,031,109,395 | 130.37 MB | 476,236 |
2Mgas | 2,000,000 | 6,243,997,347 | 133.59 MB | 458,634 |
3Mgas | 3,000,000 | 6,432,598,100 | 135.40 MB | 521,362 |
20Mgas | 20,000,000 | 8,476,207,979 | 162.85 MB | 598,232 |
估计值 | ||||
20Mgas | 20,000,000 | 9,849,299,959 | 178.39 MB | 891,545 |
100Mgas | 100,000,000 | 18,491,349,238 | 295.63 MB | 1,112,098 |
观察到的错误 | ||||
20Mgas | 20,000,000 | -16.20% | -9.54% | -49.03% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 5,933,015,834 | 127.08 MB | 513,891 |
2Mgas | 2,000,000 | 6,290,868,310 | 129.71 MB | 540,739 |
3Mgas | 3,000,000 | 6,300,316,628 | 127.04 MB | 559,180 |
20Mgas | 20,000,000 | 9,431,852,148 | 126.98 MB | 805,725 |
估计值 | ||||
20Mgas | 20,000,000 | 9,480,440,737 | 127.57 MB | 945,538 |
100Mgas | 100,000,000 | 23,909,994,957 | 122.71 MB | 2,001,824 |
观察到的错误 | ||||
20Mgas | 20,000,000 | -0.52% | -0.47% | -17.35% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 5,875,453,802 | 128.06 MB | 441,286 |
2Mgas | 2,000,000 | 5,816,233,429 | 126.04 MB | 450,449 |
3Mgas | 3,000,000 | 6,104,706,376 | 129.61 MB | 459,738 |
20Mgas | 20,000,000 | 7,940,103,065 | 144.32 MB | 577,400 |
估计值 | ||||
20Mgas | 20,000,000 | 7,995,404,368 | 141.91 MB | 616,559 |
100Mgas | 100,000,000 | 16,866,767,431 | 217.19 MB | 1,143,100 |
观察到的错误 | ||||
20Mgas | 20,000,000 | -0.70% | 1.67% | -6.78% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) |
样本 | ||||
1Mgas | 1,000,000 | 6,118,592,793 | 132.25 MB | 444,495 |
2Mgas | 2,000,000 | 6,291,711,082 | 133.95 MB | 480,941 |
3Mgas | 3,000,000 | 6,444,682,546 | 136.32 MB | 486,372 |
20Mgas | 20,000,000 | 8,167,690,035 | 156.55 MB | 567,438 |
估计值 | ||||
20Mgas | 20,000,000 | 9,219,803,251 | 170.82 MB | 847,496 |
100Mgas | 100,000,000 | 16,579,834,836 | 256.57 MB | 1,009,693 |
观察到的错误 | ||||
20Mgas | 20,000,000 | -12.88% | -9.12% | -49.35% |
标签 | Gas 使用量 | 指令 | 内存使用量 | 运行时 (ms) | |
样本 | |||||
1Mgas | 1,000,000 | 6,898,305,181 | 128.29 MB | 511,359 | |
2Mgas | 2,000,000 | 8,407,611,074 | 131.24 MB | 625,084 | |
3Mgas | 3,000,000 | 9,774,154,416 | 131.31 MB | 721,918 | |
20Mgas | 20,000,000 | 33,206,433,070 | 129.59 MB | 2,071,668 | |
** | |||||
--- | --- | --- | --- | --- | |
标签 | Gas 使用量 | 指令数 | 内存使用量 | 运行时间 (ms) | |
加粗Samples加粗 | |||||
1Mgas | 1,000,000 | 5,948,955,650 | 132.48 MB | 440,868 | |
2Mgas | 2,000,000 | 6,071,516,330 | 137.65 MB | 433,790 | |
3Mgas | 3,000,000 | 6,170,595,841 | 140.73 MB | 441,160 | |
20Mgas | 20,000,000 | 7,199,877,925 | 171.29 MB | 504,847 | |
加粗Estimates加粗 | |||||
20Mgas | 20,000,000 | 8,058,450,993 | 211.24 MB | 441,234 | |
100Mgas | 100,000,000 | 12,286,011,877 | 325.56 MB | 796,554 | |
加粗Observed Error加粗 | |||||
20Mgas | 20,000,000 | -11.92% | -23.32% | 12.60% |
标签 | Gas 使用量 | 指令数 | 内存使用量 | 运行时间 (ms) |
加粗Samples加粗 | ||||
1Mgas | 1,000,000 | 5,977,197,865 | 131.11 MB | 413,460 |
2Mgas | 2,000,000 | 6,022,014,219 | 132.55 MB | 420,963 |
3Mgas | 3,000,000 | 5,892,528,187 | 130.86 MB | 411,115 |
20Mgas | 20,000,000 | 6,494,391,967 | 150.27 MB | 496,198 |
加粗Estimates加粗 | ||||
20Mgas | 20,000,000 | 5,201,886,322 | 129.22 MB | 394,074 |
100Mgas | 100,000,000 | 8,797,267,453 | 232.79 MB | 851,951 |
加粗Observed Error加粗 | ||||
20Mgas | 20,000,000 | 19.90% | 14.01% | 20.58% |
- 原文链接: blog.base.dev/scaling-ba...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!