Batas rentang blok eth_getLogs dan kueri terbagi

Tangani batas rentang blok eth_getLogs dan error logs_range_too_large: baca max_logs_block_range setiap rantai dan bagi kueri lebar menjadi chunk.

Jawaban langsung

Satu permintaan eth_getLogs dibatasi oleh max_logs_block_range rantai target dari GET /v1/chains (untuk HyperEVM, 1,000 blok), dengan menghitung toBlock − fromBlock + 1 blok. Melebihinya mengembalikan HTTP 200, JSON-RPC -32602 dan error.data.reason: logs_range_too_large, dengan retryable: false (lihat katalog error). Bagi interval menjadi [from, min(from + max − 1, end)] dan lanjutkan ke akhir chunk sebelumnya ditambah satu setelah berhasil.

Simpan ini sebagai logs-minimal.mjs, tetapkan BLOCKVECTRA_API_KEY, alamat kontrak LOG_ADDRESS, dan jendela blok terkonfirmasi di FROM_BLOCK dan TO_BLOCK, lalu jalankan node logs-minimal.mjs dengan Node.js 24 atau lebih baru. Pilih rantai dengan CHAIN; default-nya adalah 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;
}

Setiap baris output adalah chunk yang telah selesai. Setiap error HTTP atau JSON-RPC menghentikan contoh tanpa melewati chunk yang gagal. Lihat panduan batch dan batas laju di bawah untuk menangani 429.

Batas rentang blok eth_getLogs

Saat memanggil metode JSON-RPC eth_getLogs, rentang blok dari satu permintaan dihitung sebagai toBlock − fromBlock + 1 dan tidak boleh melebihi max_logs_block_range yang dipublikasikan rantai target.

Batas ini bervariasi menurut rantai. Parameter per-rantai dipublikasikan melalui endpoint publik GET /v1/chains (rantai tercantum di Rantai yang Didukung). Endpoint ini tidak diautentikasi dan tidak ditagih. Saat mengembangkan aplikasi klien, kueri endpoint ini secara dinamis pada waktu proses alih-alih melakukan hardcoding batas rentang blok ke dalam kode Anda.

Bidang filter fromBlock dan toBlock default ke latest jika dihilangkan atau bernilai null.

Batas eth_getLogs menurut rantai

Ini adalah nilai max_logs_block_range setiap rantai yang dipublikasikan oleh GET /v1/chains. "Tidak dipublikasikan" bukan berarti tidak terbatas. Periksa juga methods.allow dan methods.deny sebelum memanggil, dengan deny didahulukan; batas rentang blok terpisah dari batas jumlah hasil atau batas durasi kueri.

RantaiSlug rantaimax_logs_block_range (blok)
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

Pesan error umum, kata demi kata

Bedakan rentang blok, jumlah hasil, dan durasi kueri: kode JSON-RPC yang sama dapat menjelaskan kegagalan yang berbeda.

Teks error / pengidentifikasiSumberYang harus dilakukan
eth_getLogs block range too large: max <N> blocks; -32602; logs_range_too_largeKatalog error BlockVectra<N> adalah max_logs_block_range rantai; kurangi rentang sebelum mengirim ulang. Mencoba ulang tanpa perubahan tidak akan membantu.
query block range exceeds server limit, narrow your filter: <N>Sumber eth_getLogs Erigon<N> adalah batas rentang node tersebut; kurangi interval yang dikueri sebelum mengirim ulang.
query returns too many logs, narrow your filter: <N>Sumber eth_getLogs Erigon<N> adalah batas hasil node tersebut; kurangi interval dan persempit address serta topics. Satu blok mungkin masih memerlukan filter yang lebih spesifik.

Dalam templat pesan ini, <N> digantikan oleh batas endpoint. Pesan pihak ketiga merujuk ke endpoint dan batas mereka sendiri; susunan kata dapat bervariasi menurut versi klien. Untuk BlockVectra, gunakan /v1/chains dan error.data.reason.

Melebihi batas rentang blok

Ketika rentang blok dari satu permintaan toBlock − fromBlock + 1 melebihi max_logs_block_range rantai, permintaan ditolak dengan HTTP 200 dan error JSON-RPC:

  • Kode error: -32602
  • Pesan error: eth_getLogs block range too large: max <N> blocks
  • Status penagihan: Tidak ditagih.

Contoh permintaan

Permintaan ini melebihi batas hanya jika rentang bloknya lebih besar dari max_logs_block_range rantai target saat ini:

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

Contoh respons

Contoh respons error terkait:

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

Di mana <N> adalah max_logs_block_range rantai target (dipublikasikan melalui GET /v1/chains).

Dalam permintaan batch yang berisi beberapa panggilan, jika panggilan eth_getLogs melebihi batas rentang blok, item spesifik tersebut mengembalikan error -32602 di atas dan tidak ditagih.

Menjalankan kueri terbagi

Untuk mengueri log pada interval blok yang besar, kueri max_logs_block_range rantai target terlebih dahulu, bagi interval target menjadi chunk bersebelahan sebesar [from, from + max - 1], dan kirim permintaan berurutan sambil menggabungkan hasilnya.

Contoh berikut menggunakan robinhood_mainnet untuk mendemonstrasikan kueri terbagi:

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

Pertimbangan permintaan batch

Jika Anda mempertimbangkan untuk mengemas beberapa kueri terbagi ke dalam satu permintaan batch JSON-RPC, perhatikan aturan ukuran batch dan kapasitas burst:

  • Batas ukuran batch: Permintaan batch menerima 1 hingga 100 panggilan. Mengirimkan lebih dari 100 panggilan akan ditolak dengan HTTP 200 dan kode error -32600 batch too large: max 100 calls (tidak ditagih).
  • Kapasitas burst permintaan tunggal: Jika jumlah bobot CU dari panggilan dalam satu permintaan melebihi kapasitas burst kunci (burst_cu), permintaan ditolak dengan HTTP 429 -32022 request cost <N> CU exceeds burst capacity <M> CU (tidak ditagih); bagi menjadi batch yang lebih kecil.
  • Kapasitas bucket tidak mencukupi: Jika jumlah bobot penuh tidak melebihi kapasitas burst tetapi token bucket tidak memiliki kapasitas yang cukup tersedia, layanan mengembalikan HTTP 429 dengan kode error -32005 rate limit exceeded dan Retry-After; lihat Apa yang tidak ditagih: kode error dan aturan penagihan untuk detail percobaan ulang dan penagihan.

Oleh karena itu, saat melakukan kueri log berskala besar, kueri terbagi berurutan direkomendasikan; jika menggunakan batch, jaga jumlah panggilan per batch cukup kecil agar jumlah bobot penuh tetap berada dalam kapasitas burst.

Panduan terkait dan aturan penagihan

Langkah selanjutnya

Terakhir diperbarui:

Di halaman ini