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

Contract event listener is not firing when running hardhat tests #1692

Closed
adamdry opened this issue Jul 18, 2021 · 5 comments
Closed

Contract event listener is not firing when running hardhat tests #1692

adamdry opened this issue Jul 18, 2021 · 5 comments
Labels
type:bug Something isn't working

Comments

@adamdry
Copy link
Contributor

adamdry commented Jul 18, 2021

Here is a very small repo to show the issue: https://github.com/adamdry/ethers-event-issue

But I'll explain it here too. This is my contract:

//SPDX-License-Identifier: UNLICENSED;
pragma solidity 0.8.4;

contract ContractA {

    event TokensMinted(uint amount);

    function mint(uint amount) public {
        emit TokensMinted(amount);
    }

}

And this is my test code:

import * as chai from 'chai'
import { BigNumber, ContractTransaction } from 'ethers'
import { ethers } from 'hardhat'
import { ContractA, ContractAFactory } from '../typechain'

const expect = chai.expect

describe("Example test", function () {
    it("should fire the event", async function () {
        const [owner] = await ethers.getSigners();

        const contractAFactory = (await ethers.getContractFactory(
            'ContractA',
            owner,
        )) as ContractAFactory

        const contractA: ContractA = await contractAFactory.deploy()

        contractA.on('TokensMinted', (amount: BigNumber) => {
            // THIS LINE NEVER GETS HIT
            console.log('###########')
        })

        const contractTx: ContractTransaction = await contractA.mint(123)
        const contractReceipt: ContractReceipt = await contractTx.wait()

        for (const event of contractReceipt.events!) {
            console.log(JSON.stringify(event))
        }
    });
});

I was expecting the ########### to get printed to the console however it doesn't so the listener function isn't being executed for some reason.

If I dig into the ContractReceipt the correct event data is there:

{
  "transactionIndex": 0,
  "blockNumber": 2,
  "transactionHash": "0x55d118548c8200e5e6c19759d9aab56cb2e6a274186a92643de776d617d51e1a",
  "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
  "topics": [
    "0x772f66a00a405709c30e7f18feadcc8f123b20c09c7260165d3eec36c9f21372"
  ],
  "data": "0x000000000000000000000000000000000000000000000000000000000000007b",
  "logIndex": 0,
  "blockHash": "0x808e6949118509b5a9e482e84cf47921a2fcffbcd943ebbd8ce4f6671469ee01",
  "args": [
    {
      "type": "BigNumber",
      "hex": "0x7b"
    }
  ],
  "event": "TokensMinted",
  "eventSignature": "TokensMinted(uint256)"
}
@fvictorio
Copy link
Member

This might be a duplicate of #588

@fvictorio
Copy link
Member

Hey @adamdry, the reason this doesn't work is that ethers.js, by default, uses polling to get events, and the polling interval is 4 seconds. If you add this at the end of your test:

await new Promise(res => setTimeout(() => res(null), 5000));

you'll see the log being printed. (The null is just for the test to compile.) As far as I know, the only way for ethers to not do this is to use a WebSocketProvider, but we can't do that for the in-process Hardhat Network.

Also, I don't think the polling interval can be configured 🙁 But maybe you can check ethers.js discussions board to see if someone asked about that.

Closing this for now, but please re-open if you think there's something we can do on our side.

@feuGeneA
Copy link
Contributor

Also, I don't think the polling interval can be configured slightly_frowning_face But maybe you can check ethers.js discussions board to see if someone asked about that.

Actually the polling interval can be configured. See how I did it in this test: https://github.com/nomiclabs/hardhat/blob/master/packages/hardhat-ethers/test/index.ts#L642

Also, I commented in that test where I got this technique, but just convenience, here too is the source: ethers-io/ethers.js#615 (comment)

@fvictorio
Copy link
Member

@feuGeneA oh, nice. I tried modifying ethers.provider that way and couldn't do it, but I think that happens because hre.ethers is a proxied object.

@adamdry
Copy link
Contributor Author

adamdry commented Aug 31, 2021

@fvictorio @feuGeneA Thank you for your input! These are both very helpful to know. This solved my problem. Cheers!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type:bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants