core: fix floor calculation

This commit is contained in:
Marius van der Wijden 2026-03-10 14:36:52 +01:00
parent 6ed41d9d83
commit e93ddc03b7
2 changed files with 21 additions and 9 deletions

View file

@ -582,7 +582,11 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
// After EIP-7623: Data-heavy transactions pay the floor gas.
if st.gasUsed() < floorDataGas {
prev := st.gasRemaining.RegularGas
st.gasRemaining.RegularGas = st.initialGas.RegularGas - floorDataGas
// When the calldata floor exceeds actual gas used, any
// remaining state gas must also be consumed
targetRemaining := (st.initialGas.RegularGas + st.initialGas.StateGas) - floorDataGas
st.gasRemaining.StateGas = 0
st.gasRemaining.RegularGas = targetRemaining
if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil {
t.OnGasChange(prev, st.gasRemaining.RegularGas, tracing.GasChangeTxDataFloor)
}

View file

@ -622,16 +622,24 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
// Charge code storage gas.
if !evm.chainRules.IsEIP4762 {
createDataGas := GasCosts{RegularGas: uint64(len(ret)) * params.CreateDataGas}
if evm.chainRules.IsAmsterdam {
words := (uint64(len(ret)) + 31) / 32
createDataGas = GasCosts{
RegularGas: words * params.Keccak256WordGas,
StateGas: uint64(len(ret)) * evm.Context.CostPerGasByte,
// EIP-8037: spec charges state gas first (charge_state_gas), then
// regular gas (charge_gas). If state gas succeeds but regular gas
// fails, state_gas_used is still recorded.
stateGas := GasCosts{StateGas: uint64(len(ret)) * evm.Context.CostPerGasByte}
if !contract.UseGas(stateGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) {
return ret, ErrCodeStoreOutOfGas
}
words := (uint64(len(ret)) + 31) / 32
regularGas := GasCosts{RegularGas: words * params.Keccak256WordGas}
if !contract.UseGas(regularGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) {
return ret, ErrCodeStoreOutOfGas
}
} else {
createDataGas := GasCosts{RegularGas: uint64(len(ret)) * params.CreateDataGas}
if !contract.UseGas(createDataGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) {
return ret, ErrCodeStoreOutOfGas
}
}
if !contract.UseGas(createDataGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) {
return ret, ErrCodeStoreOutOfGas
}
} else {
consumed, wanted := evm.AccessEvents.CodeChunksRangeGas(address, 0, uint64(len(ret)), uint64(len(ret)), true, contract.Gas.RegularGas)