A rate limit, malformed response, or process restart can interrupt a log scan after successful chunks. The useful question then is not "how do I re-run the query?" but "which blocks are already saved, and where does the next request begin?"
The first response is not a saved checkpoint
A returned eth_getLogs result is only candidate data. The client advances to the next block only after two things happen in order: the HTTP status and JSON-RPC envelope pass validation (jsonrpc, id, no error, and result is an array), and a new checkpoint containing that chunk has been committed to disk. A successful empty array is valid. If either validation or the commit fails, the run stops at that chunk. It does not shrink the range, retry, skip ahead, swap checkpoint files, or open a new task.
Run a fixed window
Before adding a fallback, list the calls your scanner actually makes: for example, eth_blockNumber, eth_getLogs, and any block or transaction lookups in your processor. Matching eth_chainId alone doesn't confirm those methods, permitted block ranges, or historical coverage. Check public and keyed endpoint policies separately. RPC workflow checklist.
Use Node.js 24 or later. Get your API key from the BlockVectra console, then download the client example first.
Pick a chain, address, and inclusive fromBlock/toBlock that you have confirmed and that the node currently serves.
# Supply BLOCKVECTRA_API_KEY through your secret manager/environment.
export CHAIN="<confirmed-chain-slug>"
export LOG_ADDRESS="<confirmed-address>"
export FROM_BLOCK="<confirmed-start-block>"
export TO_BLOCK="<confirmed-end-block>"
export CHECKPOINT_FILE="./getlogs-checkpoint.json"
# optional: export CHUNK_BLOCKS=100
node getlogs-resumable.mjs
Replace every placeholder with your own confirmed values. BLOCKVECTRA_API_KEY is read from your own environment; the client does not create accounts. CHUNK_BLOCKS is optional and must be a positive decimal integer. Each request spans min(CHUNK_BLOCKS, max_logs_block_range) blocks, where the limit is read live from GET /v1/chains; without CHUNK_BLOCKS, the catalog value is used. Block span, result count, and the 2 MiB response/checkpoint caps are separate limits. The task allows 20 saved chunks, including restored ones.
Stop, then continue the same task
Change nothing in the task identity: same chain, address, and complete window. Keep the same checkpoint file and run again. The client re-validates the checkpoint's task binding, contiguous chunk order, and nextBlock, then requests only blocks not yet saved. You may change CHUNK_BLOCKS on resume; it only affects how the remaining range is split and never re-fetches saved chunks.
One process holds the checkpoint at a time through CHECKPOINT_FILE.lock; if a crash leaves the lock behind, confirm that no process owns it, then remove it manually. Checkpoints are written through a 0600 temporary file, fsync, and an atomic rename. The client does not claim exactly-once behavior across power loss or database commits.
A final complete status means the client read every block in that fixed window successfully. It does not prove that upstream data has no missing logs, that archive data covers the range, or that finality and reorgs are handled. Persist idempotently and verify chain hashes on the consumer side.
Check one block against its receipts
A saved checkpoint tells you where a scan stopped. It does not tell you whether an RPC returned every log. For a suspicious block, the new offline checker compares the complete transaction-hash list and one receipt per transaction with your saved eth_getLogs result.
node getlogs-reconcile-block.mjs block-material.json
Use Node.js 24 or later; the script makes no network calls and does not modify checkpoints. The guide describes the input format and optional address/topic filter. It returns consistent, inconsistent or unresolved. Keep a range unresolved on either of the latter two results. Agreement between the supplied files does not establish canonicality, validate a receipts root or prove complete history.
The full walkthrough, limits, and recovery rules are in the resumable eth_getLogs guide. You can also download the public client example and check its 35 synthetic response fixtures with a mock transport.
Top comments (0)