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

Add abi.encodeError #14974

Closed
wants to merge 15 commits into from
Closed

Add abi.encodeError #14974

wants to merge 15 commits into from

Conversation

Amxx
Copy link

@Amxx Amxx commented Apr 2, 2024

Fixes #14287

TODO:

  • code deducpliation between typeCheckABIEncodeCallFunction and typeCheckABIEncodeErrorFunction ?
    • I'm not sure if there is a clean way of doing that. Considering there is already a lot of code duplication in the codebase, maybe that is ok.
  • tests
  • review

Copy link

github-actions bot commented Apr 2, 2024

Thank you for your contribution to the Solidity compiler! A team member will follow up shortly.

If you haven't read our contributing guidelines and our review checklist before, please do it now, this makes the reviewing process and accepting your contribution smoother.

If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the #solidity-dev channel on Matrix.

Copy link
Collaborator

@nikola-matic nikola-matic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs some semantic tests as well. A changelog entry as well.

abi.encodeError(g, (1));
}
// ----
// TypeError 3510: (56-57): Expected an error type. Cannot use functions for abi.encodeError.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs another case for library functions.

@r0qs
Copy link
Member

r0qs commented Apr 3, 2024

This CI error: https://app.circleci.com/pipelines/github/ethereum/solidity/33577/workflows/8c3156a6-35f8-4aeb-b6e3-18f80f4cb6cf/jobs/1512784 is because the test file name is wrong, see: test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_args_internal_function_pointer_for_uint copy.sol. There is a _copy in the filename of this test https://github.com/ethereum/solidity/pull/14974/files#diff-41100eaa90ef551806d2098a1c4f80fe0f86d9587edbfb6f1161c6d543f1f92dR1.

@Amxx
Copy link
Author

Amxx commented Apr 3, 2024

Needs some semantic tests as well. A changelog entry as well.

Yes, i'm still working on the testing part.

Edit: should be good now

@Amxx
Copy link
Author

Amxx commented Apr 3, 2024

Apparently, in the semantic tests, the returned bytes memory are processed in chunks of 32 bytes. So when the buffer has length ≡ 4 mod 0x20, we need to pad the expected output with zeros (28 bytes worth of zero exactly)

Is that supposed to happen?

@cameel
Copy link
Member

cameel commented Apr 3, 2024

Could be just another instance of #13989. The issue is about fixed bytes, but maybe it affects bytes too.
I think that soltest is just not padding byte arrays correctly.

@Amxx Amxx requested a review from nikola-matic April 3, 2024 19:35
Copy link
Collaborator

@matheusaaguiar matheusaaguiar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs documentation entries in https://docs.soliditylang.org/en/v0.8.23/cheatsheet.html and https://docs.soliditylang.org/en/v0.8.23/units-and-global-variables.html#abi-encoding-and-decoding-functions (at least, there may be other places, but those are the main ones I guess).
I think the implementation is good, just left some minor suggestions. However, I think we could avoid the duplicated code with some ifs and ternary conditions and have it all in one typeCheckABIEncodeCallFunctionOrError (or something like that), but I don't consider that should impede this PR from being merged.

libsolidity/analysis/TypeChecker.cpp Outdated Show resolved Hide resolved
libsolidity/analysis/TypeChecker.cpp Outdated Show resolved Hide resolved
libsolidity/analysis/TypeChecker.cpp Outdated Show resolved Hide resolved
@Amxx
Copy link
Author

Amxx commented May 3, 2024

@matheusaaguiar

  • I added some references in the files you mentionned
  • I fixed the merge conflicts and fixed what needed to be fixed
  • I also merged previous functions into typeCheckABIEncodeCallFunctionOrError (added the type object and some switches)

@@ -26,6 +26,8 @@ ABI Encoding and Decoding Functions
tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))``
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``
- ``abi.encodeError(error errorPointer, (...)) returns (bytes memory)``: ABI-encodes the revert data for ``errorPointer`` with the arguments found in the
tuple. Performs a full type-check, ensuring the types match the error definition. Results equals ``abi.encodeWithSelector(errorPointer.selector, (...))``
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tuple. Performs a full type-check, ensuring the types match the error definition. Results equals ``abi.encodeWithSelector(errorPointer.selector, (...))``
tuple. Performs a full type-check, ensuring the types match the error definition. Results equals ``abi.encodeWithSelector(errorPointer.selector, ...)``

This a minor imprecision that was fixed recently in the previous entry for abi.encodeCall :)
I will already commit this suggestion via github interface;
Actually, there were another instances which I already fixed via a commit.

Copy link
Collaborator

@matheusaaguiar matheusaaguiar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just have one nitpick left, but overall looks good to me.
Also, I forgot to mention that we use rebase rather than merge and this needs the former.

m_errorReporter.typeError(
5512_error,
arguments.front()->location(),
"Expected first argument to be a custom error, not \"" +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to think of some test cases and when I try something like:

error E(uint a, uint b);
contract C {
    function g() public view returns (bytes memory) {
        bytes memory b1 = abi.encodeError(E(1, 2), (1, 2));
        return b1;
    }
}

The following error message is generated:
Expected first argument to be a custom error, not "error".
Which is a bit weird. Maybe we should be more precise and change to [...] custom error name [...] ?
I think we should have a test like this anyway.

@ekpyron
Copy link
Member

ekpyron commented May 8, 2024

Pending the discussion in #14287 (comment), we decided to close this PR for now. But feel free to jump in there (or join one of our calls) and make the case for this approach and we can potentially revisit and revive this PR!
But as a general policy, we should discuss and confirm the approach before implementations, to be sure we're on the same page about it.

@ekpyron ekpyron closed this May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add abi.encodeError similarly to abi.encodeCall
6 participants