EIP-7910: eth_config JSON-RPC 方法
描述当前和下一个分叉的配置的 JSON-RPC 方法
Authors | Danno Ferrin (@shemnon) |
---|---|
Created | 2025-03-18 |
Discussion Link | https://ethereum-magicians.org/t/eth-config-json-rpc-method/23183 |
Table of Contents
摘要
本文档描述了一种 RPC 方法,该方法为当前和下一个分叉提供节点相关的配置数据。
动机
在以太坊的历史中,曾多次出现客户端未正确配置即将到来的硬分叉的情况,导致其在跨越分叉边界时失去共识。大多数事件都是轻微的,例如单个客户端在工作量证明中分叉链,或者其区块在权益证明中被孤立。
最重大的事件发生在 Holešky 测试网上的 Pectra 激活期间。网络上的六个客户端中有四个具有不正确的存款合约配置。不正确的链没有被孤立,而是被证明是合理的,并且副作用即使在达到最终确定性后仍然存在于 Holešky 上。
通过提供一种 RPC 方法,允许客户端在下一个硬分叉之前报告关键配置变量,运营团队可以更有信心地确保客户端已正确配置并为即将到来的分叉做好准备。
目标受众和用例
此方法适用于节点运营商、验证者团队和网络监控工具,以验证客户端是否已为即将到来的分叉做好准备。用例包括:
- 自动化的 pre-fork 验证脚本,用于比较跨节点的
eth_config
输出。 - 验证者运营商进行手动检查,以确保与分叉规范对齐。
- 客户端开发人员进行调试,以识别配置不匹配。
- 共识层对应方的自动检查
规范
本文档中的关键词“MUST(必须)”,“MUST NOT(禁止)”,“REQUIRED(需要)”,“SHALL(应该)”,“SHALL NOT(不应)”,“SHOULD(应该)”,“SHOULD NOT(不应该)”,“RECOMMENDED(推荐)”,“NOT RECOMMENDED(不推荐)”,“MAY(可以)”和“OPTIONAL(可选)”应按照 RFC 2119 和 RFC 8174 中的描述进行解释。
客户端 MUST 公开一个新的 RPC 方法,以通过标准 JSON-RPC 端口报告当前的函数配置和预期的下一个配置。
客户端 MAY 也可以通过 Engine API 公开此方法。
客户端 MAY 使用这些配置对象来管理其每个分叉的配置,但它们 SHOULD NOT 简单地返回未处理的配置数据。
在报告当前配置和下一个配置时,客户端 MUST 包括此 EIP 中指定的每个配置参数。
客户端 MUST 返回最新的配置值,反映他们提供的最新区块头。如果客户端缓存配置,则 MUST 确保在跨越分叉边界时清除此类缓存。
配置 RPC
引入了一个新的 JSON-RPC API eth_config
。它不接受任何参数,并返回下一节中指定的结果对象。
结果对象结构
RPC 响应包含两种类型的四个成员:
“current”和“next”成员分别包含当前生效的配置对象和下一个配置,如果客户端未配置为支持未来的分叉,则为 null。
“currentHash”和“nextHash”成员分别包含当前配置和下一个配置的哈希值,如果下一个配置也为 null,则为 null。
将分叉配置转换为哈希
要生成分叉哈希,表示分叉配置的 JSON 对象将按照 RFC-8785 转换为规范形式(简而言之,没有空格,排序的键,以及最简单的形式的数值)。然后使用 CRC-32 对结果进行哈希。
配置对象 MUST 仅包含分叉的 meta-EIP 中指定的参数及其配置的值——不多不少。解释性注释或特定于客户端的扩展 MUST NOT 包含在结果对象中。
配置对象中的字段
每个配置对象 MUST 包含以下字段,并按规范顺序呈现。此 RPC 假定网络是 post-merge,并且没有为工作量证明相关的问题指定任何调整。
未来的分叉可能会添加、调整、移除或更新字段。相应的更改 MUST 在它们各自的 meta-EIP 中定义。
activationTime
分叉激活时间戳,表示为 Unix 纪元秒数(UTC)的 JSON 数字。对于“current”配置,这反映了实际激活时间;对于“next”,这是计划的时间。
激活时间是必需的。如果分叉在创世块激活,则使用值 0
。如果未计划激活分叉或其激活时间未知,则不应在 RPC 结果中。
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_G1MSM
、BLS12_G2ADD
、BLS12_G2MSM
、BLS12_PAIRING_CHECK
、BLS12_MAP_FP_TO_G1
、BLS12_MAP_FP2_TO_G2
。
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
。
未来的分叉 MUST 在它们的 meta-EIP 中定义系统合约的列表。
理由
为什么枚举预编译?(一般来说,为什么要跟踪特定的配置项?)
此规范的目的是使节点能够在分叉之前声明它们已加载并准备好正确的配置。过去的测试网和主网分叉已经揭示了具有不正确的预编译集、链 ID、存款合约地址和其他配置错误的客户端。
特别是对于预编译,已经讨论过在未来的分叉中移除或替换预编译,因此预编译的完整枚举将反映移除。
通常,如果可配置的变量或常量导致客户端在分叉时出现分歧——无论是在主网、测试网、devnet 或公共 rollup 上——那么该变量或常量是包含在可报告配置中的候选对象。
完整配置而不是增量
最初的设计考虑使用“next”分叉的部分配置而不是完整配置。然而,对过去事件的分析表明,一些导致分歧的参数(例如,存款合约)是在较早的分叉中引入的,由于依赖于这些配置的无关 EIP,在后来的分叉中发生了共识失败。部分“next”配置哈希将无法检测到此类错误。
另一种方法——将先前分叉的哈希嵌入到下一个分叉中——将需要定义用于提取差异和合并配置的规则,以及指定所有先前分叉配置哈希。这也会使追溯添加参数(例如,gas 计划常量和变量)变得复杂。
嵌套与扁平变量
嵌套结构更易于阅读,而扁平结构更易于合并。由于此规范对当前和下一个分叉使用完整配置,因此不需要合并,从而使可读性成为优先级。
提供未在 genesis.json 中指定的数据
一些报告的值是规范级别的常量,许多客户端未将其包含在其配置文件中。但是,某些 EIP 常量(例如,存款合约)已成为测试网中的变量,因此需要将其包含在内。
JSON 作为配置格式
选择 JSON 是因为它无处不在,机器和人类可读,并且通过 RFC-8785 存在标准化的规范形式。YAML 缺乏标准的规范形式。没有以太坊软件使用 XML 进行配置,采用它会增加每个客户端的库大小。可以发明一种格式,但需要在本规范中进行定义和标准化。
CRC-32 作为哈希格式
使用 CRC-32 而不是加密哈希的原因与 EIP-2124 中的原因相同,并通过引用合并。简而言之,节点可能会撒谎,减少 4 个字节是为了方便而不是安全,并且 CRC-32 已被广泛实现。
向后兼容性
此 EIP 不会更改先前的行为。Cancun 之前的配置是非标准的,并且共享 Cancun 之前配置的客户端将产生非标准的结果。
支持 Cancun 之前分叉的客户端 MAY 返回部分或非标准配置,但 SHOULD 努力遵循为 Cancun 配置指定的字段的精神。仅对 Cancun 及以后的分叉 REQUIRED 完全符合。
测试用例
示例配置
Hoodi Prague 配置
{
"activationTime": 1742999832,
"blobSchedule": {
"baseFeeUpdateFraction": 5007716,
"max": 9,
"target": 6
},
"chainId": "0x88bb0",
"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_G1MSM",
"0x000000000000000000000000000000000000000d": "BLS12_G2ADD",
"0x000000000000000000000000000000000000000e": "BLS12_G2MSM",
"0x000000000000000000000000000000000000000f": "BLS12_PAIRING_CHECK",
"0x0000000000000000000000000000000000000010": "BLS12_MAP_FP_TO_G1",
"0x0000000000000000000000000000000000000011": "BLS12_MAP_FP2_TO_G2"
},
"systemContracts": {
"BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02",
"CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS": "0x0000bbddc7ce488642fb579f8b00f3a590007251",
"DEPOSIT_CONTRACT_ADDRESS": "0x00000000219ab540356cbb839cbe05303d7705fa",
"HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935",
"WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS": "0x00000961ef480eb55e80d19ad83579a64c007002"
}
}
Hoodi Cancun 配置
{
"activationTime": 0,
"blobSchedule": {
"baseFeeUpdateFraction": 3338477,
"max": 6,
"target": 3
},
"chainId": "0x88bb0",
"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"
}
}
示例 JSON-RPC
以下 RPC 命令在 Hoodi 上发出,当时 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": 0,
"blobSchedule": {
"baseFeeUpdateFraction": 3338477,
"max": 6,
"target": 3
},
"chainId": "0x88bb0",
"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": "243c27d1",
"next": {
"activationTime": 1742999832,
"blobSchedule": {
"baseFeeUpdateFraction": 5007716,
"max": 9,
"target": 6
},
"chainId": "0x88bb0",
"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_G1MSM",
"0x000000000000000000000000000000000000000d": "BLS12_G2ADD",
"0x000000000000000000000000000000000000000e": "BLS12_G2MSM",
"0x000000000000000000000000000000000000000f": "BLS12_PAIRING_CHECK",
"0x0000000000000000000000000000000000000010": "BLS12_MAP_FP_TO_G1",
"0x0000000000000000000000000000000000000011": "BLS12_MAP_FP2_TO_G2"
},
"systemContracts": {
"BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02",
"CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS": "0x0000bbddc7ce488642fb579f8b00f3a590007251",
"DEPOSIT_CONTRACT_ADDRESS": "0x00000000219ab540356cbb839cbe05303d7705fa",
"HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935",
"WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS": "0x00000961ef480eb55e80d19ad83579a64c007002"
}
},
"nextHash": "10368496"
}
}
参考实现
参见 Besu Pull #8417
安全考虑
- 暴露风险:不正确的配置可能会泄露操作详细信息。运营商 SHOULD 将
eth_config
限制为受信任的接口(例如,本地访问或经过身份验证的端点)。 - 不诚实的节点:客户端可能会报告错误的配置。对等方或监控工具 MAY 将
eth_config
输出与已知的分叉规范或其他节点的响应进行交叉检查,以检测异常情况。 - DDoS 缓解:客户端 SHOULD 在内部缓存配置对象并限制
eth_config
请求的速率,以防止资源耗尽。实现 MAY 强制执行最短响应间隔(例如,1 秒)。
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Danno Ferrin (@shemnon), "EIP-7910: eth_config JSON-RPC 方法 [DRAFT]," Ethereum Improvement Proposals, no. 7910, March 2025. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7910.