-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
refactor: add an argument to enable strict argument checking in abigen macro #83
Conversation
* this field enables enforcing the strict arguments checking for contracts method
Honestly had trouble coming up with this PR, so really taking any criticisms to improve the design I chose 😸 |
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.
You see, there seems to be a (very valid) misunderstanding that will lead to worse ergonomics of the abigen!
macro -- which is already relatively hard to understand for newcomers.
Adding a bool
to the abigen!
will make things much more confusing, and here's why this ended up being a valid (mis)direction: this happened because in some of the tests in harness.rs
, the JSON ABI being used was handcrafted and didn't follow what the compile generates, that's because it was handcrafted before the compiler was able to generate the JSON ABI.
In practice, this should never happen. In other words, I don't believe there's a reason to complicate the devEx around abigen!
because users will use the JSON ABI generated by the compiler, which includes the mandatory 3 params. Meaning it should always follow the "strict_checking
" logic introduced in this PR.
The original issue (#75) was created because, in Sway, if you give a different name to one of the mandatory params, it will show up in the JSON ABI generated by the compiler that way. E.g. if your sway fn is do_something(gass: u64, amount: u64, color_: b256, MyInput: u64)
(notice the inconsistency), your JSON ABI will be generated the same way and the SDK shouldn't care, it should only care that's u64, u64, b256
. This is a common mistake by Fuel users as we've seen in discussions on Discord.
I propose that we remove this extra bool
param in the abigen!
and use only the (correct) logic introduced in this PR that does the strict checking:
if strict_checking {
if n_inputs != 4 {
return Err(Error::MissingData(format!(
"Expected 4 inputs because `strict_checking` is true, found {}",
n_inputs
)));
}
let given_types: Vec<String> = fun.inputs[..3]
.iter()
.map(|x| x.type_field.clone())
.collect();
let expected = ["u64", "u64", "b256"];
if given_types != expected {
return Err(Error::InvalidType(format!(
"Expected the 3 first types to be {:?}, found {:?}",
expected, given_types
)));
};
// Ignore the first three arguments so we don't have to provide them when calling
// the contracts' methods
first_index = 3
}
Except that this will be the only path (no if strict_checking {}
).
Then we update all tests to include the 3 mandatory params in the JSON ABI, as it should've been. So that it matches the output of the compiler.
This will effectively solve the friction that users have while incorrectly naming the 3 mandatory params in the Sway code and not complicate the abigen!
macro (and not break it for current users!).
In the future, and I already have this documented somewhere, we should have the option of passing, instead of a compiler-generated JSON ABI, a human-readable list of function signatures to abigen!
that could be easily handcrafted, just like ethers provide (https://docs.ethers.io/v5/api/utils/abi/formats/#abi-formats--human-readable-abi). This should be the place for users to handcraft the ABI, not in the JSON ABI that's generated by the compiler.
cc @adlerjohn
Ok I understand, it's just that John asked in #75 that we have "two" versions of the |
Yup, I believe John asked that because you mentioned the tests that didn't include the 3 params. These tests are "invalid" because they should be using the compiler output. This distinction shouldn't be necessary under the (now corrected) assumption that the tests themselves should've included the 3 params. |
Ah I guess I wasn't clear. Yeah a |
IMO, there's a place for handcrafted input and another place for auto-generated inputs. That's one of the things that's nice about Trying to do both, in JSON, and on top of that adding more complexity to the macro... what a pain 😢. |
Updated according the remarks, which changed a lot of tests along the way. I'm always trying to factorize as much as possible, but I guess for macros it's not necessarily a good idea? |
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's looking great! I played with it a bit and now inconsistent/wrong names for the first 3 params don't break anything 🎉. Great work!
I just left some requests for additional comments.
It also closes #13 right? |
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.
Ship it!
This PR refactors the function
expand_function_arguments
to avoid checking for template arguments (gas_, amount_, color_
) every time. It propagates the argument up to the abigen macro so user can chose if the expansion should check for types or not.It closes #75