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. // After EIP-7623: Data-heavy transactions pay the floor gas.
if st.gasUsed() < floorDataGas { if st.gasUsed() < floorDataGas {
prev := st.gasRemaining.RegularGas 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 { if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil {
t.OnGasChange(prev, st.gasRemaining.RegularGas, tracing.GasChangeTxDataFloor) 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. // Charge code storage gas.
if !evm.chainRules.IsEIP4762 { if !evm.chainRules.IsEIP4762 {
createDataGas := GasCosts{RegularGas: uint64(len(ret)) * params.CreateDataGas}
if evm.chainRules.IsAmsterdam { if evm.chainRules.IsAmsterdam {
words := (uint64(len(ret)) + 31) / 32 // EIP-8037: spec charges state gas first (charge_state_gas), then
createDataGas = GasCosts{ // regular gas (charge_gas). If state gas succeeds but regular gas
RegularGas: words * params.Keccak256WordGas, // fails, state_gas_used is still recorded.
StateGas: uint64(len(ret)) * evm.Context.CostPerGasByte, 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 { } else {
consumed, wanted := evm.AccessEvents.CodeChunksRangeGas(address, 0, uint64(len(ret)), uint64(len(ret)), true, contract.Gas.RegularGas) consumed, wanted := evm.AccessEvents.CodeChunksRangeGas(address, 0, uint64(len(ret)), uint64(len(ret)), true, contract.Gas.RegularGas)