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

TxPool: refactoring for blob txs #5953

Merged
merged 170 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
d366741
add extensions
marcindsobczak Jul 10, 2023
53fcffa
adjust filters
marcindsobczak Jul 10, 2023
2bc9be5
add tests
marcindsobczak Jul 10, 2023
79588f0
Merge branch 'feature/txpool_filters' into feature/txpool_4844txs
marcindsobczak Jul 11, 2023
1a25885
draft
marcindsobczak Jul 13, 2023
414fb8f
fix metrics
marcindsobczak Jul 13, 2023
c508930
fix tx type, add test for replacing
marcindsobczak Jul 14, 2023
45115fa
adjust blob replacement comparer
marcindsobczak Jul 14, 2023
c0db165
add blob tx db and metrics
marcindsobczak Jul 14, 2023
15087f4
fix test
marcindsobczak Jul 14, 2023
c6ea9fe
resurrect old TxStorage class and adjust a bit for blobs
marcindsobczak Jul 14, 2023
d1c66c1
pass blob storage to tx pool, adjust tests
marcindsobczak Jul 14, 2023
a6a65c5
handle db writes/reads and add test
marcindsobczak Jul 14, 2023
5cf90f5
recreate light collection after restart
marcindsobczak Jul 14, 2023
2e91dcb
adjust broadcaster test
marcindsobczak Jul 14, 2023
b38a40d
cosmetic
marcindsobczak Jul 14, 2023
7f3df36
add broadcaster test
marcindsobczak Jul 14, 2023
a3d86d7
add todos
marcindsobczak Jul 14, 2023
109cca4
add MaxFeePerDataGas check when updating gas bottleneck
marcindsobczak Jul 17, 2023
0b8f72d
regression test for MaxFeePerDataGas check
marcindsobczak Jul 17, 2023
5a20486
cosmetic
marcindsobczak Jul 17, 2023
5a6b7fe
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Jul 18, 2023
a6e1e16
unify & simplify tests
marcindsobczak Jul 18, 2023
6596c1d
cosmetics in BlobTxStorage
marcindsobczak Jul 18, 2023
07870f1
add AcceptTxResult dedicated for rejected replacements
marcindsobczak Jul 18, 2023
73872e1
adjust tests, add test for blob tx replacements
marcindsobczak Jul 18, 2023
b11a27d
simplify TxPool
marcindsobczak Jul 18, 2023
5da9488
refactor to reuse id of deprecated result
marcindsobczak Jul 18, 2023
3071be3
simplify filters
marcindsobczak Jul 18, 2023
9cc03cc
add configurable sizes of blob pool and blob cache
marcindsobczak Jul 18, 2023
761a6c5
optimize TxType filter
marcindsobczak Jul 18, 2023
028f650
add light tx as separate class to reuse
marcindsobczak Jul 18, 2023
1b47921
dont return blob txs from broadcaster and other refactorings
marcindsobczak Jul 18, 2023
8145f44
add test for broadcaster
marcindsobczak Jul 18, 2023
1d3ec8d
add test for announcing txs with MaxFeePerDataGas >= current
marcindsobczak Jul 18, 2023
6201cae
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Jul 18, 2023
56d9dd4
add more tx pool metrics
marcindsobczak Jul 19, 2023
091bde6
update tx pool report
marcindsobczak Jul 19, 2023
d7daff3
add metric to filter
marcindsobczak Jul 19, 2023
fb54eb9
improve tests
marcindsobczak Jul 19, 2023
d8cf261
refactors
marcindsobczak Jul 19, 2023
647873f
clean
marcindsobczak Jul 20, 2023
5fdff5a
add test
marcindsobczak Jul 20, 2023
12e9b9a
fix TxPool
marcindsobczak Jul 20, 2023
53f4415
fix test
marcindsobczak Jul 20, 2023
e646940
fix EthereumTests
marcindsobczak Jul 21, 2023
dbd8890
fix report
marcindsobczak Jul 21, 2023
82a5110
fix whitespaces
marcindsobczak Jul 21, 2023
44b145e
fix blob txs picking when building block
marcindsobczak Jul 25, 2023
5a6cf30
fix test
marcindsobczak Jul 25, 2023
771858c
fix benchmarks solution
marcindsobczak Jul 25, 2023
a822d6f
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Jul 25, 2023
f4df112
add filtering for MaxPriorityFeePerGas < 1GWei for blob transactions
marcindsobczak Jul 26, 2023
965a003
adjust tests to min requirement of 1 gwei
marcindsobczak Jul 26, 2023
6f045a6
add test
marcindsobczak Jul 26, 2023
c3fbde1
add more txpool config options
marcindsobczak Jul 27, 2023
4aa0e0e
adjust storage
marcindsobczak Jul 27, 2023
a91b8d8
add non-persistent blob tx collection
marcindsobczak Jul 27, 2023
0ea2bc5
one more
marcindsobczak Jul 27, 2023
17e997a
adjust tests, add new one
marcindsobczak Jul 27, 2023
c41717f
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Jul 27, 2023
7c71180
post merge fixes
marcindsobczak Jul 27, 2023
ccc93e0
cosmetics
marcindsobczak Jul 27, 2023
3d3fe14
fix bug in broadcasting - use size of full blob tx in light tx
marcindsobczak Jul 27, 2023
78de5be
cosmetics
marcindsobczak Jul 28, 2023
4923d2e
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Aug 1, 2023
e515f32
lower default PersistentBlobStorageSize
marcindsobczak Aug 3, 2023
58fc2fd
Divide TxPoolTests
MarekM25 Aug 11, 2023
edd4fca
cosmetic - usings
MarekM25 Aug 11, 2023
f8801b9
more tests moved to TxPoolTests.Blobs
MarekM25 Aug 11, 2023
c98b83c
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Aug 14, 2023
001fa5c
refactor ParityRpcModuleTests to reuse setup code
marcindsobczak Aug 15, 2023
0fbc778
cosmetic
marcindsobczak Aug 15, 2023
185b22d
refactor picking txs for rebroadcasting/reannouncing
marcindsobczak Aug 15, 2023
06c3b53
Add MaxBlobsPerBlock to Eip4844Constants and use in several places in…
marcindsobczak Aug 15, 2023
5fbf208
whitespace
marcindsobczak Aug 15, 2023
93d00b1
cosmetic in BlobTxStorage + add tests
marcindsobczak Aug 16, 2023
b8030ce
make tx comparisons more readable
marcindsobczak Aug 16, 2023
b1b2c15
cosmetics in TxTypeTxFilter
marcindsobczak Aug 17, 2023
fc8e258
filter blob txs in FeeTooLowFilter just as other types
marcindsobczak Aug 17, 2023
a0bd04b
adjust test
marcindsobczak Aug 17, 2023
ff01c02
fix whitespaces and file encodings
marcindsobczak Aug 17, 2023
40456ec
simplification in TxPool
marcindsobczak Aug 17, 2023
58e8b96
another whitespace fix
marcindsobczak Aug 17, 2023
a026341
override base methods in blob collections instead of creating new one…
marcindsobczak Aug 17, 2023
bb6a6b4
cosmetics
marcindsobczak Aug 17, 2023
768ba88
add BlobTxStorage parameterless constructor that uses MemDb and simpl…
marcindsobczak Aug 17, 2023
2901068
remove unused things
marcindsobczak Aug 17, 2023
69cbeba
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Aug 18, 2023
4eee1cf
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Aug 21, 2023
a35b8af
post-merge fix
marcindsobczak Aug 21, 2023
29c30b9
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Aug 21, 2023
6b4a438
move capacity insurances to inner classes
marcindsobczak Aug 22, 2023
2ff8309
add test for pool capacity
marcindsobczak Aug 22, 2023
890ee24
clean
marcindsobczak Aug 22, 2023
9b36393
try with synchronization
marcindsobczak Aug 24, 2023
288b0e3
refactor block building
marcindsobczak Aug 25, 2023
e43ad49
fix whitespace
marcindsobczak Aug 25, 2023
0154927
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Aug 25, 2023
b3a5ffe
simplify decoding in BlobTxStorage
marcindsobczak Aug 25, 2023
22d8de7
cosmetics
marcindsobczak Aug 25, 2023
2488460
simplify tests
marcindsobczak Aug 26, 2023
5b78cf4
fix tx priority?
marcindsobczak Aug 26, 2023
ee4dfb1
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Aug 26, 2023
d0bc319
improve readability in NonceGapFilter
marcindsobczak Aug 26, 2023
6ffeb44
improve readability of TxPoolTxSource
marcindsobczak Aug 26, 2023
127e1b5
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Sep 4, 2023
59fb8a3
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Sep 11, 2023
416ab31
save sender to db
marcindsobczak Sep 11, 2023
c236326
fix recreating light collection
marcindsobczak Sep 11, 2023
056fb15
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Sep 12, 2023
1b5c1cc
adjust EthStats to show sum of blob and non-blob txs
marcindsobczak Sep 13, 2023
051c89b
fix
marcindsobczak Sep 13, 2023
d16bf52
make blob support configurable
marcindsobczak Sep 13, 2023
6f211b6
optimize snapshots
marcindsobczak Sep 13, 2023
96352c8
fix blob support disabled
marcindsobczak Sep 13, 2023
8f6b3f4
don't request blob txs if blob support disabled
marcindsobczak Sep 13, 2023
b100533
fix tests
marcindsobczak Sep 13, 2023
7de7fe6
fix files encoding
marcindsobczak Sep 13, 2023
bbe23e3
fix test
marcindsobczak Sep 13, 2023
cc33167
cosmetics
marcindsobczak Sep 13, 2023
8173c81
add MaxPendingTxsPerSenderFilter
marcindsobczak Sep 14, 2023
6195466
add test
marcindsobczak Sep 14, 2023
ee1891b
disable blob pool by default
marcindsobczak Sep 19, 2023
d2131bd
cosmetic refactoring
MarekM25 Sep 19, 2023
ae671d4
revert previous change
MarekM25 Sep 19, 2023
ccc1799
fix tests after making blob pool disabled by default
marcindsobczak Sep 19, 2023
d535ae1
Merge remote-tracking branch 'origin/feature/txpool_4844txs' into fea…
marcindsobczak Sep 19, 2023
0bb5cf0
useBlobDb -> useBlobsDb
marcindsobczak Sep 19, 2023
3040dfa
TxConfig descrptions fixes
MarekM25 Sep 19, 2023
5413f84
Merge branch 'feature/txpool_4844txs' of https://github.com/nethermin…
MarekM25 Sep 19, 2023
84e8e79
add timestamp to db, drop linq
marcindsobczak Sep 18, 2023
f2b284d
Merge remote-tracking branch 'origin/feature/txpool_4844txs' into fea…
marcindsobczak Sep 20, 2023
75163e7
add missing metric
marcindsobczak Sep 20, 2023
8f9980e
adjust txpool report
marcindsobczak Sep 20, 2023
ce6be6c
cosmetic
marcindsobczak Sep 20, 2023
0ade121
fix broadcaster to check in pending before requesting
marcindsobczak Sep 22, 2023
a4d3600
fix
marcindsobczak Sep 22, 2023
918c7b6
add metric of received hashes
marcindsobczak Sep 22, 2023
3b63ce5
improve txpool report
marcindsobczak Sep 22, 2023
f43c8a0
fix naming
marcindsobczak Sep 25, 2023
e6d1e46
make naming more relevant
marcindsobczak Sep 25, 2023
1a928e6
stopwatch
marcindsobczak Sep 25, 2023
d2e5904
add missing metric
marcindsobczak Sep 26, 2023
c50c44b
move to ColumnsDb
marcindsobczak Sep 26, 2023
16d99b3
optimize full blobs db by prefixing key with timestamp
marcindsobczak Sep 28, 2023
188de15
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Sep 29, 2023
a19c4ce
fix files encoding
marcindsobczak Sep 29, 2023
a804f51
fix and improve blob storage
marcindsobczak Oct 3, 2023
f9e7030
fix tests
marcindsobczak Oct 3, 2023
7cd6d1b
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Oct 3, 2023
ca5a37e
adjust tests to require sender of full blob txs loaded from db
marcindsobczak Oct 4, 2023
8e2ce35
refactor future nonce filter
marcindsobczak Oct 4, 2023
1542e2e
simplify and improve block building
marcindsobczak Oct 4, 2023
574725d
refactor TxPoolTxSource
marcindsobczak Oct 4, 2023
91d420c
fix block building - move loading full tx from db after all filters
marcindsobczak Oct 5, 2023
eeb9b9b
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Oct 5, 2023
76b6e25
refactor low fee filtering
marcindsobczak Oct 10, 2023
3b150cd
add new metric
marcindsobczak Oct 10, 2023
29f73f1
adjust TxPool filters pipeline and TxPoolReport
marcindsobczak Oct 10, 2023
2df4ae2
change naming as requested in review
marcindsobczak Oct 10, 2023
d90e4a2
add size estimates to descriptions in ITxPoolConfig
marcindsobczak Oct 10, 2023
544dc68
rename AcceptTxResult PendingTxsOfOtherType -> PendingTxsOfConflictin…
marcindsobczak Oct 10, 2023
9700c48
add more comments to TxPool
marcindsobczak Oct 10, 2023
222cd92
add more comments to PersistentBlobTxDistinctSortedPool
marcindsobczak Oct 10, 2023
70babe9
Merge remote-tracking branch 'origin/master' into feature/txpool_4844txs
marcindsobczak Oct 10, 2023
4e26565
fix file encoding
marcindsobczak Oct 10, 2023
fb97b14
small refactors
LukaszRozmej Oct 11, 2023
112fb91
cosmetic 1.GWei()
MarekM25 Oct 11, 2023
001be21
reduce spec lookup
LukaszRozmej Oct 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
.TestObject;
ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree);
IStateReader stateReader = new StateReader(trieStore, codeDb, _logManager);
IChainHeadInfoProvider chainHeadInfoProvider = new ChainHeadInfoProvider(specProvider, blockTree, stateReader);
ITxPool transactionPool = new TxPool(ecdsa, chainHeadInfoProvider, new TxPoolConfig(), new TxValidator(specProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer());

IReceiptStorage receiptStorage = NullReceiptStorage.Instance;
IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager);
Expand Down
2 changes: 2 additions & 0 deletions src/Nethermind/Nethermind.Api/IApiWithStores.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
using Nethermind.Crypto;
using Nethermind.Db.Blooms;
using Nethermind.State.Repositories;
using Nethermind.TxPool;
using Nethermind.Wallet;

