Alert Source Discuss
Standards Track: Core

EIP-6916: 自动重置测试网

定期回滚到创世区块的测试网

Authors Mário Havel (@taxmeifyoucan), pk910 (@pk910), Rémy Roy (@remyroy), Holly Atkinson (@atkinsonholly), Tereza Burianova (@T-ess)
Created 2023-04-10

摘要

本 EIP 提出了一种自动重置测试网的规范,这是一种可以在以太坊客户端中实现的新型测试网方法。它支持由具有确定性参数的临时网络组成的单一测试基础设施。每个网络迭代都由一个指定的函数创建,该函数确定性地生成创世状态。

动机

自动重置的测试网可以为应用程序、验证器以及客户端实现中的重大更改的短期测试提供替代环境。它可以避免长时间运行的测试网所遭受的状态膨胀、缺乏测试网资金或共识问题。定期将网络重置回创世区块可以清除验证器集合并将资金返回给水龙头,同时保持网络足够小以便于引导。

规范

测试网设置为在预定义的时间段后始终重置。重置意味着生成下一个创世区块,丢弃旧的并启动一个新网络。这可以通过引入用于创世区块生成和客户端重置的函数来实现。

创世区块

要连接到网络的当前实例,客户端必须实现创世区块函数。此函数定义了客户端如何存储有关测试网的信息并生成当前创世区块。每次重置时,网络都从一个新的创世区块开始,该创世区块需要基于给定的参数构建,并在 EL 和 CL 客户端中对应。

网络始终从一个基于原始创世区块确定性创建的创世区块开始 - 这个最初的创世区块是硬编码的,我们可以称之为 genesis 0。终止时间,即每个创世区块的到期时间,是该创世区块的启动时间 MIN_GENESIS_TIME 和测试网生命周期 period 的总和,其中 period 是一个定义单个临时网络运行时间的常量。因此,一旦当前 slot 的时间戳达到临时网络的终止时间,它就必须切换到新的创世区块。每个新的创世区块迭代中的主要变化是 chainId、创世区块时间和第一个验证者的提款凭证。

客户端应包括硬编码的 genesis 0 参数,就像客户端中预定义的其他网络一样。但是,此创世区块应仅在测试网存在的最初阶段直接使用,即在 i 等于 0 的第一次迭代中。稍后,当迭代 i 等于 1 及以上时,客户端不初始化此创世区块,而是使用它来派生当前的创世区块。当 i>0 时,给定一个已知的 period 和当前 slot 的时间戳,客户端始终从 genesis 0 计算生命周期迭代的次数,并使用最新的参数创建一个新的创世区块。

当客户端以临时测试网的选项启动时,它会检查网络是否存在创世区块。如果它不存在,或者当前 slot 的时间戳早于 current_genesis.genesis_time + period,它将触发新创世区块的生成。这个从 genesis 0 派生的新创世区块将被写入数据库并用于运行当前网络。

执行客户端

EL 客户端包括硬编码的 genesis 0,作为生成当前创世区块的前像。变量的迭代按以下方式完成:

  • 迭代次数:
    • i = int((current_slot_timestamp - genesis_0.genesis_time) / period)
  • 当前创世区块的创世区块时间:
    • current_genesis.genesis_time = period * i + genesis_0.genesis_time
  • 当前 EL ChainId:
    • chainId = genesis_0.chainId + i

共识客户端

CL 客户端中的创世区块生成包括具有迭代值的配置,类似于 EL,但还需要更新的创世区块状态。SSZ 格式的状态可以由客户端生成,也可以从外部来源下载。它包括验证者,其存款已准备好启动一个合并的网络,该网络具有由社区内受信任的实体创建的验证者集合。

MIN_GENESIS_TIME 设置为最新的创世区块时间,并定义当前周期何时开始。建议添加一个小的 GENESIS_DELAY,例如 15 分钟,以避免在基础设施使用新创世区块重启时出现问题。

为确保成功重置,每个迭代的 ForkDigest 需要是唯一的。为了保持网络的 ForkVersions 静态以获得更好的工具支持,验证者集合中第一个验证者的提款凭证需要被计算出的值覆盖。

  • genesis.validators[0].withdrawal_credentials = 0x0100000000000000000000000000000000000000000000000000000000000000 + i
  • genesis.genesis_validators_root = hash_tree_root(genesis.validators)

genesis.validators[0] 的更新会改变状态,因此,客户端必须能够生成或下载最新的创世区块状态。生成 genesis ssz 不被认为是标准的客户端功能,添加它可以在信任地创建最新创世区块状态的同时付出一定的复杂性。另一种解决方案是从第三方获取它,可以通过从服务器下载 ssz 文件或使用检查点同步功能与提供创世区块状态的端点。这已成为 Holešky 测试网的可接受做法,并且现有的检查点同步功能可用于获取自动重置测试网的创世区块状态。它还允许维护者更新创世区块验证器集合,而无需发布新的客户端版本。获取最新 CL 状态的推荐实践的完整实现应如下所示:

  • 当提供测试网标志并且客户端支持创世区块的检查点同步时,自动使用硬编码的检查点端点来使用检查点同步功能下载最新的创世区块状态
    • 如果用户提供自定义检查点同步标志,则覆盖默认选项并使用用户提供的端点
  • 包括指向具有最新测试网版本的 URL 的备份下载选项,一个公开分发的 ssz 文件,如果检查点状态同步失败,则触发此选项,或者如果客户端不支持创世区块检查点同步,则将其作为默认选项
  • 如果客户端包含用于生成创世区块或其某些参数的功能,请使用它来验证下载状态中的参数,如果值或校验和不对应,则发出错误

重要的是要注意,genesis_validators_root 通常在客户端中预定义,但在这种情况下,它不是预先知道的,这可能会破坏某些架构。例如,依赖于硬编码的 genesis_validators_root 的轻客户端将无法工作。

重置

重置函数定义了一个丢弃旧数据并从新创世区块开始的自动过程。它依赖于先前定义的创世区块生成函数,客户端必须实现该函数才能自动跟随最新的网络迭代。

对于重置函数,我们可以引入 terminal_timestamp 值,该值定义了迭代的网络到期时间。它可以与下一个迭代的创世区块时间相同(没有创世区块延迟),也可以简单地计算为 terminal_timestamp = current_genesis.genesis_time + period

当网络到达一个时间戳 >= terminal_timestamp 的 slot 时:

  • 客户端停止接受/创建新区块
    • 关闭运行网络的客户端服务,例如 p2p 通信、信标服务、执行环境
    • 此功能应与 Genesis 一起实现,即使没有进一步的重置功能,也只是为了创建始终安全的防分叉基本支持
  • 客户端调用一个丢弃当前创世区块、所有链或信标数据的函数
    • 客户端已经包括用于清除数据库的数据库工具,可以在这里使用
    • 包括一个额外的标志可能会有所帮助,例如 --retain-ephemeral-data,它会在删除数据库之前以标准格式导出现有数据
  • 客户端触发 Genesis 函数(如上定义):
    • 行为类似于创世区块不存在时的常规客户端启动
    • 新的创世区块被写入数据库并初始化
  • 主要网络服务再次启动,指向更新后的创世区块
  • 达到新的创世区块时间后,网络再次从新的创世区块开始

对于完整的重置实现,客户端应该能够执行上述操作,而无需手动重启,完全独立地运行网络并具有最短的停机时间。

请注意,根据客户端架构,可能无法完全实现这种内部重置机制,例如,如果客户端不支持平稳关机。重置功能被认为是高级支持级别,主要由基础设施提供商和创世区块验证者需要。假设即使客户端未实现重置,高级用户也可以通过系统工具处理客户端的外部脚本来实现类似的行为。

原理

具有确定性参数的临时测试网为传统测试网提供了一种可持续的替代方案,具有相同的基础设施。每次重置时,验证器集合都会被清除,水龙头会再次被填满,并且数据库保持较小。

重置后,整个状态都会被清除,这在一方面使网络保持较小且易于引导,但另一方面也为测试长期/高级应用程序带来了问题。但是,任何用户都可以在每次重置后自动部署基本合约基础设施。通常,建议将网络用于短期测试,部署不需要永远保留在长期测试网上的 Hello World 之类的合约。但是,可以有一个链下机制,在每次重置后自动部署标准合约原语,以便应用程序开发人员也可以更多地利用网络。

通过定义 Genesis 和 Reset 的两种机制,此 EIP 能够实现客户端实现支持测试网的两个级别:

  • 基本支持要求客户端确定当前网络规范,并且仅允许连接到网络。
    • 这意味着支持上面定义的 Genesis 机制
    • 足够参与短期测试的网络
    • 要遵循最新的迭代,用户必须手动关闭客户端并删除数据库
    • 仍然建议添加terminate网络的功能
  • 完全支持使客户端能够遵循重置过程并始终同步最新的链迭代
    • 这也要求客户端实现固有的 Reset 功能
    • 运行持久性基础设施、创世区块验证器和引导节点所必需
    • 由于客户端的客户端架构,实现起来可能更复杂

该设计还与由外部工具管理的节点兼容,即,即使客户端未实现这些功能,它也可以在与其他节点相同的网络上运行,这些节点通过脚本自动重置。任何支持自定义网络的客户端都可以用于测试网。

网络参数

定义测试网属性的常量和变量是任意的,但需要根据以下列出的某些限制和安全属性来制定。

重置周期

period 是一个常量,硬编码在客户端中,定义网络重置的时间段。

可以根据用户的需求来定义,但出于安全原因,它也取决于创世区块中验证者的数量。考虑到激活验证者的时间,受信任的验证者的数量应该足够高,以至于网络不会被恶意行为者超越。

Genesis Validators => Epochs until < 66% majority
10k  => 1289 Epochs (5,7 days)
50k  => 6441 Epochs (28,6 days)
75k  => 9660 Epochs (42,9 days)
100k => 12877 Epochs (57,2 days)
150k => 19323 Epochs (85,9 days)
200k => 25764 Epochs (114,5 days)

ChainId

ChainId 是一个变量,因为它需要随着每个新的创世区块不断变化,以避免重放攻击。新 ChainId 值的函数是一个简单的递增 (+1)。genesis 0 中的 ChainId 是一个硬编码的常量。客户端在每次新的创世区块时使用此常量来派生该网络迭代的新 ChainId。

即使在多次迭代后,新的 ChainId 也不应与任何其他现有的公共 EVM 链冲突。因此,不鼓励使用低 ChainId 值。

安全考虑

由于定期重置,网络本身提供了一个安全的环境。即使某种漏洞被利用,它也会在下次重置时被清除。这也是保持周期相对较短(几周/几个月,而不是几个月/几年),并具有足够大的创世区块验证器集合以保持诚实多数的原因。

由重置网络功能的实现引起的客户端更改需要与标准的安全性程序一起审查。特别是触发重置的机制,该机制必须与其他未配置为临时的网络分离。

版权

版权及相关权利通过 CC0 放弃。

Citation

Please cite this document as:

Mário Havel (@taxmeifyoucan), pk910 (@pk910), Rémy Roy (@remyroy), Holly Atkinson (@atkinsonholly), Tereza Burianova (@T-ess), "EIP-6916: 自动重置测试网," Ethereum Improvement Proposals, no. 6916, April 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6916.