本文档描述了一个RPC方法,该方法为当前和下一个分叉提供节点相关的配置数据。通过提供一个RPC方法,允许客户端在下一个硬分叉之前报告关键配置变量,运维团队可以更有信心地确认客户端已正确配置并为即将到来的分叉做好准备。该方法旨在供节点运营商、验证器团队和网络监控工具使用,以验证客户端是否为即将到来的分叉做好了准备。
本文档描述了一种 RPC 方法,该方法为当前和下一个分叉提供节点相关的配置数据。
在以太坊的历史中,曾多次出现客户端未针对即将到来的硬分叉正确配置,导致在跨越分叉边界时失去共识的情况。大多数事件都是小问题,例如单个客户端在工作量证明中分叉链,或者其区块在权益证明中变为孤块。
最重要的一次事件发生在 Holesky 测试网上的 Pectra 激活期间。网络上的六个客户端中有四个客户端的存款合约配置不正确。不正确的链不是被孤立,而是被证明是合理的,并且副作用在 Holesky 上持续存在,即使在达到最终确定性之后。
通过提供一种 RPC 方法,允许客户端在下一个硬分叉之前报告关键配置变量,运维团队可以更加确信客户端已正确配置并为即将到来的分叉做好准备。
此方法旨在供节点运营商、验证者团队和网络监控工具使用,以验证客户端是否为即将到来的分叉做好准备。用例包括:
eth_config
输出。本文档中的关键字“必须(MUST)”,“禁止(MUST NOT)”,“需要(REQUIRED)”,“将要(SHALL)”,“将不(SHALL NOT)”,“应该(SHOULD)”,“不应该(SHOULD NOT)”,“推荐(RECOMMENDED)”,“不推荐(NOT RECOMMENDED)”,“可以(MAY)”和“可选(OPTIONAL)”应按照 RFC 2119 和 RFC 8174 中的描述进行解释。
客户端必须公开一个新的 RPC 方法,以通过标准 JSON-RPC 端口报告当前功能配置和预期的下一个配置。
客户端可以通过 Engine API 公开此方法。
客户端可以使用这些配置对象来管理其每个分叉的配置,但它们不应该简单地返回未经处理的配置数据。
在报告当前和下一个配置时,客户端必须包含此 EIP 中指定的每个配置参数。
客户端必须返回最新的配置值,以反映它们提供的最新区块头。如果客户端缓存配置,则必须确保在跨越分叉边界时清除此类缓存。
引入了一个新的 JSON-RPC API,eth_config
。它不带参数,并返回下一节中指定的结果对象。
RPC 响应包含两种类型的四个成员:
"current" 和 "next" 成员分别包含当前生效的配置对象和下一个配置,如果客户端未配置为支持未来的分叉,则为空。
"currentHash" 和 "nextHash" 成员分别包含当前配置和下一个配置的哈希值,如果下一个配置也为空,则为空。
要生成分叉哈希,表示分叉配置的 JSON 对象按照 RFC-8785 转换为规范形式(简而言之,没有空格,排序的键,以及最简单的数字值)。然后使用 CRC-32 对结果进行哈希处理。
配置对象必须精确包含分叉的 meta-EIP 中指定的参数及其配置的值 —— 不多也不少。解释性注释或客户端特定的扩展不得包含在结果对象中。
每个配置对象必须包含以下字段,按规范顺序呈现。此 RPC 假定网络是合并后的,并且未指定与工作量证明相关的问题。
未来的分叉可以添加、调整、删除或更新字段。相应的更改必须在其各自的 meta-EIP 中定义。
activationTime
分叉激活时间戳,表示为 Unix 纪元秒数(UTC)的 JSON 数字。对于“current”配置,这反映了实际激活时间;对于“next”,如果已知,则为计划时间,如果未计划,则为空。
blobsSchedule
特定分叉的 blob 配置参数,如 genesis 文件中定义的那样。这是一个 JSON 对象,包含三个成员 —— basefeeUpdateFraction
、max
和 target
—— 所有这些都表示为 JSON 数字。
chainId
当前网络的链 ID,表示为带有无符号 0x
前缀的十六进制数字的字符串,并删除所有前导零。此规范不支持没有链 ID 或链 ID 为零的链。
precompiles
分叉的活动预编译合约的表示。如果预编译被链上合约替换,则不包括在内。
这是一个 JSON 对象,其中的成员是预编译的 20 字节 0x
前缀十六进制地址(保留零),值是每个合约的约定名称,通常在定义该合约的 EIP 中指定。
对于 Cancun,合约名称是(按顺序):ECREC
,SHA256
,RIPEMD160
,ID
,MODEXP
,BN256_ADD
,BN256_MUL
,BN256_PAIRING
,BLAKE2F
,KZG_POINT_EVALUATION
。
对于 Prague,添加的合约是(按顺序):BLS12_G1ADD
,BLS12_G1MULTIEXP
,BLS12_G2ADD
,BLS12_G2MULTIEXP
,BLS12_PAIRING
,BLS12_MAP_FIELD_TO_CURVE
,BLS12_MAP_FIELD_TO_CURVE
。
systemContracts
一个 JSON 对象,表示与分叉相关的系统级合约,如其定义 EIP 中引入的那样。键是合约名称(例如,BEACON_ROOTS_ADDRESS
),来自它们首次出现的 EIP,按字母顺序排序。值是 0x
前缀十六进制形式的 20 字节地址,保留前导零。在 Cancun 之前的分叉中省略。
对于 Cancun,唯一的系统合约是 BEACON_ROOTS_ADDRESS
。
对于 Prague,系统合约是(按顺序):BEACON_ROOTS_ADDRESS
,CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS
,DEPOSIT_CONTRACT_ADDRESS
,HISTORY_STORAGE_ADDRESS
和 WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS
。
未来的分叉必须在其 meta-EIP 中定义系统合约的列表。
本规范的目的是使节点能够在分叉之前声明它们已加载并准备好正确的配置。过去的测试网和主网分叉已经揭示了客户端存在不正确的预编译集、链 ID、存款合约地址和其他配置错误。
特别是对于预编译合约,已经讨论过在未来的分叉中删除或替换预编译合约,因此完整枚举预编译合约将反映删除。
通常,如果可配置的变量或常量导致客户端在分叉时发生分歧 —— 无论是在主网、测试网、开发网还是公共 rollup 上 —— 该变量或常量都是可报告配置的候选对象。
最初的设计考虑为“next”分叉使用部分配置,而不是完整的配置。但是,对过去事件的分析表明,导致分歧的一些参数(例如,存款合约)是在较早的分叉中引入的,由于依赖于这些配置的无关 EIP,因此在随后的分叉中发生了共识失败。部分“next”配置哈希将无法检测到此类错误。
另一种方法是将先前分叉的哈希嵌入到下一个分叉中 —— 将需要定义用于提取差异和合并配置的规则,以及指定所有先前的分叉配置哈希。这也会使追溯添加参数(例如,gas 计划常量和变量)变得复杂。
嵌套结构更易于阅读,而扁平结构更易于合并。由于本规范对当前和下一个分叉使用完整配置,因此无需合并,从而使可读性成为首要任务。
一些报告的值是规范级别的常量,许多客户端未将其包含在其配置文件中。但是,某些 EIP 常量(例如,存款合约)已成为测试网中的变量,因此有必要将其包括在内。
选择 JSON 是因为它的普遍性、机器和人类的可读性,以及通过 RFC-8785 存在的标准规范形式。YAML 缺少标准规范形式。没有以太坊软件使用 XML 进行配置,采用它会增加每个客户端的库大小。可以发明一种格式,但需要在本规范中进行定义和标准化。
使用 CRC-32 而不是加密哈希的原因与 EIP-2124 中的原因相同,并通过引用合并。简而言之,节点可能会说谎,减少 4 字节是为了方便而不是安全,并且 CRC-32 已被广泛实现。
此 EIP 不会更改先前的行为。Cancun 之前的配置是非标准的,共享 Cancun 之前配置的客户端将产生非标准结果。
支持 Cancun 之前的分叉的客户端可以返回部分或非标准配置,但应该努力遵循为 Cancun 配置指定的字段的精神。仅 Cancun 及以后的分叉需要完全合规。
Holesky Prague 配置
{
"activationTime": 1740434112,
"blobSchedule": {
"baseFeeUpdateFraction": 5007716,
"max": 9,
"target": 6
},
"chainId": "0x4268",
"precompiles": {
"0x0000000000000000000000000000000000000001": "ECREC",
"0x0000000000000000000000000000000000000002": "SHA256",
"0x0000000000000000000000000000000000000003": "RIPEMD160",
"0x0000000000000000000000000000000000000004": "ID",
"0x0000000000000000000000000000000000000005": "MODEXP",
"0x0000000000000000000000000000000000000006": "BN256_ADD",
"0x0000000000000000000000000000000000000007": "BN256_MUL",
"0x0000000000000000000000000000000000000008": "BN256_PAIRING",
"0x0000000000000000000000000000000000000009": "BLAKE2F",
"0x000000000000000000000000000000000000000a": "KZG_POINT_EVALUATION",
"0x000000000000000000000000000000000000000b": "BLS12_G1ADD",
"0x000000000000000000000000000000000000000c": "BLS12_G1MULTIEXP",
"0x000000000000000000000000000000000000000d": "BLS12_G2ADD",
"0x000000000000000000000000000000000000000e": "BLS12_G2MULTIEXP",
"0x000000000000000000000000000000000000000f": "BLS12_PAIRING",
"0x0000000000000000000000000000000000000010": "BLS12_MAP_FIELD_TO_CURVE",
"0x0000000000000000000000000000000000000011": "BLS12_MAP_FIELD_TO_CURVE"
},
"systemContracts": {
"BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02",
"CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS": "0x0000bbddc7ce488642fb579f8b00f3a590007251",
"DEPOSIT_CONTRACT_ADDRESS": "0x4242424242424242424242424242424242424242",
"HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935",
"WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS": "0x00000961ef480eb55e80d19ad83579a64c007002"
}
}
Holesky Cancun 配置
{
"activationTime": 1707305664,
"blobSchedule": {
"baseFeeUpdateFraction": 3338477,
"max": 6,
"target": 3
},
"chainId": "0x4268",
"precompiles": {
"0x0000000000000000000000000000000000000001": "ECREC",
"0x0000000000000000000000000000000000000002": "SHA256",
"0x0000000000000000000000000000000000000003": "RIPEMD160",
"0x0000000000000000000000000000000000000004": "ID",
"0x0000000000000000000000000000000000000005": "MODEXP",
"0x0000000000000000000000000000000000000006": "BN256_ADD",
"0x0000000000000000000000000000000000000007": "BN256_MUL",
"0x0000000000000000000000000000000000000008": "BN256_PAIRING",
"0x0000000000000000000000000000000000000009": "BLAKE2F",
"0x000000000000000000000000000000000000000a": "KZG_POINT_EVALUATION"
},
"systemContracts": {
"BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02"
}
}
以下 RPC 命令在 Holesky 上在 Prague 被安排但未激活时发出:
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_config","id":1}' http://localhost:8545
将返回(格式化后):
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"current": {
"activationTime": 1707305664,
"blobSchedule": {
"baseFeeUpdateFraction": 3338477,
"max": 6,
"target": 3
},
"chainId": "0x4268",
"precompiles": {
"0x0000000000000000000000000000000000000001": "ECREC",
"0x0000000000000000000000000000000000000002": "SHA256",
"0x0000000000000000000000000000000000000003": "RIPEMD160",
"0x0000000000000000000000000000000000000004": "ID",
"0x0000000000000000000000000000000000000005": "MODEXP",
"0x0000000000000000000000000000000000000006": "BN256_ADD",
"0x0000000000000000000000000000000000000007": "BN256_MUL",
"0x0000000000000000000000000000000000000008": "BN256_PAIRING",
"0x0000000000000000000000000000000000000009": "BLAKE2F",
"0x000000000000000000000000000000000000000a": "KZG_POINT_EVALUATION"
},
"systemContracts": {
"BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02"
}
},
"currentHash": "9c186ad4",
"next": {
"activationTime": 1740434112,
"blobSchedule": {
"baseFeeUpdateFraction": 5007716,
"max": 9,
"target": 6
},
"chainId": "0x4268",
"precompiles": {
"0x0000000000000000000000000000000000000001": "ECREC",
"0x0000000000000000000000000000000000000002": "SHA256",
"0x0000000000000000000000000000000000000003": "RIPEMD160",
"0x0000000000000000000000000000000000000004": "ID",
"0x0000000000000000000000000000000000000005": "MODEXP",
"0x0000000000000000000000000000000000000006": "BN256_ADD",
"0x0000000000000000000000000000000000000007": "BN256_MUL",
"0x0000000000000000000000000000000000000008": "BN256_PAIRING",
"0x0000000000000000000000000000000000000009": "BLAKE2F",
"0x000000000000000000000000000000000000000a": "KZG_POINT_EVALUATION",
"0x000000000000000000000000000000000000000b": "BLS12_G1ADD",
"0x000000000000000000000000000000000000000c": "BLS12_G1MULTIEXP",
"0x000000000000000000000000000000000000000d": "BLS12_G2ADD",
"0x000000000000000000000000000000000000000e": "BLS12_G2MULTIEXP",
"0x000000000000000000000000000000000000000f": "BLS12_PAIRING",
"0x0000000000000000000000000000000000000010": "BLS12_MAP_FIELD_TO_CURVE",
"0x0000000000000000000000000000000000000011": "BLS12_MAP_FIELD_TO_CURVE"
},
"systemContracts": {
"BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02",
"CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS": "0x0000bbddc7ce488642fb579f8b00f3a590007251",
"DEPOSIT_CONTRACT_ADDRESS": "0x4242424242424242424242424242424242424242",
"HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935",
"WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS": "0x00000961ef480eb55e80d19ad83579a64c007002"
}
},
"nextHash": "1c6a3b9f"
}
}
eth_config
限制为受信任的接口(例如,本地访问或经过身份验证的端点)。eth_config
输出与已知的分叉规范或其他节点的响应,以检测异常。eth_config
请求的速率,以防止资源耗尽。实现可以施加最小响应间隔(例如,1 秒)。版权和相关权利通过 CC0 放弃。
- 原文链接: hackmd.io/@shemnon/eth_c...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!