Web3js – Fixing getPastLogs Error: Query Returned More than 10000 Results

filtersgo-ethereumlogstransactionsweb3js

I have a local ethereum node and I am trying to filter an event for a contract address between a range of blocks. However it throws the following error:

node:15689) UnhandledPromiseRejectionWarning: Error: Returned error: query returned more than 10000 results
    at Object.ErrorResponse (/mnt/ssd/abi_extraction/node_modules/web3-core-helpers/src/errors.js:29:16)
    at /mnt/ssd/abi_extraction/node_modules/web3-core-requestmanager/src/index.js:170:36
    at XMLHttpRequest.request.onreadystatechange (/mnt/ssd/abi_extraction/node_modules/web3-providers-http/src/index.js:111:13)
    at XMLHttpRequestEventTarget.dispatchEvent (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpResponseEnd (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
    at IncomingMessage.<anonymous> (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
    at IncomingMessage.emit (events.js:203:15)
    at endReadableNT (_stream_readable.js:1145:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
(node:15689) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:15689) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This was when my toBlock was 9095563 and fromBlock was 8945008. Even when I reduced the block range by a mere 10 blocks, it was returning the same error. My code is below:

const Web3 = require('web3');
const fetch = require('node-fetch');

let infura_url = "https://mainnet.infura.io/v3/853346f695b740fe8bd7d8f583bcf55f"
let web3 = Web3(Web3.IPCProvider("./../.ethereum/geth.ipc"))

const params = {
    address: "0x0e3a2a1f2146d86a604adc220b4967a898d7fe07",
    topics: ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],
    fromBlock: 8945008,
    toBlock: 9095563  
};

web3.eth.getPastLogs(params).then(response => {
    console.log(response);
});

Is there a way to bypass this so that I can get more than 10000 results:

  1. For 10 block difference issue
  2. For the range mentioned in the code.

Best Answer

You can solve this problem using Divide & Conquer strategy:

async function getPastLogs(web3, address, topics, fromBlock, toBlock) {
    if (fromBlock <= toBlock) {
        try {
            return await web3.eth.getPastLogs({address, topics, fromBlock, toBlock});
        }
        catch (error) {
            const midBlock = (fromBlock + toBlock) >> 1;
            const arr1 = await getPastLogs(web3, address, topics, fromBlock, midBlock);
            const arr2 = await getPastLogs(web3, address, topics, midBlock + 1, toBlock);
            return [...arr1, ...arr2];
        }
    }
    return [];
}
Related Topic