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 similarly to abi.encodeCall #14287

Open
Amxx opened this issue Jun 1, 2023 · 7 comments
Open

Add abi.encodeError similarly to abi.encodeCall #14287

Amxx opened this issue Jun 1, 2023 · 7 comments
Labels
feature low effort There is not much implementation work to be done. The task is very easy or tiny. low impact Changes are not very noticeable or potential benefits are limited. should have We like the idea but it’s not important enough to be a part of the roadmap.

Comments

@Amxx
Copy link

Amxx commented Jun 1, 2023

Abstract

Using abi.encodeCall for encoding errors fails with error

Error (3509): Expected regular external function type, or external view on public function. Cannot use errors for abi.encodeCall.

It would be nice to have a abi.encodeError that works similarly to abi.encodeCall, but for custom errors.

Motivation

Both functions and error include a .selector getter that returns the bytes4 "signature". In the case of a function selector, this can be used, along with abi.encodeWithSelector to generate the bytes corresponding to a function call. Similarly, abi.encodeWithSelector can be used to encode a custom error.

abi.encodeCall is a safer alternative that verifies the type and number or arguments at compile type. While abi.encodeCall works well with functions, it does not currently support errors.

Being able to generate the bytes corresponding to custom errors can be particularly usefull for testing with Foundry.

Specification

Given a custom error

error SomeErrorName(address arg0, uint256 arg1, bytes4 arg2, bytes32 arg3);

Enable the syntax

abi.encodeError(SomeErrorName, (arg0, arg1, arg2, arg3));

that returns the same as

abi.encodeWithSelector(SomeErrorName.selector, arg0, arg1, arg2, arg3);

with the same type checking as abi.encodeCall

Backwards Compatibility

None. This is introducing a new syntax that doesn't conflict with existing ones.

@github-actions
Copy link

This issue has been marked as stale due to inactivity for the last 90 days.
It will be automatically closed in 7 days.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Aug 30, 2023
@ekpyron ekpyron removed the stale The issue/PR was marked as stale because it has been open for too long. label Aug 30, 2023
@ethereum ethereum deleted a comment Sep 8, 2023
Copy link

github-actions bot commented Dec 8, 2023

This issue has been marked as stale due to inactivity for the last 90 days.
It will be automatically closed in 7 days.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Dec 8, 2023
@cameel cameel added low effort There is not much implementation work to be done. The task is very easy or tiny. low impact Changes are not very noticeable or potential benefits are limited. should have We like the idea but it’s not important enough to be a part of the roadmap. and removed stale The issue/PR was marked as stale because it has been open for too long. labels Dec 8, 2023
Copy link

This issue has been marked as stale due to inactivity for the last 90 days.
It will be automatically closed in 7 days.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Mar 12, 2024
@ekpyron ekpyron removed the stale The issue/PR was marked as stale because it has been open for too long. label Mar 12, 2024
@Amxx
Copy link
Author

Amxx commented Apr 2, 2024

still relevant

@Amxx Amxx mentioned this issue Apr 2, 2024
3 tasks
@ekpyron
Copy link
Member

ekpyron commented May 6, 2024

abi.encodeError is not obviously the right way to solve these cases.
With #14913 we made a move towards treating custom errors as proper types - while we intentionally kept our options open between a single plain error type or a polymorphic class of error types, distinct for each custom error.

In either case, in the future we consider allowing to declare local variables of error type and being able to pass them along. As in:

error E(uint);
function f() {
  error e = E(42);
  require(false, e);
}

or in the latter version something more like

error E(uint);
function f() {
  error E(uint) e = E(42);
  require(false, e);
}

(which works much less gracefully until we switch to postfix types and is also less ideal until we have polymorphic functions)

In either case, the (only possible) semantics of these would be for the variable e to carry the ABI-encoded error data (so e.g. the first version would conceptually be type error = bytes memory;, if that was allowed).

And thus, the saner way to access the abi-encoding of an error would be by mere explicit conversion, as in bytes(e) (and thus also bytes(E(42))).

Now we can consider going the easier route of abi.encodeError as an immediate interim solution to be deprecated again later on - but we generally don't exactly like being put on the spot by opened PRs ;-).
I'm not yet entirely sure what to do about this particular case, but in general: could we try and discuss issues and their ramifications before jumping at implementations :-)? It's neither nice for us to have to reject work that's already put into a PR and it's also not nice for you to have wasted time, if it ends up being rejected, so it's always better to confirm with us first before starting to implement to avoid this kind of situation.

@Amxx
Copy link
Author

Amxx commented May 13, 2024

could we try and discuss issues and their ramifications before jumping at implementations :-)

Please note that 10 months happened between the issue was submitted and the PR was oppened. There was plenty of time to discuss, but discussion honestly doesn't happen (as visible in this thread) until somone actually starts pushing the thing by implementing it.

At least that is how it feels from the outside world.

Having a bytes(E(42)) syntax would be great. I'm not sure why we couldn't have both syntax to do the same thing ... but honestly I don't care as long has we have one type-safe syntax. So far we have none.

@ekpyron
Copy link
Member

ekpyron commented May 14, 2024

could we try and discuss issues and their ramifications before jumping at implementations :-)

Please note that 10 months happened between the issue was submitted and the PR was oppened. There was plenty of time to discuss, but discussion honestly doesn't happen (as visible in this thread) until somone actually starts pushing the thing by implementing it.

At least that is how it feels from the outside world.

Having a bytes(E(42)) syntax would be great. I'm not sure why we couldn't have both syntax to do the same thing ... but honestly I don't care as long has we have one type-safe syntax. So far we have none.

Well, I appreciate that it's frustrating if issues go unanswered, but we get a huge volume of incoming feature requests, a lot of them reasonable in the first instance, but we have limited resources to address all of them (and the first obvious choice is often not the best longer-term, so even seemingly innocuous requests require some careful consideration - we have a lot of unfortunate inconsistencies in the language due to moving ahead more prematurely in the past). In general, there is a lot of weak points and missing features in the language currently, and it's long-term not viable to address them safely one by one in the current manner, hard-coded in the compiler, which is why our main focus currently is to work on the longer-term evolution of the language, which will involve a standard library for which we envision a well-defined community improval process to generally mitigate this issue. This feature request here is, technically, clearly a case that would better be handled that way, if that was already possible.

Now, of course, this won't happen quickly and we also need to continue to develop the language meanwhile - examples are #14913, which was the most requested feature in the past language survey, and now also high-level transient storage support.

That being said, it's of course not tenable if the outside impression is that feature requests are ignored and discussion has to be forced. The forum was partially meant to mitigate this to allow the community to mobilize broader support for individual feature requests to allow us a more informed view on community demand for features prior to us transitioning to a formal process for a standard library - but that so far has not really lived up to expectations, so we'll try to find and define additional means for this, so bear with us on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature low effort There is not much implementation work to be done. The task is very easy or tiny. low impact Changes are not very noticeable or potential benefits are limited. should have We like the idea but it’s not important enough to be a part of the roadmap.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants