[question] Order of provider block callback
See original GitHub issueHello! Thank you for ethers.js, it is undoubtably my favorite library for interacting with the blockchain.
I would like to understand better the ordering between provider block callback and contract event callbacks ie.
contract.on('MyEvent', () => {});
provider.on('block', () => {});
When a new block is mined, I understand that the events callbacks will be invoked in the order the events occurred within the block. After the events have played for a new block I would like to do some state processing. Is the ‘block’ callback invoked at the beggining or the end of this sequence? Is it possible to trigger a callback once a block has finished invoking the event callbacks (at the end)? Thank you!
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Advanced Callbacks | Dash for Python Documentation | Plotly
In order to unblock the execution of these callbacks, first callbacks whose inputs are immediately available must be executed.
Read more >Sleep main thread but do not block callbacks - node.js
Collecting my comments into an answer per your request: Well, deasync (which sleep() depends on) uses quite a hack.
Read more >Block Callbacks - MATLAB & Simulink - MathWorks
If a block callback executes before or after a modeling action takes place, that callback occurs immediately before or after the action.
Read more >Node.js Interview Questions You'll Need to Answer - TMS
A. At the completion of a task, a callback function is called to allow other code to be run in the meantime with...
Read more >Callbacks - MoodleDocs
Callback functions one-to-one. Core API (or plugins such as blocks or reports) looks for and executes a method from the plugin/component ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Keep in mind reserEventsBlock is going away in v6. It was a bandaid added before the
contract.queryFilter
was added.I would not think that is a guarantee that code (in general) would enforce though. And there are a few important caveats.
The
didPoll
only happens after apoll
, which means the provider must be polling (i.e. have a pollable event).If you are using a dev node, it starts off with a blockNumber of 0. Certain blockNumbers are used internally, like -2 to setting to
blockNumber - 10
could set a negative blockNumber in the provider and cause havoc to ensue.More generally code like that won’t work though because events are emitted using the next event loop and your first line of
await getBlockNumber()
inside the listener will be scheduled for some future event loop, but not in any way that guarantees the call internal to the polling loop completed first. These are after all, largely calls over the internet; some response can be fast and some slow, especially when you consider backend services often throttle and ethers uses exponential back-off.Anyways, if you really need order that closely monitored, I would recommend using just the
"block"
event and then running your ownqueryFilter
orqueryLogs
for that range. Keep I. Mind you would need to sequentialize your listener.You also probable want to make sure a block has some extra confirmations too, like on each block only process up to
blockNumber - 12
To protect yourself from reorgs.It’s a lot to make sense of, but does that make sense? 😃
The block event is triggered first (internally the provider uses this to trigger scanning for events). Keep in mind this is just the order things are added to the event loop. Additional delays may occur when resolved ens names, and other things done for optimization.
I would say not to rely on this strict ordering though, since some providers offer their own event scheduling, such as the WebSocketProvider, which uses whatever scheduler the node uses.
In the case of the polling providers, there is a
didPoll
event. You could check the blockNumber at each event to see if it has changed?For your purpose, you could also just trigger your callback in a setTimeout with an interval of 0 (or setImmediate in node), which will pint it to the next event loop.
Does that help?