Skip to content
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
36a0f7e
PoC of delayed sending if requested
flcl42 Sep 8, 2025
d8294a2
Add retry cache
flcl42 Sep 9, 2025
bcc06a3
Merge remote-tracking branch 'origin/master' into dont-cache-requeste…
flcl42 Sep 10, 2025
1d29ad5
Fix logs and multiple requests expiration
flcl42 Sep 29, 2025
2adbcbe
Merge remote-tracking branch 'origin/master' into dont-cache-requeste…
flcl42 Sep 29, 2025
fb8e9e3
Add tests
flcl42 Oct 1, 2025
a474531
Rename
flcl42 Oct 1, 2025
b831531
Add more tests
flcl42 Oct 3, 2025
5cfaf85
Improve
flcl42 Oct 6, 2025
0825d2d
Simplify dependencies
flcl42 Oct 6, 2025
9414c22
Improve
flcl42 Oct 6, 2025
62b1ca8
Rename
flcl42 Oct 6, 2025
a49c3b7
Merge remote-tracking branch 'origin/master' into dont-cache-requeste…
flcl42 Oct 6, 2025
d883a0a
no requestoor draft
flcl42 Oct 10, 2025
d5e60b2
Use messages
flcl42 Oct 15, 2025
34ec276
Merge remote-tracking branch 'origin/master' into dont-cache-requeste…
flcl42 Oct 15, 2025
aab4e49
Remove the requestoor
flcl42 Oct 15, 2025
805f8df
Fix tests
flcl42 Oct 15, 2025
f2db9a6
Fix tests
flcl42 Oct 15, 2025
f615bd5
More fixes
flcl42 Oct 15, 2025
ca79d70
Merge remote-tracking branch 'origin/master' into dont-cache-requeste…
flcl42 Oct 16, 2025
78e4de6
Substitute
flcl42 Oct 16, 2025
d41d386
Disconnect peers with invalid txs
flcl42 Oct 16, 2025
a197f6c
Update src/Nethermind/Nethermind.Network.Contract/Messages/IResourceR…
flcl42 Oct 16, 2025
1c8f173
Merge branch 'dont-cache-requested-txhashes' of github.com:Nethermind…
flcl42 Oct 16, 2025
eb2213e
Merge remote-tracking branch 'origin/master' into dont-cache-requeste…
flcl42 Oct 16, 2025
dc8f823
Compress code
flcl42 Oct 20, 2025
3605567
Try pooled set
flcl42 Oct 21, 2025
f06ff7d
Handle as eth66
flcl42 Oct 21, 2025
0d8fdd3
Fix review
flcl42 Oct 21, 2025
83eee29
Fix tests
flcl42 Oct 21, 2025
ff5da9a
No need in syncing handling
flcl42 Oct 22, 2025
152a0a4
Validate sizes and types
flcl42 Oct 22, 2025
53d16f0
Add a test
flcl42 Oct 22, 2025
f0011fa
Merge remote-tracking branch 'origin/master' into validate-sizes-and-…
flcl42 Oct 23, 2025
8242e69
Fix test
flcl42 Oct 23, 2025
011af56
Add tests
flcl42 Oct 23, 2025
4698baf
Merge branch 'master' into validate-sizes-and-types
flcl42 Oct 23, 2025
35b1382
Fix test
flcl42 Oct 23, 2025
f70d145
Code style
flcl42 Oct 23, 2025
7e4535b
Rollback
flcl42 Oct 23, 2025
45349cf
Fix tests
flcl42 Oct 23, 2025
44ef48b
Move to proper class
flcl42 Oct 24, 2025
7910ec6
Rollback that rollback
flcl42 Oct 24, 2025
b582c66
Merge branch 'master' into validate-sizes-and-types
flcl42 Oct 24, 2025
73ef0c9
Merge branch 'validate-sizes-and-types' of github.com:NethermindEth/n…
flcl42 Oct 24, 2025
3ffb44c
Mark not invalid txs as received
flcl42 Oct 24, 2025
b8c9b52
Move
flcl42 Oct 24, 2025
f6b8876
Fix dispose
flcl42 Oct 24, 2025
9229a78
Fix
flcl42 Oct 24, 2025
e34e86f
Moar
flcl42 Oct 24, 2025
bd5b964
Clean up cache
flcl42 Oct 24, 2025
2a6af80
Using
flcl42 Oct 24, 2025
6fb8387
Merge branch 'master' into validate-sizes-and-types
flcl42 Oct 24, 2025
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
15 changes: 14 additions & 1 deletion src/Nethermind/Nethermind.Core.Test/Caching/ClockCacheTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
Expand Down Expand Up @@ -242,6 +242,19 @@ public void Can_delete()
cache.Delete(_addresses[0]).Should().BeFalse();
}

[Test]
public void Delete_returns_value()
{
Cache cache = Create();
cache.Set(_addresses[0], _accounts[0]);

cache.Delete(_addresses[0], out Account? value).Should().BeTrue();
value.Should().Be(_accounts[0]);

cache.Delete(_addresses[0], out Account? noValue).Should().BeFalse();
noValue.Should().BeNull();
}

