EIP-8037: State Creation Gas Cost Increase#10712
Conversation
There was a problem hiding this comment.
Pull request overview
Implements EIP-8037 (“State Creation Gas Cost Increase”) by introducing an EIP-8037 enablement flag in specs/chainspecs and plumbing two-dimensional (regular + state) gas metering through transaction processing and EVM execution.
Changes:
- Add
IsEip8037Enabledto release specs/forks and make it configurable via chainspec transition timestamps. - Introduce/extend two-dimensional gas accounting in
IGasPolicy/EthereumGasPolicyand update opcode dispatch + CREATE/CALL/SSTORE/SELFDESTRUCT/deposit paths to charge/consume state gas. - Update refund/block-gas accounting and add tests covering intrinsic split, code-deposit split, and state reservoir mechanics.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Nethermind/Nethermind.Specs/ReleaseSpec.cs | Adds EIP-8037 enablement flag to specs. |
| src/Nethermind/Nethermind.Specs/Forks/25_Amsterdam.cs | Enables EIP-8037 for Amsterdam fork. |
| src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs | Adds chainspec transition timestamp field for EIP-8037. |
| src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs | Loads Eip8037TransitionTimestamp from JSON into chain parameters. |
| src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs | Enables EIP-8037 per-release based on transition timestamp. |
| src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs | Stores Eip8037TransitionTimestamp in chain parameters. |
| src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs | Allows overriding IsEip8037Enabled in tests. |
| src/Nethermind/Nethermind.Evm/VirtualMachine.cs | Splits code-deposit into regular/state components and attempts dual-dimension charging. |
| src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs | Adjusts intrinsic validation, top-level code deploy charging, and refund/block-gas accounting for EIP-8037. |
| src/Nethermind/Nethermind.Evm/TransactionProcessing/GasConsumed.cs | Formatting update to record struct declaration. |
| src/Nethermind/Nethermind.Evm/RefundOf.cs | Adds EIP-8037-specific refund constants. |
| src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs | Routes opcode implementations through EIP-8037-aware generic variants. |
| src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Storage.cs | Adds EIP-8037 handling to SSTORE net-metering/refunds. |
| src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Eof.cs | Adds EIP-8037 handling to EOF call/create gas frame setup and new-account charging. |
| src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Create.cs | Splits CREATE cost into regular/state components under EIP-8037. |
| src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.ControlFlow.cs | Adds EIP-8037 handling to SELFDESTRUCT new-account charging. |
| src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs | Adds EIP-8037 handling to CALL new-account charging and child frame gas creation. |
| src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs | Introduces state reservoir/state usage helpers and state+regular combined consumption helper. |
| src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs | Implements state reservoir, state gas usage accounting, intrinsic split, and child-frame state transfer. |
| src/Nethermind/Nethermind.Evm/GasCostOf.cs | Adds EIP-8037 gas constants (devnet-3 values). |
| src/Nethermind/Nethermind.Evm/CodeDepositHandler.cs | Splits code-deposit costs into regular/state components and adds overloads. |
| src/Nethermind/Nethermind.Evm.Test/IntrinsicGasCalculatorTests.cs | Adds intrinsic split test for authorization list under EIP-8037. |
| src/Nethermind/Nethermind.Evm.Test/Eip7928Tests.cs | Disables EIP-8037 for BAL tests to stabilize gas expectations. |
| src/Nethermind/Nethermind.Evm.Test/Eip2200Tests.cs | Adds tests for EIP-8037 constants, code-deposit split, and state reservoir behavior. |
| src/Nethermind/Nethermind.Core/Specs/ReleaseSpecDecorator.cs | Exposes IsEip8037Enabled through decorator. |
| src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs | Adds IsEip8037Enabled to the spec interface. |
Comments suppressed due to low confidence (1)
src/Nethermind/Nethermind.Evm/VirtualMachine.cs:546
- Same issue as the EOF-create path: on code-deposit failure this drains only regular gas via
Consume(..., gasAvailableForCodeDeposit), which can leave a non-zero state reservoir when EIP-8037 is enabled. For an exceptional out-of-gas on code deposit, gas should be exhausted across both dimensions.
Consider using SetOutOfGas(ref _currentState.Gas) (or equivalent) when FailOnOutOfGasCodeDeposit is in effect so state reservoir is also cleared.
if (!chargedCodeDeposit && (spec.FailOnOutOfGasCodeDeposit || invalidCode) && (invalidCode || outOfGasOnCodeDeposit))
{
// Consume all remaining gas allocated for the code deposit.
TGasPolicy.Consume(ref _currentState.Gas, gasAvailableForCodeDeposit);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
EVM Opcode Benchmark DiffAggregated runs: base=3, pr=3 Regressions (1)
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
LukaszRozmej
left a comment
There was a problem hiding this comment.
On one side GasPolicy makes it painful to implement.
On the other there is a lot of AI sloppiness in this PR visible. Please make it tight!
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 38 out of 38 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The hasEnoughGas check is only a pre-check gate; the actual gas charge goes through TryConsumeStateAndRegularGas on a copy. When the pre-check is too permissive, the real charge fails and the CREATE fails anyway. Both code paths produce identical behavior.
The hasEnoughGas pre-check used child-only gas but TryConsumeStateAndRegularGas charged the merged parent+child pool. When state deposit cost spills into regular gas, the spill was taken from the parent's retained gas instead of the child's. Tighten the pre-check to account for state spill so the charge is never attempted when the child alone can't afford it. Add VM-level regression test that fails without this fix.
|
Raised EEST test gaps ethereum/execution-specs#2426 |
|
PR to add eest tests ethereum/execution-specs#2427 |
LukaszRozmej
left a comment
There was a problem hiding this comment.
I kind of hate this EIP complexity.
Made some refactors to make tests better in: #10737 , please merge if you like it first
|
I'd like to suggest an architectural refinement that could simplify the implementation and improve long-term maintainability. The PR introduces several new fields to
Suggested approach: Vector-based gas with enum Indexing public enum GasDimension : byte
{
Regular = 0, // Execution gas
State = 1, // EIP-8037 state creation gas
// Future EIPs can add dimensions here
}
[InlineArray(2)]
public struct GasVector
{
private long _element0;
}
public struct MultiDimensionalGas
{
private GasVector _gas;
public void Charge(GasDimension dim, long cost)
=> _gas[(int)dim] -= cost;
public long Get(GasDimension dim)
=> _gas[(int)dim];
...
}Refactoring public struct EthereumGasPolicy : IGasPolicy<EthereumGasPolicy>
{
private MultiDimensionalGas _gas;
// Wrapper methods handle dimension assignment internally
public static bool ConsumeNewAccountCreation(ref EthereumGasPolicy gas, IReleaseSpec spec)
{
if (gas._gas.Get(GasDimension.Regular) < GasCostOf.NewAccount)
return false;
gas._gas.Charge(GasDimension.Regular, GasCostOf.NewAccount);
if (spec.IsEip8037Enabled)
ChargeFromReservoir(ref gas, GasCostOf.Eip8037NewAccount);
return true;
}
}These key principles can be defined:
Benefits
Upd |
Changes
Types of changes
What types of changes does your code introduce?
Testing
Requires testing
If yes, did you write tests?
Notes on testing
Bal-devnet 3