Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
13 changes: 13 additions & 0 deletions src/Nethermind/Nethermind.Core/Eip7825Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core.Specs;

namespace Nethermind.Core;

public static class Eip7825Constants
{
public static readonly long DefaultTxGasLimitCap = 30_000_000;
public static long GetTxGasLimitCap(IReleaseSpec _)
=> DefaultTxGasLimitCap;
}
5 changes: 5 additions & 0 deletions src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec
/// </summary>
bool IsEip7623Enabled { get; }

/// <summary>
/// Transaction gas limit cap
/// </summary>
bool IsEip7825Enabled { get; }

/// <summary>
/// Should transactions be validated against chainId.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public class ReleaseSpecDecorator(IReleaseSpec spec) : IReleaseSpec
public virtual bool IsOpHoloceneEnabled => spec.IsOpHoloceneEnabled;
public virtual bool IsOpIsthmusEnabled => spec.IsOpIsthmusEnabled;
public virtual bool IsEip7623Enabled => spec.IsEip7623Enabled;
public virtual bool IsEip7825Enabled => spec.IsEip7825Enabled;
public virtual ulong WithdrawalTimestamp => spec.WithdrawalTimestamp;
public virtual ulong Eip4844TransitionTimestamp => spec.Eip4844TransitionTimestamp;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ protected virtual TransactionResult Execute(Transaction tx, in BlockExecutionCon
bool deleteCallerAccount = RecoverSenderIfNeeded(tx, spec, opts, effectiveGasPrice);

if (!(result = ValidateSender(tx, header, spec, tracer, opts))) return result;
if (!(result = ValidateGasLimit(tx, header, spec, tracer, opts))) return result;
if (!(result = BuyGas(tx, blCtx, spec, tracer, opts, effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment, out UInt256 blobBaseFee))) return result;
if (!(result = IncrementNonce(tx, header, spec, tracer, opts))) return result;

Expand Down Expand Up @@ -452,6 +453,19 @@ protected virtual TransactionResult ValidateSender(Transaction tx, BlockHeader h
return TransactionResult.Ok;
}

protected virtual TransactionResult ValidateGasLimit(Transaction tx, BlockHeader header, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts)
{
bool validate = !opts.HasFlag(ExecutionOptions.SkipValidation);

if (validate && spec.IsEip7825Enabled && tx.GasLimit > Eip7825Constants.GetTxGasLimitCap(spec))
{
TraceLogInvalidTx(tx, "TX_GAS_LIMIT_OVER_CAP");
return TransactionResult.TransactionGasLimitOverCap;
}

return TransactionResult.Ok;
}

protected virtual TransactionResult BuyGas(Transaction tx, in BlockExecutionContext blkContext, IReleaseSpec spec, ITxTracer tracer, ExecutionOptions opts,
in UInt256 effectiveGasPrice, out UInt256 premiumPerGas, out UInt256 senderReservedGasPayment, out UInt256 blobBaseFee)
{
Expand Down Expand Up @@ -912,5 +926,6 @@ public readonly struct TransactionResult(string? error) : IEquatable<Transaction
public static readonly TransactionResult SenderNotSpecified = "sender not specified";
public static readonly TransactionResult TransactionSizeOverMaxInitCodeSize = "EIP-3860 - transaction size over max init code size";
public static readonly TransactionResult WrongTransactionNonce = "wrong transaction nonce";
public static readonly TransactionResult TransactionGasLimitOverCap = "EIP-7825 - transaction gas limit over cap";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ public ulong Eip4844TransitionTimestamp
public Address Eip2935ContractAddress => _spec.Eip2935ContractAddress;
public bool IsEip7702Enabled => _spec.IsEip7702Enabled;
public bool IsEip7823Enabled => _spec.IsEip7823Enabled;
public bool IsEip7825Enabled => _spec.IsEip7825Enabled;
public UInt256 ForkBaseFee => _spec.ForkBaseFee;
public UInt256 BaseFeeMaxChangeDenominator => _spec.BaseFeeMaxChangeDenominator;
public long ElasticityMultiplier => _spec.ElasticityMultiplier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ public class ChainParameters

public ulong? Eip7623TransitionTimestamp { get; set; }

public ulong? Eip7825TransitionTimestamp { get; set; }

public Dictionary<string, ChainSpecBlobCountJson> BlobSchedule { get; set; } = [];

#region EIP-4844 parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ protected virtual ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releas
releaseSpec.Eip7251ContractAddress = chainSpec.Parameters.Eip7251ContractAddress;
releaseSpec.IsEip7623Enabled = (chainSpec.Parameters.Eip7623TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp;

releaseSpec.IsEip7825Enabled = (chainSpec.Parameters.Eip7825TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp;

bool eip1559FeeCollector = releaseSpec.IsEip1559Enabled && (chainSpec.Parameters.Eip1559FeeCollectorTransition ?? long.MaxValue) <= releaseStartBlock;
bool eip4844FeeCollector = releaseSpec.IsEip4844Enabled && (chainSpec.Parameters.Eip4844FeeCollectorTransitionTimestamp ?? long.MaxValue) <= releaseStartTimestamp;
releaseSpec.FeeCollector = (eip1559FeeCollector || eip4844FeeCollector) ? chainSpec.Parameters.FeeCollector : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ internal class ChainSpecParamsJson
public ulong? Eip7692TransitionTimestamp { get; set; }
public ulong? Eip7702TransitionTimestamp { get; set; }
public ulong? Eip7823TransitionTimestamp { get; set; }
public ulong? Eip7825TransitionTimestamp { get; set; }
public ulong? OpGraniteTransitionTimestamp { get; set; }
public ulong? OpHoloceneTransitionTimestamp { get; set; }
public ulong? OpIsthmusTransitionTimestamp { get; set; }
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Specs/ReleaseSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public bool IsEip1559Enabled
public bool IsEip4844FeeCollectorEnabled { get; set; }
public bool IsEip7002Enabled { get; set; }
public bool IsEip7251Enabled { get; set; }
public bool IsEip7825Enabled { get; set; }
public ulong TargetBlobCount { get; set; }
public ulong MaxBlobCount { get; set; }
public UInt256 BlobBaseFeeUpdateFraction { get; set; }
Expand Down
42 changes: 27 additions & 15 deletions src/Nethermind/Nethermind.TxPool/Filters/GasLimitTxFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,30 @@

using System;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Logging;

namespace Nethermind.TxPool.Filters
{
/// <summary>
/// Ignores transactions that outright exceed block gas limit or configured max block gas limit.
/// </summary>
internal sealed class GasLimitTxFilter : IIncomingTxFilter
internal sealed class GasLimitTxFilter(
IChainHeadSpecProvider specProvider,
IChainHeadInfoProvider chainHeadInfoProvider,
ITxPoolConfig txPoolConfig,
ILogger logger) : IIncomingTxFilter
{
private readonly IChainHeadInfoProvider _chainHeadInfoProvider;
private readonly ILogger _logger;
private readonly long _configuredGasLimit;

public GasLimitTxFilter(IChainHeadInfoProvider chainHeadInfoProvider, ITxPoolConfig txPoolConfig,
ILogger logger)
{
_chainHeadInfoProvider = chainHeadInfoProvider;
_logger = logger;
_configuredGasLimit = txPoolConfig.GasLimit ?? long.MaxValue;
}
private readonly IChainHeadSpecProvider _specProvider = specProvider;
private readonly IChainHeadInfoProvider _chainHeadInfoProvider = chainHeadInfoProvider;
private readonly ILogger _logger = logger;
private readonly long _configuredGasLimit = txPoolConfig.GasLimit ?? long.MaxValue;

public AcceptTxResult Accept(Transaction tx, ref TxFilteringState state, TxHandlingOptions handlingOptions)
{
long gasLimit = Math.Min(_chainHeadInfoProvider.BlockGasLimit ?? long.MaxValue, _configuredGasLimit);
if (tx.GasLimit > gasLimit)
long txGasLimitCap = GetTxGasLimitCap();

if (tx.GasLimit > txGasLimitCap)
{
Metrics.PendingTransactionsGasLimitTooHigh++;

Expand All @@ -39,10 +38,23 @@ public AcceptTxResult Accept(Transaction tx, ref TxFilteringState state, TxHandl
bool isNotLocal = (handlingOptions & TxHandlingOptions.PersistentBroadcast) == 0;
return isNotLocal ?
AcceptTxResult.GasLimitExceeded :
AcceptTxResult.GasLimitExceeded.WithMessage($"Gas limit: {gasLimit}, gas limit of rejected tx: {tx.GasLimit}");
AcceptTxResult.GasLimitExceeded.WithMessage($"Tx gas limit cap: {txGasLimitCap}, gas limit of rejected tx: {tx.GasLimit}");
}

return AcceptTxResult.Accepted;
}

private long GetTxGasLimitCap()
{
IReleaseSpec spec = _specProvider.GetCurrentHeadSpec();

long gasLimit = Math.Min(_chainHeadInfoProvider.BlockGasLimit ?? long.MaxValue, _configuredGasLimit);
if (spec.IsEip7825Enabled)
{
gasLimit = Math.Min(gasLimit, Eip7825Constants.GetTxGasLimitCap(spec));
}

return gasLimit;
}
}
}
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.TxPool/TxPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public TxPool(IEthereumEcdsa ecdsa,
[
new NotSupportedTxFilter(txPoolConfig, _logger),
new SizeTxFilter(txPoolConfig, _logger),
new GasLimitTxFilter(_headInfo, txPoolConfig, _logger),
new GasLimitTxFilter(_specProvider, _headInfo, txPoolConfig, _logger),
new PriorityFeeTooLowFilter(_logger),
new FeeTooLowFilter(_headInfo, _transactions, _blobTransactions, thereIsPriorityContract, _logger),
new MalformedTxFilter(_specProvider, validator, _logger)
Expand Down