Skip to content

Events matching a filter are fired by the square of the number of filters #404

Closed
@asselstine

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:

  1. Looking at the BaseProvider class, it appears that the filters are stored in a _events array using the _addEventListener() function.

  2. 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

  1. 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:

  1. poll(): For each listener, find the block logs that match the listener and call emit()
  2. emit(): Receive log, find each listener that is listening to the log and dispatch it

Thoughts?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

bugVerified to be an issue.fixed/completeThis Bug is fixed or Enhancement is complete and published.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions