Límite de rango de bloques de eth_getLogs y consultas fragmentadas

Gestione el límite de rango de bloques de eth_getLogs y el error logs_range_too_large: consulte el max_logs_block_range de cada cadena y divida consultas amplias en fragmentos.

Respuesta directa

Una sola solicitud de eth_getLogs está limitada al max_logs_block_range de la cadena de destino desde GET /v1/chains (para HyperEVM, 1,000 bloques), contando los bloques como toBlock − fromBlock + 1. Superarlo devuelve HTTP 200, JSON-RPC -32602 y error.data.reason: logs_range_too_large, con retryable: false (consulte el catálogo de errores). Divida el intervalo en [from, min(from + max − 1, end)] y avance hasta el final del fragmento anterior más uno después de tener éxito.

Guarde esto como logs-minimal.mjs, establezca BLOCKVECTRA_API_KEY, la dirección del contrato LOG_ADDRESS y un intervalo de bloques confirmados en FROM_BLOCK y TO_BLOCK, luego ejecute node logs-minimal.mjs con Node.js 24 o posterior. Seleccione una cadena con CHAIN; la predeterminada es robinhood_mainnet.

const { BLOCKVECTRA_API_KEY: key, LOG_ADDRESS: address, FROM_BLOCK, TO_BLOCK } = process.env;
if (!key || !/^0x[0-9a-f]{40}$/i.test(address ?? '')) throw new Error('Set BLOCKVECTRA_API_KEY and LOG_ADDRESS');
if (![FROM_BLOCK, TO_BLOCK].every(value => /^(0x[0-9a-f]+|[0-9]+)$/i.test(value ?? ''))) {
  throw new Error('Set FROM_BLOCK and TO_BLOCK to nonnegative block numbers');
}
const start = BigInt(FROM_BLOCK), end = BigInt(TO_BLOCK);
if (start > end) throw new Error('FROM_BLOCK must not exceed TO_BLOCK');
const chainSlug = process.env.CHAIN ?? 'robinhood_mainnet';
const chainsUrl = 'https://api.blockvectra.com/v1/chains';
const catalogResponse = await fetch(chainsUrl, { signal: AbortSignal.timeout(15_000) });
if (!catalogResponse.ok) throw new Error(`Chains HTTP ${catalogResponse.status}`);
const catalog = await catalogResponse.json();
const chain = catalog.chains.find(item => item.chain === chainSlug);
if (!chain || !Number.isSafeInteger(chain.max_logs_block_range) || chain.max_logs_block_range <= 0) {
  throw new Error('Missing or invalid max_logs_block_range');
}
const matches = pattern => pattern.endsWith('*') ? 'eth_getLogs'.startsWith(pattern.slice(0, -1)) : pattern === 'eth_getLogs';
if (!chain.methods?.allow?.some(matches) || chain.methods?.deny?.some(matches)) {
  throw new Error('eth_getLogs is unavailable on this chain');
}
const max = BigInt(chain.max_logs_block_range);
const rpcUrl = new URL(`./${chainSlug}`, chainsUrl).href;
const hex = value => `0x${value.toString(16)}`;
for (let from = start; from <= end;) {
  const to = from + max - 1n < end ? from + max - 1n : end;
  const response = await fetch(rpcUrl, {
    method: 'POST', redirect: 'error', signal: AbortSignal.timeout(15_000),
    headers: { 'Content-Type': 'application/json', 'x-api-key': key },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_getLogs',
      params: [{ address, fromBlock: hex(from), toBlock: hex(to) }] }),
  });
  const body = await response.json();
  if (!response.ok || body.error || !Array.isArray(body.result)) {
    throw new Error(`RPC HTTP ${response.status}: ${JSON.stringify(body.error ?? 'Invalid result')}`);
  }
  console.log(JSON.stringify({ fromBlock: hex(from), toBlock: hex(to), result: body.result }));
  from = to + 1n;
}

Cada línea de salida es un fragmento completado. Cualquier error HTTP o JSON-RPC detiene el ejemplo sin omitir el fragmento fallido. Consulte las pautas de lotes y límites de tasa a continuación para gestionar el error 429.

Límites de rango de bloques de eth_getLogs

Al llamar al método JSON-RPC eth_getLogs, la amplitud de bloques de una sola solicitud se calcula como toBlock − fromBlock + 1 y no puede superar el max_logs_block_range publicado de la cadena de destino.

Este límite varía según la cadena. Los parámetros por cadena se publican a través del endpoint público GET /v1/chains (las cadenas se enumeran en Cadenas compatibles). Este endpoint no requiere autenticación ni se factura. Al desarrollar aplicaciones cliente, consulte este endpoint dinámicamente en tiempo de ejecución en lugar de codificar los límites de rango de bloques de forma fija en su código.

Los campos de filtro fromBlock y toBlock tienen como valor predeterminado latest cuando se omiten o son null.

Límites de eth_getLogs por cadena

Estos son los valores de max_logs_block_range de cada cadena publicados por GET /v1/chains. «No publicado» no significa ilimitado. Verifique también methods.allow y methods.deny antes de llamar, teniendo prioridad la denegación; el límite de amplitud de bloques es independiente de los límites en la cantidad de resultados o la duración de la consulta.

