core/vm: remove initial gas tracking

This commit is contained in:
MariusVanDerWijden 2026-04-14 15:23:46 +02:00
parent 3958039619
commit 48a1c96603
4 changed files with 26 additions and 18 deletions

View file

@ -242,11 +242,12 @@ func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, err
// 5. Run Script section // 5. Run Script section
// 6. Derive new state root // 6. Derive new state root
type stateTransition struct { type stateTransition struct {
gp *GasPool gp *GasPool
msg *Message msg *Message
gasRemaining vm.GasBudget initialBudget vm.GasBudget
state vm.StateDB gasRemaining vm.GasBudget
evm *vm.EVM state vm.StateDB
evm *vm.EVM
} }
// newStateTransition initialises and returns a new state transition object. // newStateTransition initialises and returns a new state transition object.
@ -304,6 +305,7 @@ func (st *stateTransition) buyGas() error {
st.evm.Config.Tracer.OnGasChange(0, st.msg.GasLimit, tracing.GasChangeTxInitialBalance) st.evm.Config.Tracer.OnGasChange(0, st.msg.GasLimit, tracing.GasChangeTxInitialBalance)
} }
st.gasRemaining = vm.NewGasBudget(st.msg.GasLimit) st.gasRemaining = vm.NewGasBudget(st.msg.GasLimit)
st.initialBudget = st.gasRemaining.Copy()
mgvalU256, _ := uint256.FromBig(mgval) mgvalU256, _ := uint256.FromBig(mgval)
st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy) st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy)
@ -552,7 +554,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
// Return gas to the gas pool // Return gas to the gas pool
if rules.IsAmsterdam { if rules.IsAmsterdam {
// Refund is excluded for returning // Refund is excluded for returning
err = st.gp.ReturnGas(st.gasRemaining.InitialGas-peakGasUsed, st.gasUsed()) err = st.gp.ReturnGas(st.initialBudget.RegularGas-peakGasUsed, st.gasUsed())
} else { } else {
// Refund is included for returning // Refund is included for returning
err = st.gp.ReturnGas(st.gasRemaining.RegularGas, st.gasUsed()) err = st.gp.ReturnGas(st.gasRemaining.RegularGas, st.gasUsed())
@ -684,7 +686,7 @@ func (st *stateTransition) returnGas() {
// gasUsed returns the amount of gas used up by the state transition. // gasUsed returns the amount of gas used up by the state transition.
func (st *stateTransition) gasUsed() uint64 { func (st *stateTransition) gasUsed() uint64 {
return st.gasRemaining.Used() return st.gasRemaining.Used(st.initialBudget)
} }
// blobGasUsed returns the amount of blob gas used by the message. // blobGasUsed returns the amount of blob gas used by the message.

View file

@ -97,12 +97,12 @@ func TestEIP2200(t *testing.T) {
Transfer: func(StateDB, common.Address, common.Address, *uint256.Int, *params.Rules) {}, Transfer: func(StateDB, common.Address, common.Address, *uint256.Int, *params.Rules) {},
} }
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
initialGas := NewGasBudget(tt.gaspool)
_, leftOver, err := evm.Call(common.Address{}, address, nil, NewGasBudget(tt.gaspool), new(uint256.Int)) _, leftOver, err := evm.Call(common.Address{}, address, nil, initialGas.Copy(), new(uint256.Int))
if !errors.Is(err, tt.failure) { if !errors.Is(err, tt.failure) {
t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure) t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
} }
if used := leftOver.Used(); used != tt.used { if used := leftOver.Used(initialGas); used != tt.used {
t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used) t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used)
} }
if refund := evm.StateDB.GetRefund(); refund != tt.refund { if refund := evm.StateDB.GetRefund(); refund != tt.refund {
@ -157,11 +157,12 @@ func TestCreateGas(t *testing.T) {
} }
evm := NewEVM(vmctx, statedb, chainConfig, config) evm := NewEVM(vmctx, statedb, chainConfig, config)
ret, leftOver, err := evm.Call(common.Address{}, address, nil, NewGasBudget(uint64(testGas)), new(uint256.Int)) initialGas := NewGasBudget(uint64(testGas))
ret, leftOver, err := evm.Call(common.Address{}, address, nil, initialGas.Copy(), new(uint256.Int))
if err != nil { if err != nil {
return false return false
} }
gasUsed = leftOver.Used() gasUsed = leftOver.Used(initialGas)
if len(ret) != 32 { if len(ret) != 32 {
t.Fatalf("test %d: expected 32 bytes returned, have %d", i, len(ret)) t.Fatalf("test %d: expected 32 bytes returned, have %d", i, len(ret))
} }

View file

@ -43,17 +43,16 @@ func (g GasCosts) String() string {
type GasBudget struct { type GasBudget struct {
RegularGas uint64 // The leftover gas for execution and state gas usage RegularGas uint64 // The leftover gas for execution and state gas usage
StateGas uint64 // The state gas reservoir StateGas uint64 // The state gas reservoir
InitialGas uint64 // records the starting allowance for usage tracking
} }
// NewGasBudget creates a GasBudget with the given initial regular gas allowance. // NewGasBudget creates a GasBudget with the given initial regular gas allowance.
func NewGasBudget(gas uint64) GasBudget { func NewGasBudget(gas uint64) GasBudget {
return GasBudget{RegularGas: gas, InitialGas: gas} return GasBudget{RegularGas: gas}
} }
// Used returns the amount of regular gas consumed so far. // Used returns the amount of regular gas consumed so far.
func (g GasBudget) Used() uint64 { func (g GasBudget) Used(initial GasBudget) uint64 {
return g.InitialGas - g.RegularGas return initial.RegularGas - g.RegularGas
} }
// Exhaust sets all remaining gas to zero, preserving the initial amount // Exhaust sets all remaining gas to zero, preserving the initial amount
@ -63,6 +62,10 @@ func (g *GasBudget) Exhaust() {
g.StateGas = 0 g.StateGas = 0
} }
func (g *GasBudget) Copy() GasBudget {
return GasBudget{RegularGas: g.RegularGas, StateGas: g.StateGas}
}
// String returns a visual representation of the gas budget vector. // String returns a visual representation of the gas budget vector.
func (g GasBudget) String() string { func (g GasBudget) String() string {
return fmt.Sprintf("<%v,%v>", g.RegularGas, g.StateGas) return fmt.Sprintf("<%v,%v>", g.RegularGas, g.StateGas)

View file

@ -315,8 +315,10 @@ func runBenchmark(b *testing.B, t *StateTest) {
b.StartTimer() b.StartTimer()
start := time.Now() start := time.Now()
initialGas := vm.NewGasBudget(msg.GasLimit)
// Execute the message. // Execute the message.
_, leftOverGas, err := evm.Call(sender.Address(), *msg.To, msg.Data, vm.NewGasBudget(msg.GasLimit), uint256.MustFromBig(msg.Value)) _, leftOverGas, err := evm.Call(sender.Address(), *msg.To, msg.Data, initialGas.Copy(), uint256.MustFromBig(msg.Value))
if err != nil { if err != nil {
b.Error(err) b.Error(err)
return return
@ -325,7 +327,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
b.StopTimer() b.StopTimer()
elapsed += uint64(time.Since(start)) elapsed += uint64(time.Since(start))
refund += state.StateDB.GetRefund() refund += state.StateDB.GetRefund()
gasUsed += leftOverGas.Used() gasUsed += leftOverGas.Used(initialGas)
state.StateDB.RevertToSnapshot(snapshot) state.StateDB.RevertToSnapshot(snapshot)
} }