Holešky Pectra 事件事后分析

  • ethereum
  • 发布于 2025-03-21 15:36
  • 阅读 12

Holešky 测试网在 Pectra 升级后由于执行层客户端配置错误的存款合约地址导致网络分裂,Erigon 和 Reth 正确拒绝了无效区块,而 Geth、Nethermind 和 Besu 接受了,大多数节点跟随了无效链,共识客户端难以同步到正确的链,通过协调运营商遵循正确的链,最终使网络恢复。但这也导致了测试窗口缩短,网络被 Hoodi 替代。

Holešky Pectra 事件事后分析

作者:Tim Beiko, Mario Havel

状态:已解决

日期:2025 年 3 月 20 日

当前状态

Holešky 网络已成功恢复。在没有最终确定性的情况下运行 2 周后,该链于 3 月 10 日 19:21 UTC 在 epoch 119090 再次最终确定。

恢复是通过协调运营商遵循正确的链,直到参与验证器达到足够的数量以实现最终确定性来实现的。此后,参与度持续缓慢上升,网络看起来稳定。详细的恢复工作和最初的验证器指南如下所述。

在达到最终确定性后,共识开始处理验证器事件,退出队列在接下来的约 1.5 年内已满。因此,完整的验证器生命周期测试和其他 Electra 测试(如合并)是不可能的。Holešky 长期支持窗口已缩短,为了立即进行测试,该网络已被 Hoodi 取代。

恢复工作

最初在 ACDE#206 中计划的,通过禁用 slashing 保护来协调 slashing 的策略并未成功。ACDC#152 讨论了结果和新的选项。在那个时候,slashings 和协调验证器以遵循正确的分叉并没有达到必要的 66% 阈值,网络仍然处于长期未最终确定状态。这种情况是共识客户端没有设计的,并导致显著的资源开销。客户端团队实施了修复和缓解措施,允许客户端即使在长时间的未最终确定状态下也能更高效地运行。

ACDC#152 之后,基于概述的策略,PandaOps 发起了另一项协调工作,以实现网络的最终确定性,计划持续到 3 月 12 日。一项分析表明,由于 3 月 28 日左右的非活跃泄漏,网络最终将达到最终确定性。然而,这将导致损失大量时间来测试 Pectra,因此该策略旨在在 3 月 12 日之前再次尝试。作为替代方案,如果这种方法不成功,将创建一个最后最终确定状态的影子分叉,作为替代测试环境。

随着参与度缓慢增加,目标是在 3 月 12 日之前提示尽可能多的验证器连接到正确的网络。这在 3 月 10 日晚上成功实现。创建了正确链的新的最终确定 epoch,客户端可以使用它再次正常同步。

<details> <summary>恢复的原始验证器说明</summary>

Holešky 验证器参与并为恢复做出贡献的原始说明:

EL 客户端需要使用完整同步而不是快照同步。这应该是包含修复的发行版中的默认配置。

协调 Slashings

ACDE#206 上,客户端团队决定尝试协调在 slot 3737760 (2 月 28 日,UTC 时间 15:12:00) 附近的批量 Holešky slashings。 目标是让网络达到足够的在线验证器,以便同时在有效链上最终确定一个 epoch

禁用 Slashing 保护

每个客户端禁用 slashing 保护的说明:

Grandine

rm ~/.grandine/holesky/validator/slashing_protection*

Lodestar

  1. 确保你的配置 使用 doppelganger 保护
  2. 停止验证器客户端
  3. 通过运行 rm -r &lt;dataDir>/validator-db 删除 slashing 保护数据库
  4. 启动验证器客户端

Lighthouse

参见 https://github.com/sigp/lighthouse/issues/7040

Nimbus

rm ~/.cache/nimbus/validators/slashing_protection.sqlite3

请注意,确切的路径将取决于个人配置。如果节点没有干净地关闭,用户可能还需要删除 SQLite WAL 文件,例如 slashing_protection.sqlite3-walslashing_protection.sqlite3-shm

Prysm

