Web3.py: createFilter event syntax does not work while eventFilter works

Created on 8 May 2018  路  5Comments  路  Source: ethereum/web3.py

  • Version: 4.2.0
  • Python: 3.6
  • OS: linux

What was wrong?

Filtering for an event with Syntax 2 does not work, while the deprecated Syntax 1 works:

Syntax 1:

event_filt= instance.eventFilter(
        'EventName',
        {
            'fromBlock': 0,
            'toBlock': 'latest',
        })

Syntax 2

event_filt = instance.events.EventName.createFilter(fromBlock=0, toBlock='latest')

How can it be fixed?

By inspecting event_filt.filter_params, when using Syntax 2, the address field is populated with a list which includes the contract address twice. This happens because in the following snippet, the call is made to construct_event_filter_params with both address and contract_address which have the same value.

https://github.com/ethereum/web3.py/blob/ee8e217fec8231e6262473d1f72fa9dad68ff3c8/web3/contract.py#L1211-L1219

Commenting out contract.py:1217 solves the issue for me.
If you are using ganache as a node you need to monkey-patch web3 to bypass trufflesuite/ganache-cli#494, and create the contract object with a lowercase address https://github.com/ethereum/web3.py/issues/674, https://github.com/jordanjambazov/web3.py/commit/a61b382dd5c11de1102779868d377408c7590839

Most helpful comment

Someone has already created an issue: https://github.com/trufflesuite/ganache-core/issues/38

All 5 comments

I am curious why this issue came up. My understanding of the address parameter is that it can be a list where logs from ANY of the addresses matching the filter parameters will be caught. Having two of the same address shouldnt prevent seeing logs.

It doesnt make sense to have 2 identical contract addresses passed in a list and is a needed clean up (Thank you for catching that!), but it does seem weird that this would have caused no logs to show.

I would be interested to see what would happen when comparing ganache to another node when passing identical addresses in the address parameter.

I started doing a little bit of testing to see if I could find out if there is a deeper issue made apparent by the double address issue. The behavior seems specific to ganache. Im going to do some digging into ganache with multiple emanating contract addresses next.

Here is a comparison between ganache and eth_tester:

>>> ganache_filter = ganache_contracts.StoreVar.events.MyEvent.createFilter(fromBlock="latest")
>>> ethtester_filter = contracts.StoreVar.events.MyEvent.createFilter(fromBlock="latest")
>>> tx = ganache_contracts.StoreVar.functions.setVar(50).buildTransaction()
>>> tx['nonce'] = w3_ganache.eth.getTransactionCount(local_account.address)
>>> signed_tx = w3_ganache.eth.account.signTransaction(tx, private_key=local_account.privateKey)
>>> tx_hash = w3_ganache.eth.sendRawTransaction(signed_tx.rawTransaction)
>>> ethtester_tx_hash = contracts.StoreVar.functions.setVar(50).transact()
>>> ganache_filter.get_new_entries()
[]
>>> ethtester_filter.get_new_entries()
[AttributeDict({'args': AttributeDict({'_var': 50}), 'event': 'MyEvent', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0x91469c5ce4e986ec26816c123e6d2a213cd20a08e2c782bda4bf5ca3bea6d619'), 'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', 'blockHash': HexBytes('0xb82a3189b7512b8530fb5adf66dba8745a457c1912ef8fe050aee2b95485e351'), 'blockNumber': 2})]
>>> ganache_filter.filter_params
{'topics': ['0x6c2b4666ba8da5a95717621d879a77de725f3d816709b9cbe9f059b8f875e284'], 'address': ['0xE6845126f012B1b22B5Ea8ec4f340F37ed05fde5', '0xE6845126f012B1b22B5Ea8ec4f340F37ed05fde5'], 'fromBlock': 'latest', 'toBlock': 'latest'}
>>> ethtester_filter.filter_params
{'topics': ['0x6c2b4666ba8da5a95717621d879a77de725f3d816709b9cbe9f059b8f875e284'], 'address': ['0xF2E246BB76DF876Cef8b38ae84130F4F55De395b', '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b'], 'fromBlock': 'latest', 'toBlock': 'latest'}
>>> 

I realize that the above test is useless, as Im not forcing the contract address to be lowercase. Here is a repeat of the full test with the checksum address validation monkey patch, and forced lowercased addresses:

>>> setattr(ganache_contracts.StoreVar.events.MyEvent, 'address', ganache_contracts.StoreVar.address.lower())
>>> setattr(ganache_contracts.StoreVar2.events.MyEvent, 'address', ganache_contracts.StoreVar2.address.lower())
>>> ganache_filter = ganache_contracts.StoreVar.events.MyEvent.createFilter(fromBlock="latest")
>>> ganache_filter.filter_params
{'topics': ['0x6c2b4666ba8da5a95717621d879a77de725f3d816709b9cbe9f059b8f875e284'], 'address': '0x36fa4ba8ecb651b3d163bc84c421d3318645e89b', 'fromBlock': 'latest', 'toBlock': 'latest'}
>>> tx = ganache_contracts.StoreVar.functions.setVar(50).buildTransaction()
>>> tx['nonce'] = w3_ganache.eth.getTransactionCount(local_account.address)
>>> signed_tx = w3_ganache.eth.account.signTransaction(tx, private_key=local_account.privateKey)
>>> tx_hash = w3_ganache.eth.sendRawTransaction(signed_tx.rawTransaction)
>>> ganache_filter.get_new_entries()
[AttributeDict({'args': AttributeDict({'_var': 50}), 'event': 'MyEvent', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0x4bb4b66fefd1b5bfb7ffc5b45502cc2bcad0f37c98bbc15ef3b9639ad743e920'), 'address': '0x36fa4BA8eCb651B3d163BC84C421D3318645e89B', 'blockHash': HexBytes('0x588fde020d431a517b7c8cd2f6c0fb725514eeb27d392a222337d31ff03a4a2b'), 'blockNumber': 13})]
>>> ganache_filter_2_addresses = ganache_contracts.StoreVar.events.MyEvent.createFilter(fromBlock="latest", address=ganache_contracts.StoreVar2.events.MyEvent.address)
>>> ganache_filter_2_addresses.filter_params
{'topics': ['0x6c2b4666ba8da5a95717621d879a77de725f3d816709b9cbe9f059b8f875e284'], 'address': ['0x5d16ab2e33bf0aea978cb7dbad572fc694824811', '0x36fa4ba8ecb651b3d163bc84c421d3318645e89b'], 'fromBlock': 'latest', 'toBlock': 'latest'}
>>> tx = ganache_contracts.StoreVar.functions.setVar(50).buildTransaction()
>>> tx['nonce'] = w3_ganache.eth.getTransactionCount(local_account.address)
>>> signed_tx = w3_ganache.eth.account.signTransaction(tx, private_key=local_account.privateKey)
>>> tx_hash = w3_ganache.eth.sendRawTransaction(signed_tx.rawTransaction)
>>> ganache_filter_2_addresses.get_new_entries()
[]
>>> 

It appears ganache does not properly handle mutliple address filters.

Someone has already created an issue: https://github.com/trufflesuite/ganache-core/issues/38

Good find dylanjw. Closing as this isn't really a web3.py bug (if you squint and don't look too closely), but it's still good that we uncovered #827 with it.

Was this page helpful?
0 / 5 - 0 ratings