When filtering an event by multiple topics you expect testrpc to return all events that match your topics.
For example if you have an event MyEvent which contains a bytes32 indexed field username:
event MyEvent(bytes32 indexed username);
And you filter MyEvent by multiple topics (usernames):
const myEvent = instance.MyEvent(
{ username: ["henry", "billy"] },
{
fromBlock: 0,
toBlock: "latest"
}
);
myEvent.watch((err, res) => console.log(res));
You would expect to receive all events where username matches "henry" or "billy" from block 0 up to the latest block.
You can successfully filter the above event by only one topic:
const myEvent = instance.MyEvent(
{ username: ["henry"] },
{
fromBlock: 0,
toBlock: "latest"
}
);
myEvent.watch((err, res) => console.log(res));
In the example above you will successfully receive all events from block 0 where the username is "henry". If you change "henry" to "billy" you will also successfully receive all events from block 0 where the username is "billy".
However, if you filter by multiple topics you will receive no events from testrpc.
```
const myEvent = instance.MyEvent(
{ username: ["henry", "billy"] },
{
fromBlock: 0,
toBlock: "latest"
}
);
myEvent.watch((err, res) => console.log(res));
The above example will not return any events.
The topics successfully make it to testrpc too but it does not return the events:
{
"jsonrpc":"2.0",
"id":15,
"method":"eth_newFilter",
"params":[
{
"topics":[
"0x0b359f4efbc50d2440bd4e2b304c6896768824a96dde51c585b6c2a9fcb1aec2",
[
"0x68656e7279000000000000000000000000000000000000000000000000000000",
"0x62696c6c79000000000000000000000000000000000000000000000000000000"
]
],
"address":"0x92e359fd56617571ec94de1281792c20f878f05a",
"fromBlock":"0x0"
}
],
"external":true
}
```
ethereumjs-testrpc v3.0.3
web3 ^0.18.4
OSX 10.11.6
It looks like this line in getLogs is causing issues and that it does not support multiple topic filters in general.
What confused me the most was that if getLogs doesn't support an array of topics why does passing an array with just one topic work? For example like in my snippet above: username: ["henry"]. It's because javascript is weird and evaluates the following as true:
"henry" == ["henry"]
And so the issue is the following code in getLogs, which makes it seem like an array is accepted when really it isn't:
expectedTopics[i] != log.topics[i]
Anyway, I'm about to submit a PR for a fix to that issue and to accept multiple topic filters.
Nice catch! Bonus points if you add a test...
I did! 馃憤 馃槃
I'm not sure testrpc events work very well AT ALL. I have specific web3.js watchers for events fired by multiple contracts - they work perfectly using geth, but barely at all using testrpc.
Just a side note that could be relevant.
Also, please be aware that it seems multiple addresses for eth_newFilter are not supported.
Unlike geth (which address: DATA|Array), ganache is only capable of filtering on a single address.
It has something in lines of blockLogs.filter(function(log) { return (expectedAddress == null || log.address == expectedAddress); }) which obviously only assumes strings - but I've lost track of where it currently is on the master branch so can't pinpoint the current location.
@drdaeman it would be great if you raised a new issue for that so that we don't lose track of it!
@benjamincburns Sure. Found the relevant code and posted an issue in ganache-core: https://github.com/trufflesuite/ganache-core/issues/38
I'm pretty this was closed due to #323, but we'd like to still validate this before closing
This issue has been validated and no longer exists. Closing the issue.
Most helpful comment
This issue has been validated and no longer exists. Closing the issue.