2

Currently there does not seem to be an easy way to query the content of multiple blocks in the same RPC operation, I guess for spam protection reasons?

What is then the best way to know how many concurrent requests can be fired to an RPC node from a client, and why is there no RPC to allow for more than a single block to be fetched? Not knowing the former means that if too many requests are fired, the node responds by closing the connection to the client, which is not desirable.

I am thinking to something like api.rpc.chain.getBlocks([hash_1, hash_2, hash_3])

2 Answers 2

1

Depends on what node you have. For a local node you can send as many requests as you want.
There are some additional flags like --rpc-max-request-size and --rpc-max-response-size that can be tweaked.
Keep in mind that an RPC node is not a database server. It is primarily a blockchain node which follows consensus. That it exposes RPC is more of a curtesy. If you want to query massive amounts of data; use an indexer which exposes proper DB operations.

Some naive JS implementation could use Promise.all to batch requests:

import { ApiPromise, WsProvider } from '@polkadot/api';

const wsProvider = new WsProvider('ws://localhost:9944');
const api = await ApiPromise.create({ provider: wsProvider });

// Load the last block number:
const lastHeader = await api.rpc.chain.getHeader();
var last_number = lastHeader.number.toBigInt();
console.log(`Last block number: ${last_number}`);

// Load all past blocks in batches of 10.
var total_blocks = 0;
for (;last_number > 0;) {
    var promises = [];
    for (var i = 0; i < 10 && last_number > 0; i++) {
        promises.push(api.rpc.chain.getBlockHash(last_number).then((hash) => 
            api.rpc.chain.getBlock(hash)
        ));
        last_number--;
    }
    var blocks = await Promise.all(promises);
    total_blocks += blocks.length;
    console.log(`Loaded ${blocks.length} more blocks, ${total_blocks} in total`);
}

If you do this with a non-archive node you will probably end up with a State already discarded error after 256 blocks.

1
  • It may be reasonable to assume that the person asking is trying to build an indexer.
    – Squirrel
    Nov 30, 2023 at 9:21
1

To complete Oliver's answer, the required functionality is already available on API Sidecar with the endpoint GET /blocks?range=0-499. You can query a max of 500 blocks at a time by specifying the initial and the final height to query at.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.