[Test]
public void Clear_should_free_all_capacity()
{
Expand Down
16 changes: 12 additions & 4 deletions src/Nethermind/Nethermind.Core/Caching/ClockCache.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
Expand Down Expand Up @@ -136,9 +136,15 @@ void ThrowInvalidOperationException()
}
}

public bool Delete(TKey key)
public bool Delete(TKey key) => Delete(key, out _);

public bool Delete(TKey key, [NotNullWhen(true)] out TValue? value)
{
if (MaxCapacity == 0) return false;
if (MaxCapacity == 0)
{
value = default;
return false;
}

using var lockRelease = _lock.Acquire();

Expand All @@ -148,9 +154,11 @@ public bool Delete(TKey key)
KeyToOffset[ov.Offset] = default;
ClearAccessed(ov.Offset);
FreeOffsets.Enqueue(ov.Offset);
return true;
value = ov.Value;
return ov.Value != null;
}

value = default;
return false;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Net;
using DotNetty.Buffers;
using FluentAssertions;
using Nethermind.Consensus;
Expand All @@ -19,6 +17,7 @@
using Nethermind.Network.P2P.Messages;
using Nethermind.Network.P2P.Subprotocols;
using Nethermind.Network.P2P.Subprotocols.Eth.V62.Messages;
using Nethermind.Network.P2P.Subprotocols.Eth.V66;
using Nethermind.Network.P2P.Subprotocols.Eth.V66.Messages;
using Nethermind.Network.P2P.Subprotocols.Eth.V68;
using Nethermind.Network.P2P.Subprotocols.Eth.V68.Messages;
Expand All @@ -31,6 +30,8 @@
using Nethermind.TxPool;
using NSubstitute;
using NUnit.Framework;
using System;
using System.Net;

namespace Nethermind.Network.Test.P2P.Subprotocols.Eth.V68;

Expand Down Expand Up @@ -146,6 +147,38 @@ public void Should_throw_when_sizes_doesnt_match(bool removeSize)
action.Should().Throw<SubprotocolException>();
}


[Test]
public void Should_disconnect_if_tx_size_is_wrong()
{
GenerateTxLists(4, out ArrayPoolList<byte> types, out ArrayPoolList<int> sizes, out ArrayPoolList<Hash256> hashes, out ArrayPoolList<Transaction> txs);
sizes[0] += 10;
using NewPooledTransactionHashesMessage68 hashesMsg = new(types, sizes, hashes);
using PooledTransactionsMessage txsMsg = new(1111, new(txs));

HandleIncomingStatusMessage();
HandleZeroMessage(hashesMsg, Eth68MessageCode.NewPooledTransactionHashes);
HandleZeroMessage(txsMsg, Eth66MessageCode.PooledTransactions);

_session.Received().InitiateDisconnect(DisconnectReason.BackgroundTaskFailure, "invalid pooled tx type or size");
}


[Test]
public void Should_disconnect_if_tx_type_is_wrong()
{
GenerateTxLists(4, out ArrayPoolList<byte> types, out ArrayPoolList<int> sizes, out ArrayPoolList<Hash256> hashes, out ArrayPoolList<Transaction> txs);
types[0]++;
using NewPooledTransactionHashesMessage68 hashesMsg = new(types, sizes, hashes);
using PooledTransactionsMessage txsMsg = new(1111, new(txs));

HandleIncomingStatusMessage();
HandleZeroMessage(hashesMsg, Eth68MessageCode.NewPooledTransactionHashes);
HandleZeroMessage(txsMsg, Eth66MessageCode.PooledTransactions);

_session.Received().InitiateDisconnect(DisconnectReason.BackgroundTaskFailure, "invalid pooled tx type or size");
}

[Test]
public void Should_process_huge_transaction()
{
Expand Down Expand Up @@ -273,20 +306,28 @@ private void HandleZeroMessage<T>(T msg, byte messageCode) where T : MessageBase
}

private void GenerateLists(int txCount, out ArrayPoolList<byte> types, out ArrayPoolList<int> sizes, out ArrayPoolList<Hash256> hashes)
{
GenerateTxLists(txCount, out types, out sizes, out hashes, out ArrayPoolList<Transaction> txs);
txs.Dispose();
}