将以下 CLI 参数添加到验证器客户端 而不是信标节点,然后重新启动验证器客户端 而不是信标节点--force-clear-db

Teku

  1. 确保你的配置未使用 doppelganger 保护 (--doppelganger-detection-enabled)
  2. 停止 Teku
  3. 删除 slashing 保护文件:rm &lt;teku_data_directory>/validator/slashprotection/*
  4. 启动 Teku

Vouch/Dirk

参见 https://github.com/attestantio/vouch/issues/304

Web3Signer

参见 https://docs.web3signer.consensys.io/concepts/slashing-protection

客户端发布和资源

对原始 Pectra 测试网公告 中列出的版本的更新

执行层已发布的修复程序:

  • Geth: v1.15.3 及后续版本
  • Nethermind: v1.31.1 及后续版本
  • Besu: 25.2.1 及后续版本
  • Reth 和 Erigon: 无需更新(正确处理了存款合约)

共识层修复:

共识层团队一直在发布补丁,以改进分支机构和 docker 版本上的对等连接和同步。以下信息截至 3 月 10 日 UTC 时间 19:00 准确。此 HackMD 文档 可能包含更新的信息。

  • Lighthouse
  • Lodestar:
  • Prysm:
    • 分支: hackSync
    • Docker 镜像: ethpandaops/prysm-beacon-chain:hackSync-a9dc6a1
  • Nimbus
    • 分支: splitview
    • Docker 镜像: ethpandaops/nimbus-eth2/splitview-49a5263
  • Grandine
  • Teku:
    • 分支: master
    • Docker 镜像: consensys/teku:develop

有用资源:

</details>

来自客户端团队的事后分析

根本原因分析

执行层问题

最初问题的根本原因是几个执行客户端(Geth、Nethermind 和 Besu)为 Holešky 测试网配置了不正确的存款合约地址。具体来说:

  • Holesky 的存款合约地址应该是 0x4242424242424242424242424242424242424242
  • 一些 EL 客户端正在使用主网存款合约地址,或者没有为 Holesky 进行特定配置,导致它们使用 0x0000...0000

当包含存款交易的区块在 slot 3711006 (区块 3419724)被提议时,这些客户端使用一个空的请求列表处理了它,导致了不正确的请求哈希。这导致了一个网络分裂 ,其中:

  • Erigon 和 Reth 正确地拒绝了这个无效区块
  • Geth、Nethermind 和 Besu 接受了这个无效区块

有问题的存款交易可以在以下位置找到:https://holesky.etherscan.io/tx/0x48d5201b36db1122ce4d67367d03ad97d7c2e5b497c324843496230859be1bc7/advanced#eventlog

之前在 devnetsEphemery 上的 Pectra 激活没有触发这个问题,因为那些网络使用手动初始化的创世区块进行操作。

共识层问题

一旦网络分裂发生,出现了一个次要问题:共识客户端难以同步到正确的链。这是由于:

  1. 大多数节点跟随无效链
  2. 无效链在 epoch 115968 中达到 justified 状态 (虽然没有 finalized),使其成为主导链
  3. 共识客户端在他们无法在有效链上找到足够多的对等节点时进入 “同步” 模式
  4. 验证器在他们的信标节点处于 “同步” 模式时没有生产区块
  5. 在证明无效链后,Slashing 保护阻止验证器证明正确的链

无效链的 justification 创造了一个特别具有挑战性的情况。这种 justification 意味着曾经证明过无效链上的 justified 检查点的验证器,如果他们尝试证明正确的链将面临 “环绕” slashing 条件。

这创建了一个负反馈循环,其中有效链只有少量区块和少量对等节点,使其越来越难以同步到它。这种情况因共识客户端被设计为跟随具有最多证明权重的链而加剧,并且在这种情况下,该链是无效链。

根本原因补救措施

验证配置和分叉参数化

必须更好地验证配置和分叉参数,并且 genesis 配置正在跨客户端标准化。 EL 客户端正在实现一种新的 RPC 方法,以启用检索和验证正确的配置。eth_config。不兼容的配置会导致早期错误。

用户指定的未最终确定检查点同步

客户端将启用自定义检查点同步区块,并提高即使从任意未最终确定的检查点进行同步的功能。这将使用户能够在特定的链周围进行社交协调,强制客户端同步到该链。 进一步的改进可以是基于领导者的协调系统,用于正确的链识别和修复无效的链修剪功能。

例如,Prysm 添加了 “从头部同步” 功能 (PR #15000,更多计划 #14988),geth 正在开发类似的功能 #31375,Teku 考虑了它,但它的代码库在很大程度上依赖于最终确定的源来启动同步

进一步的问题和缓解措施

除了最初的根本问题外,该事件还揭示了由于长时间非最终确定性的极端情况而引起的许多其他问题,特别是对于 CL 客户端。客户端实施了更多修复和改进。

跨共识客户端的问题

高资源使用率

随着非最终确定性持续时间的延长,大多数客户端最终都存在过度的内存使用率和性能下降的情况(例如,Prysm/Geth 机器的 RAM 使用率超过 300GB)。如果没有最终确定的检查点写入数据库,客户端必须在内存中存储大量数据。

分叉选择问题

具有无效区块的不正确链被 justify,给分叉选择造成了问题。客户端必须处理许多竞争性分叉,而正确的分叉是少数,没有 justification

对等节点发现和连接问题

即使通过手动 ENR 共享和协调,所有客户端都难以在正确的链上找到对等节点。对等节点评分和许多并发分叉使得难以找到一个好的对等节点。

Slashing保护问题

每个客户端团队都需要自定义程序来管理 slashing 保护。对于证明无效链的验证器来说,环绕 slashing 条件是一个问题。

客户端特定的改进

  • Lighthouse

    • 正在开发 “热树状态” 功能,以便在非最终确定期间更有效地将数据存储在热数据库中。允许以类似于冷数据库的方式将数据存储在磁盘的热数据库中,而不会占用过多的磁盘空间。
    • 添加了 lighthouse/add_peer 端点,以帮助节点找到规范链对等节点,尤其在使用 --disable-discovery 时非常有用
    • 优化了 BlocksByRange 以尽可能从分叉选择中加载
    • 添加了 --invalid-block-roots 标志以自动使有问题的区块无效(例如 2db899...)
    • 改进了缓存管理和其他优化
  • Prysm

  • Lodestar

    • 添加了检查黑名单区块的功能,并引入了一个新端点来返回它们
    • 修复了检查点状态修剪以防止 OOM 崩溃 #7497, #7505
    • 添加了对持久化检查点状态的修剪 #7510, #7495
    • 添加了使用本地状态源作为检查点的功能 #7509
    • 添加了新端点 eth/v1/lodestar/persisted_checkpoint_state 以返回基于可选 rootHex:epoch 参数的状态 #7541
    • 改进了同步停滞期间的对等节点管理,添加了检查对等节点是否 starved #7508
    • 修复了 Electra 中引入的证明 gossip 验证中的错误 #7543
    • 考虑添加悲观同步,但可能会导致 EL 快照同步出现问题,并且看起来没有那么有用 #7511
    • 添加了无效区块的状态持久性以允许对其进行分析 #7482
    • 探索二进制差异状态和时代文件以导入状态 #7535, #7048
  • Teku

    • 修复了与等效投票相关的分叉选择错误 #9234
    • 修复了长时间非最终确定期间的同步问题,同步过程从旧区块重新启动,因为 protoArray 使用 0 权重初始化,并且规范头变成了过去的随机链尖
    • 修复了节点从上一个最终确定状态重新启动同步的问题
    • 修复了由于太多的单次证明而导致的区块生成缓慢的问题
    • 添加了排序以在聚合期间更好地选择证明
    • 识别并正在处理各种较小的问题 https://github.com/Consensys/teku/issues?q=%5BHOLESKY%20PECTRA%5D
    • 为了处理巨大的性能开销,团队在新机器上创建了一个具有大量 CPU/RAM 资源的 “超级信标” 节点来处理负载
  • Nimbus

    • 没有遇到主要的性能问题
    • 创建了 feat/splitview 分支,可以更好地跟踪分叉
    • 即使区块 INVALID,它也被添加到分叉选择并被 justified,由于引擎 API 的根本乐观性质,这造成了一个难以恢复的局面
    • 虽然 feat/splitview 分支能够有效地从不同节点查找/探索大量分叉,但它无法让 EL 经常响应任何内容,但 SYNCING,因此无法排除实际的 INVALID 分叉
    • 在联网最终确定后,Nimbus 花了一段时间完成了它所做的一些最终确定处理,并中断了一段时间的 slot 和区块处理。一旦它过去了,一切都很好,并且不再需要 feat/splitview
  • Grandine

    • 修复了导致 OOM 错误的内存使用量增加的问题
  • Besu

    • 修复了存款合约地址配置错误 #8346
    • Besu 正在使用第三方 web3 库来处理存款合约,团队将审查在关键共识路径中使用外部库 #8391
    • 修复了快照同步停滞问题 #8393
  • Geth

    • 修复了存款合约地址配置 #31247
    • 正在研究 --synctarget 标志以强制客户端跟随特定链 #31375
    • 识别出在同步良好分支后尝试添加无效区块时发生的崩溃 #31320

测试和流程改进

更多非最终确定性测试

客户端以前没有在如此长时间的非最终确定性条件下进行过测试。一定时期的非最终确定性应该成为一个标准的测试程序。

测试网和分叉管理**

测试网和硬分叉需要更仔细地处理,Holesky/Sepolia/Hoodi 应该被认为是合适的 staging 环境。测试网设置应尽可能接近主网,硬分叉激活应以类似于主网的方式处理,并采用适当的程序。有关此主题的更多见解可以在此处找到:https://learnblockchain.cn/article/14874

事件响应协调

事件响应流程需要清晰,并在所有客户端团队中执行。尤其是在测试网或主网的硬分叉期间,开发人员和 devops 需要随时待命并积极监控情况。客户端之间的沟通需要清晰,团队之间不能孤立工作。需要建立适当的事件响应标准程序,并制定明确的准则和责任。

验证器客户端分离

通过使用单独的验证器客户端来实现模块化已被证明是有价值的,它允许团队将他们的验证器连接到健康的信标节点提供商。在客户端之间移动验证器密钥可能具有挑战性且耗时。

事件时间表

注意: 我使用了一个 LLM 根据 Discord 聊天记录来编译这个。我已经对其中的大部分内容进行了完整性检查,但可能存在细微的不准确之处。

2025 年 2 月 24 日

22:04-23:00 UTC:识别出网络分裂

  • 22:04: 多位用户在 Pectra 升级后报告了 Holešky 网络上的无效区块问题
  • 22:05: Lighthouse 中首次报告验证错误:

    “无效的执行 payload... validation_error: 不匹配的区块请求哈希: 得到 0x12e7307cb8a29c779310bea59482500fb917e433f6849de7394f9e2f5c34bf31, 预期 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855”

  • 22:07: 确认 Erigon 也看到了无效区块:“我们在 erigon 上也有坏区块”
  • 22:13: Lodestar 报告了与无效区块类似的错误
  • 22:19: 初步调查显示,一些执行客户端具有错误的存款合约地址
  • 22:30: 团队确定 Erigon 和 Reth 正确地拒绝了无效区块,而 Geth、Nethermind 和 Besu 接受了它们
  • 22:44: 确认该问题与哈希为 0x40a656c88b9ceb7d6251adc8819228a98ae26511faa246cb88004ca402a9f642 的区块 3419724 相关
  • 22:47: somnergy (Erigon) 解释说:“Erigon 收到一个 header,表明请求哈希为空,但 erigon 在处理该区块时发现了一个或多个请求”

23:00-23:59 UTC:EL 根本原因识别 + 修复

  • 23:10: Marius van der Wijden 分享了来自有问题区块的已解析存款请求数据
  • 23:14: Marek (Nethermind) 建议:“对于所有 EL 客户端,请检查你的 depositContractAddress 配置”
  • 23:19: 团队确认了正确的存款合约地址:
    • Holesky: 0x4242424242424242424242424242424242424242
    • Sepolia: 0x7f02c3e3c98b133055b8b348b2ac625669ed295d
  • 23:23: 创建 Geth PR: ethereum/go-ethereum#31247
  • 23:23: 创建 Nethermind PR: NethermindEth/nethermind#8265
  • 23:28: 打开 Besu PR: hyperledger/besu#8346
  • 23:29: 打开 EthereumJS PR: ethereumjs/ethereumjs-monorepo#3882

2025 年 2 月 25 日

00:00-03:00 UTC:早期同步恢复尝试

  • 00:26: 首次报告 Lighthouse 节点成功同步到正确的链
  • 00:31: 首次尝试使用 debug_setHead(0x342e4b) (区块 3419723) 来重置 Besu 节点:
    curl -X POST --data '{"jsonrpc":"2.0","method":"debug_setHead","params":["0x342e4b", true],"id":1}' http://127.0.0.1:8545/ -H "Content-Type: application/json"
  • 00:41: Nethermind 发布了包含修复的版本 1.31.1:Nethermind v1.31.1

    “我们将默认同步方法从快照更改为启用修剪的完整同步,因此它将从创世区块赶上正确的fork。”

  • 01:12: Besu 发布了包含修复的版本 25.2.1:Besu 25.2.1
  • 01:16: 在正确的链上首次成功生成区块
  • 01:22: Kamil (Nethermind) 报告:“我们刚刚重新组织到这个区块!” 表明在正确的链上取得进展
  • 02:00: 确认在正确的链上生成了更多区块

03:00-06:00 UTC:链稳定开始

  • 03:34: 首次报告 Reth 验证器成功同步到正确的链
  • 03:36: 确认正确的链上的最新区块位于 slot 3715626,区块根为 0xe2975407c4d0a06671dfbdfd7b4eaf168d49009b78178e99a44f5d0ae104215e
  • 03:48: 讨论关于在正确的链上查找对等节点的困难
  • 04:02: 共享了正确链的检查点同步 URL:https://checkpoint-sync.holesky.ethpandaops.io/
  • 04:13: 在 https://learnblockchain.cn/article/14872 上创建并共享了正确链节点的 ENR 列表
  • 05:38: 为正确的链创建了第一个 Nethermind 快照
  • 05:44: Ben Adams 确认成功同步:“已将链头同步到 3420047 (0xdd482e...08c37a) 🥳”

06:00-12:00 UTC:协调和策略制定

18:00-24:00 UTC:验证器参与度增加

  • 18:03: Prysm 验证器开始在正确的链上生成区块
  • 18:04: Dora 区块浏览器已更新以将坏链列入黑名单:

    “我也在 Dora 中添加了一个根黑名单,因此坏链不应再显示为规范链。”

  • 19:26: Teku 团队开始同步其验证器节点:

    “我们最终同步了我们的一个验证器节点。我正在将它的数据库复制到其他节点。我们应该会在下一个小时内启动并运行我们的 10 万个验证器!🚀”

  • 20:04: Besu 验证器 (20K) 与 Prysm 一起上线
  • 21:21: 创建了一个脚本来跟踪客户端生成的区块:[https://gist.github.com/fab-10/3bf1cfc8c905b2059762aa5d5f669702](https://gist.github.com/fab-10/3bf1cfc8c905b2059762aa5d5f#### 14:30 UTC - 续:网络健康改善
  • 15:43:Terence 报告显著改善:“我现在在我的本地节点上同步得非常顺利,一切从头开始(geth - prysm)。正在跟进 6 小时前的区块。Dora 存活使得这非常容易。我印象深刻的是,与昨天相比,今天一切都顺畅多了”
  • 17:33:讨论长期恢复计划,估计需要 18 天才能最终完成
  • 19:09:Marius 估计 Holesky 获得了 10% 的证明参与率和 30-50% 的计划区块提议。
  • 原文链接: github.com/ethereum/pm/b...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

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