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

Cherry pick upstream PR for revert reason in eth_call (upstream #21083) #1425

Merged
merged 1 commit into from
Mar 18, 2021

Conversation

oneeman
Copy link
Contributor

@oneeman oneeman commented Mar 10, 2021

Description

This cherry-picks a PR from upstream that adds the revert reason to the error returned from eth_call if there was a revert.

The eth_call behavior in case of a revert was as follows:

  • go-ethereum v1.9.13 and earlier: the revert reason is in the return data. web3 checks the return data and generates an error with the revert reason
  • go-ethereum v1.9.14: the return data and error are both nil (which is a bug introduced in v1.9.14). web3 thinks the call succeeded
  • go-etherem v1.9.15: the return value is nil, and the error includes a data property with the revert reason. web3 checks the error's data and generates and error with the revert reason

On celo-blockchain, v1.2.x and earlier have the pre-1.9.14 behavior, master currently has the v1.9.14, and this PR pulls in the v1.9.15 behavior

Tested

Manually generated an eth_call request which reverts, using contractkit, and logged both the RPC response and contractkit's handling

With this branch:

  rpc:response { jsonrpc: '2.0',
  rpc:response   id: 3,
  rpc:response   error:
  rpc:response    { code: 3,
  rpc:response      message:
  rpc:response       'execution reverted: UptimeLookbackWindow must be within safe range',
  rpc:response      data:
  rpc:response       '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002e557074696d654c6f6f6b6261636b57696e646f77206d7573742062652077697468696e20736166652072616e6765000000000000000000000000000000000000' } } +10ms
Error from web3: Error: execution reverted: UptimeLookbackWindow must be within safe range

With master:

  rpc:response { jsonrpc: '2.0', id: 3, result: '0x' } +9ms
No error from web3

With v1.2.3:

  rpc:response { jsonrpc: '2.0',
  rpc:response   id: 3,
  rpc:response   result:
  rpc:response    '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002e557074696d654c6f6f6b6261636b57696e646f77206d7573742062652077697468696e20736166652072616e6765000000000000000000000000000000000000' } +10ms
Error from web3: { Error: Your request got reverted with the following reason string: UptimeLookbackWindow must be within safe range

The difference in errors between this PR and v1.2.x (Error: Your request got reverted with the following reason string: vs Error: execution reverted: ) is due to the following code in contractkit: https://github.com/celo-org/celo-monorepo/blob/oneeman/cip35-e2e-tests/packages/sdk/connect/src/utils/rpc-caller.ts#L104-L112

If the error has a message, this code generates a new error with that message, discarding the original error object, which has the data property (which is what web3 then uses if it's available, see https://github.com/ChainSafe/web3.js/blob/2c5a8ec7bbb678b8e718a28fd5fec7709bacde25/packages/web3-core-method/src/index.js#L624-L648).

As a reference, this is the error object before this code in rpc-caller.ts:

{
  "code": 3,
  "message": "execution reverted: Ownable: caller is not the owner",
  "data": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000204f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572"
}

Backwards compatibility

There was both a breaking change and a bug on master when merging in part of v1.9.14. Relative to v1.2.3, this PR results in a breaking change (eth_call now returns an error in case of revert rather than reporting a success with the revert reason in the return data). But this breaking change is already handled in web3 (and, specifically, the version of web3 used in contractkit), so both the old and new will result in an error when it should (see above). However, the message will be different (see above).

…r eth_call (#21083)

* internal/ethapi: return revert reason for eth_call

* internal/ethapi: moved revert reason logic to doCall

* accounts/abi/bind/backends: added revert reason logic to simulated backend

* internal/ethapi: fixed linting error

* internal/ethapi: check if require reason can be unpacked

* internal/ethapi: better error logic

* internal/ethapi: simplify logic

* internal/ethapi: return vmError()

* internal/ethapi: move handling of revert out of docall

* graphql: removed revert logic until spec change

* rpc: internal/ethapi: added custom error types

* graphql: use returndata instead of return

Return() checks if there is an error. If an error is found, we return nil.
For most use cases it can be beneficial to return the output even if there
was an error. This code should be changed anyway once the spec supports
error reasons in graphql responses

* accounts/abi/bind/backends: added tests for revert reason

* internal/ethapi: add errorCode to revert error

* internal/ethapi: add errorCode of 3 to revertError

* internal/ethapi: unified estimateGasErrors, simplified logic

* internal/ethapi: unified handling of errors in DoEstimateGas

* rpc: print error data field

* accounts/abi/bind/backends: unify simulatedBackend and RPC

* internal/ethapi: added binary data to revertError data

* internal/ethapi: refactored unpacking logic into newRevertError

* accounts/abi/bind/backends: fix EstimateGas

* accounts, console, internal, rpc: minor error interface cleanups

* Revert "accounts, console, internal, rpc: minor error interface cleanups"

This reverts commit 2d3ef53c5304e429a04983210a417c1f4e0dafb7.

* re-apply the good parts of 2d3ef53c53

* rpc: add test for returning server error data from client

Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
Co-authored-by: Felix Lange <fjl@twurst.com>
rpc/errors.go Show resolved Hide resolved
@oneeman oneeman marked this pull request as ready for review March 16, 2021 15:11
@oneeman oneeman requested a review from a team as a code owner March 16, 2021 15:11
@oneeman oneeman requested review from hbandura and trianglesphere and removed request for a team March 16, 2021 15:11
@oneeman
Copy link
Contributor Author

oneeman commented Mar 16, 2021

@nambrot @gastonponti I investigated the difference in the resulting error between v1.2.x and master and wrote down my findings in the PR description. If we want it to be the same as it was with v1.2.x we would have to make a change to the contractkit code mentioned there. Please have a look and weigh in on whether such a difference could be problematic.

@mcortesi
Copy link
Contributor

@nambrot @gastonponti I investigated the difference in the resulting error between v1.2.x and master and wrote down my findings in the PR description. If we want it to be the same as it was with v1.2.x we would have to make a change to the contractkit code mentioned there. Please have a look and weigh in on whether such a difference could be problematic.

I think it's fine to leave it as it is... i don't expect for software to rely on error string pattern matching.

@oneeman oneeman merged commit e86b1d3 into master Mar 18, 2021
@oneeman oneeman deleted the oneeman/cherry-pick-eth-call-revert-reason branch March 18, 2021 17:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants