Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use blob gas instead of count #6229

Merged
merged 3 commits into from
Oct 31, 2023
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
20 changes: 20 additions & 0 deletions src/Nethermind/Nethermind.Blockchain.Test/TestEip4844Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core;

namespace Nethermind.Consensus.Producers.Test;

public class TestEip4844Config : IEip4844Config
{
public TestEip4844Config(ulong? maxBlobGasPerBlock = null)
{
MaxBlobGasPerBlock = maxBlobGasPerBlock ?? Eip4844Constants.MaxBlobGasPerBlock;
}

public ulong MaxBlobGasPerBlock { get; }

public ulong GasPerBlob => Eip4844Constants.GasPerBlob;

public int GetMaxBlobsPerBlock() => (int)(MaxBlobGasPerBlock / GasPerBlob);
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ public static IEnumerable Eip1559TestCases
}
}


public static IEnumerable EnoughShardBlobTransactionsSelectedTestCases
{
get
Expand Down
65 changes: 65 additions & 0 deletions src/Nethermind/Nethermind.Blockchain.Test/TxPoolSourceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Consensus.Transactions;
using Nethermind.Logging;
using Nethermind.Specs.Forks;
using Nethermind.TxPool;
using NUnit.Framework;
using Nethermind.Consensus.Comparers;
using Nethermind.Core.Test.Builders;
using Nethermind.Specs;
using Nethermind.Core;
using System.Linq;
using System.Collections.Generic;
using NSubstitute;

namespace Nethermind.Consensus.Producers.Test;

public class TxPoolSourceTests
{
[TestCaseSource(nameof(BlobTransactionsWithBlobGasLimitPerBlock))]
public void GetTransactions_should_respect_customizable_blob_gas_limit(int[] blobCountPerTx, ulong customMaxBlobGasPerBlock)
{
TestSingleReleaseSpecProvider specProvider = new(Cancun.Instance);
TransactionComparerProvider transactionComparerProvider = new(specProvider, Build.A.BlockTree().TestObject);

ITxPool txPool = Substitute.For<ITxPool>();
Dictionary<Address, Transaction[]> transactionsWithBlobs = blobCountPerTx
.Select((blobsCount, index) => (blobCount: blobsCount, index))
.ToDictionary(
pair => new Address((new byte[19]).Concat(new byte[] { (byte)pair.index }).ToArray()),
pair => new Transaction[] { Build.A.Transaction.WithShardBlobTxTypeAndFields(pair.blobCount).TestObject });
txPool.GetPendingTransactions().Returns(new Transaction[0]);
txPool.GetPendingLightBlobTransactionsBySender().Returns(transactionsWithBlobs);

ITxFilterPipeline txFilterPipeline = Substitute.For<ITxFilterPipeline>();
txFilterPipeline.Execute(Arg.Any<Transaction>(), Arg.Any<BlockHeader>()).Returns(true);

TestEip4844Config eip4844Config = new(customMaxBlobGasPerBlock);

TxPoolTxSource transactionSelector = new(txPool, specProvider, transactionComparerProvider, LimboLogs.Instance, txFilterPipeline, eip4844Config);

IEnumerable<Transaction> txs = transactionSelector.GetTransactions(new BlockHeader { }, long.MaxValue);
int blobsCount = txs.Sum(tx => tx.BlobVersionedHashes?.Length ?? 0);

Assert.Multiple(() =>
{
Assert.That((ulong)blobsCount * eip4844Config.GasPerBlob, Is.LessThanOrEqualTo(eip4844Config.MaxBlobGasPerBlock));
Assert.That(blobsCount, Is.LessThanOrEqualTo(eip4844Config.GetMaxBlobsPerBlock()));
});
}

public static IEnumerable<TestCaseData> BlobTransactionsWithBlobGasLimitPerBlock()
{
yield return new TestCaseData(new int[] { 1, 2, 4 }, Eip4844Constants.GasPerBlob * 6);
yield return new TestCaseData(new int[] { 1, 2, 6 }, Eip4844Constants.GasPerBlob * 6);
yield return new TestCaseData(new int[] { 1, 6 }, Eip4844Constants.GasPerBlob * 6);
yield return new TestCaseData(new int[] { 6, 1, 5 }, Eip4844Constants.GasPerBlob * 6);
yield return new TestCaseData(new int[] { 1, 2 }, Eip4844Constants.GasPerBlob * 2);
yield return new TestCaseData(new int[] { 1, 1 }, Eip4844Constants.GasPerBlob * 2);
yield return new TestCaseData(new int[] { 2, 1 }, Eip4844Constants.GasPerBlob * 2);
yield return new TestCaseData(new int[] { 2, 2 }, Eip4844Constants.GasPerBlob * 2);
yield return new TestCaseData(new int[] { 3 }, Eip4844Constants.GasPerBlob * 2);
}
}
22 changes: 12 additions & 10 deletions src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Nethermind.Consensus.Transactions;
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Evm;
using Nethermind.Int256;
Expand All @@ -29,19 +28,22 @@ public class TxPoolTxSource : ITxSource
private readonly ITxFilterPipeline _txFilterPipeline;
private readonly ISpecProvider _specProvider;
protected readonly ILogger _logger;
private readonly IEip4844Config _eip4844Config;

public TxPoolTxSource(
ITxPool? transactionPool,
ISpecProvider? specProvider,
ITransactionComparerProvider? transactionComparerProvider,
ILogManager? logManager,
ITxFilterPipeline? txFilterPipeline)
ITxFilterPipeline? txFilterPipeline,
IEip4844Config? eip4844ConstantsProvider = null)
{
_transactionPool = transactionPool ?? throw new ArgumentNullException(nameof(transactionPool));
_transactionComparerProvider = transactionComparerProvider ?? throw new ArgumentNullException(nameof(transactionComparerProvider));
_txFilterPipeline = txFilterPipeline ?? throw new ArgumentNullException(nameof(txFilterPipeline));
_specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
_logger = logManager?.GetClassLogger<TxPoolTxSource>() ?? throw new ArgumentNullException(nameof(logManager));
_eip4844Config = eip4844ConstantsProvider ?? ConstantEip4844Config.Instance;
}

public IEnumerable<Transaction> GetTransactions(BlockHeader parent, long gasLimit, PayloadAttributes? payloadAttributes = null)
Expand All @@ -60,7 +62,7 @@ public IEnumerable<Transaction> GetTransactions(BlockHeader parent, long gasLimi

int checkedTransactions = 0;
int selectedTransactions = 0;
using ArrayPoolList<Transaction> selectedBlobTxs = new(Eip4844Constants.MaxBlobsPerBlock);
using ArrayPoolList<Transaction> selectedBlobTxs = new(_eip4844Config.GetMaxBlobsPerBlock());

SelectBlobTransactions(blobTransactions, parent, spec, selectedBlobTxs);

Expand Down Expand Up @@ -121,21 +123,21 @@ private void SelectBlobTransactions(IEnumerable<Transaction> blobTransactions, B
{
int checkedBlobTransactions = 0;
int selectedBlobTransactions = 0;
int blobsCounter = 0;
UInt256 blobGasCounter = 0;
UInt256 blobGasPrice = UInt256.Zero;

foreach (Transaction blobTx in blobTransactions)
{
if (blobsCounter == Eip4844Constants.MaxBlobsPerBlock)
if (blobGasCounter >= _eip4844Config.MaxBlobGasPerBlock)
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, no more blob space. Block already have {blobsCounter} which is max value allowed.");
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, no more blob space. Block already have {blobGasCounter} blob gas which is max value allowed.");
break;
}

checkedBlobTransactions++;

int txAmountOfBlobs = blobTx.BlobVersionedHashes?.Length ?? 0;
if (blobsCounter + txAmountOfBlobs > Eip4844Constants.MaxBlobsPerBlock)
ulong txBlobGas = (ulong)(blobTx.BlobVersionedHashes?.Length ?? 0) * _eip4844Config.GasPerBlob;
if (txBlobGas > _eip4844Config.MaxBlobGasPerBlock - blobGasCounter)
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, not enough blob space.");
continue;
Expand All @@ -162,8 +164,8 @@ private void SelectBlobTransactions(IEnumerable<Transaction> blobTransactions, B
continue;
}

blobsCounter += txAmountOfBlobs;
if (_logger.IsTrace) _logger.Trace($"Selected shard blob tx {fullBlobTx.ToShortString()} to be potentially included in block, total blobs included: {blobsCounter}.");
blobGasCounter += txBlobGas;
if (_logger.IsTrace) _logger.Trace($"Selected shard blob tx {fullBlobTx.ToShortString()} to be potentially included in block, total blob gas included: {blobGasCounter}.");

selectedBlobTransactions++;
selectedBlobTxs.Add(fullBlobTx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,5 @@ public SinglePendingTxSelector(ITxSource innerSource)
.Take(1);

public override string ToString() => $"{nameof(SinglePendingTxSelector)} [ {_innerSource} ]";

}
}
38 changes: 22 additions & 16 deletions src/Nethermind/Nethermind.Core/Eip4844Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,45 @@ namespace Nethermind.Core;
/// </summary>
public class Eip4844Constants
{
/// <summary>
/// Gets the <c>GAS_PER_BLOB</c> parameter.
/// </summary>
/// <remarks>Defaults to 2e17.</remarks>
public const ulong GasPerBlob = 1 << 17;

public const int MaxBlobsPerBlock = 6;
public const int MinBlobsPerTransaction = 1;

/// <summary>
/// Gets the <c>BLOB_GASPRICE_UPDATE_FRACTION</c> parameter.
/// Gets the <c>GAS_PER_BLOB</c> parameter.
/// </summary>
/// <remarks>Defaults to 3338477.</remarks>
public static UInt256 BlobGasPriceUpdateFraction { get; private set; } = 3338477;
/// <remarks>Defaults to 131072.</remarks>
public const ulong GasPerBlob = 131072;

/// <summary>
/// Gets the <c>MAX_BLOB_GAS_PER_BLOCK</c> parameter.
/// </summary>
/// <remarks>Defaults to 786432.</remarks>
public static ulong MaxBlobGasPerBlock { get; private set; } = GasPerBlob * MaxBlobsPerBlock;

public static ulong MaxBlobGasPerTransaction => MaxBlobGasPerBlock;
public static ulong MaxBlobGasPerBlock { get; private set; } = 786432;

/// <summary>
/// Gets the <c>MIN_BLOB_GASPRICE</c> parameter, in wei.
/// Gets the <c>MAX_BLOB_GAS_PER_BLOCK</c> parameter.
/// </summary>
/// <remarks>Defaults to 1.</remarks>
public static UInt256 MinBlobGasPrice { get; private set; } = 1;
/// <remarks>The same as <see cref="MaxBlobGasPerBlock"/>.</remarks>
public static ulong MaxBlobGasPerTransaction => MaxBlobGasPerBlock;

/// <summary>
/// Gets the <c>TARGET_BLOB_GAS_PER_BLOCK</c> parameter.
/// </summary>
/// <remarks>Defaults to 393216.</remarks>
public static ulong TargetBlobGasPerBlock { get; private set; } = MaxBlobGasPerBlock / 2;

/// <summary>
/// Gets the <c>BLOB_GASPRICE_UPDATE_FRACTION</c> parameter.
/// </summary>
/// <remarks>Defaults to 3338477.</remarks>
public static UInt256 BlobGasPriceUpdateFraction { get; private set; } = 3338477;

/// <summary>
/// Gets the <c>MIN_BLOB_GASPRICE</c> parameter, in wei.
/// </summary>
/// <remarks>Defaults to 1.</remarks>
public static UInt256 MinBlobGasPrice { get; private set; } = 1;


// The parameter mutators are kept separate deliberately to ensure no accidental value changes.
public static void OverrideIfAny(
UInt256? blobGasPriceUpdateFraction = null,
Expand All @@ -64,4 +68,6 @@ public class Eip4844Constants
if (targetBlobGasPerBlock.HasValue)
TargetBlobGasPerBlock = targetBlobGasPerBlock.Value;
}

public static int GetMaxBlobsPerBlock() => (int)(MaxBlobGasPerBlock / GasPerBlob);
}
26 changes: 26 additions & 0 deletions src/Nethermind/Nethermind.Core/IEip4844Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

namespace Nethermind.Core;

/// <summary>
/// <see cref="Eip4844Constants" /> wrapper, made for testing convenience.
/// </summary>
public interface IEip4844Config
{
ulong MaxBlobGasPerBlock { get; }
ulong GasPerBlob { get; }
int GetMaxBlobsPerBlock();
}

public class ConstantEip4844Config : IEip4844Config
{
public ulong MaxBlobGasPerBlock => Eip4844Constants.MaxBlobGasPerBlock;
public ulong GasPerBlob => Eip4844Constants.GasPerBlob;
public int GetMaxBlobsPerBlock() => Eip4844Constants.GetMaxBlobsPerBlock();

static ConstantEip4844Config() => Instance = new ConstantEip4844Config();
private ConstantEip4844Config() { }

public static IEip4844Config Instance { get; private set; }
}
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.TxPool/LightTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Nethermind.TxPool;
public class LightTransaction : Transaction
{
private static readonly Dictionary<int, byte[][]> _blobVersionedHashesCache =
Enumerable.Range(1, Eip4844Constants.MaxBlobsPerBlock).ToDictionary(i => i, i => new byte[i][]);
Enumerable.Range(1, Eip4844Constants.GetMaxBlobsPerBlock()).ToDictionary(i => i, i => new byte[i][]);


public LightTransaction(Transaction fullTx)
Expand Down
Loading