We’ve been discussing in a past blog article about the way we were able to reliable provide blockchain events at scale. That architecture has been greatly improved since then and it’s been extending across multiple networks.
As we all know, no system is error free so it’s always good to have your code catching and reacting on any sporadic inconsistencies.
There’s a common technique used by developers when scanning for smart contract logs - one would call eth_blockNumber and then used it as a
toBlock argument in the getLogs request.
By doing this it’s easy to control the block ranges that you’re scanning. However, because of the lack of standard in JSON-RPC on how clients handle an empty vs a missing block in
eth_getLogs this could expose a bit of inconsistency around the chain head. We mimic Geth’s behaviour (and many other blockchain clients for that matter) which is returning an empty list when the block is missing.
So the question is, how can I be sure that I have received all the logs from that block range ? Or maybe better, how can I make sure that whatever serves my
getLogs request knows about the last block I’ve retrieved via
There is a simple way to check if that block has logs or not by calling eth_getBlockByNumber - check
logsBloom value. If it contains
0x000000000........00000000 , then that block does not have any logs.
That way you’ll know and you can verify the getLogs response, if you were expecting logs for that last block and you have none then the safest thing is to retry the request, it could be some delay in indexing the last block.
Of course, you could also subscribe and listen for events via websockets subscriptions. In that case don’t forget to deal with potential disconnects on idle connections, see Web3.js How to keep Websocket subscriptions alive and reconnect on failures