2023年4月5日,Moonbeam网络经历了短暂的区块生产暂停问题,这是已批准的88号公投带来的意外结果。该问题源于链上公投的批准结果先于runtime升级发布,然而对这次公投的调用顺序却被安排在了runtime升级之后的区块。本文提供了对该事件的详细事后分析,概述了导致网络中断的事件顺序,以及为解决该问题并防止其再次发生而采取的后续措施。
事件摘要
一个包含system.remark调用的88号公投已在区块3276000上通过社区治理获得批准,并计划于区块3291300上执行。
在执行88号公投之前的一些区块(区块 3290853)已成功应用于runtime 2201升级。新的runtime包含了一个Substrate中的底层更改——变更了system.remark的调用索引,造成其与system.setHeapPages的调用索引匹配。
由于此更改,计划中的system.remark调用无意中切换为system.setHeapPages调用。新的调用有一个无效值,阻止了收集人生产区块,并且最终导致网络停止。
网络停止前的最后一个区块(即区块3291299)生产于2023年4月5日14:43:24 UTC。后续区块(即区块3291300)无法被生产,因为其区块中包含了一个计划中的,且带有错误配置的新HEAP_PAGES参数的调用。
Moonbeam开发贡献者和Parity立即着手调查,迅速发布了一个可供所有节点使用的新客户端,在接近4小时的中断后,网络重新恢复区块生产。
根本原因
Runtime 2201包含了一个Substrate中的底层更改——改变了system.remark的调用索引,造成其与system.setHeapPages的调用索引匹配。按照正常情况,这本来不是问题,因为一个基于新的runtime升级中的调用可以被分配给另一个新的调用索引。
88号公投包含了一个system.remark调用,这次公投本应该在Runtime2100上启动。对于该runtime,被分配了一个调用索引1。公投获得批准后,网络自动计划了把此公投的调用派送到区块3291300上执行。然而,该区块是Runtime2201的一部分。
当开始生产区块3291300时,新映射的system.setHeapPages的执行意味着一个非重要的链上配置值被更改,以至于收集人无法生产区块。最终导致在2023年4月5日14:43:24 UTC,网络停止生产区块。
Runtime升级会通过几个测试网络,在Moonbeam主网升级之前会通过完整测试。此次事件与runtime升级本身无关,而是因为一个错配在不同runitime升级的调用,导致执行关系发生了变化,调用索引在两者间发生了改变,才造成此次问题。
解决方案
Moonbeam团队发布了新客户端version 0.30.3以解决问题。更新的客户端可忽略链上储存的错误的HEAP_PAGES值,允许收集人继续生产区块。
在当天18:55:48 UTC(约问题产生后4小时12分24秒),随着区块3291300创建,网络恢复区块生产。
在收集人更新至新客户端(v0.30.3)后,网络开始以固定节奏生产区块,并逐渐恢复正常。反应迅速的升级离不开社区收集人对新客户端信息的重视,也是帮助网络区块生产恢复正常的关键。
未来计划
公投88号批准后的影响,以及后续从system.remark调用意外切换到system.setHeapPages调用而导致Moonbeam网络暂停事件,对社区来说是一次重要的经验教训。
Moonbeam开发贡献者们迅速发布新客户端,准确解决问题,体现了Moonbeam致力于维护安全可靠网络的承诺。来自Parity团队成员Basti对Moonbeam网络的恢复提供了重大帮助。该事件凸显了全面测试、runtime升级本身,以及基于不同场景的链上治理方案重要性。
为了防止将来的runtime版本发布中的调用索引再次发生类似问题,已经实施的解决方案被提交。应对于未来,runtime升级期间需要解决两个关键点:
-
所有技术团队需在更新客户端或runtime至少一天前检查发布条件的清单
-
改进测试工具,包含借助新客户端和runtime验证未来的公投
展望未来,加强网络的韧性以及确保稳健的性能,Moonbeam团队和社区将继续携手共进。
事件节点
-
88号公投通过,一个system.remark的extrinsic已计划,准备在区块3291300上执行
-
Runtime 2201已成功在区块3290853上应用
-
新的runtime包含一个在Substrate中的底层更改,改变了system.remark的调用索引,导致其与system.setHeapPages的调用索引匹配。造成计划中的system.remark调用自动切换为system.setHeapPages调用
-
新的调用(system.setHeapPages)有一个无效值,阻止了收集人生产区块,并且最终导致网络停止。
-
在网络停止前的最后一个区块(即区块3291299)生产于2023年4月5日14:43:24 UTC。后续区块(即区块3291300)无法被生产,因其发送了一个计划中包含带有新的错误配置的HEAP_PAGES参数的调用。
-
Moonbeam推出新的客户端(v0.30.3)来解决问题。更新的客户端可忽略链上储存的错误的HEAP_PAGES值,允许收集人继续生产区块。
-
在当天18:55:48 UTC(约问题产生后4小时12分24秒),区块3291300创建。
-
在收集人更新至新客户端(v0.30.3)后,网络开始以固定节奏生产区块,逐渐恢复正常。