core: introduce vm.GasBudget

This commit is contained in:
Marius van der Wijden 2026-04-08 15:26:28 +02:00
parent 0578ebbe1a
commit 778326725b
12 changed files with 69 additions and 69 deletions

View file

@ -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)
}

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)
}

View file

@ -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()

View file

@ -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) {

View file

@ -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 (

View file

@ -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 {

View file

@ -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)

View file

@ -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

View file

@ -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