diff --git a/Directory.Packages.props b/Directory.Packages.props
index 065d95f8a88..de1da8ae56d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -70,7 +70,7 @@
-
+
diff --git a/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs b/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs
index 55746e2c850..523e03e089c 100644
--- a/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs
+++ b/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
using System.Diagnostics.CodeAnalysis;
@@ -20,6 +20,7 @@
using NBitcoin.Secp256k1;
using Nethermind.Config;
using Nethermind.Core;
+using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
using Nethermind.Core.ServiceStopper;
using Nethermind.Crypto;
@@ -205,11 +206,13 @@ public async Task StartAsync()
public async IAsyncEnumerable DiscoverNodes([EnumeratorCancellation] CancellationToken token)
{
- Channel ch = Channel.CreateBounded(1);
+ Channel discoveredNodesChannel = Channel.CreateBounded(1);
- async Task DiscoverAsync(IEnumerable startingNode, byte[] nodeId)
+ async Task DiscoverAsync(IEnumerable startingNode, ArrayPoolSpan nodeId)
{
- static int[] GetDistances(byte[] srcNodeId, byte[] destNodeId)
+ using ArrayPoolSpan _ = nodeId;
+
+ static int[] GetDistances(byte[] srcNodeId, in ArrayPoolSpan destNodeId)
{
const int WiderDistanceRange = 3;
@@ -243,8 +246,10 @@ static int[] GetDistances(byte[] srcNodeId, byte[] destNodeId)
if (TryGetNodeFromEnr(newEntry, out Node? node2))
{
- await ch.Writer.WriteAsync(node2!, token);
+ await discoveredNodesChannel.Writer.WriteAsync(node2!, token);
+
if (_logger.IsDebug) _logger.Debug($"A node discovered via discv5: {newEntry} = {node2}.");
+
_discoveryReport?.NodeFound();
}
@@ -253,13 +258,11 @@ static int[] GetDistances(byte[] srcNodeId, byte[] destNodeId)
continue;
}
- IEnumerable? newNodesFound = (await _discv5Protocol.SendFindNodeAsync(newEntry, GetDistances(newEntry.NodeId, nodeId)))?.Where(x => !checkedNodes.Contains(x));
-
- if (newNodesFound is not null)
+ foreach (IEnr newEnr in await _discv5Protocol.SendFindNodeAsync(newEntry, GetDistances(newEntry.NodeId, in nodeId)) ?? [])
{
- foreach (IEnr? node in newNodesFound)
+ if (!checkedNodes.Contains(newEnr))
{
- nodesToCheck.Enqueue(node);
+ nodesToCheck.Enqueue(newEnr);
}
}
}
@@ -272,16 +275,20 @@ static int[] GetDistances(byte[] srcNodeId, byte[] destNodeId)
Task discoverTask = Task.Run(async () =>
{
- byte[] randomNodeId = new byte[32];
+ using ArrayPoolSpan selfNodeId = new(32);
+ _discv5Protocol.SelfEnr.NodeId.CopyTo(selfNodeId);
+
while (!token.IsCancellationRequested)
{
try
{
- List discoverTasks = new List();
- discoverTasks.Add(DiscoverAsync(GetStartingNodes(), _discv5Protocol.SelfEnr.NodeId));
+ using ArrayPoolList discoverTasks = new(RandomNodesToLookupCount);
+
+ discoverTasks.Add(DiscoverAsync(GetStartingNodes(), selfNodeId));
for (int i = 0; i < RandomNodesToLookupCount; i++)
{
+ ArrayPoolSpan randomNodeId = new(32);
random.NextBytes(randomNodeId);
discoverTasks.Add(DiscoverAsync(GetStartingNodes(), randomNodeId));
}
@@ -293,11 +300,11 @@ static int[] GetDistances(byte[] srcNodeId, byte[] destNodeId)
if (_logger.IsError) _logger.Error($"Discovery via custom random walk failed.", ex);
}
}
- });
+ }, token);
try
{
- await foreach (Node node in ch.Reader.ReadAllAsync(token))
+ await foreach (Node node in discoveredNodesChannel.Reader.ReadAllAsync(token))
{
yield return node;
}
diff --git a/src/Nethermind/Nethermind.Network.Discovery/Discv5/NettyDiscoveryV5Handler.cs b/src/Nethermind/Nethermind.Network.Discovery/Discv5/NettyDiscoveryV5Handler.cs
index ea7d25a16f6..1cb6e9a4e91 100644
--- a/src/Nethermind/Nethermind.Network.Discovery/Discv5/NettyDiscoveryV5Handler.cs
+++ b/src/Nethermind/Nethermind.Network.Discovery/Discv5/NettyDiscoveryV5Handler.cs
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
using System.Net;
@@ -36,9 +36,12 @@ public NettyDiscoveryV5Handler(ILogManager loggerManager) : base(loggerManager)
protected override void ChannelRead0(IChannelHandlerContext ctx, DatagramPacket msg)
{
- var udpPacket = new UdpReceiveResult(msg.Content.ReadAllBytesAsArray(), (IPEndPoint)msg.Sender);
- if (!_inboundQueue.Writer.TryWrite(udpPacket) && _logger.IsWarn)
+ UdpReceiveResult udpPacket = new(msg.Content.ReadAllBytesAsArray(), (IPEndPoint)msg.Sender);
+
+ if (!_inboundQueue.Writer.TryWrite(udpPacket) && _logger.IsDebug)
+ {
_logger.Warn("Skipping discovery v5 message as inbound buffer is full");
+ }
}
public async Task SendAsync(byte[] data, IPEndPoint destination)
@@ -53,7 +56,7 @@ public async Task SendAsync(byte[] data, IPEndPoint destination)
}
catch (SocketException exception)
{
- if (_logger.IsError) _logger.Error("Error sending data", exception);
+ if (_logger.IsDebug) _logger.Error("DEBUG/ERROR Error sending data", exception);
throw;
}
}
diff --git a/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json b/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json
index bcd13f9650c..e4d89748f40 100644
--- a/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json
+++ b/src/Nethermind/Nethermind.Runner/configs/base-sepolia.json
@@ -36,4 +36,4 @@
"Optimism": {
"SequencerUrl": "https://sepolia-sequencer.base.org"
}
-}
\ No newline at end of file
+}
diff --git a/src/Nethermind/Nethermind.Runner/packages.lock.json b/src/Nethermind/Nethermind.Runner/packages.lock.json
index 7f71a26adc3..b4dd4eabb03 100644
--- a/src/Nethermind/Nethermind.Runner/packages.lock.json
+++ b/src/Nethermind/Nethermind.Runner/packages.lock.json
@@ -510,20 +510,20 @@
},
"PierTwo.Lantern.Discv5.Enr": {
"type": "Transitive",
- "resolved": "1.0.0-preview.6",
- "contentHash": "rHuVBANEsOdf+5p1uU35mrdJfb+2z9EtDU5LeHKWDWx5nfGMRK4LtcrbfvDnrdsTLQbxmV88PoBuS23FMLrpYQ==",
+ "resolved": "1.0.0-preview.7",
+ "contentHash": "oNF8cPIbYt+8xWoCqPCDfKOEsxhlFUWEXmoV45/XTKipU5ZqvmdTsESCv0o97TP2sNZaZrFrvpovf7aNk3BUKw==",
"dependencies": {
"Keccak256": "1.0.0",
"Multiformats.Base": "2.0.2",
"Multiformats.Hash": "1.5.0",
"NBitcoin.Secp256k1": "3.1.5",
- "PierTwo.Lantern.Discv5.Rlp": "1.0.0-preview.6"
+ "PierTwo.Lantern.Discv5.Rlp": "1.0.0-preview.7"
}
},
"PierTwo.Lantern.Discv5.Rlp": {
"type": "Transitive",
- "resolved": "1.0.0-preview.6",
- "contentHash": "X1mOhKZytX60uZwh9aCex0BVidN0hVlf5jKZsufacWpfsN/yMstc/fh3aRM9JWm8x7PQVeY300JXVFhDk4roqA=="
+ "resolved": "1.0.0-preview.7",
+ "contentHash": "tAwonG4x8SWFBxd06JvzYNo0xvTsDoM9xfk2tnwIcFzCvY7PORvpOiy9AQcyjqomFQmCNqF4ezwZoRZJV32iQg=="
},
"Polly.Core": {
"type": "Transitive",
@@ -1002,7 +1002,7 @@
"Nethermind.Facade": "[1.37.0-unstable, )",
"Nethermind.Network": "[1.37.0-unstable, )",
"Nethermind.Network.Enr": "[1.37.0-unstable, )",
- "PierTwo.Lantern.Discv5.WireProtocol": "[1.0.0-preview.6, )"
+ "PierTwo.Lantern.Discv5.WireProtocol": "[1.0.0-preview.7, )"
}
},
"nethermind.network.dns": {
@@ -1519,14 +1519,14 @@
},
"PierTwo.Lantern.Discv5.WireProtocol": {
"type": "CentralTransitive",
- "requested": "[1.0.0-preview.6, )",
- "resolved": "1.0.0-preview.6",
- "contentHash": "WjVYiDxyZ3z00kuJJXuWJwRqkWfTrZF1v7qWz4mMASRP6AEhDCF4jMdCuAWkH1uPj00kkluONOc426Z//FcjDw==",
+ "requested": "[1.0.0-preview.7, )",
+ "resolved": "1.0.0-preview.7",
+ "contentHash": "wfa8Drf8r8Ty8r6cebobxANFmM2h0ckA/fWIKkQCnC+Af91IKFTAtiVhtu5oCjRxY21MLuWxqObV8r+JkKSYrg==",
"dependencies": {
"BouncyCastle.Cryptography": "2.4.0",
"NBitcoin.Secp256k1": "3.1.5",
- "PierTwo.Lantern.Discv5.Enr": "1.0.0-preview.6",
- "PierTwo.Lantern.Discv5.Rlp": "1.0.0-preview.6"
+ "PierTwo.Lantern.Discv5.Enr": "1.0.0-preview.7",
+ "PierTwo.Lantern.Discv5.Rlp": "1.0.0-preview.7"
}
},
"Polly": {