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

> Source: https://docs.blockvectra.com/es/guides/getlogs-block-range/

## Respuesta directa

Una sola solicitud de `eth_getLogs` está limitada al `max_logs_block_range` de la cadena de destino desde [GET /v1/chains](https://api.blockvectra.com/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](https://docs.blockvectra.com/en/errors/#logs_range_too_large)). 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`.

```js
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](https://docs.blockvectra.com/en/chains/)). 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](https://api.blockvectra.com/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.

| Cadena | Slug de la cadena | max_logs_block_range (bloques) |
| --- | --- | --- |
| Arbitrum One | `arb_mainnet` | 1,000 |
| Base | `base_mainnet` | 1,000 |
| BNB Smart Chain | `bsc_mainnet` | 1,000 |
| Ethereum | `eth_mainnet` | 1,000 |
| Ethereum Sepolia | `eth_sepolia` | 1,000 |
| HyperEVM | `hyperevm_mainnet` | 1,000 |
| Polygon | `polygon_mainnet` | 1,000 |
| Robinhood Chain | `robinhood_mainnet` | 1,000 |
| Robinhood Chain Testnet | `robinhood_testnet` | 1,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 / identificador                                                        | Origen                                                                                                                                                              | Qué hacer                                                                                                                                                        |
| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `eth_getLogs block range too large: max <N> blocks`; `-32602`; `logs_range_too_large` | [Catálogo de errores de BlockVectra](https://docs.blockvectra.com/en/errors/#logs_range_too_large)                                                                                              | `<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](https://github.com/erigontech/erigon/blob/9e603d74f60c21ca793a03a7ce373de19aa3fdc7/rpc/jsonrpc/eth_receipts.go#L343-L347) | `<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](https://github.com/erigontech/erigon/blob/9e603d74f60c21ca793a03a7ce373de19aa3fdc7/rpc/jsonrpc/eth_receipts.go#L439-L442) | `<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:

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

### Respuesta de ejemplo

El ejemplo de respuesta de error correspondiente:

```json
{
  "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:

**cURL**

```bash
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"
    }]
  }'
```


  **TypeScript**

```ts
const CHAIN = "robinhood_mainnet";
const RPC_ENDPOINT = "https://api.blockvectra.com/v1/robinhood_mainnet";

// 1. Fetch max_logs_block_range from the public GET /v1/chains endpoint (unauthenticated, unbilled)
const chainsUrl = new URL("/v1/chains", RPC_ENDPOINT);
const chainsRes = await fetch(chainsUrl);
const { chains } = (await chainsRes.json()) as {
  chains: Array<{ chain: string; max_logs_block_range: number }>;
};

const targetChain = chains.find((c) => c.chain === CHAIN);
if (!targetChain) {
  throw new Error(`Chain ${CHAIN} not found`);
}

const maxRange = targetChain.max_logs_block_range;

// 2. Query chunks sequentially over [from, from + max - 1] and aggregate results (both endpoints inclusive)
const fromBlock = 0x45a2409;
const toBlock = 0x45a2900;

const allLogs: unknown[] = [];
let cur = fromBlock;

while (cur <= toBlock) {
  const chunkEnd = Math.min(cur + maxRange - 1, toBlock);

  const res = await fetch(RPC_ENDPOINT, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": process.env.BLOCKVECTRA_API_KEY!,
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "eth_getLogs",
      params: [
        {
          address: "0x1111111111111111111111111111111111111111",
          fromBlock: "0x" + cur.toString(16),
          toBlock: "0x" + chunkEnd.toString(16),
        },
      ],
    }),
  });

  const body = (await res.json()) as {
    result?: unknown[];
    error?: { code: number; message: string };
  };

  if (body.error) {
    throw new Error(`eth_getLogs error ${body.error.code}: ${body.error.message}`);
  }

  if (body.result) {
    allLogs.push(...body.result);
  }

  cur = chunkEnd + 1;
}

console.log(`Fetched ${allLogs.length} logs across blocks`);

// npx tsx example.mts
```


  **Python**

```python
import os
from urllib.parse import urljoin
import requests

CHAIN = "robinhood_mainnet"
RPC_ENDPOINT = "https://api.blockvectra.com/v1/robinhood_mainnet"

# 1. Fetch max_logs_block_range from the public GET /v1/chains endpoint (unauthenticated, unbilled)
chains_url = urljoin(RPC_ENDPOINT, "/v1/chains")
chains_res = requests.get(chains_url)
chains_res.raise_for_status()

chains = chains_res.json().get("chains", [])
target_chain = next((c for c in chains if c["chain"] == CHAIN), None)
if not target_chain:
    raise RuntimeError(f"Chain {CHAIN} not found")

max_range = target_chain["max_logs_block_range"]

# 2. Query chunks sequentially over [from, from + max - 1] and aggregate results (both endpoints inclusive)
from_block = 0x45a2409
to_block = 0x45a2900

all_logs: list = []
cur = from_block

while cur <= to_block:
    chunk_end = min(cur + max_range - 1, to_block)

    res = requests.post(
        RPC_ENDPOINT,
        headers={
            "Content-Type": "application/json",
            "x-api-key": os.environ["BLOCKVECTRA_API_KEY"],
        },
        json={
            "jsonrpc": "2.0",
            "id": 1,
            "method": "eth_getLogs",
            "params": [
                {
                    "address": "0x1111111111111111111111111111111111111111",
                    "fromBlock": hex(cur),
                    "toBlock": hex(chunk_end),
                }
            ],
        },
    )
    res.raise_for_status()
    body = res.json()

    if "error" in body:
        err = body["error"]
        raise RuntimeError(f"eth_getLogs error {err.get('code')}: {err.get('message')}")

    all_logs.extend(body.get("result", []))
    cur = chunk_end + 1

print(f"Fetched {len(all_logs)} logs across blocks")
```


## 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](https://docs.blockvectra.com/en/guides/billing-rules/) 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

* Consulte la [referencia del método eth\_getLogs](https://docs.blockvectra.com/en/api/json-rpc/methods/eth_getLogs/) para ver los parámetros de filtrado, los valores devueltos y los pesos de CU.
* Consulte la [referencia del error logs\_range\_too\_large](https://docs.blockvectra.com/en/errors/#logs_range_too_large) para ver detalles del error y acciones recomendadas.
* Para una comparación entre `eth_getLogs` y los endpoints de transferencias de la Data API (transferencias de direcciones y transferencias de tokens), incluidas las diferencias de cobertura y finalidad, consulte [Datos recientes del nodo frente a historial indexado: cuándo usar eth\_getLogs y cuándo usar la API de transferencias](https://docs.blockvectra.com/en/guides/logs-vs-transfers/).
* Para obtener detalles completos sobre unidades de cómputo (CU), liquidación horaria y respuestas de error no facturadas, consulte [Qué no se factura: códigos de error y reglas de facturación](https://docs.blockvectra.com/en/guides/billing-rules/).

## Próximos pasos

* [Explore el directorio de conjuntos de datos](https://blockvectra.com/en/data/) para ver todos los conjuntos de datos indexados por BlockVectra.
* [Consulte el plan gratuito y los precios](https://blockvectra.com/en/pricing/#free) para comprobar lo que incluye su cuenta.
* [Inicie sesión en la consola](https://console.blockvectra.com/login/?next=%2Fkeys%2F) para crear una API key.
