ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Foundry `cast run` 历史交易重放修复解析:移除区块 Gas Limit 与 Beacon Root 的重复校验

Foundry `cast run` 历史交易重放修复解析:移除区块 Gas Limit 与 Beacon Root 的重复校验 Foundrycast run历史交易重放修复解析移除区块 Gas Limit 与 Beacon Root 的重复校验【免费下载链接】foundryFoundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.项目地址: https://gitcode.com/GitHub_Trending/fo/foundrycast run是 Foundry 中用于在本地 EVM 中重放replay链上已挖出交易、并输出详细执行轨迹与 gas 消耗的核心调试命令。本篇基于 .changelog/cast-run-historical-validation.md 中的变更说明结合 crates/cast/src/cmd/run.rs 的源码实现与 crates/cast/tests/cli/run_networks.rs 的跨网络端到端测试深入讲解这次修复的技术背景、实现细节与配套命令行参数帮助读者理解为什么 BSC、Polygon、Scroll 等链的交易曾经无法重放以及修复后如何正确使用cast run完成历史交易重放与调试。变更说明一次让多链交易恢复可重放性的 Patch.changelog/cast-run-historical-validation.md的变更条目原文如下cast: patchStoppedcast runfrom re-validating mined transactions against the block gas limit and from requiring a parent beacon block root, which made BSC, Polygon and Scroll transactions unreplayable.翻译过来即停止cast run对已挖出交易重新执行区块 Gas Limit 校验同时不再强制要求区块头包含 parent beacon block root。此前这两项重复校验导致 BNB Smart ChainBSC、Polygon 与 Scroll 上的交易无法被本地重放。为什么“已挖出的交易”不需要再次校验理解这次修复的关键在于交易已经被链本身打包并执行成功。链的共识规则包括区块 Gas Limit 校验在挖矿阶段已经完整执行过一遍本地重放时若再次套用同样的校验只会产生一种结果——拒绝链上已经接受的交易。这一点在 crates/cast/src/cmd/run.rs 的prepare方法中有明确注释与实现// Mined transactions already passed the block gas limit check their chain applies, and // some chains admit transactions whose gas limit exceeds it: BSC validator transactions // carry a gas limit of i64::MAX. Re-applying the check can only reject a transaction // the chain accepted. fork.evm_env.cfg_env.disable_block_gas_limit true;注释点出了两个核心事实已挖出的交易必然已通过所在链自己的校验本地重复校验没有信息增量部分链会接收 Gas Limit 超出常规范围的交易——例如 BSC 的 validator验证者交易携带的 Gas Limit 是i64::MAX远超区块 Gas Limit。本地 EVM 若以标准区块 Gas Limit 去校验这类交易必然被拒导致整条链上的相关交易都无法重放。EIP-4788 的 Beacon Root 带来的第二重障碍第二处修复与 EIP-4788Beacon block root 指令相关。Cancun 升级后以太坊区块头携带parentBeaconBlockRoot字段Foundry 在重放时会通过executor.apply_beacon_root(...)将其注入 EVM 环境。但并非所有运行 Cancun 及以上 EVM 的链都运行以太坊信标链beacon chain。在 crates/cast/src/cmd/run.rs 的parent_beacon_block_root_for_network函数中给出了明确结论const fn parent_beacon_block_root_for_network( networks: NetworkConfigs, spec_id: SpecId, parent_beacon_block_root: OptionB256, ) - OptionB256 { if networks.is_monad() || !spec_id.is_enabled_in(SpecId::CANCUN) { return None; } // Chains that run a Cancun or later EVM without Ethereums beacon chain, such as Polygon and // Scroll, never populate this header field and never deploy the EIP-4788 contract, so there // is no root to apply. Requiring one makes their blocks unreplayable. parent_beacon_block_root }该函数的三层判断逻辑场景行为Monad 网络networks.is_monad()返回None不应用 beacon rootEVM 规格低于 CancunSpecId::SHANGHAI及更早返回NoneEIP-4788 尚未生效Cancun 及以上且区块头确实包含parentBeaconBlockRoot原样返回注入 EVM 环境Cancun 及以上但区块头未填充该字段如 Polygon、Scroll返回None不再强制要求注释明确指出Polygon 与 Scroll 运行着 Cancun 或更高版本的 EVM却没有以太坊信标链既不填充该区块头字段也没有部署 EIP-4788 合约。修复前 Foundry 一旦发现 EVM 规格达到 Cancun就会强制要求该字段存在导致这两个链的区块无法重放。同时在prepare方法中beacon root 的应用被限定为“只有当区块头实际提供该字段时才注入”if let Some(parent_beacon_block_root) parent_beacon_block_root_for_network(networks, spec_id, parent_beacon_block_root) { executor.apply_beacon_root(parent_beacon_block_root)?; }源码级实现重放前的 EVM 环境准备prepare方法中的四项关键调整在 crates/cast/src/cmd/run.rs 的prepare方法中除了上述两项修复还包含一组完整的历史交易重放环境准备逻辑按顺序执行定位目标交易所在区块tx.block_number()获取交易区块号随后将 fork 点设置为tx_block_number - 1父区块确保重放时状态恰好处于交易执行前一刻let tx_block_number tx .block_number() .ok_or_else(|| eyre::eyre!(tx may still be pending: {:?}, tx_hash))?; // we need to fork off the parent block config.fork_block_number Some(tx_block_number - 1);禁用区块 Gas Limit 校验即上文所述的fork.evm_env.cfg_env.disable_block_gas_limit true;。默认放开 EIP-7825Osaka交易 Gas Limit 上限// By default do not enforce transaction gas limits imposed by Osaka (EIP-7825). // Users can opt-in to enable these limits by setting enable_tx_gas_limit to true. if !self.enable_tx_gas_limit { fork.evm_env.cfg_env.tx_gas_limit_cap Some(u64::MAX); }EIP-7825 在 Osaka 硬分叉中引入了交易 Gas Limit 上限tx_gas_limit_cap。由于是历史交易重放默认放开该上限以避免拒绝链上已接受的交易用户可通过--enable-tx-gas-limit显式开启。放开合约代码大小限制fork.evm_env.cfg_env.limit_contract_code_size None;避免 EIP-170 的 24KB 代码大小限制拒绝链上已存在的大合约。此外prepare还会根据区块头重建block_env并针对未知链使用 blob-gas 启发式回退推断 EVM 规格见run.rs中关于excess_blob_gas的判断分支。系统交易的识别与拒绝重放前的run_with_evm会先检查目标交易是否为系统交易if is_system_transaction(target.tx) !self.replay_system_txes { eyre::bail!( {:?} is a system transaction.\nReplaying system transactions is currently not supported., target.tx.tx_hash() ); }系统交易由 crates/cast/src/cmd/run.rs 的is_system_transaction判定发送方为已知系统账户is_known_system_sender或交易类型为系统交易类型SYSTEM_TRANSACTION_TYPE。链会将这些交易注入到正常执行流程之外因此默认拒绝重放可通过--replay-system-txes别名--sys开启。命令行参数详解控制历史交易重放的行为本次修复涉及的校验开关加上cast run本身的重放模式参数共同构成了一套完整的控制面。以下参数定义均可在 crates/cast/src/cmd/run.rs 的RunArgs结构中找到本次修复相关的校验开关参数默认值说明--disable-block-gas-limit隐含开启禁用区块 Gas Limit 校验。注释明确Always implied: a mined transaction already passed its chains own check.已挖出交易必然已通过链自身校验因此该参数默认恒为开启属于语义上的兼容性保留--enable-tx-gas-limit关闭启用 EIP-7825Osaka规定的交易 Gas Limit 上限检查。默认关闭以保证历史交易可重放需要时显式开启重放模式控制参数别名说明--quick无仅用前一区块的状态执行目标交易跳过整块重放。结果可能与链上实际执行不同代码注释明确提示 May result in different results than the live execution!--prestate-tracer无使用debug_traceTransaction的 prestate tracer 直接获取交易前状态替代重放区块内所有前置交易。显著更快但要求节点暴露debug_命名空间多数公共 RPC 不支持失败时静默回退到区块重放--debug-trace-transaction无直接从节点通过debug_traceTransactioncallTracer获取交易轨迹并渲染完全跳过本地重放。反映链上真实执行结果含链特有 EVM 行为但同样要求debug_命名空间与--debug、--decode-internal、--trace-printer、--quick、--prestate-tracer、--evm-version互斥--debug-d在调试器中打开交易--trace-printer-t打印 opcode 级轨迹--replay-system-txes--sys重放系统交易默认拒绝--evm-version无指定 EVM 版本覆盖配置文件中的设置用于历史区块的硬分叉匹配区块重放的整体流程综合 crates/cast/src/cmd/run.rs 的execute_ordinarycast run的本地重放流程为从 RPC 获取目标交易与所在完整区块以目标交易的父区块为 fork 点构建 EVM 环境状态恰好停在交易执行前默认情况下顺序重放区块内目标交易之前的所有前置交易for_each_prefix_transaction进度条提示 Executing previous transactions from the block.以恢复准确的世界状态使用--quick或成功应用 prestate trace 时跳过第 3 步执行目标交易收集 opcode 级轨迹与 gas 消耗输出Gas used: ...结果。值得注意的是区块重放前会先解码目标交易信封TxEnvFor::FEN::from_any_rpc_transaction实现失败快速退出——如果当前构建无法解码该交易信封就不必为整块重放付费。测试佐证跨网络端到端重放矩阵针对本次修复的单元测试crates/cast/src/cmd/run.rs 中的parent_beacon_block_root_is_applied_only_when_the_header_has_one测试直接验证了 beacon root 判定逻辑Cancun 规格 区块头无 rootPolygon、Scroll 场景→ 不应用Cancun 规格 区块头有 root → 应用Shanghai 规格 → 无论有无 root 均不应用Monad 网络PRAGUE / OSAKA→ 均不应用。公共网络端到端测试crates/cast/tests/cli/run_networks.rs 定义了一张覆盖 13 条公链的端到端重放测试矩阵每条测试从链上挑选最近交易、通过cast run重放并与链上 receipt 的gasUsed对比网络预期 gas 匹配策略备注ethereum / optimism / base / avalanche / lineaExact重放 gas 与 receipt 完全一致scrollExact测试注释Blocks carry noparentBeaconBlockRooteven though the EVM is Cancun or later.即本次修复的 beacon root 场景bscExact测试注释Validator transactions carry a gas limit ofi64::MAX, past the block gas limit.即本次修复的 gas limit 场景arbitrumExactMinusL1Gasreceipt 将 L1 发布成本计入gasUsed需扣除gasUsedForL1polygonReplaysOnly每条新建存储槽额外收取 840 gasrevm 未建模仅断言可重放gnosis / mantle / hyperevmReplaysOnly链特有定价或注入行为仅断言重放成功这些测试被命名为flaky_前缀默认 nextest profile 跳过nightlyflakyprofile 带重试运行避免免费公共端点限流导致的偶发失败干扰常规 CI。测试文件头部的模块注释点明了这套测试的价值这是唯一能捕获整链重放断裂的覆盖——包括无法解码的区块体、Foundry 假设存在的区块头字段、以及链自身并不执行的校验恰好对应本次变更修复的两类问题。重放结果对比机制测试通过gas_used辅助函数从cast run输出中解析Gas used: n行与cast receipt的gasUsed十六进制字段对比Exact两者必须完全相等ExactMinusL1Gas重放值等于 receipt 值减去 L1 数据可用性成本ReplaysOnly只要求命令执行成功并输出 gas不比较数值如 Polygon 的 840 gas/槽位定价。总结与实战建议本次.changelog/cast-run-historical-validation.md记录的 patch本质上是让cast run的历史重放回归其正确语义本地重放的目的是复现链上已发生的执行而不是对链的共识规则进行二次审判。由此衍生出两条工程原则也适用于其他 EVM 调试工具的设计已挖出交易是已验证的事实凡链已接受的交易本地重放默认应放行禁用区块 Gas Limit 校验、放开 EIP-7825 上限与合约代码大小限制把校验选项留给用户按需开启区块头字段不能作为硬性前置条件不同链对 EIP-4788 等机制的实现差异显著Polygon、Scroll 无信标链字段是否存在应以实际区块头为准而不是以 EVM 规格推断。实战中若你在 BSC、Polygon、Scroll 等链上执行cast run tx_hash遭遇不可重放问题优先确认三点使用支持历史状态查询的 RPC 节点存档节点优先因为重放需要读取目标交易父区块的状态无需额外传参——本次修复后gas limit 与 beacon root 相关校验默认即处于放行状态若节点暴露debug_命名空间可考虑--prestate-tracer或--debug-trace-transaction加速否则默认的整块重放最保守也最可靠。对于需要精确匹配特定硬分叉的历史区块使用--evm-version显式指定 EVM 版本对于验证者/系统交易cast run默认拒绝重放仅在确有必要时通过--replay-system-txes开启。以上所有行为均可通过 crates/cast/src/cmd/run.rs 的源码与 crates/cast/tests/cli/run_networks.rs 的测试矩阵逐一印证。【免费下载链接】foundryFoundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.项目地址: https://gitcode.com/GitHub_Trending/fo/foundry创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表