Skip to content

Discussion: How to improve filter api #872

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

Closed
dylanjw opened this issue May 30, 2018 · 0 comments
Closed

Discussion: How to improve filter api #872

dylanjw opened this issue May 30, 2018 · 0 comments

Comments

@dylanjw
Copy link
Contributor

dylanjw commented May 30, 2018

What was wrong?

See #836. Current web3 filter api's are not intuitive and are just unable to do certain things. An example is creating a filter for array event arguments. Current argument encoding can not differentiate between argument options and arguments that are arrays:

Current api:

some_contract.events.eventWithArrayArg.createFilter(fromBlock='latest', filter={'array_arg': [b'00', b'11'])

The following lines in web3/utils/events.py parse the above array incorrectly into argument options:

 67  	    encoded_args = [
 68  	        [
 69  	            None if option is None else encode_hex(encode_single(arg['type'], option))
 70  	            for option in arg_options]
 71  ->	        for arg, arg_options in zipped_abi_and_args
 72  	    ]

How can it be fixed?

Argument values to filter on should have abi type aware handling, so that the filter parameters can be validated, and array type arguments can be distinguished from lists of multiple match targets. A few ideas for how this could look:

Option 1. A filter argument type, that evaluates to the encoded topic or topics. Can
be supplied to the topic parameter list when creating an event filter.

my_array_arg_single_value = contract.events.SomeEvent.args['my_array_argument']([b'11', b'22'])
my_array_arg_single_value
b'\xac{\x94\xf1X\x12S\xf5\x02\xa5\xfa \xba\xeb.\xcf<\x8b\xfa\xd2G6\xcbw\xe4,\x84\x99\x0eMew'
    
my_array_arg_multiple_values = contract.events.SomeEvent.args['my_array_argument']([b'00'], [b'11', b'22'])
[b'\xd3R@\xdf\xb7\xd5\xf3\xe7\xa3?i\x87+\x84Y\x04g\xe5\xd4\xce.z3\x12\xff\xa8\xe5\xc5\xab6{\xbe', b'\xac{\x94\xf1X\x12S\xf5\x02\xa5\xfa \xba\xeb.\xcf<\x8b\xfa\xd2G6\xcbw\xe4,\x84\x99\x0eMew']
        
contract.events.SomeEvent.createFilter(fromBlock='latest', topics=[my_array_arg_multiple_values])

Although this is a bit awkward, it is nice that the argument object could be immutable.

Option 2. The createFilter method to accept kwargs for event arguements

Single value:

contract.events.SomeEvent.createFilter(fromBlock='latest', my_array_argument=[b'11', b'22'])

Mutiple argument values:

contract.events.SomeEvent.createFilter(fromBlock='latest', my_array_argument=[[b'00'], [b'11', b'22']])

I like this for its simplicity, although setting multiple values as lists still feels a bit unclear.

Option 3. A FilterParameters object that manages parameter checking, that gets passed into createFilter.

params = contract.events.SomeEvent.new_filter_parameters()
params.args['my_array_argument'].match_values([b'00'], [b'11, b'22'])
params.fromBlock = 'latest'
new_filter = contract.events.SomeEvent.createFilter(params)

Accepting multiple values as method arguments makes the intention more readable, but having a mutable object manage the parameters is not ideal.

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

1 participant