namespace Nethermind.Api
{
public interface IApiWithStores : IBasicApi
{
ITxStorage? BlobTxStorage { get; set; }
IBlockTree? BlockTree { get; set; }
IBloomStorage? BloomStorage { get; set; }
IChainLevelInfoRepository? ChainLevelInfoRepository { get; set; }
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Api/NethermindApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public IBlockchainBridge CreateBlockchainBridge()
}

public IAbiEncoder AbiEncoder { get; } = Nethermind.Abi.AbiEncoder.Instance;
public ITxStorage? BlobTxStorage { get; set; }
public IBlockchainProcessor? BlockchainProcessor { get; set; }
public CompositeBlockPreprocessorStep BlockPreprocessor { get; } = new();
public IBlockProcessingQueue? BlockProcessingQueue { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ protected override async Task<IDbProvider> CreateDbProvider()
{
IDbProvider dbProvider = new DbProvider(DbModeHint.Persisted);
RocksDbFactory rocksDbFactory = new(new DbConfig(), LogManager, TempDirectory.Path);
StandardDbInitializer standardDbInitializer = new(dbProvider, rocksDbFactory, new MemDbFactory(), new FileSystem(), true);
StandardDbInitializer standardDbInitializer = new(dbProvider, rocksDbFactory, new MemDbFactory(), new FileSystem());
LukaszRozmej marked this conversation as resolved.
Show resolved Hide resolved
await standardDbInitializer.InitStandardDbsAsync(true);
return dbProvider;
}
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public void Setup()

TxPool.TxPool txPool = new(
ecdsa,
new BlobTxStorage(),
new ChainHeadInfoProvider(specProvider, _blockTree, stateProvider),
new TxPoolConfig(),
new TxValidator(specProvider.ChainId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using NSubstitute;
using NUnit.Framework;
using Nethermind.Config;
using Nethermind.Core.Crypto;

namespace Nethermind.Blockchain.Test
{
Expand Down Expand Up @@ -229,13 +230,30 @@ void SetAccountStates(IEnumerable<Address> missingAddresses)
new(specProvider, blockTree);
IComparer<Transaction> defaultComparer = transactionComparerProvider.GetDefaultComparer();
IComparer<Transaction> comparer = CompareTxByNonce.Instance.ThenBy(defaultComparer);
Dictionary<Address, Transaction[]> transactions = testCase.Transactions
.Where(t => t.SenderAddress is not null)
.GroupBy(t => t.SenderAddress)
.ToDictionary(
g => g.Key!,
g => g.OrderBy(t => t, comparer).ToArray());

Dictionary<Address, Transaction[]> GroupTransactions(bool supportBlobs) =>
testCase.Transactions
.Where(t => t.SenderAddress is not null)
.Where(t => t.SupportsBlobs == supportBlobs)
.GroupBy(t => t.SenderAddress)
.ToDictionary(
g => g.Key!,
g => g.OrderBy(t => t, comparer).ToArray());

Dictionary<Address, Transaction[]> transactions = GroupTransactions(false);
Dictionary<Address, Transaction[]> blobTransactions = GroupTransactions(true);
transactionPool.GetPendingTransactionsBySender().Returns(transactions);
transactionPool.GetPendingLightBlobTransactionsBySender().Returns(blobTransactions);
foreach (Transaction blobTx in blobTransactions.SelectMany(kvp => kvp.Value))
{
transactionPool.TryGetPendingBlobTransaction(Arg.Is<Keccak>(h => h == blobTx.Hash),
out Arg.Any<Transaction?>()).Returns(x =>
{
x[1] = blobTx;
return true;
});
}

BlocksConfig blocksConfig = new() { MinGasPrice = testCase.MinGasPriceForMining };
ITxFilterPipeline txFilterPipeline = new TxFilterPipelineBuilder(LimboLogs.Instance)
.WithMinGasPriceFilter(blocksConfig, specProvider)
Expand All @@ -252,6 +270,7 @@ void SetAccountStates(IEnumerable<Address> missingAddresses)
{
parentHeader = parentHeader.WithExcessBlobGas(0);
}

IEnumerable<Transaction> selectedTransactions =
poolTxSource.GetTransactions(parentHeader.TestObject,
testCase.GasLimit);
Expand Down
7 changes: 7 additions & 0 deletions src/Nethermind/Nethermind.Blockchain/ChainHeadInfoProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Nethermind.Blockchain.Spec;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Evm;
using Nethermind.Int256;
using Nethermind.State;
using Nethermind.TxPool;
Expand Down Expand Up @@ -42,12 +43,18 @@ public ChainHeadInfoProvider(IChainHeadSpecProvider specProvider, IBlockTree blo

public UInt256 CurrentBaseFee { get; private set; }

public UInt256 CurrentPricePerBlobGas { get; internal set; }

public event EventHandler<BlockReplacementEventArgs>? HeadChanged;

private void OnHeadChanged(object? sender, BlockReplacementEventArgs e)
{
BlockGasLimit = e.Block!.GasLimit;
CurrentBaseFee = e.Block.Header.BaseFeePerGas;
CurrentPricePerBlobGas =
BlobGasCalculator.TryCalculateBlobGasPricePerUnit(e.Block.Header, out UInt256 currentPricePerBlobGas)
? currentPricePerBlobGas
: UInt256.Zero;
HeadChanged?.Invoke(sender, e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,13 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f
ITransactionComparerProvider transactionComparerProvider =
new TransactionComparerProvider(specProvider, blockTree);

TxPool.TxPool txPool = new(_ethereumEcdsa, new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(GoerliSpecProvider.Instance), blockTree, stateProvider), new TxPoolConfig(), new TxValidator(goerliSpecProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer());
TxPool.TxPool txPool = new(_ethereumEcdsa,
new BlobTxStorage(),
new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(GoerliSpecProvider.Instance), blockTree, stateProvider),
new TxPoolConfig(),
new TxValidator(goerliSpecProvider.ChainId),
_logManager,
transactionComparerProvider.GetDefaultComparer());
_pools[privateKey] = txPool;

BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ protected override TxPool.TxPool CreateTxPool()

return new TxPool.TxPool(
_api.EthereumEcdsa,
_api.BlobTxStorage ?? NullBlobTxStorage.Instance,
new ChainHeadInfoProvider(_api.SpecProvider, _api.BlockTree, _api.StateReader),
NethermindApi.Config<ITxPoolConfig>(),
_api.TxValidator,
Expand Down
163 changes: 121 additions & 42 deletions src/Nethermind/Nethermind.Consensus/Producers/TxPoolTxSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using Nethermind.Consensus.Comparers;
Expand Down Expand Up @@ -46,26 +47,26 @@ public class TxPoolTxSource : ITxSource
public IEnumerable<Transaction> GetTransactions(BlockHeader parent, long gasLimit)
{
long blockNumber = parent.Number + 1;
IEip1559Spec specFor1559 = _specProvider.GetSpecFor1559(blockNumber);
UInt256 baseFee = BaseFeeCalculator.Calculate(parent, specFor1559);
IReleaseSpec spec = _specProvider.GetSpec(parent);
UInt256 baseFee = BaseFeeCalculator.Calculate(parent, spec);
IDictionary<Address, Transaction[]> pendingTransactions = _transactionPool.GetPendingTransactionsBySender();
IDictionary<Address, Transaction[]> pendingBlobTransactionsEquivalences = _transactionPool.GetPendingLightBlobTransactionsBySender();
IComparer<Transaction> comparer = GetComparer(parent, new BlockPreparationContext(baseFee, blockNumber))
.ThenBy(ByHashTxComparer.Instance); // in order to sort properly and not lose transactions we need to differentiate on their identity which provided comparer might not be doing

IEnumerable<Transaction> transactions = GetOrderedTransactions(pendingTransactions, comparer);
IEnumerable<Transaction> blobTransactions = GetOrderedTransactions(pendingBlobTransactionsEquivalences, comparer);
if (_logger.IsDebug) _logger.Debug($"Collecting pending transactions at block gas limit {gasLimit}.");

int checkedTransactions = 0;
int selectedTransactions = 0;
int i = 0;
using ArrayPoolList<Transaction> selectedBlobTxs = new(Eip4844Constants.MaxBlobsPerBlock);
marcindsobczak marked this conversation as resolved.
Show resolved Hide resolved

// TODO: removing transactions from TX pool here seems to be a bad practice since they will
// not come back if the block is ignored?
int blobsCounter = 0;
UInt256 blobGasPrice = UInt256.Zero;
SelectBlobTransactions(blobTransactions, parent, spec, selectedBlobTxs);

foreach (Transaction tx in transactions)
{
i++;
checkedTransactions++;

if (tx.SenderAddress is null)
{
Expand All @@ -77,52 +78,130 @@ public IEnumerable<Transaction> GetTransactions(BlockHeader parent, long gasLimi
bool success = _txFilterPipeline.Execute(tx, parent);
if (!success) continue;

if (tx.SupportsBlobs)
foreach (Transaction blobTx in PickBlobTxsBetterThanCurrentTx(selectedBlobTxs, tx, comparer))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we can do it in more efficient/simpler way - let's discuss it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's already simplified a lot comparing to initial version 😄 But I'm open for discussion. What is important here, we need to have all transactions (mix of blob and non-blob) in correct order, so we can't add blobs at the beginning or at the end.
In current implementation we are picking max possible number of blob transactions which can be included in the block (from Eip4844Constants - 6 blobs for now) and then we are iterating non-blob txs and adding blob txs in between according to priority fee, from highest to lowest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's needed cos is already fast enough. But if we could sort SelectBlobTransactions firstly and pass it as iterator to PickBlobTxsBetterThanCurrentTx it might save some cycles, because it's seems more efficient to merge already sorted datas.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is already sorted. PickBlobTxsBetterThanCurrentTx in first step is comparing best blob tx with current std tx, if best blob tx is worse, than breaking the while loop, not iterating and comparing more

{
if (blobGasPrice.IsZero)
{
ulong? excessBlobGas = BlobGasCalculator.CalculateExcessBlobGas(parent, _specProvider.GetSpec(parent));
if (excessBlobGas is null)
{
if (_logger.IsTrace) _logger.Trace($"Declining {tx.ToShortString()}, the specification is not configured to handle shard blob transactions.");
continue;
}
if (!BlobGasCalculator.TryCalculateBlobGasPricePerUnit(excessBlobGas.Value, out blobGasPrice))
{
if (_logger.IsTrace) _logger.Trace($"Declining {tx.ToShortString()}, failed to calculate blob gas price.");
continue;
}
}
yield return blobTx;
}

int txAmountOfBlobs = tx.BlobVersionedHashes?.Length ?? 0;
if (_logger.IsTrace) _logger.Trace($"Selected {tx.ToShortString()} to be potentially included in block.");

if (blobGasPrice > tx.MaxFeePerBlobGas)
{
if (_logger.IsTrace) _logger.Trace($"Declining {tx.ToShortString()}, blob gas fee is too low.");
continue;
}
selectedTransactions++;
yield return tx;
}

if (BlobGasCalculator.CalculateBlobGas(blobsCounter + txAmountOfBlobs) >
Eip4844Constants.MaxBlobGasPerBlock)
{
if (_logger.IsTrace) _logger.Trace($"Declining {tx.ToShortString()}, no more blob space.");
continue;
}
if (selectedBlobTxs.Count > 0)
{
foreach (Transaction blobTx in selectedBlobTxs)
{
yield return blobTx;
LukaszRozmej marked this conversation as resolved.
Show resolved Hide resolved
}
}

if (_logger.IsDebug) _logger.Debug($"Potentially selected {selectedTransactions} out of {checkedTransactions} pending transactions checked.");
}

blobsCounter += txAmountOfBlobs;
if (_logger.IsTrace) _logger.Trace($"Selected shard blob tx {tx.ToShortString()} to be potentially included in block, total blobs included: {blobsCounter}.");
private IEnumerable<Transaction> PickBlobTxsBetterThanCurrentTx(ArrayPoolList<Transaction> selectedBlobTxs, Transaction tx, IComparer<Transaction> comparer)
{
while (selectedBlobTxs.Count > 0)
{
Transaction blobTx = selectedBlobTxs[0];
if (comparer.Compare(blobTx, tx) > 0)
{
yield return blobTx;
selectedBlobTxs.Remove(blobTx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have to shift all the blob transactions each time, would be better to keep blob transactions in reverse order and remove last

}
else
{
if (_logger.IsTrace)
_logger.Trace($"Selected {tx.ToShortString()} to be potentially included in block.");
break;
}
}
}

selectedTransactions++;
yield return tx;
private void SelectBlobTransactions(IEnumerable<Transaction> blobTransactions, BlockHeader parent, IReleaseSpec spec, ArrayPoolList<Transaction> selectedBlobTxs)
{
int checkedBlobTransactions = 0;
int selectedBlobTransactions = 0;
int blobsCounter = 0;
UInt256 blobGasPrice = UInt256.Zero;

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

checkedBlobTransactions++;

int txAmountOfBlobs = blobTx.BlobVersionedHashes?.Length ?? 0;
if (blobsCounter + txAmountOfBlobs > Eip4844Constants.MaxBlobsPerBlock)
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, not enough blob space.");
continue;
}

if (blobGasPrice.IsZero && !TryUpdateBlobGasPrice(blobTx, parent, spec, out blobGasPrice))
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, failed to get full version of this blob tx from TxPool.");
continue;
}

if (blobGasPrice > blobTx.MaxFeePerBlobGas)
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, data gas fee is too low.");
continue;
}

bool success = _txFilterPipeline.Execute(blobTx, parent);
if (!success) continue;

if (!TryGetFullBlobTx(blobTx, out Transaction fullBlobTx))
{
if (_logger.IsTrace) _logger.Trace($"Declining {blobTx.ToShortString()}, failed to get full version of this blob tx from TxPool.");
continue;
}

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

selectedBlobTransactions++;
selectedBlobTxs.Add(fullBlobTx);
}

if (_logger.IsDebug) _logger.Debug($"Potentially selected {selectedBlobTransactions} out of {checkedBlobTransactions} pending blob transactions checked.");
}

private bool TryGetFullBlobTx(Transaction blobTx, [NotNullWhen(true)] out Transaction? fullBlobTx)
{
if (blobTx.NetworkWrapper is not null)
{
fullBlobTx = blobTx;
return true;
}

fullBlobTx = null;
return blobTx.Hash is not null && _transactionPool.TryGetPendingBlobTransaction(blobTx.Hash, out fullBlobTx);
}

private bool TryUpdateBlobGasPrice(Transaction lightBlobTx, BlockHeader parent, IReleaseSpec spec, out UInt256 blobGasPrice)
{
ulong? excessDataGas = BlobGasCalculator.CalculateExcessBlobGas(parent, spec);
if (excessDataGas is null)
{
if (_logger.IsTrace) _logger.Trace($"Declining {lightBlobTx.ToShortString()}, the specification is not configured to handle shard blob transactions.");
blobGasPrice = UInt256.Zero;
return false;
}

if (!BlobGasCalculator.TryCalculateBlobGasPricePerUnit(excessDataGas.Value, out blobGasPrice))
{
if (_logger.IsTrace) _logger.Trace($"Declining {lightBlobTx.ToShortString()}, failed to calculate data gas price.");
blobGasPrice = UInt256.Zero;
return false;
}

if (_logger.IsDebug) _logger.Debug($"Potentially selected {selectedTransactions} out of {i} pending transactions checked.");
return true;
}

protected virtual IEnumerable<Transaction> GetOrderedTransactions(IDictionary<Address, Transaction[]> pendingTransactions, IComparer<Transaction> comparer) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,9 @@ protected virtual IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTx
protected virtual TxPool.TxPool CreateTxPool() =>
new(
EthereumEcdsa,
new BlobTxStorage(),
new ChainHeadInfoProvider(new FixedForkActivationChainHeadSpecProvider(SpecProvider), BlockTree, ReadOnlyState),
new TxPoolConfig(),
new TxPoolConfig() { BlobSupportEnabled = true },
new TxValidator(SpecProvider.ChainId),
LogManager,
TransactionComparerProvider.GetDefaultComparer());
Expand Down
5 changes: 3 additions & 2 deletions src/Nethermind/Nethermind.Core/Eip4844Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ namespace Nethermind.Core;
public class Eip4844Constants
{
public const int MinBlobsPerTransaction = 1;
public const int MaxBlobsPerBlock = 6;

public const ulong BlobGasPerBlob = 1 << 17;
public const ulong TargetBlobGasPerBlock = BlobGasPerBlob * 3;
public const ulong MaxBlobGasPerBlock = BlobGasPerBlob * 6;
public const ulong MaxBlobGasPerBlock = BlobGasPerBlob * MaxBlobsPerBlock;
public const ulong TargetBlobGasPerBlock = MaxBlobGasPerBlock / 2;
public const ulong MaxBlobGasPerTransaction = MaxBlobGasPerBlock;

public static readonly UInt256 BlobGasUpdateFraction = 3338477;
Expand Down
3 changes: 2 additions & 1 deletion src/Nethermind/Nethermind.Core/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ private void ClearPreHashInternal()
/// <remarks>Used for sorting in edge cases.</remarks>
public ulong PoolIndex { get; set; }

private int? _size = null;
protected int? _size = null;

/// <summary>
/// Encoded transaction length
/// </summary>
Expand Down