Лимит диапазона блоков eth_getLogs и составные запросы

При ошибке logs_range_too_large прочитайте max_logs_block_range сети, разбейте диапазон блоков с включением обоих концов в пределах лимита и переходите дальше только после успеха текущего фрагмента.

Прямой ответ

Один запрос eth_getLogs ограничен значением max_logs_block_range целевой сети из GET /v1/chains (для HyperEVM — 1,000 блоков), с подсчетом toBlock − fromBlock + 1 блоков. Превышение лимита возвращает HTTP 200, JSON-RPC -32602 и error.data.reason: logs_range_too_large с retryable: false (см. каталог ошибок). Разделите интервал на [from, min(from + max − 1, end)] и переходите к блоку, следующему за концом предыдущего фрагмента, после успеха.

  • Первый шаг: выполните curl -s "https://api.blockvectra.com/v1/chains" и прочитайте max_logs_block_range, methods.allow и methods.deny целевой сети.
  • Критерий завершения: logs-minimal.mjs выводит fromBlock, toBlock и массив result для каждого завершенного фрагмента вплоть до выбранного TO_BLOCK без ошибок HTTP или JSON-RPC.

Параметры сети и варианты доступа.

Сохраните этот код как logs-minimal.mjs, задайте BLOCKVECTRA_API_KEY, адрес контракта LOG_ADDRESS, а также подтвержденное окно блоков в FROM_BLOCK и TO_BLOCK, затем запустите node logs-minimal.mjs с Node.js 24 или новее. Выберите сеть с помощью CHAIN; по умолчанию используется 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;
}

Каждая строка вывода представляет собой завершенный фрагмент. Любая ошибка HTTP или JSON-RPC останавливает выполнение примера, не пропуская завершившийся сбоем фрагмент. Рекомендации по пакетной обработке и лимитам скорости для обработки ошибок 429 см. ниже.

Лимиты диапазона блоков eth_getLogs

При вызове метода JSON-RPC eth_getLogs диапазон блоков одного запроса вычисляется как toBlock − fromBlock + 1 и не может превышать опубликованное значение max_logs_block_range целевой сети.

Этот лимит различается в зависимости от сети. Параметры для каждой сети публикуются через публичный эндпоинт GET /v1/chains (список сетей приведен на странице Поддерживаемые сети). Этот эндпоинт не требует аутентификации и не тарифицируется. При разработке клиентских приложений запрашивайте этот эндпоинт динамически во время выполнения вместо жесткого кодирования лимитов диапазона блоков в коде.

Поля фильтра fromBlock и toBlock по умолчанию принимают значение latest, если они опущены или равны null.

Лимиты eth_getLogs по сетям

Ниже приведены значения max_logs_block_range для каждой сети, опубликованные в GET /v1/chains. «Не опубликовано» не означает отсутствие ограничений. Также проверьте methods.allow и methods.deny перед вызовом, при этом deny имеет приоритет; лимит диапазона блоков действует отдельно от лимитов на количество результатов или длительность выполнения запроса.

СетьСлаг сетиmax_logs_block_range (блоков)
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

Распространенные сообщения об ошибках дословно

Различайте диапазон блоков, количество результатов и длительность запроса: один и тот же код JSON-RPC может описывать разные типы сбоев.

Текст ошибки / идентификаторИсточникЧто делать
eth_getLogs block range too large: max <N> blocks; -32602; logs_range_too_largeКаталог ошибок BlockVectra<N> — это max_logs_block_range сети; уменьшите диапазон перед повторной отправкой. Повтор без изменений не поможет.
query block range exceeds server limit, narrow your filter: <N>Исходный код eth_getLogs в Erigon<N> — лимит диапазона этого узла; уменьшите запрашиваемый интервал перед повторной отправкой.
query returns too many logs, narrow your filter: <N>Исходный код eth_getLogs в Erigon<N> — лимит результатов этого узла; уменьшите интервал и сузьте параметры address и topics. Для одного блока могут потребоваться более конкретные фильтры.

В этих шаблонах сообщений <N> заменяется лимитом конкретного эндпоинта. Сторонние сообщения относятся к их собственным эндпоинтам и лимитам; формулировки могут различаться в зависимости от версии клиента. Для BlockVectra используйте /v1/chains и error.data.reason.

Превышение лимита диапазона блоков

Когда диапазон блоков одного запроса toBlock − fromBlock + 1 превышает max_logs_block_range сети, запрос отклоняется со статусом HTTP 200 и ошибкой JSON-RPC:

  • Код ошибки: -32602
  • Сообщение об ошибке: eth_getLogs block range too large: max <N> blocks
  • Статус тарификации: Не тарифицируется.

Пример запроса

Этот запрос превышает лимит только в том случае, если диапазон его блоков больше текущего max_logs_block_range целевой сети:

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

Пример ответа

Пример соответствующего ответа с ошибкой:

{
  "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. 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"
    }]
  }'

Особенности пакетных запросов

Если вы рассматриваете возможность упаковки нескольких составных запросов в один пакетный запрос JSON-RPC, учитывайте правила пакетной обработки и емкости всплеска:

  • Лимит размера пакета: Пакетные запросы принимают от 1 до 100 вызовов. Отправка более 100 вызовов отклоняется с HTTP 200 и кодом ошибки -32600 batch too large: max 100 calls (не тарифицируется).
  • Емкость всплеска одиночного запроса: Если суммарный вес вызовов в одном запросе в CU превышает емкость всплеска ключа (burst_cu), запрос отклоняется с HTTP 429 -32022 request cost <N> CU exceeds burst capacity <M> CU (не тарифицируется); разделите его на пакеты меньшего размера.
  • Недостаточная емкость корзины: Если сумма полных весов не превышает емкость всплеска, но в корзине токенов недостаточно доступной емкости, сервис возвращает HTTP 429 с кодом ошибки -32005 rate limit exceeded и заголовком Retry-After; подробности о повторных попытках и тарификации см. в руководстве Что не тарифицируется: коды ошибок и правила тарификации.

Поэтому при выполнении крупномасштабных запросов логов рекомендуются последовательные фрагментированные запросы; при пакетной обработке сохраняйте количество вызовов в пакете достаточно малым, чтобы сумма полных весов оставалась в пределах емкости всплеска.

Следующие шаги

Последнее обновление:

На этой странице