Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/Nethermind/Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public static bool ConsumeStateGas(ref EthereumGasPolicy gas, long stateGasCost)
return true;
}

public static bool TryConsumeStateAndRegularGas(ref EthereumGasPolicy gas, long stateGasCost, long regularGasCost) =>
(regularGasCost <= 0 || UpdateGas(ref gas, regularGasCost)) &&
(stateGasCost <= 0 || ConsumeStateGas(ref gas, stateGasCost));

public static bool ConsumeSelfDestructGas(ref EthereumGasPolicy gas)
=> UpdateGas(ref gas, GasCostOf.SelfDestructEip150);

Expand Down Expand Up @@ -196,6 +200,21 @@ public static bool UpdateGas(ref EthereumGasPolicy gas,
return true;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ConsumeStorageWrite<TEip8037, TIsSlotCreation>(ref EthereumGasPolicy gas, IReleaseSpec spec)
where TEip8037 : struct, IFlag
where TIsSlotCreation : struct, IFlag
{
if (!TIsSlotCreation.IsActive) return UpdateGas(ref gas, spec.GasCosts.SStoreResetCost);
return TEip8037.IsActive switch
{
// EIP-8037: charge the regular component first so an OOG halt does not
// spill state gas into gas_left and then restore it to the parent frame.
true => TryConsumeStateAndRegularGas(ref gas, GasCostOf.SSetState, GasCostOf.SSetRegular),
false => UpdateGas(ref gas, GasCostOf.SSet),
};
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void UpdateGasUp(ref EthereumGasPolicy gas,
long refund)
Expand Down Expand Up @@ -230,8 +249,14 @@ public static bool ConsumeCallValueTransfer(ref EthereumGasPolicy gas)
=> UpdateGas(ref gas, GasCostOf.CallValue);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ConsumeNewAccountCreation(ref EthereumGasPolicy gas)
=> ConsumeStateGas(ref gas, GasCostOf.NewAccountState);
public static bool ConsumeNewAccountCreation<TEip8037>(ref EthereumGasPolicy gas) where TEip8037 : struct, IFlag
{
return TEip8037.IsActive switch
{
true => ConsumeStateGas(ref gas, GasCostOf.NewAccountState),
false => UpdateGas(ref gas, GasCostOf.NewAccount)
};
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ConsumeLogEmission(ref EthereumGasPolicy gas, long topicCount, long dataSize)
Expand Down
18 changes: 14 additions & 4 deletions src/Nethermind/Nethermind.Evm/GasPolicy/IGasPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,7 @@ static virtual bool ConsumeStateGas(ref TSelf gas, long stateGasCost) =>
/// <param name="stateGasCost">State gas component.</param>
/// <param name="regularGasCost">Regular gas component.</param>
/// <returns><c>true</c> if both deductions succeeded; otherwise, <c>false</c>.</returns>
static virtual bool TryConsumeStateAndRegularGas(ref TSelf gas, long stateGasCost, long regularGasCost) =>
(regularGasCost <= 0 || TSelf.UpdateGas(ref gas, regularGasCost)) &&
(stateGasCost <= 0 || TSelf.ConsumeStateGas(ref gas, stateGasCost));
static abstract bool TryConsumeStateAndRegularGas(ref TSelf gas, long stateGasCost, long regularGasCost);

/// <summary>
/// Refunds gas by adding the specified amount back to the available gas.
Expand All @@ -226,6 +224,18 @@ static virtual bool TryConsumeStateAndRegularGas(ref TSelf gas, long stateGasCos
/// <param name="refund">The gas amount to refund.</param>
static abstract void UpdateGasUp(ref TSelf gas, long refund);

/// <summary>
/// Charges gas for SSTORE write operation (after cold/warm access cost).
/// Cost is calculated internally based on whether it's a slot creation or update.
/// </summary>
/// <param name="gas">The gas state to update.</param>
/// <param name="isSlotCreation">True if creating a new slot (original was zero).</param>
/// <param name="spec">The release specification for determining reset cost.</param>
/// <returns>True if sufficient gas available</returns>
static abstract bool ConsumeStorageWrite<TEip8037, TIsSlotCreation>(ref TSelf gas, IReleaseSpec spec)
where TEip8037 : struct, IFlag
where TIsSlotCreation : struct, IFlag;

/// <summary>
/// Refunds state gas back to the state reservoir.
/// Pre-EIP-8037 fallback refunds into regular gas.
Expand Down Expand Up @@ -262,7 +272,7 @@ static virtual long ApplyCodeInsertRefunds(ref TSelf gas, int codeInsertRefunds,
/// </summary>
/// <param name="gas">The gas state to update.</param>
/// <returns>True if sufficient gas available</returns>
static abstract bool ConsumeNewAccountCreation(ref TSelf gas);
static abstract bool ConsumeNewAccountCreation<TEip8037>(ref TSelf gas) where TEip8037 : struct, IFlag;

/// <summary>
/// Charges gas for LOG emission with topic and data costs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,7 @@ public static EvmExceptionType InstructionCall<TGasPolicy, TOpCall, TTracingInst
true => transferValue != 0 && state.IsDeadAccount(target),
};

bool newAccountOutOfGas = chargesNewAccount && !(TEip8037.IsActive switch
{
true => TGasPolicy.ConsumeNewAccountCreation(ref gas),
false => TGasPolicy.UpdateGas(ref gas, GasCostOf.NewAccount),
});
bool newAccountOutOfGas = chargesNewAccount && !TGasPolicy.ConsumeNewAccountCreation<TEip8037>(ref gas);

if (newAccountOutOfGas) goto OutOfGas;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,7 @@ private static EvmExceptionType InstructionSelfDestruct<TGasPolicy, TEip8037, TE
false => !inheritorAccountExists && spec.UseShanghaiDDosProtection,
};

bool outOfGas = chargesNewAccount && !(TEip8037.IsActive switch
{
true => TGasPolicy.ConsumeNewAccountCreation(ref gas),
false => TGasPolicy.UpdateGas(ref gas, GasCostOf.NewAccount),
});
bool outOfGas = chargesNewAccount && !(TGasPolicy.ConsumeNewAccountCreation<TEip8037>(ref gas));

if (outOfGas) goto OutOfGas;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,19 +505,12 @@ internal static EvmExceptionType InstructionSStoreMetered<TGasPolicy, TTracingIn
{
if (currentIsZero)
{
bool ssetOutOfGas = TEip8037.IsActive switch
{
// EIP-8037: charge the regular component first so an OOG halt does not
// spill state gas into gas_left and then restore it to the parent frame.
true => !TGasPolicy.TryConsumeStateAndRegularGas(ref gas, GasCostOf.SSetState, GasCostOf.SSetRegular),
false => !TGasPolicy.UpdateGas(ref gas, GasCostOf.SSet),
};

bool ssetOutOfGas = !TGasPolicy.ConsumeStorageWrite<TEip8037, OnFlag>(ref gas, spec);
if (ssetOutOfGas) goto OutOfGas;
}
else
{
if (!TGasPolicy.UpdateGas(ref gas, spec.GasCosts.SStoreResetCost))
if (!TGasPolicy.ConsumeStorageWrite<TEip8037, OffFlag>(ref gas, spec))
goto OutOfGas;

if (newIsZero)
Expand Down
Loading