CadenaSlug de la cadenamax_logs_block_range (bloques)
Arbitrum Onearb_mainnet1,000
Basebase_mainnet1,000
BNB Smart Chainbsc_mainnet1,000
Ethereumeth_mainnet1,000
Ethereum Sepoliaeth_sepolia1,000
HyperEVMhyperevm_mainnet1,000
Polygonpolygon_mainnet1,000
Robinhood Chainrobinhood_mainnet1,000
Robinhood Chain Testnetrobinhood_testnet1,000

Mensajes de error comunes, textuales

Distinga entre amplitud de bloques, cantidad de resultados y duración de la consulta: el mismo código JSON-RPC puede describir fallos diferentes.

Texto de error / identificadorOrigenQué hacer
eth_getLogs block range too large: max <N> blocks; -32602; logs_range_too_largeCatálogo de errores de BlockVectra<N> es el max_logs_block_range de la cadena; reduzca la amplitud antes de reenviar. Reintentar sin cambios no ayuda.
query block range exceeds server limit, narrow your filter: <N>Código fuente de eth_getLogs en Erigon<N> es el límite de rango de ese nodo; reduzca el intervalo consultado antes de reenviar.
query returns too many logs, narrow your filter: <N>Código fuente de eth_getLogs en Erigon<N> es el límite de resultados de ese nodo; reduzca el intervalo y restrinja address y topics. Un solo bloque aún puede necesitar filtros más específicos.

En estas plantillas de mensajes, <N> se sustituye por el límite del endpoint. Los mensajes de terceros se refieren a sus propios endpoints y límites; la redacción puede variar según la versión del cliente. Para BlockVectra, use /v1/chains y error.data.reason.

Superar el límite de amplitud de bloques

Cuando la amplitud de bloques de una sola solicitud toBlock − fromBlock + 1 supera el max_logs_block_range de la cadena, la solicitud se rechaza con HTTP 200 y un error de JSON-RPC:

  • Código de error: -32602
  • Mensaje de error: eth_getLogs block range too large: max <N> blocks
  • Estado de facturación: No facturado.

Solicitud de ejemplo

Esta solicitud supera el límite solo si su amplitud de bloques es mayor que el max_logs_block_range actual de la cadena de destino:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getLogs",
  "params": [
    {
      "fromBlock": "0x45a2409",
      "toBlock": "0x45a27f1"
    }
  ]
}

Respuesta de ejemplo

El ejemplo de respuesta de error correspondiente:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "eth_getLogs block range too large: max <N> blocks"
  }
}

Donde <N> es el max_logs_block_range de la cadena de destino (publicado a través de GET /v1/chains).

En una solicitud por lotes que contiene múltiples llamadas, si una llamada a eth_getLogs supera el límite de amplitud de bloques, ese elemento específico devuelve el error -32602 anterior y no se factura.

Realizar consultas fragmentadas

Para consultar logs en un intervalo grande de bloques, primero consulte el max_logs_block_range de la cadena de destino, divida el intervalo de destino en fragmentos contiguos de [from, from + max - 1] y envíe solicitudes secuenciales mientras agrega los resultados.

Los siguientes ejemplos utilizan robinhood_mainnet para demostrar las consultas fragmentadas:

export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# 1. Read max_logs_block_range from the public chains endpoint (unauthenticated, unbilled)
curl -s "https://api.blockvectra.com/v1/chains"

# 2. Make a single compliant request within the chain's max_logs_block_range (toBlock - fromBlock + 1)
curl -s "https://api.blockvectra.com/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"
    }]
  }'

Consideraciones sobre solicitudes por lotes

Si considera empaquetar múltiples consultas fragmentadas en una sola solicitud por lotes de JSON-RPC, tenga en cuenta las reglas sobre el tamaño de lote y la capacidad de ráfaga:

  • Límite de tamaño de lote: Las solicitudes por lotes aceptan de 1 a 100 llamadas. Enviar más de 100 llamadas se rechaza con HTTP 200 y el código de error -32600 batch too large: max 100 calls (no facturado).
  • Capacidad de ráfaga en una sola solicitud: Si el peso total de CU de las llamadas en una solicitud supera la capacidad de ráfaga de la clave (burst_cu), la solicitud se rechaza con HTTP 429 -32022 request cost <N> CU exceeds burst capacity <M> CU (no facturado); divídala en lotes más pequeños.
  • Capacidad de depósito insuficiente: Si la suma de los pesos totales no supera la capacidad de ráfaga pero el depósito de tokens carece de capacidad disponible suficiente, el servicio devuelve HTTP 429 con el código de error -32005 rate limit exceeded y Retry-After; consulte Qué no se factura: códigos de error y reglas de facturación para ver los detalles de reintento y facturación.

Por lo tanto, al realizar consultas de logs a gran escala, se recomiendan consultas fragmentadas secuenciales; si usa lotes, mantenga la cantidad de llamadas por lote lo suficientemente pequeña para que la suma de pesos totales permanezca dentro de la capacidad de ráfaga.

Guías relacionadas y reglas de facturación

Próximos pasos

Última actualización:

En esta página