Search code examples
node.jsweb3jsbsc

Web3 BSC pair contract returning a -32602 error


I'm trying to load all Sync events for a BSC pair on Pancake Swap. I'm using one of the free quiknode BSC nodes and nodejs web3 library.

The request looks like this:

const blocksPerRequest = 10;
    const reserves = await pairContract.getPastEvents('Sync', {
      filter: {},
      fromBlock: blockNumber - BigInt((i +1) * blocksPerRequest),
      toBlock: blockNumber - BigInt(i * blocksPerRequest),
    });

the i variable is set to 0.

I'm getting this error that the requests are limited to 10000 but I'm only loading these events for 10 blocks:

innerError: {
    code: -32602,
    message: 'getMultipleAccounts, eth_getLogs, and eth_newFilter are limited to a 10000 range'
  },
  code: 101,
  data: undefined,
  request: {
    jsonrpc: '2.0',
    id: '96ec05fe-b8ad-4cfa-8abf-9eaf7fb22c69',
    method: 'eth_getLogs',
    params: [
      {
        fromBlock: '0x20793fc',
        toBlock: '0x2079406',
        topics: [
          '0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1'
        ],
        address: '0x8ff7115defd48165aa3f70153a644e8f58e71f42'
      }
    ]
  }```

This was working a few months ago.

Solution

  • The issue, which states that requests are limited to 10,000, is likely due to the limitations imposed by the QuikNode BSC node you're using. Nodes often have constraints on the number of records they can return in a single call to prevent overloading. This limit is not about the number of blocks you're querying but the total number of event logs (in your case, 'Sync' events) that the node is willing to return in a single request. Here is quicknode pricing.

    const Web3 = require('web3');
    const web3 = new Web3('YOUR_QUICKNODE_BSC_URL');
    
    // Assuming you have already initialized the pairContract
    // ...
    
    async function loadSyncEvents(pairContract, startBlock, endBlock, maxBlocksPerRequest) {
        let events = [];
        while (startBlock <= endBlock) {
            let toBlock = Math.min(startBlock + maxBlocksPerRequest - 1, endBlock);
            try {
                let batchEvents = await pairContract.getPastEvents('Sync', {
                    fromBlock: startBlock,
                    toBlock: toBlock,
                });
                events = events.concat(batchEvents);
                startBlock = toBlock + 1;
            } catch (error) {
                console.error(`Error fetching events for blocks ${startBlock} to ${toBlock}: ${error}`);
                if (maxBlocksPerRequest > 1) {
                    // If error, try with fewer blocks
                    maxBlocksPerRequest = Math.floor(maxBlocksPerRequest / 2);
                } else {
                    // If already at minimum block range, log and skip ahead
                    console.error(`Skipping blocks ${startBlock} to ${toBlock}`);
                    startBlock = toBlock + 1;
                }
            }
        }
        return events;
    }
    
    // Example usage:
    const startBlock = /* Your start block number */;
    const endBlock = /* Your end block number */;
    const maxBlocksPerRequest = 10; // You can adjust this based on your requirements
    
    loadSyncEvents(pairContract, startBlock, endBlock, maxBlocksPerRequest)
        .then(events => {
            console.log(`Loaded ${events.length} Sync events`);
            // Process events...
        })
        .catch(error => {
            console.error('Failed to load events:', error);
        });
    

    Above is a demo code where you can add dynamic block range adjustment. Hope it will help you!