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

all: improve EstimateGas API #20830

Merged
merged 9 commits into from
Apr 22, 2020

Conversation

rjl493456442
Copy link
Member

There are actually two types of error will be returned when
a tranaction/message call is executed: (a) consensus error
(b) evm internal error. The former should be converted to
a consensus issue, e.g. The sender doesn't enough asset to
purchase the gas it specifies. The latter is allowed since
evm itself is a blackbox and internal error is allowed to happen.

This PR emphasizes the difference by introducing a executionResult
structure. The evm error is embedded inside. So if any error
returned, it indicates consensus issue happens.

And also this PR improve the EstimateGas API to return the concrete
revert reason if the transaction always fails

core/error.go Outdated
ErrInsufficientBalanceForFee = errors.New("insufficient balance to pay fee")

// ErrGasOverflow is returned when calculating gas usage.
ErrGasOverflow = errors.New("gas overflow")
Copy link
Contributor

Choose a reason for hiding this comment

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

I get a bit confused, because at another place (core/vm/errors.go) you have also defined ErrGasUintOverflow. So I guess two questions:

  • Why are some vm errors defined here, and some in core/vm/errors? What is the difference between the two categories?
  • Why do we have both ErrGasUintOverflow and ErrGasOverflow? Seems like it would be easy to mix those two up, and I'm not sure what (if any) the consequence would be?

Copy link
Member Author

Choose a reason for hiding this comment

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

The errors defined here is for transaction pre-checking. If any error returned, it can lead to "BAD BLOCK".

The errors defined in core/vm/errors is for evm internal error. It's allowed behavior and will eventually be packed into ExecutionResult.

The former refers to some critical issues, the latter refers to evm execution status.
So it would be better to define them separately for better distinguish.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the separation is a good idea, but maybe it could be made more obvious, for example if the errors in core/vm were called EvmErrStackOverflow instead of ErrStackOverflow ?
I'm not sure..

@holiman
Copy link
Contributor

holiman commented Mar 28, 2020

Overall a really nice change, good job!

@holiman
Copy link
Contributor

holiman commented Apr 1, 2020

Adding a reference, this fixes #20714

@holiman
Copy link
Contributor

holiman commented Apr 1, 2020

I've now started benchmrks for

from block ~7M.
The benchmarks are not not particularly to intended to benchmark speeds, more to sanity-check that they can chug through a couple of million blocks
without any faults.

ansible-playbook configure_bench01-02.yaml -t wipe,reinit,prep,bench  \
   -e "s3file={{ block7M }}" \
   -e "img_a=holiman/geth-experimental:latest" \
   -e "img_b=holiman/geth-gary:latest" \
   -e "syncmode=full"

papertrail startup logs:

Apr 01 15:14:17 bench01.ethdevops.io geth INFO [04-01|13:14:16.962] Starting peer-to-peer node instance=Geth/v1.9.12-unstable-4d236fb1-20200327/linux-amd64/go1.13.9
Apr 01 15:14:21 bench02.ethdevops.io geth INFO [04-01|13:14:21.696] Starting peer-to-peer node instance=Geth/v1.9.13-unstable-db1ef6e7-20200331/linux-amd64/go1.13.9 

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

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

LGTM

@rjl493456442 rjl493456442 force-pushed the evm-execution-result branch from db1ef6e to ef81461 Compare April 6, 2020 02:46
@rjl493456442
Copy link
Member Author

@MariusVanDerWijden Please take another look

@@ -882,6 +882,23 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOr
return result.Return(), nil
}

type estimateGasError struct {
Copy link
Member

Choose a reason for hiding this comment

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

I think this error type should be exported, s.th. users can use it to cast an error into it and read the fields

Copy link
Member

Choose a reason for hiding this comment

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

These are internal packages, they can't be imported either way.

Copy link
Member

Choose a reason for hiding this comment

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

I know, but I think this error should be moved to an external package (abi or bind) s.th. users can read the revert reason without having to parse the error string

Copy link
Member Author

@rjl493456442 rjl493456442 Apr 7, 2020

Choose a reason for hiding this comment

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

This error is mostly for the API(as Felix required, ErrorCode should also be implemented). The internal shouldn't call this function directly since it's for API.

@holiman
Copy link
Contributor

holiman commented Apr 7, 2020

Sync from ~7M to head done, see #20761 (comment)

@holiman
Copy link
Contributor

holiman commented Apr 7, 2020

Sorry @rjl493456442 , my PR caused a conflict, so it needs a rebase now

if len(result.Revert()) > 0 {
ret, err := abi.UnpackRevert(result.Revert())
if err != nil {
revert = "0x" + common.Bytes2Hex(result.Revert())
Copy link
Member

Choose a reason for hiding this comment

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

Please use hexutil, trying to get rid of the common byte hex converters.

@@ -75,6 +68,41 @@ type Message interface {
Data() []byte
}

// ExecutionResult includes all output after executing given evm
Copy link
Member

@karalabe karalabe Apr 20, 2020

Choose a reason for hiding this comment

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

Wondering if we should move this to vm? Seems a bit clearer to type vm.ExecutionResult vs. core.EvexutionResult. Is there some dependency loop that would make this undoable?

Copy link
Member Author

Choose a reason for hiding this comment

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

The reason to put this definition here is: after raw evm execution(we get the ret and vmerr), we still need to apply some additional rules(e.g. refund gas), so the usedGas field has to be updated in the core scope.

Btw now all my VPN nodes are blocked :P. Now I can't login my discord account(also the reason for missing standup). Sorry about it.

if len(result.Revert()) > 0 {
ret, err := abi.UnpackRevert(result.Revert())
if err != nil {
errMsg += fmt.Sprintf(" (0x%x)", result.Revert())
Copy link
Member

Choose a reason for hiding this comment

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

I think %#x does the prefixing so you don't have to explicitly specify 0x

@karalabe karalabe added this to the 1.9.14 milestone Apr 20, 2020
There are actually two types of error will be returned when
a tranaction/message call is executed: (a) consensus error
(b) evm internal error. The former should be converted to
a consensus issue, e.g. The sender doesn't enough asset to
purchase the gas it specifies. The latter is allowed since
evm itself is a blackbox and internal error is allowed to happen.

This PR emphasizes the difference by introducing a executionResult
structure. The evm error is embedded inside. So if any error
returned, it indicates consensus issue happens.

And also this PR improve the `EstimateGas` API to return the concrete
revert reason if the transaction always fails
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 25, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 25, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 25, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 26, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 26, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 27, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 27, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 27, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Nov 28, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Dec 20, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Dec 20, 2024
gzliudan pushed a commit to XinFinOrg/XDPoSChain that referenced this pull request Dec 21, 2024
JukLee0ira added a commit to JukLee0ira/XDPoSChain that referenced this pull request Dec 23, 2024
gzliudan pushed a commit to XinFinOrg/XDPoSChain that referenced this pull request Dec 28, 2024
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 6, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 7, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 7, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 7, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 9, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 10, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 10, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 10, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 10, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 14, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 16, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 17, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 22, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 22, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 23, 2025
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Jan 24, 2025
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.

7 participants