mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
all: address comments
This commit is contained in:
parent
af58d13ca3
commit
662dab7bf5
12 changed files with 79 additions and 74 deletions
|
|
@ -352,7 +352,7 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Result, nil
|
||||
return res.Return(), nil
|
||||
}
|
||||
|
||||
// PendingCallContract executes a contract call on the pending state.
|
||||
|
|
@ -365,7 +365,7 @@ func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereu
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Result, nil
|
||||
return res.Return(), nil
|
||||
}
|
||||
|
||||
// PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving
|
||||
|
|
@ -411,7 +411,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
|
|||
b.pendingState.RevertToSnapshot(snapshot)
|
||||
|
||||
if err != nil {
|
||||
if err == core.ErrInsufficientIntrinsicGas {
|
||||
if err == core.ErrIntrinsicGas {
|
||||
return true, nil, nil // Special case, raise gas limit
|
||||
}
|
||||
return true, nil, err // Bail out
|
||||
|
|
@ -424,8 +424,8 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
|
|||
failed, _, err := executable(mid)
|
||||
|
||||
// If the error is not nil(consensus error), it means the provided message
|
||||
// call or transaction will never be accpeted no matter how many gas assigened.
|
||||
// Return the error directly, don't struggle any more
|
||||
// call or transaction will never be accepted no matter how much gas it is
|
||||
// assigned. Return the error directly, don't struggle any more
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -445,8 +445,8 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
|
|||
if result != nil {
|
||||
if result.Err != vm.ErrOutOfGas {
|
||||
errMsg := fmt.Sprintf("always failing transaction (%v)", result.Err)
|
||||
if len(result.RevertReason) > 0 {
|
||||
errMsg += fmt.Sprintf(" (0x%x)", result.RevertReason)
|
||||
if len(result.Revert()) > 0 {
|
||||
errMsg += fmt.Sprintf(" (0x%x)", result.Revert())
|
||||
}
|
||||
return 0, errors.New(errMsg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,13 @@ var (
|
|||
ErrNoGenesis = errors.New("genesis not found in chain")
|
||||
)
|
||||
|
||||
// State transition consensus errors, any of them encountered during
|
||||
// the block processing can lead to consensus issue.
|
||||
// List of evm-call-message pre-checking errors. All state transtion messages will
|
||||
// be pre-checked before execution. If any invalidation detected, the corresponding
|
||||
// error should be returned which is defined here.
|
||||
//
|
||||
// - If the pre-checking happens in the miner, then the transaction won't be packed.
|
||||
// - If the pre-checking happens in the block processing procedure, then a "BAD BLOCk"
|
||||
// error should be emitted.
|
||||
var (
|
||||
// ErrNonceTooLow is returned if the nonce of a transaction is lower than the
|
||||
// one present in the local chain.
|
||||
|
|
@ -44,18 +49,18 @@ var (
|
|||
// by a transaction is higher than what's left in the block.
|
||||
ErrGasLimitReached = errors.New("gas limit reached")
|
||||
|
||||
// ErrInsufficientBalanceForTransfer is returned if the transaction sender doesn't
|
||||
// have enough balance for transfer(topmost call only).
|
||||
ErrInsufficientBalanceForTransfer = errors.New("insufficient balance for transfer")
|
||||
// ErrInsufficientFundsForTransfer is returned if the transaction sender doesn't
|
||||
// have enough funds for transfer(topmost call only).
|
||||
ErrInsufficientFundsForTransfer = errors.New("insufficient funds for transfer")
|
||||
|
||||
// ErrInsufficientBalanceForFee is returned if transaction sender doesn't have
|
||||
// enough balance to cover transaction fee.
|
||||
ErrInsufficientBalanceForFee = errors.New("insufficient balance to pay fee")
|
||||
// ErrInsufficientFunds is returned if the total cost of executing a transaction
|
||||
// is higher than the balance of the user's account.
|
||||
ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value")
|
||||
|
||||
// ErrGasOverflow is returned when calculating gas usage.
|
||||
ErrGasOverflow = errors.New("gas overflow")
|
||||
// ErrGasUintOverflow is returned when calculating gas usage.
|
||||
ErrGasUintOverflow = errors.New("gas uint64 overflow")
|
||||
|
||||
// ErrInsufficientIntrinsicGas is returned when the gas limit speicified in transaction
|
||||
// is not enought to cover intrinsic gas usage.
|
||||
ErrInsufficientIntrinsicGas = errors.New("insufficient intrinsic gas")
|
||||
// ErrIntrinsicGas is returned if the transaction is specified to use less gas
|
||||
// than required to start the invocation.
|
||||
ErrIntrinsicGas = errors.New("intrinsic gas too low")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -68,13 +68,12 @@ type Message interface {
|
|||
Data() []byte
|
||||
}
|
||||
|
||||
// ExecutionResult includes all output after executing given evm message
|
||||
// no matter the execution itself is successful or not.
|
||||
// ExecutionResult includes all output after executing given evm
|
||||
// message no matter the execution itself is successful or not.
|
||||
type ExecutionResult struct {
|
||||
UsedGas uint64 // Total used gas but include the refunded gas
|
||||
Err error // Any error encountered during the exection(listed in core/vm/errors.go)
|
||||
Result []byte // Returned value of the calling function
|
||||
RevertReason []byte // Reason to perform revert thrown by solidity code
|
||||
ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode)
|
||||
}
|
||||
|
||||
// Unwrap returns the internal evm error which allows us for further
|
||||
|
|
@ -86,6 +85,24 @@ func (result *ExecutionResult) Unwrap() error {
|
|||
// Failed returns the indicator whether the execution is successful or not
|
||||
func (result *ExecutionResult) Failed() bool { return result.Err != nil }
|
||||
|
||||
// Return is a helper function to help caller distinguish between revert reason
|
||||
// and function return. Return returns the data after execution if no error occurs.
|
||||
func (result *ExecutionResult) Return() []byte {
|
||||
if result.Err != nil {
|
||||
return nil
|
||||
}
|
||||
return common.CopyBytes(result.ReturnData)
|
||||
}
|
||||
|
||||
// Revert returns the concrete revert reason if the execution is aborted by `REVERT`
|
||||
// opcode. Note the reason can be nil if no data supplied with revert opcode.
|
||||
func (result *ExecutionResult) Revert() []byte {
|
||||
if result.Err != vm.ErrExecutionReverted {
|
||||
return nil
|
||||
}
|
||||
return common.CopyBytes(result.ReturnData)
|
||||
}
|
||||
|
||||
// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
|
||||
func IntrinsicGas(data []byte, contractCreation, isHomestead bool, isEIP2028 bool) (uint64, error) {
|
||||
// Set the starting gas for the raw transaction
|
||||
|
|
@ -110,13 +127,13 @@ func IntrinsicGas(data []byte, contractCreation, isHomestead bool, isEIP2028 boo
|
|||
nonZeroGas = params.TxDataNonZeroGasEIP2028
|
||||
}
|
||||
if (math.MaxUint64-gas)/nonZeroGas < nz {
|
||||
return 0, ErrGasOverflow
|
||||
return 0, ErrGasUintOverflow
|
||||
}
|
||||
gas += nz * nonZeroGas
|
||||
|
||||
z := uint64(len(data)) - nz
|
||||
if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
|
||||
return 0, ErrGasOverflow
|
||||
return 0, ErrGasUintOverflow
|
||||
}
|
||||
gas += z * params.TxDataZeroGas
|
||||
}
|
||||
|
|
@ -158,7 +175,7 @@ func (st *StateTransition) to() common.Address {
|
|||
func (st *StateTransition) buyGas() error {
|
||||
mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), st.gasPrice)
|
||||
if st.state.GetBalance(st.msg.From()).Cmp(mgval) < 0 {
|
||||
return ErrInsufficientBalanceForFee
|
||||
return ErrInsufficientFunds
|
||||
}
|
||||
if err := st.gp.SubGas(st.msg.Gas()); err != nil {
|
||||
return err
|
||||
|
|
@ -188,10 +205,8 @@ func (st *StateTransition) preCheck() error {
|
|||
//
|
||||
// - used gas:
|
||||
// total gas used (including gas being refunded)
|
||||
// - execution result:
|
||||
// the return value of the calling function
|
||||
// - revert reason:
|
||||
// reason to perform revert thrown by solidity code
|
||||
// - returndata:
|
||||
// the returned data from evm
|
||||
// - concrete execution error:
|
||||
// various **EVM** error which aborts the execution,
|
||||
// e.g. ErrOutOfGas, ErrExecutionReverted
|
||||
|
|
@ -225,13 +240,13 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
return nil, err
|
||||
}
|
||||
if st.gas < gas {
|
||||
return nil, ErrInsufficientIntrinsicGas
|
||||
return nil, ErrIntrinsicGas
|
||||
}
|
||||
st.gas -= gas
|
||||
|
||||
// Check clause 6
|
||||
if msg.Value().Sign() > 0 && !st.evm.CanTransfer(st.state, msg.From(), msg.Value()) {
|
||||
return nil, ErrInsufficientBalanceForTransfer
|
||||
return nil, ErrInsufficientFundsForTransfer
|
||||
}
|
||||
var (
|
||||
ret []byte
|
||||
|
|
@ -247,17 +262,10 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
st.refundGas()
|
||||
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
|
||||
|
||||
var revert, result []byte
|
||||
if vmerr == vm.ErrExecutionReverted {
|
||||
revert = ret // Revert reason will be returned in ret iif the vmerr is ErrExecutionReverted
|
||||
} else {
|
||||
result = ret // Otherwise the ret represents the execution result, may nil
|
||||
}
|
||||
return &ExecutionResult{
|
||||
UsedGas: st.gasUsed(),
|
||||
Err: vmerr,
|
||||
Result: result,
|
||||
RevertReason: revert,
|
||||
ReturnData: ret,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,14 +67,6 @@ var (
|
|||
// with a different one without the required price bump.
|
||||
ErrReplaceUnderpriced = errors.New("replacement transaction underpriced")
|
||||
|
||||
// ErrInsufficientFunds is returned if the total cost of executing a transaction
|
||||
// is higher than the balance of the user's account.
|
||||
ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value")
|
||||
|
||||
// ErrIntrinsicGas is returned if the transaction is specified to use less gas
|
||||
// than required to start the invocation.
|
||||
ErrIntrinsicGas = errors.New("intrinsic gas too low")
|
||||
|
||||
// ErrGasLimit is returned if a transaction's requested gas limit exceeds the
|
||||
// maximum allowance of the current block.
|
||||
ErrGasLimit = errors.New("exceeds block gas limit")
|
||||
|
|
|
|||
|
|
@ -51,16 +51,16 @@ func (e *ErrStackUnderflow) Error() string {
|
|||
// the maximum allowance.
|
||||
type ErrStackOverflow struct {
|
||||
stackLen int
|
||||
allowance int
|
||||
limit int
|
||||
}
|
||||
|
||||
func (e *ErrStackOverflow) Error() string {
|
||||
return fmt.Sprintf("stack limit reached %d (%d)", e.stackLen, e.allowance)
|
||||
return fmt.Sprintf("stack limit reached %d (%d)", e.stackLen, e.limit)
|
||||
}
|
||||
|
||||
// ErrInvalidOpCode wraps an evm error when an invalid opcode is encountered.
|
||||
type ErrInvalidOpCode struct {
|
||||
opcode int
|
||||
opcode OpCode
|
||||
}
|
||||
|
||||
func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode 0x%x", e.opcode) }
|
||||
func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode 0x%x", byte(e.opcode)) }
|
||||
|
|
|
|||
|
|
@ -269,8 +269,8 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
|||
}
|
||||
// Fail if we're trying to transfer more than the available balance
|
||||
// Note although it's noop to transfer X ether to caller itself. But
|
||||
// if caller doesn't have enough balance, it can lead to an evm error.
|
||||
// So the check here is necessary.
|
||||
// if caller doesn't have enough balance, it would be an error to allow
|
||||
// over-charging itself. So the check here is necessary.
|
||||
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||
return nil, gas, ErrInsufficientBalance
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,13 +222,13 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
|||
op = contract.GetOp(pc)
|
||||
operation := in.cfg.JumpTable[op]
|
||||
if !operation.valid {
|
||||
return nil, &ErrInvalidOpCode{opcode: int(op)}
|
||||
return nil, &ErrInvalidOpCode{opcode: op}
|
||||
}
|
||||
// Validate stack
|
||||
if sLen := stack.len(); sLen < operation.minStack {
|
||||
return nil, &ErrStackUnderflow{stackLen: sLen, required: operation.minStack}
|
||||
} else if sLen > operation.maxStack {
|
||||
return nil, &ErrStackOverflow{stackLen: sLen, allowance: operation.maxStack}
|
||||
return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack}
|
||||
}
|
||||
// If the operation is valid, enforce and write restrictions
|
||||
if in.readOnly && in.evm.chainRules.IsByzantium {
|
||||
|
|
|
|||
|
|
@ -768,7 +768,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
|||
return ðapi.ExecutionResult{
|
||||
Gas: result.UsedGas,
|
||||
Failed: result.Failed(),
|
||||
ReturnValue: fmt.Sprintf("%x", result.Result),
|
||||
ReturnValue: fmt.Sprintf("%x", result.Return()),
|
||||
StructLogs: ethapi.FormatLogs(tracer.StructLogs()),
|
||||
}, nil
|
||||
|
||||
|
|
|
|||
|
|
@ -812,7 +812,7 @@ func (b *Block) Call(ctx context.Context, args struct {
|
|||
status = 0
|
||||
}
|
||||
return &CallResult{
|
||||
data: result.Result,
|
||||
data: result.Return(),
|
||||
gasUsed: hexutil.Uint64(result.UsedGas),
|
||||
status: status,
|
||||
}, nil
|
||||
|
|
@ -881,7 +881,7 @@ func (p *Pending) Call(ctx context.Context, args struct {
|
|||
status = 0
|
||||
}
|
||||
return &CallResult{
|
||||
data: result.Result,
|
||||
data: result.Return(),
|
||||
gasUsed: hexutil.Uint64(result.UsedGas),
|
||||
status: status,
|
||||
}, nil
|
||||
|
|
|
|||
|
|
@ -879,7 +879,7 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOr
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.Result, nil
|
||||
return result.Return(), nil
|
||||
}
|
||||
|
||||
func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap *big.Int) (hexutil.Uint64, error) {
|
||||
|
|
@ -915,7 +915,7 @@ 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 {
|
||||
if err == core.ErrIntrinsicGas {
|
||||
return true, nil, nil // Special case, raise gas limit
|
||||
}
|
||||
return true, nil, err // Bail out
|
||||
|
|
@ -928,8 +928,8 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
|
|||
failed, _, err := executable(mid)
|
||||
|
||||
// If the error is not nil(consensus error), it means the provided message
|
||||
// call or transaction will never be accpeted no matter how many gas assigened.
|
||||
// Return the error directly, don't struggle any more
|
||||
// call or transaction will never be accepted no matter how much gas it is
|
||||
// assigened. Return the error directly, don't struggle any more.
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -949,8 +949,8 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
|
|||
if result != nil {
|
||||
if result.Err != vm.ErrOutOfGas {
|
||||
errMsg := fmt.Sprintf("always failing transaction (%v)", result.Err)
|
||||
if len(result.RevertReason) > 0 {
|
||||
errMsg += fmt.Sprintf(" (0x%x)", result.RevertReason)
|
||||
if len(result.Revert()) > 0 {
|
||||
errMsg += fmt.Sprintf(" (0x%x)", result.Revert())
|
||||
}
|
||||
return 0, errors.New(errMsg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
result, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
res = append(res, result.Result...)
|
||||
res = append(res, result.Return()...)
|
||||
}
|
||||
} else {
|
||||
header := lc.GetHeaderByHash(bhash)
|
||||
|
|
@ -148,7 +148,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
result, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
if state.Error() == nil {
|
||||
res = append(res, result.Result...)
|
||||
res = append(res, result.Return()...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
result, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||
res = append(res, result.Result...)
|
||||
res = append(res, result.Return()...)
|
||||
if st.Error() != nil {
|
||||
return res, st.Error()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue