mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-04-10 03:47:30 +00:00
core: introduce vm.GasBudget
This commit is contained in:
parent
0578ebbe1a
commit
778326725b
12 changed files with 69 additions and 69 deletions
|
|
@ -286,7 +286,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.GasBudget{RegularGas: 30_000_000}, common.U2560)
|
||||
return evm.StateDB.Finalise(true)
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +310,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.GasBudget{RegularGas: 30_000_000}, common.U2560)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -350,8 +350,13 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte
|
|||
}
|
||||
evm.SetTxContext(NewEVMTxContext(msg))
|
||||
evm.StateDB.AddAddressToAccessList(addr)
|
||||
<<<<<<< HEAD
|
||||
ret, _, _, err := evm.Call(msg.From, *msg.To, msg.Data, vm.GasCosts{RegularGas: 30_000_000}, common.U2560)
|
||||
mut := evm.StateDB.Finalise(true)
|
||||
=======
|
||||
ret, _, _, err := evm.Call(msg.From, *msg.To, msg.Data, vm.GasBudget{RegularGas: 30_000_000}, common.U2560)
|
||||
evm.StateDB.Finalise(true)
|
||||
>>>>>>> 96f0b19c51 (core: introduce vm.GasBudget)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("system call failed to execute: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,8 +256,8 @@ func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, err
|
|||
type stateTransition struct {
|
||||
gp *GasPool
|
||||
msg *Message
|
||||
gasRemaining vm.GasCosts
|
||||
initialGas vm.GasCosts
|
||||
gasRemaining vm.GasBudget
|
||||
initialGas vm.GasBudget
|
||||
state vm.StateDB
|
||||
evm *vm.EVM
|
||||
}
|
||||
|
|
@ -323,7 +323,7 @@ func (st *stateTransition) buyGas() error {
|
|||
if st.evm.ChainConfig().IsAmsterdam(st.evm.Context.BlockNumber, st.evm.Context.Time) {
|
||||
limit = min(st.msg.GasLimit, params.MaxTxGas)
|
||||
}
|
||||
st.initialGas = vm.GasCosts{RegularGas: limit, StateGas: st.msg.GasLimit - limit}
|
||||
st.initialGas = vm.GasBudget{RegularGas: limit, StateGas: st.msg.GasLimit - limit}
|
||||
mgvalU256, _ := uint256.FromBig(mgval)
|
||||
st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy)
|
||||
return nil
|
||||
|
|
@ -496,7 +496,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
// Split remaining execution gas into regular and state reservoir.
|
||||
executionGas := msg.GasLimit - gas.Sum()
|
||||
regularGas := min(params.MaxTxGas-gas.RegularGas, executionGas)
|
||||
st.gasRemaining = vm.GasCosts{RegularGas: regularGas, StateGas: executionGas - regularGas}
|
||||
st.gasRemaining = vm.GasBudget{RegularGas: regularGas, StateGas: executionGas - regularGas}
|
||||
} else {
|
||||
if st.gasRemaining.Underflow(gas) {
|
||||
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining.RegularGas, gas.RegularGas)
|
||||
|
|
@ -605,8 +605,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
// 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
|
||||
txState := (gas.StateGas - authRefund) + execGasUsed.StateGas
|
||||
txRegular := gas.RegularGas + execGasUsed.RegularGas
|
||||
txRegular = max(txRegular, floorDataGas)
|
||||
if err := st.gp.ReturnGasAmsterdam(txRegular, txState, st.gasUsed()); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -42,13 +42,13 @@ type Contract struct {
|
|||
IsDeployment bool
|
||||
IsSystemCall bool
|
||||
|
||||
Gas GasCosts
|
||||
Gas GasBudget
|
||||
GasUsed GasUsed // EIP-8037: canonical per-frame gas usage accumulator
|
||||
value *uint256.Int
|
||||
}
|
||||
|
||||
// NewContract returns a new contract environment for the execution of EVM.
|
||||
func NewContract(caller common.Address, address common.Address, value *uint256.Int, gas GasCosts, jumpDests JumpDestCache) *Contract {
|
||||
func NewContract(caller common.Address, address common.Address, value *uint256.Int, gas GasBudget, jumpDests JumpDestCache) *Contract {
|
||||
// Initialize the jump analysis cache if it's nil, mostly for tests
|
||||
if jumpDests == nil {
|
||||
jumpDests = newMapJumpDests()
|
||||
|
|
@ -145,10 +145,10 @@ func (c *Contract) RefundGas(err error, initialRegularGasUsed uint64, gas GasCos
|
|||
// If the preceding call errored, return the state gas
|
||||
// to the parent call
|
||||
if err != nil {
|
||||
gas.StateGas += gasUsed.StateGasCharged
|
||||
gasUsed.StateGasCharged = 0
|
||||
gas.StateGas += gasUsed.StateGas
|
||||
gasUsed.StateGas = 0
|
||||
}
|
||||
if gas.RegularGas == 0 && gas.StateGas == 0 && gasUsed.StateGasCharged == 0 && gasUsed.RegularGasUsed == 0 {
|
||||
if gas.RegularGas == 0 && gas.StateGas == 0 && gasUsed.StateGas == 0 && gasUsed.RegularGas == 0 {
|
||||
return
|
||||
}
|
||||
if logger != nil && logger.OnGasChange != nil && reason != tracing.GasChangeIgnored {
|
||||
|
|
@ -156,8 +156,8 @@ func (c *Contract) RefundGas(err error, initialRegularGasUsed uint64, gas GasCos
|
|||
}
|
||||
c.Gas.RegularGas += gas.RegularGas
|
||||
c.Gas.StateGas = gas.StateGas
|
||||
c.GasUsed.StateGasCharged += gasUsed.StateGasCharged
|
||||
c.GasUsed.RegularGasUsed = initialRegularGasUsed + gasUsed.RegularGasUsed
|
||||
c.GasUsed.StateGas += gasUsed.StateGas
|
||||
c.GasUsed.RegularGas = initialRegularGasUsed + gasUsed.RegularGas
|
||||
}
|
||||
|
||||
// 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, gasUsed GasUsed, err error) {
|
||||
func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, gas GasBudget, value *uint256.Int) (ret []byte, leftOverGas GasBudget, 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())
|
||||
|
|
@ -264,7 +264,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
wgas := evm.AccessEvents.CodeHashGas(addr, true, gas.RegularGas, false)
|
||||
if gas.RegularGas < wgas {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
return nil, GasCosts{}, GasUsed{}, ErrOutOfGas
|
||||
return nil, GasBudget{}, GasUsed{}, ErrOutOfGas
|
||||
}
|
||||
gas.RegularGas -= wgas
|
||||
}
|
||||
|
|
@ -289,7 +289,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
gasUsed.RegularGas += gasBefore - gas.RegularGas
|
||||
} else {
|
||||
// Initialise a new contract and set the code that is to be used by the EVM.
|
||||
code := evm.resolveCode(addr)
|
||||
|
|
@ -315,7 +315,7 @@ 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
|
||||
gasUsed.RegularGas += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -329,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, gasUsed GasUsed, err error) {
|
||||
func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byte, gas GasBudget, value *uint256.Int) (ret []byte, leftOverGas GasBudget, 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())
|
||||
|
|
@ -355,7 +355,7 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
|||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
gasUsed.RegularGas += 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.
|
||||
|
|
@ -372,7 +372,7 @@ 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
|
||||
gasUsed.RegularGas += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -384,7 +384,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, gasUsed GasUsed, err error) {
|
||||
func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address, addr common.Address, input []byte, gas GasBudget, value *uint256.Int) (ret []byte, leftOverGas GasBudget, 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
|
||||
|
|
@ -407,7 +407,7 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
|||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
gasUsed.RegularGas += gasBefore - gas.RegularGas
|
||||
} else {
|
||||
contract := NewContract(originCaller, caller, value, gas, evm.jumpDests)
|
||||
contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
|
||||
|
|
@ -422,7 +422,7 @@ 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
|
||||
gasUsed.RegularGas += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -433,7 +433,7 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
|||
// 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, gasUsed GasUsed, err error) {
|
||||
func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []byte, gas GasBudget) (ret []byte, leftOverGas GasBudget, 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)
|
||||
|
|
@ -456,7 +456,7 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
|
|||
}
|
||||
gasBefore := gas.RegularGas
|
||||
ret, gas.RegularGas, err = RunPrecompiledContract(stateDB, p, addr, input, gas.RegularGas, evm.Config.Tracer)
|
||||
gasUsed.RegularGasUsed += gasBefore - gas.RegularGas
|
||||
gasUsed.RegularGas += gasBefore - gas.RegularGas
|
||||
} else {
|
||||
contract := NewContract(caller, addr, new(uint256.Int), gas, evm.jumpDests)
|
||||
contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
|
||||
|
|
@ -471,7 +471,7 @@ 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
|
||||
gasUsed.RegularGas += gas.RegularGas
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -479,7 +479,7 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []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, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas GasCosts, used GasUsed, err error) {
|
||||
func (evm *EVM) create(caller common.Address, code []byte, gas GasBudget, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas GasBudget, used GasUsed, err error) {
|
||||
// Depth check execution. Fail if we're trying to execute above the
|
||||
// limit.
|
||||
var nonce uint64
|
||||
|
|
@ -511,7 +511,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
if evm.chainRules.IsEIP4762 {
|
||||
statelessGas := evm.AccessEvents.ContractCreatePreCheckGas(address, gas.RegularGas)
|
||||
if statelessGas > gas.RegularGas {
|
||||
return nil, common.Address{}, GasCosts{}, GasUsed{}, ErrOutOfGas
|
||||
return nil, common.Address{}, GasBudget{}, GasUsed{}, ErrOutOfGas
|
||||
}
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, gas.RegularGas-statelessGas, tracing.GasChangeWitnessContractCollisionCheck)
|
||||
|
|
@ -539,7 +539,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
// Burn all gas on collision
|
||||
collisionUsed := GasUsed{RegularGasUsed: gas.RegularGas}
|
||||
collisionUsed := GasUsed{RegularGas: gas.RegularGas}
|
||||
gas.RegularGas = 0
|
||||
return nil, common.Address{}, gas, collisionUsed, ErrContractAddressCollision
|
||||
}
|
||||
|
|
@ -564,7 +564,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{}, GasUsed{}, ErrOutOfGas
|
||||
return nil, common.Address{}, GasBudget{}, GasUsed{}, ErrOutOfGas
|
||||
}
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, gas.RegularGas-consumed, tracing.GasChangeWitnessContractInit)
|
||||
|
|
@ -589,7 +589,7 @@ 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.GasUsed.RegularGas += contract.Gas.RegularGas
|
||||
contract.Gas.RegularGas = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -652,7 +652,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, gasUsed GasUsed, err error) {
|
||||
func (evm *EVM) Create(caller common.Address, code []byte, gas GasBudget, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas GasBudget, gasUsed GasUsed, err error) {
|
||||
contractAddr = crypto.CreateAddress(caller, evm.StateDB.GetNonce(caller))
|
||||
return evm.create(caller, code, gas, value, contractAddr, CREATE)
|
||||
}
|
||||
|
|
@ -661,7 +661,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, gasUsed GasUsed, err error) {
|
||||
func (evm *EVM) Create2(caller common.Address, code []byte, gas GasBudget, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas GasBudget, gasUsed GasUsed, err error) {
|
||||
inithash := crypto.Keccak256Hash(code)
|
||||
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:])
|
||||
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2)
|
||||
|
|
@ -699,7 +699,7 @@ func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash {
|
|||
// ChainConfig returns the environment's chain configuration
|
||||
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
||||
|
||||
func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to common.Address, input []byte, startGas GasCosts, value *big.Int) {
|
||||
func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to common.Address, input []byte, startGas GasBudget, value *big.Int) {
|
||||
tracer := evm.Config.Tracer
|
||||
if tracer.OnEnter != nil {
|
||||
tracer.OnEnter(depth, byte(typ), from, to, input, startGas.RegularGas, value)
|
||||
|
|
@ -709,7 +709,7 @@ func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to comm
|
|||
}
|
||||
}
|
||||
|
||||
func (evm *EVM) captureEnd(depth int, startGas GasCosts, leftOverGas GasCosts, ret []byte, err error) {
|
||||
func (evm *EVM) captureEnd(depth int, startGas GasBudget, leftOverGas GasBudget, ret []byte, err error) {
|
||||
tracer := evm.Config.Tracer
|
||||
if leftOverGas.RegularGas != 0 && tracer.OnGasChange != nil {
|
||||
tracer.OnGasChange(leftOverGas.RegularGas, 0, tracing.GasChangeCallLeftOverReturned)
|
||||
|
|
|
|||
|
|
@ -7,16 +7,17 @@ type GasCosts struct {
|
|||
StateGas uint64
|
||||
}
|
||||
|
||||
// GasBudget tracks how much gas is available in a call frame.
|
||||
type GasBudget = GasCosts
|
||||
|
||||
// GasUsed tracks how much gas has been consumed during execution.
|
||||
type GasUsed struct {
|
||||
RegularGasUsed uint64
|
||||
StateGasCharged uint64
|
||||
}
|
||||
type GasUsed = GasCosts
|
||||
|
||||
// Add increments gas used counters based on a GasCosts charge.
|
||||
// doesn't check for overflows.
|
||||
func (g *GasUsed) Add(cost GasCosts) {
|
||||
g.RegularGasUsed += cost.RegularGas
|
||||
g.StateGasCharged += cost.StateGas
|
||||
g.RegularGas += cost.RegularGas
|
||||
g.StateGas += cost.StateGas
|
||||
}
|
||||
|
||||
func (g GasCosts) Max() uint64 {
|
||||
|
|
@ -56,12 +57,6 @@ func (g *GasCosts) Sub(b GasCosts) {
|
|||
}
|
||||
}
|
||||
|
||||
// Add doesn't check for overflows
|
||||
func (g *GasCosts) Add(b GasCosts) {
|
||||
g.RegularGas += b.RegularGas
|
||||
g.StateGas += b.StateGas
|
||||
}
|
||||
|
||||
func (g GasCosts) String() string {
|
||||
return fmt.Sprintf("<%v,%v>", g.RegularGas, g.StateGas)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ func opCreate(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
// reuse size int for stackvalue
|
||||
stackvalue := size
|
||||
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGasUsed
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGas
|
||||
scope.Contract.UseGas(GasCosts{RegularGas: gas.RegularGas}, evm.Config.Tracer, tracing.GasChangeCallContractCreation)
|
||||
|
||||
res, addr, returnGas, childGasUsed, suberr := evm.Create(scope.Contract.Address(), input, GasCosts{RegularGas: gas.RegularGas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
|
|
@ -724,7 +724,7 @@ func opCreate2(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGasUsed
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGas
|
||||
scope.Contract.UseGas(GasCosts{RegularGas: gas.RegularGas}, evm.Config.Tracer, tracing.GasChangeCallContractCreation2)
|
||||
|
||||
// reuse size int for stackvalue
|
||||
|
|
@ -767,7 +767,7 @@ func opCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
if !value.IsZero() {
|
||||
gas += params.CallStipend
|
||||
}
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGasUsed
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGas
|
||||
ret, returnGas, childGasUsed, err := evm.Call(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas}, &value)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -802,7 +802,7 @@ func opCallCode(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
gas += params.CallStipend
|
||||
}
|
||||
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGasUsed
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGas
|
||||
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()
|
||||
|
|
@ -832,7 +832,7 @@ func opDelegateCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
// Get arguments from the memory.
|
||||
args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
|
||||
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGasUsed
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGas
|
||||
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()
|
||||
|
|
@ -862,7 +862,7 @@ func opStaticCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
|||
// Get arguments from the memory.
|
||||
args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
|
||||
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGasUsed
|
||||
regularGasUsed := scope.Contract.GasUsed.RegularGas
|
||||
ret, returnGas, childGasUsed, err := evm.StaticCall(scope.Contract.Address(), toAddr, args, GasCosts{RegularGas: gas, StateGas: scope.Contract.Gas.StateGas})
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
|
|
|
|||
|
|
@ -196,7 +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
|
||||
contract.GasUsed.RegularGas += cost // EIP-8037: track constant gas
|
||||
}
|
||||
|
||||
// All ops with a dynamic memory usage also has a dynamic gas cost.
|
||||
|
|
@ -231,7 +231,7 @@ func (evm *EVM) Run(contract *Contract, input []byte, readOnly bool) (ret []byte
|
|||
if contract.Gas.RegularGas < dynamicCost.RegularGas {
|
||||
return nil, ErrOutOfGas
|
||||
}
|
||||
contract.GasUsed.RegularGasUsed += dynamicCost.RegularGas
|
||||
contract.GasUsed.RegularGas += dynamicCost.RegularGas
|
||||
contract.Gas.RegularGas -= dynamicCost.RegularGas
|
||||
stateOnly := GasCosts{StateGas: dynamicCost.StateGas}
|
||||
if contract.Gas.Underflow(stateOnly) {
|
||||
|
|
|
|||
|
|
@ -355,8 +355,8 @@ func makeCallVariantGasCallEIP7702(intrinsicFunc intrinsicGasFunc) gasFunc {
|
|||
contract.Gas.RegularGas += eip2929Cost + eip7702Cost
|
||||
// Undo the RegularGasUsed increments from the direct UseGas charges,
|
||||
// since this gas will be re-charged via the returned cost.
|
||||
contract.GasUsed.RegularGasUsed -= eip2929Cost
|
||||
contract.GasUsed.RegularGasUsed -= eip7702Cost
|
||||
contract.GasUsed.RegularGas -= eip2929Cost
|
||||
contract.GasUsed.RegularGas -= eip7702Cost
|
||||
|
||||
// Aggregate the gas costs from all components, including EIP-2929, EIP-7702,
|
||||
// the CALL opcode itself, and the cost incurred by nested calls.
|
||||
|
|
@ -446,7 +446,7 @@ func makeCallVariantGasCallEIP8037(intrinsicFunc intrinsicGasFunc, stateGasFunc
|
|||
// Temporarily undo direct regular charges for tracer reporting.
|
||||
// The interpreter will charge the returned totalCost.
|
||||
contract.Gas.RegularGas += eip2929Cost + eip7702Cost + intrinsicCost
|
||||
contract.GasUsed.RegularGasUsed -= eip2929Cost + eip7702Cost + intrinsicCost
|
||||
contract.GasUsed.RegularGas -= eip2929Cost + eip7702Cost + intrinsicCost
|
||||
|
||||
// Aggregate total cost.
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
|||
cfg.Origin,
|
||||
common.BytesToAddress([]byte("contract")),
|
||||
input,
|
||||
vm.GasCosts{RegularGas: cfg.GasLimit},
|
||||
vm.GasBudget{RegularGas: cfg.GasLimit},
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
|
||||
|
|
@ -180,7 +180,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
code, address, leftOverGas, _, err := vmenv.Create(
|
||||
cfg.Origin,
|
||||
input,
|
||||
vm.GasCosts{RegularGas: cfg.GasLimit},
|
||||
vm.GasBudget{RegularGas: cfg.GasLimit},
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
|
||||
|
|
@ -215,7 +215,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
|
|||
cfg.Origin,
|
||||
address,
|
||||
input,
|
||||
vm.GasCosts{RegularGas: cfg.GasLimit},
|
||||
vm.GasBudget{RegularGas: cfg.GasLimit},
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCo
|
|||
gasLimit uint64 = 31000
|
||||
startGas uint64 = 10000
|
||||
value = uint256.NewInt(0)
|
||||
contract = vm.NewContract(common.Address{}, common.Address{}, value, vm.GasCosts{RegularGas: startGas}, nil)
|
||||
contract = vm.NewContract(common.Address{}, common.Address{}, value, vm.GasBudget{RegularGas: startGas}, nil)
|
||||
)
|
||||
evm.SetTxContext(vmctx.txCtx)
|
||||
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
|
||||
|
|
@ -183,7 +183,7 @@ func TestHaltBetweenSteps(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
scope := &vm.ScopeContext{
|
||||
Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), vm.GasCosts{}, nil),
|
||||
Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), vm.GasBudget{}, nil),
|
||||
}
|
||||
evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, chainConfig, vm.Config{Tracer: tracer.Hooks})
|
||||
evm.SetTxContext(vm.TxContext{GasPrice: uint256.NewInt(1)})
|
||||
|
|
@ -281,7 +281,7 @@ func TestEnterExit(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
scope := &vm.ScopeContext{
|
||||
Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), vm.GasCosts{}, nil),
|
||||
Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), vm.GasBudget{}, nil),
|
||||
}
|
||||
tracer.OnEnter(1, byte(vm.CALL), scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int))
|
||||
tracer.OnExit(1, []byte{}, 400, nil, false)
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func TestStoreCapture(t *testing.T) {
|
|||
var (
|
||||
logger = NewStructLogger(nil)
|
||||
evm = vm.NewEVM(vm.BlockContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: logger.Hooks()})
|
||||
contract = vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), vm.GasCosts{RegularGas: 100000}, nil)
|
||||
contract = vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), vm.GasBudget{RegularGas: 100000}, nil)
|
||||
)
|
||||
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)}
|
||||
var index common.Hash
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
|
|||
evm.SetTxContext(txContext)
|
||||
|
||||
// Create "contract" for sender to cache code analysis.
|
||||
sender := vm.NewContract(msg.From, msg.From, nil, vm.GasCosts{}, nil)
|
||||
sender := vm.NewContract(msg.From, msg.From, nil, vm.GasBudget{}, nil)
|
||||
|
||||
var (
|
||||
gasUsed uint64
|
||||
|
|
@ -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.GasBudget{RegularGas: msg.GasLimit}, uint256.MustFromBig(msg.Value))
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in a new issue