Description
Ok, found some weird behaviour that may need an explanation, or is a bug.
When I listen for an event in multiple places, i.e.:
const contract = new ethers.Contract(...etc, ethersProvider)
var filter = contract.filters.TestEvent()
ethersProvider.on(filter, console.log) // listen in one place
ethersProvider.on(filter, console.log) // listen in another place
When the smart contract emits a TestEvent, the above code prints out the event four times.
If I added a third ethersProvider.on(filter, console.log)
then it prints out the event nine times.
I think I have an explanation:
-
Looking at the BaseProvider class, it appears that the filters are stored in a
_events
array using the _addEventListener() function. -
Events are broadcast using a polling function. When a new block comes in, it loops through all of the
_events
to see what needs to be emitted from the block.
For each log
that matches the _event
, it is emitted using the emit() function
- Finally, the
emit()
function dispatches the log to every_event
that was listening to it.
Now, this would explain the (event listeners)^2 results I was getting above, because:
poll()
: For each listener, find the block logs that match the listener and callemit()
emit()
: Receive log, find each listener that is listening to the log and dispatch it
Thoughts?
Activity