Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provider events are not being forwarded by wrapper #73

Open
fvictorio opened this issue Jul 11, 2024 · 4 comments
Open

Provider events are not being forwarded by wrapper #73

fvictorio opened this issue Jul 11, 2024 · 4 comments

Comments

@fvictorio
Copy link
Contributor

hre.network.provider is an EventEmitter. One way Hardhat uses this is to emit events when the network is reset or a snapshot is reverted. But when hardhat-tracer is used, any listener already set is "removed". This is easier to understand with an example.

Take this hardhat.config.js:

extendEnvironment(hre => {
  hre.network.provider.on("hardhatNetworkReset", () => console.log("reset"))
})

require("hardhat-tracer")

module.exports = {
  solidity: "0.8.24",
};

Here the extendEnvironment before loading hardhat-tracer is used to represent a plugin that registers a listener on the provider. I'm placing it before loading hardhat-tracer, but it actually doesn't matter if it's after it (because of the way Hardhat executes its initailization).

If you open a console with npx hardhat console and run await hre.network.provider.send("hardhat_reset"), you should see reset being logged, but it's not. If you comment out the hardhat-tracer require, then it will work as expected.

I'm not sure what's the right fix here, but I suspect wrapProvider should somehow re-register any listeners already set in the existing provider.

@zemse
Copy link
Owner

zemse commented Jul 11, 2024

I'm using BackwardsCompatibilityProviderAdapter, is this a problem with other plugins as well that use this adapter? In that case would it make sense for the BackwardsCompatibilityProviderAdapter to handle this? In case I need to do this I can do that.

@fvictorio
Copy link
Contributor Author

fvictorio commented Jul 11, 2024

So, as far as I understand, BackwardsCompatibilityProviderAdapter extends EventEmitterWrapper, which helps as a wrapper that forwards new registered events to the underlying provider. But I don't think it exposes existing registered listeners. Perhaps we could update it to do that, but it might be a bit risky since that's a very core component.

Since this bug happens with a very specific combination of ethers v5, hardhat-tracer, and fixtures/reset, IMO a less risky workaround at the hardhat-tracer would be ideal.

I can help with figuring out how to do it. Off the top of my head, you would need to do something like:

// get existing listeners and remove them from the provider
let eventListeners = {}
for (const eventName of provider.eventNames()) {
  eventListeners[eventName] = []
  for (const listener of provider.listeners(eventName)) {
    eventListeners[eventName].push(listener)
  }
  provider.removeAllListeners(eventName)
}

// wrap the provider as you are doing today
hre.network.provider = wrapProvider(...)

// re-register the listeners
for (const [eventName, listeners] of Object.entries(eventListeners)) {
  for (const listener of listeners) {
    hre.network.provider.on(eventName, listener)
  }
}

(I haven't tested this though)

zemse added a commit that referenced this issue Aug 5, 2024
@zemse
Copy link
Owner

zemse commented Aug 5, 2024

I have included this in [email protected]

@fvictorio
Copy link
Contributor Author

Tested my reproduction steps with v3.1.0 but the behavior is the same 😕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants