十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Foundry Anvil 状态查询 RPC 区块参数默认化解析:省略 block 参数时默认查询最新区块

Foundry Anvil 状态查询 RPC 区块参数默认化解析:省略 block 参数时默认查询最新区块 Foundry Anvil 状态查询 RPC 区块参数默认化解析省略 block 参数时默认查询最新区块【免费下载链接】foundryFoundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.项目地址: https://gitcode.com/GitHub_Trending/fo/foundry本篇围绕 Foundry 仓库.changelog/anvil-default-state-block.md记录的 Anvil 行为变更展开当eth_getBalance、eth_getCode、eth_getProof、eth_getTransactionCount等状态查询 RPC 省略区块参数block number/tag时Anvil 现在默认将其解析为「最新区块latest」。读完本文你将理解该默认化的 JSON-RPC 背景、底层ensure_block_number的区块解析逻辑、全部区块标签earliest / latest / safe / finalized / pending / 具体区块号的语义差异以及越界与 fork 模式下的边界行为。变更速览changelog 条目原文与定位仓库根目录的.changelog/anvil-default-state-block.md是一个标准的 Foundry changelog 碎片文件全文如下--- anvil: patch --- Defaulted omitted state query block parameters to the latest block.它由两部分构成frontmatter声明本次变更作用于anvil包升级级别为patch缺陷修复级别不涉及 API 破坏。按 .changelog/README.md 中描述的条目规范frontmatter 将 workspace 包名映射到patch、minor或major并必须包含非空的发布说明该条目满足至少一个包 非空说明的校验要求。正文一句话描述了行为变更——状态查询中省略的区块参数现在默认指向最新区块。虽然正文只有一行但它背后对应着 Anvil 节点中一条完整的区块参数解析链路下文结合源码逐一展开。为什么需要默认值JSON-RPC 规范下的可选区块参数在以太坊 JSON-RPC 规范中eth_getBalance、eth_getCode、eth_getTransactionCount、eth_getStorageAt、eth_getProof等状态查询类方法其区块参数block number 或 tag是可选的客户端可以在调用时不传入该参数也可以显式传入latest。这一可选性带来了一个语义问题当调用方省略该参数时节点应查询哪个高度的状态不同实现历史上存在差异。本次变更明确了 Anvil 的答案——省略即视为latest。核心实现ensure_block_number的默认化解析区块参数默认化的逻辑核心位于 Anvil 的内存后端Backend中crates/anvil/src/eth/backend/mem/mod.rs 的ensure_block_number方法第 2210–2238 行pub async fn ensure_block_numberT: IntoBlockId( self, block_id: OptionT, ) - Resultu64, BlockchainError { let current self.best_number(); let requested match block_id.map(Into::into).unwrap_or(BlockId::Number(BlockNumber::Latest)) { BlockId::Hash(hash) { self.block_by_hash(hash.block_hash) .await? .ok_or(BlockchainError::BlockNotFound)? .header .number } BlockId::Number(num) match num { BlockNumber::Latest | BlockNumber::Pending current, BlockNumber::Earliest U64::ZERO.to::u64(), BlockNumber::Number(num) num, BlockNumber::Safe current.saturating_sub(self.slots_in_an_epoch), BlockNumber::Finalized current.saturating_sub(self.slots_in_an_epoch * 2), }, }; if requested current { Err(BlockchainError::BlockOutOfRange(current, requested)) } else { Ok(requested) } }关键的一行是match block_id.map(Into::into).unwrap_or(BlockId::Number(BlockNumber::Latest)) {从源码结构可以清晰看到本次变更的落点当调用方传入None即省略区块参数时unwrap_or会将其替换为BlockId::Number(BlockNumber::Latest)随后在BlockNumber的分支匹配中Latest与Pending都被解析为current也就是self.best_number()当前最优区块高度。这正是 changelog 所述省略的状态查询区块参数默认指向最新区块的直接实现。各区块标签的解析语义同一段match揭示了 Anvil 对各类区块标签的统一处理规则区块参数解析结果说明省略None最新区块高度本次变更的核心默认化行为latest/pendingcurrent最优区块高度二者在状态查询中均取当前链头earliest0创世区块高度safecurrent - slots_in_an_epoch安全区块按一个 epoch 的 slot 数向前偏移saturating_sub防止下溢finalizedcurrent - slots_in_an_epoch * 2最终确认区块偏移两个 epoch具体区块号原样使用如0x10区块哈希BlockId::Hash按哈希查块取高度查不到时报BlockNotFound从代码可以推断safe/finalized在 Anvil 本地非 PoS 全节点语境下是基于链头高度的相对估算其偏移量由slots_in_an_epochepoch 内 slot 数决定并非真实的共识确认状态。状态查询处理链block_request与各 RPC handlerensure_block_number并非被直接调用而是经由 API 层的统一辅助方法block_request完成参数归一化。crates/anvil/src/eth/api.rs 第 1611–1626 行async fn block_request( self, block_number: OptionBlockId, ) - ResultBlockRequestFoundryTxEnvelope { let block_request match block_number { Some(BlockId::Number(BlockNumber::Pending)) { let pending_txs self.pool.ready_transactions().collect(); BlockRequest::Pending(pending_txs) } _ { let number self.backend.ensure_block_number(block_number).await?; BlockRequest::Number(number) } }; Ok(block_request) }该方法的处理逻辑为若显式传入Pending则收集交易池中就绪交易构造BlockRequest::Pending状态查询将在待打包区块视角下执行其余所有情况包括None、latest、earliest、safe、finalized、具体区块号、区块哈希一律交给ensure_block_number归一化为具体区块号即省略参数时在这里走默认latest分支。随后各状态查询 RPC handler 都复用block_request与 fork 判定逻辑形成统一的状态查询处理链。典型的调用方包括eth_getBalanceapi.rs 的balance方法第 2424–2437 行先block_request再检查 fork 模式下目标区块是否早于 fork 锚点fork.predates_fork(number)是则直接委托给 fork 提供方查询远端历史状态否则由本地后端get_balance处理eth_getAccountget_account第 2442–2459 行结构与balance对称eth_getCodeget_code第 2720–2731 行同样先经block_request归一化eth_getProofget_proof第 2737–2757 行此处 fork 判定使用predates_fork_inclusive包含 fork 锚点本身eth_getTransactionCountget_transaction_count第 4887 行起接受OptionBlockId区块参数。由于所有状态查询共享block_request→ensure_block_number这条路径本次默认化变更一次性覆盖了上述全部方法而无需在各 handler 中分别处理空参数。边界行为越界报错与 fork 模式区块越界ensure_block_number在归一化后会做一次守卫检查if requested current { Err(BlockchainError::BlockOutOfRange(current, requested)) } else { Ok(requested) }即解析出的区块高度若高于当前链头Anvil 返回BlockOutOfRange错误而不是静默截断或返回空状态。这对于省略参数默认 latest必然不超过链头的场景影响不大但保护了显式传入未来区块号的调用。fork 模式下的历史状态委托当 Anvil 以--fork-url运行、且查询区块早于 fork 锚点时状态查询会被委托给远端 fork 提供方见balance与get_account中的fork.predates_fork分支、get_proof中的predates_fork_inclusive分支从而返回真实的链上历史状态eth_getCode同样如此api.rs 第 2724–2729 行。省略区块参数默认走 latest即返回 fork 之后本地最新状态。实操验证典型调用与预期结果以eth_getBalance为例以下三种调用在本次变更后行为一致省略参数等价于显式latest# 省略区块参数默认 latest curl http://localhost:8545 \ -H Content-Type: application/json \ -d {jsonrpc:2.0,method:eth_getBalance,params:[0x0000000000000000000000000000000000000000],id:1} # 显式 latest curl http://localhost:8545 \ -H Content-Type: application/json \ -d {jsonrpc:2.0,method:eth_getBalance,params:[0x0000000000000000000000000000000000000000,latest],id:1} # 指定历史区块号低于当前链头时返回历史余额 curl http://localhost:8545 \ -H Content-Type: application/json \ -d {jsonrpc:2.0,method:eth_getBalance,params:[0x0000000000000000000000000000000000000000,0x10],id:1}eth_getCode、eth_getTransactionCount、eth_getProof、eth_getStorageAt等状态查询方法遵循同一规则省略区块参数 → 最新区块显式pending→ 待打包区块视角显式历史区块号/earliest→ 对应历史状态fork 模式下委托远端。总结.changelog/anvil-default-state-block.md记录的虽是一行 patch 说明其背后是 Anvil 状态查询链路上一次语义收敛通过 ensure_block_number 中unwrap_or(BlockId::Number(BlockNumber::Latest))的默认化处理将省略区块参数的调用统一归一到最新区块避免了不同状态查询方法之间对空参数的差异化解释。该行为由 API 层 block_request 统一承载覆盖eth_getBalance、eth_getCode、eth_getProof、eth_getTransactionCount、eth_getAccount等全部状态查询 RPC配合earliest/safe/finalized/pending/ 具体区块号 / 区块哈希的完整解析矩阵以及BlockOutOfRange越界守卫和 fork 模式下的历史状态委托Anvil 为开发者在本地复现任意历史状态提供了语义明确、行为一致的状态查询入口。【免费下载链接】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),仅供参考
返回列表