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

createFilter event syntax does not work while eventFilter works #826

Closed
gakonst opened this issue May 8, 2018 · 5 comments
Closed

createFilter event syntax does not work while eventFilter works #826

gakonst opened this issue May 8, 2018 · 5 comments

Comments

@gakonst
Copy link
Contributor

gakonst commented May 8, 2018

  • 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.

web3.py/web3/contract.py

Lines 1211 to 1219 in ee8e217

data_filter_set, event_filter_params = construct_event_filter_params(
self._get_event_abi(),
contract_address=self.address,
argument_filters=_filters,
fromBlock=fromBlock,
toBlock=toBlock,
address=address,
topics=topics,
)

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#494, and create the contract object with a lowercase address #674, jordanjambazov@a61b382

@dylanjw
Copy link
Contributor

dylanjw commented May 9, 2018

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.

@dylanjw
Copy link
Contributor

dylanjw commented May 9, 2018

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'}
>>> 

@dylanjw
Copy link
Contributor

dylanjw commented May 9, 2018

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.

@dylanjw
Copy link
Contributor

dylanjw commented May 9, 2018

Someone has already created an issue: trufflesuite/ganache#38

@pipermerriam
Copy link
Member

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.

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

3 participants