eth_getLogs 区块跨度上限与分段查询
理解 eth_getLogs 单次调用的区块跨度限制,解决 eth_getLogs block range too large 报错,并通过按链动态切分实现大跨度日志分段查询。
eth_getLogs 的区块跨度上限
在调用 JSON-RPC 方法 eth_getLogs 时,单次请求的区块跨度按照 toBlock − fromBlock + 1 计算,不能超过目标链通过 GET /v1/chains 公布的 max_logs_block_range 上限。
该限制因链而异——各链的参数通过公开接口 GET /v1/chains 发布(链列表见支持的链)。该接口免鉴权、不计费、不限流。在编写客户端代码时,请在运行时通过该接口动态读取目标链的 max_logs_block_range,不要将上限数值写死在代码中。
根据规格,过滤参数 fromBlock 与 toBlock 的取值规则如下:
- 缺省与 null:
fromBlock与toBlock缺省或为null时,按latest处理。 - 标签解析:
latest等标签按服务最近一次轮询的高度解析。 - 不检查场景:带有
blockHash的过滤器、无法解析的值,以及toBlock < fromBlock的情形,不做跨度检查,直接交给节点处理。
超出跨度上限的表现
当单次请求的区块跨度 toBlock − fromBlock + 1 超过该链的 max_logs_block_range 时,请求会被服务直接拒绝,返回 HTTP 200 与 JSON-RPC 错误:
- 错误码:
-32602 - 错误信息:
eth_getLogs block range too large: max <N> blocks - 计费状态:该错误属于服务自身拒绝,不计费(
billed: false)。
规格示例请求
以下为规格中的超限请求示例(reqLogsTooWide):
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getLogs",
"params": [
{
"fromBlock": "0x45a2409",
"toBlock": "0x45a27f1"
}
]
}规格示例返回
超出上限时返回的错误响应示例(errLogsRangeTooLarge):
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "eth_getLogs block range too large: max <N> blocks"
}
}其中 <N> 为该链的 max_logs_block_range(通过 GET /v1/chains 发布)。
在包含多个调用的批量请求中,如果其中某个 eth_getLogs 跨度过大,该调用同样会在对应位置返回上述 -32602 错误,且该调用不计费。
分段查询实现
当需要检索跨越较长区间的日志时,应先读取目标链的 max_logs_block_range,再将目标区间按照 [from, from + max - 1] 划分为若干段闭区间,按顺序逐段请求并合并结果。
以下示例以 robinhood_mainnet 为例演示分段查询流程:
export BLOCKVECTRA_API_KEY="rgw_your_api_key"
# 1. 从公开接口读取目标链的 max_logs_block_range(免鉴权、不计费)
curl -s "https://dev-api.blockvectra.network/v1/chains"
# 2. 发起单次合规请求:区块跨度(toBlock - fromBlock + 1)不超过该链的 max_logs_block_range
curl -s "https://dev-api.blockvectra.network/v1/robinhood_mainnet" \
-H 'Content-Type: application/json' \
-H "x-api-key: $BLOCKVECTRA_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getLogs",
"params": [{
"address": "0x1111111111111111111111111111111111111111",
"fromBlock": "0x45a2409",
"toBlock": "0x45a246c"
}]
}'批量请求注意事项
若考虑将切分后的多个分段调用打包进单个 JSON-RPC 批量请求,需要遵循规格中的批量与突发上限规则:
- 批量大小限制:批量请求支持 1~100 个调用;超过 100 个调用会被直接拒绝,返回 HTTP 200 与错误码
-32600 batch too large: max 100 calls(不计费)。 - 单请求突发上限:请求到达服务时,会先按请求内所有调用的满权重之和进行预扣。如果单个请求内调用的满权重之和超过突发上限,服务会立即返回 HTTP 429 与错误码
-32022 request cost <N> CU exceeds burst capacity <M> CU(不计费)。该错误等待多久都不会成功,必须将请求拆分成更小的批次或逐个调用。 - 令牌桶余量不足:若单请求满权重之和未超过突发上限,但当前令牌桶内可用余量不足,服务返回 HTTP 429 与错误码
-32005 rate limit exceeded(带Retry-After),详见哪些请求不计费:错误码与计费规则。
因此,在大跨度日志查询时,建议采用顺序逐段请求;若使用批量请求,应严格控制批内调用数量,避免满权重之和超出突发上限。
相关接口与计费规则
- 关于
eth_getLogs与 Data API 转账接口(按地址转账与代币转账)的功能定位、覆盖范围及最终性差异,请参阅节点近况与已索引历史:什么时候用 eth_getLogs,什么时候用转账接口。 - 关于方法权重、计算单元(CU)结算与各类错误码计费判定的完整说明,请参阅哪些请求不计费:错误码与计费规则。