mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-03-21 02:18:07 +00:00
core/vm: update to newest tests, rework gas mechanism
This commit is contained in:
parent
41feef2a84
commit
e5d453c086
14 changed files with 125 additions and 81 deletions
|
|
@ -5,10 +5,10 @@
|
|||
# https://github.com/ethereum/execution-spec-tests/releases/download/v5.1.0
|
||||
a3192784375acec7eaec492799d5c5d0c47a2909a3cc40178898e4ecd20cc416 fixtures_develop.tar.gz
|
||||
|
||||
# version:spec-tests-bal v5.4.0
|
||||
# version:spec-tests-bal v5.5.1
|
||||
# https://github.com/ethereum/execution-spec-tests/releases
|
||||
# https://github.com/ethereum/execution-spec-tests/releases/download/bal%40v5.4.0
|
||||
be300cbc5dcae213850bc5688d8fd0f572785ec64801f28653e1c01a03805127 fixtures_bal.tar.gz
|
||||
# https://github.com/ethereum/execution-spec-tests/releases/download/bal%40v5.5.1
|
||||
79f81379bc456b9f05d4e7298eba939855d0147b525cd2cadd1206513284ab9e fixtures_bal.tar.gz
|
||||
|
||||
# version:golang 1.25.7
|
||||
# https://go.dev/dl/
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM) bal.StateMutati
|
|||
}
|
||||
evm.SetTxContext(NewEVMTxContext(msg))
|
||||
evm.StateDB.AddAddressToAccessList(params.BeaconRootsAddress)
|
||||
_, _, _ = evm.Call(msg.From, *msg.To, msg.Data, vm.GasCosts{RegularGas: 30_000_000}, common.U2560)
|
||||
_, _, _, _ = evm.Call(msg.From, *msg.To, msg.Data, vm.GasCosts{RegularGas: 30_000_000}, common.U2560)
|
||||
return evm.StateDB.Finalise(true)
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +322,7 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) bal.StateMutation
|
|||
}
|
||||
evm.SetTxContext(NewEVMTxContext(msg))
|
||||
evm.StateDB.AddAddressToAccessList(params.HistoryStorageAddress)
|
||||
_, _, err := evm.Call(msg.From, *msg.To, msg.Data, vm.GasCosts{RegularGas: 30_000_000}, common.U2560)
|
||||
_, _, _, err := evm.Call(msg.From, *msg.To, msg.Data, vm.GasCosts{RegularGas: 30_000_000}, common.U2560)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -362,7 +362,7 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte
|
|||
}
|
||||
evm.SetTxContext(NewEVMTxContext(msg))
|
||||
evm.StateDB.AddAddressToAccessList(addr)
|
||||
ret, _, err := evm.Call(msg.From, *msg.To, msg.Data, vm.GasCosts{RegularGas: 30_000_000}, common.U2560)
|
||||
ret, _, _, err := evm.Call(msg.From, *msg.To, msg.Data, vm.GasCosts{RegularGas: 30_000_000}, common.U2560)
|
||||
mut := evm.StateDB.Finalise(true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("system call failed to execute: %v", err)
|
||||
|
|
|
|||
|
|
@ -545,8 +545,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
|
||||
authRefund uint64
|
||||
)
|
||||
var execGasUsed vm.GasUsed
|
||||
if contractCreation {
|
||||
ret, _, st.gasRemaining, vmerr = st.evm.Create(msg.From, msg.Data, st.gasRemaining, value)
|
||||
ret, _, st.gasRemaining, execGasUsed, vmerr = st.evm.Create(msg.From, msg.Data, st.gasRemaining, value)
|
||||
} else {
|
||||
// Increment the nonce for the next transaction.
|
||||
st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1, tracing.NonceChangeEoACall)
|
||||
|
|
@ -570,19 +571,13 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
}
|
||||
|
||||
// Execute the transaction's call.
|
||||
ret, st.gasRemaining, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value)
|
||||
ret, st.gasRemaining, execGasUsed, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value)
|
||||
}
|
||||
|
||||
// Record the gas used excluding gas refunds. This value represents the actual
|
||||
// gas allowance required to complete execution.
|
||||
peakGasUsed := st.gasUsed()
|
||||
|
||||
// EIP-8037: Capture pre-refund remaining for 2D gas accounting.
|
||||
var preRefundRemaining uint64
|
||||
if rules.IsAmsterdam {
|
||||
preRefundRemaining = st.gasRemaining.Sum()
|
||||
}
|
||||
|
||||
// Compute refund counter, capped to a refund quotient.
|
||||
st.gasRemaining.RegularGas += st.calcRefund()
|
||||
if rules.IsPrague {
|
||||
|
|
@ -607,10 +602,11 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
|
||||
if rules.IsAmsterdam {
|
||||
// EIP-8037: 2D gas accounting for Amsterdam.
|
||||
// tx_state = adjusted_intrinsic_state + exec_state_used (spec: set_delegation adjusts intrinsic)
|
||||
// tx_regular = total_dimensional_used - tx_state
|
||||
txState := (gas.StateGas - authRefund) + st.gasRemaining.StateGasCharged
|
||||
txRegular := (msg.GasLimit - preRefundRemaining) - txState
|
||||
// tx_regular = intrinsic_regular + exec_regular_gas_used
|
||||
// tx_state = intrinsic_state (adjusted) + exec_state_gas_used
|
||||
// These are tracked independently, not derived from remaining gas.
|
||||
txState := (gas.StateGas - authRefund) + execGasUsed.StateGasCharged
|
||||
txRegular := gas.RegularGas + execGasUsed.RegularGasUsed
|
||||
txRegular = max(txRegular, floorDataGas)
|
||||
if err := st.gp.ReturnGasAmsterdam(returned, txRegular, txState, st.gasUsed()); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -42,8 +42,9 @@ type Contract struct {
|
|||
IsDeployment bool
|
||||
IsSystemCall bool
|
||||
|
||||
Gas GasCosts
|
||||
value *uint256.Int
|
||||
Gas GasCosts
|
||||
GasUsed GasUsed // EIP-8037: canonical per-frame gas usage accumulator
|
||||
value *uint256.Int
|
||||
}
|
||||
|
||||
// NewContract returns a new contract environment for the execution of EVM.
|
||||
|
|
@ -133,19 +134,21 @@ func (c *Contract) UseGas(gas GasCosts, logger *tracing.Hooks, reason tracing.Ga
|
|||
if logger != nil && logger.OnGasChange != nil && reason != tracing.GasChangeIgnored {
|
||||
logger.OnGasChange(c.Gas.RegularGas, c.Gas.RegularGas-gas.RegularGas, reason)
|
||||
}
|
||||
c.GasUsed.Add(gas)
|
||||
c.Gas.Sub(gas)
|
||||
return true
|
||||
}
|
||||
|
||||
// RefundGas refunds gas to the contract
|
||||
func (c *Contract) RefundGas(err error, gas GasCosts, logger *tracing.Hooks, reason tracing.GasChangeReason) {
|
||||
// RefundGas refunds gas to the contract. gasUsed carries the child frame's
|
||||
// accumulated gas usage metrics (EIP-8037), incorporated on both success and error.
|
||||
func (c *Contract) RefundGas(err error, gas GasCosts, gasUsed GasUsed, logger *tracing.Hooks, reason tracing.GasChangeReason) {
|
||||
// If the preceding call errored, return the state gas
|
||||
// to the parent call
|
||||
if err != nil {
|
||||
gas.StateGas += gas.StateGasCharged
|
||||
gas.StateGasCharged = 0
|
||||
gas.StateGas += gasUsed.StateGasCharged
|
||||
gasUsed.StateGasCharged = 0
|
||||
}
|
||||
if gas.RegularGas == 0 && gas.StateGas == 0 && gas.StateGasCharged == 0 {
|
||||
if gas.RegularGas == 0 && gas.StateGas == 0 && gasUsed.StateGasCharged == 0 && gasUsed.RegularGasUsed == 0 {
|
||||
return
|
||||
}
|
||||
if logger != nil && logger.OnGasChange != nil && reason != tracing.GasChangeIgnored {
|
||||
|
|
@ -153,7 +156,8 @@ func (c *Contract) RefundGas(err error, gas GasCosts, logger *tracing.Hooks, rea
|
|||
}
|
||||
c.Gas.RegularGas += gas.RegularGas
|
||||
c.Gas.StateGas = gas.StateGas
|
||||
c.Gas.StateGasCharged += gas.StateGasCharged
|
||||
c.GasUsed.StateGasCharged += gasUsed.StateGasCharged
|
||||
c.GasUsed.RegularGasUsed += gasUsed.RegularGasUsed
|
||||
}
|
||||
|
||||
// Address returns the contracts address
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ func isSystemCall(caller common.Address) bool {
|
|||
// parameters. It also handles any necessary value transfer required and takse
|
||||
// the necessary steps to create accounts and reverses the state in case of an
|
||||
// execution error or failed value transfer.
|
||||
func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, gas GasCosts, value *uint256.Int) (ret []byte, leftOverGas GasCosts, err error) {
|
||||
func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, gas GasCosts, value *uint256.Int) (ret []byte, leftOverGas GasCosts, gasUsed GasUsed, err error) {
|
||||
// Capture the tracer start/end events in debug mode
|
||||
if evm.Config.Tracer != nil {
|
||||
evm.captureBegin(evm.depth, CALL, caller, addr, input, gas, value.ToBig())
|
||||
|
|
@ -248,37 +248,30 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
}
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
return nil, gas, GasUsed{}, ErrDepth
|
||||
}
|
||||
syscall := isSystemCall(caller)
|
||||
|
||||
// Fail if we're trying to transfer more than the available balance.
|
||||
if !syscall && !value.IsZero() && !evm.Context.CanTransfer(evm.StateDB, caller, value) {
|
||||
return nil, gas, ErrInsufficientBalance
|
||||
return nil, gas, GasUsed{}, ErrInsufficientBalance
|
||||
}
|
||||
snapshot := evm.StateDB.Snapshot()
|
||||
|
||||
p, isPrecompile := evm.precompile(addr)
|
||||
if !evm.StateDB.Exist(addr) {
|
||||
if !isPrecompile && evm.chainRules.IsEIP4762 && !isSystemCall(caller) {
|
||||
// Add proof of absence to witness
|
||||
// At this point, the read costs have already been charged, either because this
|
||||
// is a direct tx call, in which case it's covered by the intrinsic gas, or because
|
||||
// of a CALL instruction, in which case BASIC_DATA has been added to the access
|
||||
// list in write mode. If there is enough gas paying for the addition of the code
|
||||
// hash leaf to the access list, then account creation will proceed unimpaired.
|
||||
// Thus, only pay for the creation of the code hash leaf here.
|
||||
wgas := evm.AccessEvents.CodeHashGas(addr, true, gas.RegularGas, false)
|
||||
if gas.RegularGas < wgas {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
return nil, GasCosts{}, ErrOutOfGas
|
||||
return nil, GasCosts{}, GasUsed{}, ErrOutOfGas
|
||||
}
|
||||
gas.RegularGas -= wgas
|
||||
}
|
||||
|
||||
if !isPrecompile && evm.chainRules.IsEIP158 && value.IsZero() {
|
||||
// Calling a non-existing account, don't do anything.
|
||||
return nil, gas, nil
|
||||
return nil, gas, GasUsed{}, nil
|
||||
}
|
||||
evm.StateDB.CreateAccount(addr)
|
||||
}
|
||||
|
|
@ -294,7 +287,9 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
if evm.chainRules.IsAmsterdam {
|
||||
stateDB = evm.StateDB
|
||||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
} else {
|
||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
code := evm.resolveCode(addr)
|
||||
|
|
@ -307,6 +302,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
contract.SetCallCode(evm.resolveCodeHash(addr), code)
|
||||
ret, err = evm.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
gasUsed = contract.GasUsed
|
||||
}
|
||||
}
|
||||
// When an error was returned by the EVM or when setting the creation code
|
||||
|
|
@ -319,10 +315,11 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
gasUsed.RegularGasUsed += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
return ret, gas, err
|
||||
return ret, gas, gasUsed, err
|
||||
}
|
||||
|
||||
// CallCode executes the contract associated with the addr with the given input
|
||||
|
|
@ -332,7 +329,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
//
|
||||
// CallCode differs from Call in the sense that it executes the given address'
|
||||
// code with the caller as context.
|
||||
func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byte, gas GasCosts, value *uint256.Int) (ret []byte, leftOverGas GasCosts, err error) {
|
||||
func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byte, gas GasCosts, value *uint256.Int) (ret []byte, leftOverGas GasCosts, gasUsed GasUsed, err error) {
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if evm.Config.Tracer != nil {
|
||||
evm.captureBegin(evm.depth, CALLCODE, caller, addr, input, gas, value.ToBig())
|
||||
|
|
@ -342,14 +339,14 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
|||
}
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
return nil, gas, GasUsed{}, ErrDepth
|
||||
}
|
||||
// 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 would be an error to allow
|
||||
// over-charging itself. So the check here is necessary.
|
||||
if !evm.Context.CanTransfer(evm.StateDB, caller, value) {
|
||||
return nil, gas, ErrInsufficientBalance
|
||||
return nil, gas, GasUsed{}, ErrInsufficientBalance
|
||||
}
|
||||
var snapshot = evm.StateDB.Snapshot()
|
||||
|
||||
|
|
@ -359,7 +356,9 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
|||
if evm.chainRules.IsAmsterdam {
|
||||
stateDB = evm.StateDB
|
||||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
} else {
|
||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
// The contract is a scoped environment for this execution context only.
|
||||
|
|
@ -367,6 +366,7 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
|||
contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
|
||||
ret, err = evm.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
gasUsed = contract.GasUsed
|
||||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
|
|
@ -375,10 +375,11 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
|||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
gasUsed.RegularGasUsed += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
return ret, gas, err
|
||||
return ret, gas, gasUsed, err
|
||||
}
|
||||
|
||||
// DelegateCall executes the contract associated with the addr with the given input
|
||||
|
|
@ -386,7 +387,7 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
|||
//
|
||||
// DelegateCall differs from CallCode in the sense that it executes the given address'
|
||||
// code with the caller as context and the caller is set to the caller of the caller.
|
||||
func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address, addr common.Address, input []byte, gas GasCosts, value *uint256.Int) (ret []byte, leftOverGas GasCosts, err error) {
|
||||
func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address, addr common.Address, input []byte, gas GasCosts, value *uint256.Int) (ret []byte, leftOverGas GasCosts, gasUsed GasUsed, err error) {
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if evm.Config.Tracer != nil {
|
||||
// DELEGATECALL inherits value from parent call
|
||||
|
|
@ -397,7 +398,7 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
|||
}
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
return nil, gas, GasUsed{}, ErrDepth
|
||||
}
|
||||
var snapshot = evm.StateDB.Snapshot()
|
||||
|
||||
|
|
@ -407,7 +408,9 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
|||
if evm.chainRules.IsAmsterdam {
|
||||
stateDB = evm.StateDB
|
||||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
} else {
|
||||
// Initialise a new contract and make initialise the delegate values
|
||||
//
|
||||
|
|
@ -416,6 +419,7 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
|||
contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
|
||||
ret, err = evm.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
gasUsed = contract.GasUsed
|
||||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
|
|
@ -424,17 +428,18 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
|||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
gasUsed.RegularGasUsed += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
return ret, gas, err
|
||||
return ret, gas, gasUsed, err
|
||||
}
|
||||
|
||||
// StaticCall executes the contract associated with the addr with the given input
|
||||
// as parameters while disallowing any modifications to the state during the call.
|
||||
// Opcodes that attempt to perform such modifications will result in exceptions
|
||||
// instead of performing the modifications.
|
||||
func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []byte, gas GasCosts) (ret []byte, leftOverGas GasCosts, err error) {
|
||||
func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []byte, gas GasCosts) (ret []byte, leftOverGas GasCosts, gasUsed GasUsed, err error) {
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if evm.Config.Tracer != nil {
|
||||
evm.captureBegin(evm.depth, STATICCALL, caller, addr, input, gas, nil)
|
||||
|
|
@ -444,7 +449,7 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
|
|||
}
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
if evm.depth > int(params.CallCreateDepth) {
|
||||
return nil, gas, ErrDepth
|
||||
return nil, gas, GasUsed{}, ErrDepth
|
||||
}
|
||||
// We take a snapshot here. This is a bit counter-intuitive, and could probably be skipped.
|
||||
// However, even a staticcall is considered a 'touch'. On mainnet, static calls were introduced
|
||||
|
|
@ -464,7 +469,9 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
|
|||
if evm.chainRules.IsAmsterdam {
|
||||
stateDB = evm.StateDB
|
||||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
} else {
|
||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
// The contract is a scoped environment for this execution context only.
|
||||
|
|
@ -476,6 +483,7 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
|
|||
// when we're in Homestead this also counts for code storage gas errors.
|
||||
ret, err = evm.Run(contract, input, true)
|
||||
gas = contract.Gas
|
||||
gasUsed = contract.GasUsed
|
||||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
|
|
@ -484,14 +492,15 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
|
|||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
gasUsed.RegularGasUsed += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
return ret, gas, err
|
||||
return ret, gas, gasUsed, err
|
||||
}
|
||||
|
||||
// create creates a new contract using code as deployment code.
|
||||
func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas GasCosts, err error) {
|
||||
func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas GasCosts, gasUsed GasUsed, err error) {
|
||||
// Depth check execution. Fail if we're trying to execute above the
|
||||
// limit.
|
||||
var nonce uint64
|
||||
|
|
@ -516,13 +525,13 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
}(gas)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, common.Address{}, gas, err
|
||||
return nil, common.Address{}, gas, GasUsed{}, err
|
||||
}
|
||||
// Charge the contract creation init gas in verkle mode
|
||||
if evm.chainRules.IsEIP4762 {
|
||||
statelessGas := evm.AccessEvents.ContractCreatePreCheckGas(address, gas.RegularGas)
|
||||
if statelessGas > gas.RegularGas {
|
||||
return nil, common.Address{}, GasCosts{}, ErrOutOfGas
|
||||
return nil, common.Address{}, GasCosts{}, GasUsed{}, ErrOutOfGas
|
||||
}
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, gas.RegularGas-statelessGas, tracing.GasChangeWitnessContractCollisionCheck)
|
||||
|
|
@ -550,7 +559,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
gas.RegularGas = 0
|
||||
return nil, common.Address{}, gas, ErrContractAddressCollision
|
||||
return nil, common.Address{}, gas, GasUsed{}, ErrContractAddressCollision
|
||||
}
|
||||
// Create a new account on the state only if the object was not present.
|
||||
// It might be possible the contract code is deployed to a pre-existent
|
||||
|
|
@ -573,7 +582,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
if evm.chainRules.IsEIP4762 {
|
||||
consumed, wanted := evm.AccessEvents.ContractCreateInitGas(address, gas.RegularGas)
|
||||
if consumed < wanted {
|
||||
return nil, common.Address{}, GasCosts{}, ErrOutOfGas
|
||||
return nil, common.Address{}, GasCosts{}, GasUsed{}, ErrOutOfGas
|
||||
}
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, gas.RegularGas-consumed, tracing.GasChangeWitnessContractInit)
|
||||
|
|
@ -601,10 +610,11 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(contract.Gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
contract.GasUsed.RegularGasUsed += contract.Gas.RegularGas
|
||||
contract.Gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
return ret, address, contract.Gas, err
|
||||
return ret, address, contract.Gas, contract.GasUsed, err
|
||||
}
|
||||
|
||||
// initNewContract runs a new contract's creation code, performs checks on the
|
||||
|
|
@ -661,7 +671,7 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
|
|||
}
|
||||
|
||||
// Create creates a new contract using code as deployment code.
|
||||
func (evm *EVM) Create(caller common.Address, code []byte, gas GasCosts, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas GasCosts, err error) {
|
||||
func (evm *EVM) Create(caller common.Address, code []byte, gas GasCosts, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas GasCosts, gasUsed GasUsed, err error) {
|
||||
contractAddr = crypto.CreateAddress(caller, evm.StateDB.GetNonce(caller))
|
||||
return evm.create(caller, code, gas, value, contractAddr, CREATE)
|
||||
}
|
||||
|
|
@ -670,7 +680,7 @@ func (evm *EVM) Create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
//
|
||||
// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
|
||||
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
|
||||
func (evm *EVM) Create2(caller common.Address, code []byte, gas GasCosts, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas GasCosts, err error) {
|
||||
func (evm *EVM) Create2(caller common.Address, code []byte, gas GasCosts, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas GasCosts, gasUsed GasUsed, err error) {
|
||||
inithash := crypto.Keccak256Hash(code)
|
||||
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:])
|
||||
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2)
|
||||
|
|
|
|||
|
|
@ -710,6 +710,7 @@ func gasSStore8037(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
|
|||
if contract.Gas.Underflow(stateGas) {
|
||||
return GasCosts{}, errors.New("out of gas for state gas")
|
||||
}
|
||||
contract.GasUsed.Add(stateGas)
|
||||
contract.Gas.Sub(stateGas)
|
||||
return GasCosts{RegularGas: cost.RegularGas + params.SstoreResetGasEIP2200 - params.ColdSloadCostEIP2929}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ func TestEIP2200(t *testing.T) {
|
|||
}
|
||||
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
|
||||
|
||||
_, gas, err := evm.Call(common.Address{}, address, nil, GasCosts{RegularGas: tt.gaspool}, new(uint256.Int))
|
||||
_, gas, _, err := evm.Call(common.Address{}, address, nil, GasCosts{RegularGas: tt.gaspool}, new(uint256.Int))
|
||||
if !errors.Is(err, tt.failure) {
|
||||
t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
|
||||
}
|
||||
|
|
@ -154,7 +154,7 @@ func TestCreateGas(t *testing.T) {
|
|||
|
||||
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, config)
|
||||
var startGas = uint64(testGas)
|
||||
ret, gas, err := evm.Call(common.Address{}, address, nil, GasCosts{RegularGas: startGas}, new(uint256.Int))
|
||||
ret, gas, _, err := evm.Call(common.Address{}, address, nil, GasCosts{RegularGas: startGas}, new(uint256.Int))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,24 @@ import "fmt"
|
|||
type GasCosts struct {
|
||||
RegularGas uint64
|
||||
StateGas uint64
|
||||
}
|
||||
|
||||
// StateGasCharged tracks the cumulative state gas charged during execution.
|
||||
// GasUsed tracks per-frame gas usage metrics for EIP-8037 2D block gas accounting.
|
||||
type GasUsed struct {
|
||||
// RegularGasUsed accumulates all gas charged via charge_gas() in the spec:
|
||||
// State-gas spillover (when StateGas is exhausted and the excess
|
||||
// is paid from RegularGas) does NOT increment RegularGasUsed.
|
||||
RegularGasUsed uint64
|
||||
// StateGasCharged accumulates all gas charged via charge_state_gas()
|
||||
// On child error the charged state gas is restored to the parent's state gas reservoir.
|
||||
StateGasCharged uint64
|
||||
}
|
||||
|
||||
func (g *GasUsed) Add(cost GasCosts) {
|
||||
g.RegularGasUsed += cost.RegularGas
|
||||
g.StateGasCharged += cost.StateGas
|
||||
}
|
||||
|
||||
func (g GasCosts) Max() uint64 {
|
||||
return max(g.RegularGas, g.StateGas)
|
||||
}
|
||||
|
|
@ -38,11 +51,11 @@ func (g GasCosts) Underflow(b GasCosts) bool {
|
|||
// Sub doesn't check for underflows
|
||||
func (g *GasCosts) Sub(b GasCosts) {
|
||||
g.RegularGas -= b.RegularGas
|
||||
g.StateGasCharged += b.StateGas
|
||||
if b.StateGas > g.StateGas {
|
||||
diff := b.StateGas - g.StateGas
|
||||
g.StateGas = 0
|
||||
g.RegularGas -= diff
|
||||
// Note: spillover does NOT increment RegularGasUsed, matching the spec
|
||||
} else {
|
||||
g.StateGas -= b.StateGas
|
||||
}
|
||||
|
|
@ -52,7 +65,6 @@ func (g *GasCosts) Sub(b GasCosts) {
|
|||
func (g *GasCosts) Add(b GasCosts) {
|
||||
g.RegularGas += b.RegularGas
|
||||
g.StateGas += b.StateGas
|
||||
g.StateGasCharged += b.StateGasCharged
|
||||
}
|
||||
|
||||
func (g GasCosts) String() string {
|
||||
|
|
|
|||
|
|
@ -674,8 +674,10 @@ func opCreate(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
stackvalue := size
|
||||
|
||||
scope.Contract.UseGas(GasCosts{RegularGas: gas.RegularGas}, evm.Config.Tracer, tracing.GasChangeCallContractCreation)
|
||||
// UseGas inflates RegularGasUsed, so we need to undo that here.
|
||||
scope.Contract.GasUsed.RegularGasUsed -= gas.RegularGas
|
||||
|
||||
res, addr, returnGas, suberr := evm.Create(scope.Contract.Address(), input, GasCosts{RegularGas: gas.RegularGas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
res, addr, returnGas, childGasUsed, suberr := evm.Create(scope.Contract.Address(), input, GasCosts{RegularGas: gas.RegularGas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
// Push item on the stack based on the returned error. If the ruleset is
|
||||
// homestead we must check for CodeStoreOutOfGasError (homestead only
|
||||
// rule) and treat as an error, if the ruleset is frontier we must
|
||||
|
|
@ -689,7 +691,7 @@ func opCreate(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
}
|
||||
scope.Stack.push(&stackvalue)
|
||||
|
||||
scope.Contract.RefundGas(suberr, returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
scope.Contract.RefundGas(suberr, returnGas, childGasUsed, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
|
||||
if suberr == ErrExecutionReverted {
|
||||
evm.returnData = res // set REVERT data to return data buffer
|
||||
|
|
@ -724,9 +726,11 @@ func opCreate2(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
}
|
||||
|
||||
scope.Contract.UseGas(GasCosts{RegularGas: gas.RegularGas}, evm.Config.Tracer, tracing.GasChangeCallContractCreation2)
|
||||
// UseGas inflates RegularGasUsed, so we need to undo that here.
|
||||
scope.Contract.GasUsed.RegularGasUsed -= gas.RegularGas
|
||||
// reuse size int for stackvalue
|
||||
stackvalue := size
|
||||
res, addr, returnGas, suberr := evm.Create2(scope.Contract.Address(), input, GasCosts{RegularGas: gas.RegularGas, StateGas: scope.Contract.Gas.StateGas},
|
||||
res, addr, returnGas, childGasUsed, suberr := evm.Create2(scope.Contract.Address(), input, GasCosts{RegularGas: gas.RegularGas, StateGas: scope.Contract.Gas.StateGas},
|
||||
&endowment, &salt)
|
||||
// Push item on the stack based on the returned error.
|
||||
if suberr != nil {
|
||||
|
|
@ -736,7 +740,7 @@ func opCreate2(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
}
|
||||
scope.Stack.push(&stackvalue)
|
||||
|
||||
scope.Contract.RefundGas(suberr, returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
scope.Contract.RefundGas(suberr, returnGas, childGasUsed, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
|
||||
if suberr == ErrExecutionReverted {
|
||||
evm.returnData = res // set REVERT data to return data buffer
|
||||
|
|
@ -764,7 +768,10 @@ func opCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
if !value.IsZero() {
|
||||
gas += params.CallStipend
|
||||
}
|
||||
ret, returnGas, err := evm.Call(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
// We need to substract the gas here, otherwise its double counted by UseGas
|
||||
scope.Contract.GasUsed.RegularGasUsed -= gas
|
||||
|
||||
ret, returnGas, childGasUsed, err := evm.Call(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
|
|
@ -776,7 +783,7 @@ func opCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
|
||||
scope.Contract.RefundGas(err, returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
scope.Contract.RefundGas(err, returnGas, childGasUsed, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
|
||||
evm.returnData = ret
|
||||
return ret, nil
|
||||
|
|
@ -797,8 +804,10 @@ func opCallCode(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
if !value.IsZero() {
|
||||
gas += params.CallStipend
|
||||
}
|
||||
// We need to substract the gas here, otherwise its double counted by UseGas
|
||||
scope.Contract.GasUsed.RegularGasUsed -= gas
|
||||
|
||||
ret, returnGas, err := evm.CallCode(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
ret, returnGas, childGasUsed, err := evm.CallCode(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
} else {
|
||||
|
|
@ -809,7 +818,7 @@ func opCallCode(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
|
||||
scope.Contract.RefundGas(err, returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
scope.Contract.RefundGas(err, returnGas, childGasUsed, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
|
||||
evm.returnData = ret
|
||||
return ret, nil
|
||||
|
|
@ -827,8 +836,10 @@ func opDelegateCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
// Get arguments from the memory.
|
||||
args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
|
||||
|
||||
stateGas := scope.Contract.Gas.StateGas
|
||||
ret, returnGas, err := evm.DelegateCall(scope.Contract.Caller(), scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: stateGas}, scope.Contract.value)
|
||||
// We need to substract the gas here, otherwise its double counted by UseGas
|
||||
scope.Contract.GasUsed.RegularGasUsed -= gas
|
||||
|
||||
ret, returnGas, childGasUsed, err := evm.DelegateCall(scope.Contract.Caller(), scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas}, scope.Contract.value)
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
} else {
|
||||
|
|
@ -839,7 +850,7 @@ func opDelegateCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
|
||||
scope.Contract.RefundGas(err, returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
scope.Contract.RefundGas(err, returnGas, childGasUsed, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
|
||||
evm.returnData = ret
|
||||
return ret, nil
|
||||
|
|
@ -857,8 +868,10 @@ func opStaticCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
// Get arguments from the memory.
|
||||
args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
|
||||
|
||||
stateGas := scope.Contract.Gas.StateGas
|
||||
ret, returnGas, err := evm.StaticCall(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: stateGas})
|
||||
// We need to substract the gas here, otherwise its double counted by UseGas
|
||||
scope.Contract.GasUsed.RegularGasUsed -= gas
|
||||
|
||||
ret, returnGas, childGasUsed, err := evm.StaticCall(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas})
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
} else {
|
||||
|
|
@ -869,7 +882,7 @@ func opStaticCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
|
||||
scope.Contract.RefundGas(err, returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
scope.Contract.RefundGas(err, returnGas, childGasUsed, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||
|
||||
evm.returnData = ret
|
||||
return ret, nil
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ func (evm *EVM) Run(contract *Contract, input []byte, readOnly bool) (ret []byte
|
|||
return nil, ErrOutOfGas
|
||||
} else {
|
||||
contract.Gas.RegularGas -= cost
|
||||
contract.GasUsed.RegularGasUsed += cost // EIP-8037: track constant gas
|
||||
}
|
||||
|
||||
// All ops with a dynamic memory usage also has a dynamic gas cost.
|
||||
|
|
@ -228,6 +229,7 @@ func (evm *EVM) Run(contract *Contract, input []byte, readOnly bool) (ret []byte
|
|||
if contract.Gas.Underflow(dynamicCost) {
|
||||
return nil, ErrOutOfGas
|
||||
} else {
|
||||
contract.GasUsed.Add(dynamicCost)
|
||||
contract.Gas.Sub(dynamicCost)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func TestLoopInterrupt(t *testing.T) {
|
|||
timeout := make(chan bool)
|
||||
|
||||
go func(evm *EVM) {
|
||||
_, _, err := evm.Call(common.Address{}, address, nil, GasCosts{RegularGas: math.MaxUint64}, new(uint256.Int))
|
||||
_, _, _, err := evm.Call(common.Address{}, address, nil, GasCosts{RegularGas: math.MaxUint64}, new(uint256.Int))
|
||||
errChannel <- err
|
||||
}(evm)
|
||||
|
||||
|
|
|
|||
|
|
@ -307,6 +307,7 @@ func makeCallVariantGasCall(oldCalculatorStateful, oldCalculatorStateless gasFun
|
|||
if contract.Gas.Underflow(stateGasCost) {
|
||||
return GasCosts{}, ErrOutOfGas
|
||||
}
|
||||
contract.GasUsed.Add(stateGasCost)
|
||||
contract.Gas.Sub(stateGasCost)
|
||||
}
|
||||
|
||||
|
|
@ -327,10 +328,15 @@ func makeCallVariantGasCall(oldCalculatorStateful, oldCalculatorStateless gasFun
|
|||
if overflow {
|
||||
return GasCosts{}, ErrGasUintOverflow
|
||||
}
|
||||
// EIP-8037: undo the RegularGasUsed increment from the direct UseGas
|
||||
// charge, since this gas will be re-charged via the returned cost.
|
||||
contract.GasUsed.RegularGasUsed -= eip2929Gas
|
||||
|
||||
contract.Gas.RegularGas, overflow = math.SafeAdd(contract.Gas.RegularGas, eip7702Gas)
|
||||
if overflow {
|
||||
return GasCosts{}, ErrGasUintOverflow
|
||||
}
|
||||
contract.GasUsed.RegularGasUsed -= eip7702Gas
|
||||
|
||||
var totalCost uint64
|
||||
totalCost, overflow = math.SafeAdd(eip2929Gas, eip7702Gas)
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
|||
// set the receiver's (the executing contract) code for execution.
|
||||
cfg.State.SetCode(address, code, tracing.CodeChangeUnspecified)
|
||||
// Call the code with the given configuration.
|
||||
ret, leftOverGas, err := vmenv.Call(
|
||||
ret, leftOverGas, _, err := vmenv.Call(
|
||||
cfg.Origin,
|
||||
common.BytesToAddress([]byte("contract")),
|
||||
input,
|
||||
|
|
@ -177,7 +177,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
// - reset transient storage(eip 1153)
|
||||
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, nil, vm.ActivePrecompiles(rules), nil)
|
||||
// Call the code with the given configuration.
|
||||
code, address, leftOverGas, err := vmenv.Create(
|
||||
code, address, leftOverGas, _, err := vmenv.Create(
|
||||
cfg.Origin,
|
||||
input,
|
||||
vm.GasCosts{RegularGas: cfg.GasLimit},
|
||||
|
|
@ -211,7 +211,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
|
|||
statedb.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil)
|
||||
|
||||
// Call the code with the given configuration.
|
||||
ret, leftOverGas, err := vmenv.Call(
|
||||
ret, leftOverGas, _, err := vmenv.Call(
|
||||
cfg.Origin,
|
||||
address,
|
||||
input,
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
|
|||
start := time.Now()
|
||||
|
||||
// Execute the message.
|
||||
_, leftOverGas, err := evm.Call(sender.Address(), *msg.To, msg.Data, vm.GasCosts{RegularGas: msg.GasLimit}, uint256.MustFromBig(msg.Value))
|
||||
_, leftOverGas, _, err := evm.Call(sender.Address(), *msg.To, msg.Data, vm.GasCosts{RegularGas: msg.GasLimit}, uint256.MustFromBig(msg.Value))
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in a new issue