Replies: 6 comments 5 replies
-
Do you mean the past events from the current block (the last mined block)? The pooling mechanism in ethers.js considers block numbers up to This is generally not a problem when you have a chain continuously mining blocks in a short interval. But if you have a chain with a large block time or an environment like ganache, which mines a block only when a tx is received. To handle these situations, the logic you described is fine. const startBlockNumber = await provider.getBlockNumber();
contract.on(filter, (...args) => {
const event = args[args.length - 1];
if(event.blockNumber <= startBlockNumber) return; // do not react to this event
// further logic
}) |
Beta Was this translation helpful? Give feedback.
-
So shouldn't it consider currentBlockNumber as the past block too since if eventListener is attached on it, it is obvious that the eventListener will be looking for events in the next block? Or we should provide some string like "latest"(as is the case with Web3js) where it only listens to Future Events? |
Beta Was this translation helpful? Give feedback.
-
Actually Though I understand what you mean. But I think it depends on what you consider a confirmed block. All the blocks behind your confirmation block are in the past, while anything next to it is in the future. If you don't consider any confirmations, then it can be valid to consider the current block as past (in the case of PoA chains, or Ganache). In ethereum mainnet, most of the forked blocks have a depth of 1. So you can fairly say the block behind the current block is in the past but the current block is not necessarily past yet. |
Beta Was this translation helpful? Give feedback.
-
Yes, ethers considers the current block as part of "from now on". Often you want your process that is mining information to start with events from the current block. There are many use cases for the event emitter, and if the event listener is registered outside the context of a transaction, there is no distinction between starting at the current block or next block. And if you submit a transactions, that certainly won't be part of the current block, so in those cases it is handled implicitly. You can either add a guard in your event handler (like your above example), or something like this might work for your purposes too: provider.once("block", () => {
provider.on(filter, (...args) => { ... });
}); Does that make sense? |
Beta Was this translation helpful? Give feedback.
-
(moving to discussions) |
Beta Was this translation helpful? Give feedback.
-
I still have this issue. I'm running ethers.js 5.6.8 with HardHat environment. I'm building a basic ERC721 contract. When I register a listener, I receive all events that have been emitted from the contract from its creation. If I add
Here's the event code:
The event handler is registered once, so this is not the issue. |
Beta Was this translation helpful? Give feedback.
-
The closed issue here talks about how to obtain future events as @mrwillis previous example of getting only future events, does produce events from the past as well.
@ricmoo has pointed out a poll approach using queryFilter, but if we want to subscribe to events, and only get for future events, I don't see there is way to do that with contract.on() - is that correct? queryFilter is only going to allow for a polling approach as opposed to being notified on an emitted Solidity event.
The only way I have found for this to work, is to get the current block number
getBlockNumber
and check on every fired event that I am subscribed tocontract.on(filter, callback))
and react to only block number above the current block number.Beta Was this translation helpful? Give feedback.
All reactions