core/vm: fix EIP-8037 blockGasUsed underflow from code-store OOG

When CREATE init code produces valid code but UseGas fails for code
storage, TotalStateGasCharged was incremented by the full code storage
state gas (potentially millions) without consuming any actual gas.
This inflated TSC propagated up through RefundGas and caused
blockGasUsed() to underflow (execRegularUsed = totalExecUsed - TSC
wraps uint64), resulting in incorrect gas pool accounting and state
root mismatches when validating blocks from other clients.

The fix removes the TSC increment when UseGas fails for code storage.
Since the contract creation failed and state was reverted, the state
gas demand didn't materialize and shouldn't be tracked.

Also removes the ErrCodeStoreOutOfGas case from isCodeValidation since
TSC is no longer inflated in that code path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
qu0b 2026-03-07 01:26:33 +00:00
parent c33c10cb1b
commit 734fa6f8a5

View file

@ -619,8 +619,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
// State gas charges must persist for block 2D gas accounting even
// though the state is reverted. Only zero regular gas as penalty.
isCodeValidation := evm.chainRules.IsAmsterdam &&
(errors.Is(err, ErrMaxCodeSizeExceeded) || errors.Is(err, ErrInvalidCode) ||
(err == ErrCodeStoreOutOfGas && contract.Gas.TotalStateGasCharged > savedTotalStateGas))
(errors.Is(err, ErrMaxCodeSizeExceeded) || errors.Is(err, ErrInvalidCode))
if !isRevert {
if isCodeValidation {
contract.Gas.RegularGas = 0
@ -663,13 +662,6 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
}
}
if !contract.UseGas(createDataGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) {
if evm.chainRules.IsAmsterdam && codeErr == nil {
// Valid code that merely ran out of gas: track state gas for
// block accounting (EIP-8037).
contract.Gas.TotalStateGasCharged += createDataGas.StateGas
contract.Gas.RegularGas = 0
contract.Gas.StateGas = 0
}
return ret, ErrCodeStoreOutOfGas
}
} else {