private void GenerateTxLists(int txCount, out ArrayPoolList<byte> types, out ArrayPoolList<int> sizes, out ArrayPoolList<Hash256> hashes, out ArrayPoolList<Transaction> txs)
{
TxDecoder txDecoder = TxDecoder.Instance;
types = new(txCount);
sizes = new(txCount);
hashes = new(txCount);
txs = new(txCount);

for (int i = 0; i < txCount; ++i)
{
Transaction tx = Build.A.Transaction.WithType((TxType)(i % 3)).WithData(new byte[i])
Transaction tx = Build.A.Transaction.WithType((TxType)(i % 3)).SignedAndResolved().WithData(new byte[i])
.WithHash(i % 2 == 0 ? TestItem.KeccakA : TestItem.KeccakB).TestObject;

types.Add((byte)tx.Type);
sizes.Add(txDecoder.GetLength(tx, RlpBehaviors.None));
hashes.Add(tx.Hash);
txs.Add(tx);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
using Nethermind.Serialization.Rlp;
using Nethermind.Stats;
using Nethermind.Stats.Model;
using Nethermind.Synchronization;

namespace Nethermind.Network.P2P.ProtocolHandlers
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ public Eth62ProtocolHandler(ISession session,
EnsureGossipPolicy();
}

public void DisableTxFiltering()
{
_floodController.IsEnabled = false;
}
public void DisableTxFiltering() => _floodController.IsEnabled = false;

public override byte ProtocolVersion => EthVersions.Eth62;
public override string ProtocolCode => Protocol.Eth;
Expand All @@ -75,6 +72,8 @@ public override event EventHandler<ProtocolEventArgs>? SubprotocolRequested
remove { }
}

protected ClockCache<ValueHash256, (int, TxType)> TxShapeAnnouncements { get; } = new(MemoryAllowance.TxHashCacheSize / 10);
Comment thread
flcl42 marked this conversation as resolved.
Outdated

protected virtual void EnrichStatusMessage(StatusMessage statusMessage) { }

public override void Init()
Expand Down Expand Up @@ -242,14 +241,15 @@ protected void Handle(TransactionsMessage msg)
BackgroundTaskScheduler.ScheduleBackgroundTask((iList, 0), _handleSlow);
}

private ValueTask HandleSlow((IOwnedReadOnlyList<Transaction> txs, int startIndex) request, CancellationToken cancellationToken)
protected virtual ValueTask HandleSlow((IOwnedReadOnlyList<Transaction> txs, int startIndex) request, CancellationToken cancellationToken)
{
IOwnedReadOnlyList<Transaction> transactions = request.txs;
ReadOnlySpan<Transaction> transactionsSpan = transactions.AsSpan();
try
{
int startIdx = request.startIndex;
bool isTrace = Logger.IsTrace;

for (int i = startIdx; i < transactionsSpan.Length; i++)
{
if (cancellationToken.IsCancellationRequested)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Nethermind.Network.P2P.Subprotocols.Eth.V68;

Expand Down Expand Up @@ -125,6 +127,7 @@ protected void RequestPooledTransactions(IOwnedReadOnlyList<Hash256> hashes, IOw
Hash256 hash = hashes[index];
int txSize = sizes[index];
TxType txType = (TxType)types[index];
TxShapeAnnouncements.Set(hash, (txSize, txType));

long maxTxSize = txType.SupportsBlobs() ? _configuredMaxBlobTxSize : _configuredMaxTxSize;

Expand Down Expand Up @@ -239,4 +242,21 @@ private void SendMessage(IOwnedReadOnlyList<byte> types, IOwnedReadOnlyList<int>
NewPooledTransactionHashesMessage68 message = new(types, sizes, hashes);
Send(message);
}

protected override ValueTask HandleSlow((IOwnedReadOnlyList<Transaction> txs, int startIndex) request, CancellationToken cancellationToken)
{
int startIdx = request.startIndex;
for (int i = startIdx; i < request.txs.Count; i++)
{
if (!ValidateSizeAndType(request.txs[i]))
{
throw new SubprotocolException("invalid pooled tx type or size");
}
}

return base.HandleSlow(request, cancellationToken);
}

private bool ValidateSizeAndType(Transaction tx)
=> !TxShapeAnnouncements.Delete(tx.Hash!, out (int Size, TxType Type) txShape) || (tx.GetLength() == txShape.Size && tx.Type == txShape.Type);
}
5 changes: 3 additions & 2 deletions src/Nethermind/Nethermind.TxPool/TxPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,6 @@ public void RemovePeer(PublicKey nodeId)

public AcceptTxResult SubmitTx(Transaction tx, TxHandlingOptions handlingOptions)
{
_retryCache.Received(tx.Hash!);

bool startBroadcast = _txPoolConfig.PersistentBroadcastEnabled
&& (handlingOptions & TxHandlingOptions.PersistentBroadcast) ==
TxHandlingOptions.PersistentBroadcast;
Expand All @@ -500,6 +498,7 @@ public AcceptTxResult SubmitTx(Transaction tx, TxHandlingOptions handlingOptions
// If local tx allow it to be accepted even when syncing
!startBroadcast)
{
_retryCache.Received(tx.Hash!);
return AcceptTxResult.Syncing;
}

Expand Down Expand Up @@ -541,6 +540,8 @@ public AcceptTxResult SubmitTx(Transaction tx, TxHandlingOptions handlingOptions

if (accepted)
{
_retryCache.Received(tx.Hash!);
Comment thread
marcindsobczak marked this conversation as resolved.

// Clear proper snapshot
if (tx.SupportsBlobs)
_blobTransactionSnapshot = null;
Expand Down