diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 852be1ed3a..70c6e56c6f 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -412,9 +412,9 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs if err != nil { if err == core.ErrInsufficientIntrinsicGas { - return true, nil, nil + return true, nil, nil // Special case, raise gas limit } - return true, nil, err + return true, nil, err // Bail out } return res.Failed(), res, nil } @@ -442,9 +442,17 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs return 0, err } if failed { - if result != nil && len(result.RevertReason) != 0 { - return 0, fmt.Errorf("Reverted %x", result.RevertReason) + if result != nil { + // If the revert reason is provided, return it to user. + if result.Err == vm.ErrExecutionReverted { + return 0, fmt.Errorf("transaction reverted (0x%x)", result.RevertReason) + } + // If it's an invalid transaction, return the concrete vm error + if result.Err != vm.ErrOutOfGas { + return 0, fmt.Errorf("always failing transaction (%v)", result.Err) + } } + // Otherwise, the specified gas cap is too low return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) } } diff --git a/core/error.go b/core/error.go index 587887bba3..8e0716e6c1 100644 --- a/core/error.go +++ b/core/error.go @@ -29,8 +29,8 @@ var ( ErrNoGenesis = errors.New("genesis not found in chain") ) -// State transition consensus errors, any of them -// encountered can lead to consensus issue. +// State transition consensus errors, any of them encountered during +// the block processing can lead to consensus issue. var ( // ErrNonceTooLow is returned if the nonce of a transaction is lower than the // one present in the local chain. @@ -59,11 +59,3 @@ var ( // is not enought to cover intrinsic gas usage. ErrInsufficientIntrinsicGas = errors.New("insufficient intrinsic gas") ) - -type ConsensusError struct { - Reason error -} - -func (ce *ConsensusError) Unwarp() error { - return ce.Reason -} diff --git a/core/state_transition.go b/core/state_transition.go index 19ddd44b75..5afbfc4c1e 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -219,7 +219,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.BlockNumber) contractCreation := msg.To() == nil - // Check clauses 4-5, subtract intrinsic if everything is correct + // Check clauses 4-5, subtract intrinsic gas if everything is correct gas, err := IntrinsicGas(st.data, contractCreation, homestead, istanbul) if err != nil { return nil, err @@ -229,7 +229,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } st.gas -= gas - // Check clauses 6 + // Check clause 6 if msg.Value().Sign() > 0 && !st.evm.CanTransfer(st.state, msg.From(), msg.Value()) { return nil, ErrInsufficientBalanceForTransfer } diff --git a/graphql/graphql.go b/graphql/graphql.go index 34e7f82efc..159c6845f3 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -815,7 +815,7 @@ func (b *Block) Call(ctx context.Context, args struct { data: result.Result, gasUsed: hexutil.Uint64(result.UsedGas), status: status, - }, err + }, nil } func (b *Block) EstimateGas(ctx context.Context, args struct { @@ -884,7 +884,7 @@ func (p *Pending) Call(ctx context.Context, args struct { data: result.Result, gasUsed: hexutil.Uint64(result.UsedGas), status: status, - }, err + }, nil } func (p *Pending) EstimateGas(ctx context.Context, args struct { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index c319b5bb20..e5a61aee12 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -916,9 +916,9 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash result, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, gasCap) if err != nil { if err == core.ErrInsufficientIntrinsicGas { - return true, nil, nil + return true, nil, nil // Special case, raise gas limit } - return true, nil, err + return true, nil, err // Bail out } return result.Failed(), result, nil } @@ -946,9 +946,17 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash return 0, err } if failed { - if result != nil && len(result.RevertReason) != 0 { - return 0, fmt.Errorf("Reverted %x", result.RevertReason) + if result != nil { + // If the revert reason is provided, return it to user. + if result.Err == vm.ErrExecutionReverted { + return 0, fmt.Errorf("transaction reverted (0x%x)", result.RevertReason) + } + // If it's an invalid transaction, return the concrete vm error + if result.Err != vm.ErrOutOfGas { + return 0, fmt.Errorf("always failing transaction (%v)", result.Err) + } } + // Otherwise, the specified gas cap is too low return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) } }