-
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
Raise MismatchedABI
exceptions with detailed error messaging
#3491
Conversation
d7ddfef
to
a4cd1d4
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.
This is awesome! I left a few comments on the wording of the messages, but I think this will really help!
"Multiple elements were found matching 1 arguments.\n" | ||
"Provided argument types: (str)\n" | ||
"Provided keyword argument types: {}\n\n" | ||
"Encountered problems with the following elements named `a`.\n" |
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.
It took me a minute to figure out what this error message was telling me. Maybe something along the lines of: Tried to find a matching ABI Element
a, but encountered the following problems:
🤷
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.
/cc our resident words guy ™️ @wolovim
tests/core/contracts/test_contract_method_to_argument_matching.py
Outdated
Show resolved
Hide resolved
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 made an initial pass to contribute to the messaging conversation. I think we can probably add (s)
around the descriptors for dynamic singular or multiple values, e.g. 1 elements(s)
, 2 argument(s)
, etc...
I'll take a more careful pass at the rest on Monday 👀
tests/core/contracts/test_contract_method_to_argument_matching.py
Outdated
Show resolved
Hide resolved
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 looks great. I left some comments on error message wording. I think they could be good changes for clarity, including @kclowes comment.
I have some small outstanding questions on possible breaking changes as well. Exceptions that were raised before this PR and new classes seem to be raised now. Let's make sure we're not braking anything there.
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.
lgtm! I retracted the accept for now... I think we need to solve for some edge cases in messaging, etc. See comments below.
Some minor outstanding things to look into
@reedsa I'm also seeing a recursion issue with simplistic ABI structures. If I try to reproduce with: python -c "from web3.utils import get_abi_element;get_abi_element([{'type': 'function', 'name': 'Nonexistent'},{'type': 'event', 'name': 'Nonexistent'}], 'Nonexistent')" |
@fselmo Interesting to see the function/event name overlap. I think the general rule of thumb in solidity is using TitleCase for events, camelCase for functions. Though that is not explicitly enforced by Solidity as far as I know. I'll have a look at the empty messages and recursive issue, good finds! |
Yeah that was more of a lazy quick example to test. I think the important takeaway is a graceful handling of the recursion / edge case rather than just letting it recurse. |
@fselmo Found a better approach that eliminates recursive calls entirely. Also doing validations up front in |
I think we can probably still trim this messaging a bit. It seems quite lengthy when I think we can convey the same message more briefly. I'm seeing double errors as well, one for each of the identifying elements. Was that intentional? $ python -c "from web3.utils import get_abi_element;get_abi_element([{'type': 'event', 'name': 'MyElement'}, {'type': 'function', 'name': 'MyElement'}], 'MyElement')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/fselmo/codigo/e/py/web3.py/web3/utils/abi.py", line 611, in get_abi_element
raise MismatchedABI(error_diagnosis)
web3.exceptions.MismatchedABI:
ABI Not Found!
Multiple elements were found that accept 0 argument(s).
Provided argument types: ()
Provided keyword argument types: {}
Tried to find a matching ABI element named `MyElement`, but encountered the following problems:
MyElement()
The provided identifier matches multiple elements.
If you meant to call `MyElement()`, please specify the full signature.
MyElement()
The provided identifier matches multiple elements.
If you meant to call `MyElement()`, please specify the full signature. Doubled part:
What do you think? I can consider this a nit on my part if we think this is desirable. I'm not sure how much of an overhead it would be to not repeat the messaging per item found at the end. |
Oh that does look strange for that case, since it lists both ABI elements in the abi that match the name. Maybe the error message should include the type of each MyElement() - Type: `function`
The provided identifier matches multiple elements.
If you meant to call `MyElement()`, please specify the full signature.
MyElement() - Type: `event`
The provided identifier matches multiple elements.
If you meant to call `MyElement()`, please specify the full signature. |
@reedsa I think I see the point of the repeat (in this case). I'm also breaking the API on purpose... an ABI should never really define an event or function like that. I think this looks good. Messaging seems pretty clear to me and I'm not sure I mind the verbosity as much. It is at least very descriptive of the issues.
I think including the type would be a great clarifying addition 👌🏼 |
@reedsa it would be ideal if we could avoid repeating the obvious parts. Something more along the lines of:
Or something along those lines. Specifically removing the unnecessary repeat of "The provided identifier matches multiple elements. If you meant to call |
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.
Good stuff. There's a lot of surface area here, maybe one more approval couldn't hurt but lgtm!
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.
Looking good! I didn't see anything major really. Just a few small things I noticed, mostly in the testing department:
- I didn't comment on all of the instances I saw, but left a comment around splitting out branching
if
statements in tests into separate tests. Feel free to take or leave. - I also left a few nits and see a few warnings in the tests that weren't there before that could be cleaned up 🧹 (UserWarnings in the extracting_event_data test, and some DeprecationWarnings in the test_abi test)
c83b101
to
f89f379
Compare
@kclowes I noticed that |
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.
LGTM! I left one comment about recompiling with solidity 0.8.28 but then I think it's ready when you're ready to pull the trigger!
This changes to async_contract.py and contract.py (especially (Async)ContractFunction.call) slows down the performance of obtaining the call of contract functions e.g. contract.function_name(*args) considerably. ~ 5x. This is a problem if having a lot of such calls. |
What was wrong?
In
get_abi_element
, exception handling between functions and events is now shared. The messages referencefunctions
, but should instead sayelement
and provide additional details about any element that matches the name. The provided arguments and their types should be checked with the encodability for each element ABI in order to list each argument error.Closes #964, #3482
How was it fixed?
Add logic for mismatched ABI errors to invoke a new private method that generates a list of errors for each ABI that matches the provided
abi_element_identifier
. The messages returned depend on the number of matches and if there are arguments, the number of matching ABIs that have the same number of arguments is also considered.The messages will include all potential matches (by name) so that users can identify the function or event they intended to reference. The specific messages for each match depend on the arguments provided.
When an argument is not encodable to a certain type, the message appends information about the argument position, the provided value, and the expected type.
Todo:
Cute Animal Picture