-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Introduce a better filter argument api with EventFilterBuilder #953
Conversation
76dd3d3
to
2b0a16a
Compare
e2cc598
to
2685ecc
Compare
web3/utils/normalizers.py
Outdated
@implicitly_identity | ||
def decode_abi_strings(abi_type, data): | ||
if abi_type == 'string': | ||
return abi_type, codecs.decode(data, 'utf8', 'backslashreplace') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im getting various DecodingErrors when using the updated eth_abi package that has the change to return strings as string types.
Likely the string data in these tests are not encodable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, well feel free to copy in a trace if you want another pair of eyes on it.
BTW, there might be other things besides contract arguments/return values that depend on this decode_abi_strings()
method, so it's not clear it should be deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0b04593
to
041e2ba
Compare
web3/contract.py
Outdated
if topics is not None: | ||
raise NotImplementedError( | ||
"Directly setting topics is not currently supported. " | ||
"Use the argument_filters parameter instead.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this not implemented error to simplify things, as a temporary measure. The ability to set topics directly should be added back to createFilter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping to merge the manually entered and the generated topic arguments together, but I realize that that would yield filter results that are entirely different than adding the results from the two sets of filtered data. e.g. merging (A, B) with (C, D) to get a topic list like ((A, C), (B, D)). The merged topic list would match AB, AD, CB, CD instead of just AC, BD. For this reason, manually entering topics needs to either be disabled, or throw an exception if topics have already been generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extend tests to include:
filtering dynamic types: bytes, string, un-fixed arrays
web3/contract.py
Outdated
if topics is not None: | ||
raise NotImplementedError( | ||
"Directly setting topics is not currently supported. " | ||
"Use the argument_filters parameter instead.") |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
ebcb41a
to
f00f03f
Compare
db30ac4
to
57daae3
Compare
eff2856
to
0b3bb9f
Compare
7246875
to
18c69b4
Compare
I don't see a problem with raising exceptions in cases where previously failures were silent. |
Thanks, that helped a lot! Getting support back for 5 is great 👍
Totally, if the code was already broken (or failing silently), then raising exceptions is a good option. 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GTG when CI is green
Hypothesis has found a failing example, when the event array argument has 38 or more elements. Ive set the max number of elements to 35. This is probably a eth-tester issue. |
@pipermerriam @carver I made some changes to limit value reset, and limit value setting after a filter has been deployed from a filter builder instance. I did the following to share the deployment state between the EventFilterBuilder object and the child argument objects: cf3f795 Is this an anti-pattern? It feels like an anti-pattern. |
web3/utils/events.py
Outdated
self.formatter = formatter | ||
self.event_topic = initialize_event_topics(self.event_abi) | ||
self.args = AttributeDict( | ||
_build_argument_filters_from_event_abi(event_abi, self._deployed_flag)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re:
Is this an anti-pattern? It feels like an anti-pattern.
Yeah, I think so too. Maybe instead of this shared flag, replace the args
attribute in deploy()
. Something like (pseudocode):
- self._deployed_flag(True)
+ old_args = self.args
+ self.args = ImmutableArgs(old_args)
+ old_args.clear() # make it clear that people should not use an old saved copy of args
06d5644
to
63c3cdc
Compare
- Replace the data filter match function with ABI decoded value compare function - Include 'string' type utf-8 conversion in match function. - Disallow array types and match options in old filter API, as these remain broken. The array type arg filtering and multiple option arg matching is provided by EventFilterBuilder api.
e7c5479
to
a76402b
Compare
@pipermerriam @carver Do you want to give this a final review? Im just about ready to merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to squash all the fixup commits.
@@ -45,52 +50,41 @@ def fixed_values(draw): | |||
|
|||
@st.composite | |||
def array_values(draw): | |||
matching = draw(st.lists(elements=st.binary(min_size=2, max_size=2))) | |||
matching = draw(st.lists(elements=st.binary(min_size=2, max_size=2), max_size=35, min_size=1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hypothesis has found a failing example, when the event array argument has 38 or more elements. Ive set the max number of elements to 35. This is probably a eth-tester issue.
Did you find out any more about this? Does a filter with 38 elements work on, say, geth --dev
?
I hate to have this constraint on the test, until we know what's going on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ended up being an issue with insufficient gas. I was thrown off in the beginning because I was getting an eth.exceptions.ValidationError: Insufficient gas
error with sufficiently large arrays, but there is a range of lower array lengths that fail to emit the event without raising the ValidationError.
Make function name more accurate
4ccc612
to
801780e
Compare
Replace hardcoded topic with deriving function Speed up tests Fix breaking change: filter argument options static types Set upper limit on array event arg tests Parametrize match_fn test Block value changes post-deployment Fix broken _utils imports Update filter data normalizer for eth-abi v2 Remove eventFilter pytest parameter Estimate gas for array argument tests
Also fix Web3 import
801780e
to
c4a373d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GTG on green tests
What was wrong?
Related to Issue #872
The existing filter apis are unable to properly differentiate array arguments and multiple match arguments.
How was it fixed?
This PR introduces a new "filter builder" api, where parameters can be set prior to deploying the filter. example:
Additionally this PR contains a bug fix to the data argument filters, by replacing the regex mechanism with an abi decoding and direct value comparison. EDIT: Replacing the
data_filter_set_function
created the need to update the contract.py filter api's, as they are required to pass in the data filter set with the abi type.Cute Animal Picture