diff --git a/src/Nethermind/Nethermind.Core/Crypto/PublicKey.cs b/src/Nethermind/Nethermind.Core/Crypto/PublicKey.cs index 84d5d1b6c64..c76225ffdc8 100644 --- a/src/Nethermind/Nethermind.Core/Crypto/PublicKey.cs +++ b/src/Nethermind/Nethermind.Core/Crypto/PublicKey.cs @@ -70,19 +70,7 @@ public Hash256 Hash public byte[] Bytes { get; } - public byte[] PrefixedBytes - { - get - { - if (_prefixedBytes is null) - { - return LazyInitializer.EnsureInitialized(ref _prefixedBytes, - () => Core.Extensions.Bytes.Concat(0x04, Bytes)); - } - - return _prefixedBytes; - } - } + public byte[] PrefixedBytes => _prefixedBytes ??= Core.Extensions.Bytes.Concat(0x04, Bytes); public bool Equals(PublicKey? other) => other is not null && Core.Extensions.Bytes.AreEqual(Bytes, other.Bytes); diff --git a/src/Nethermind/Nethermind.Db/SimpleFilePublicKeyDb.cs b/src/Nethermind/Nethermind.Db/SimpleFilePublicKeyDb.cs index 6bc28dbdb45..979ff10526d 100644 --- a/src/Nethermind/Nethermind.Db/SimpleFilePublicKeyDb.cs +++ b/src/Nethermind/Nethermind.Db/SimpleFilePublicKeyDb.cs @@ -65,11 +65,26 @@ public void Set(ReadOnlySpan key, byte[]? value, WriteFlags flags = WriteF { if (value is null) { - _cacheSpan.TryRemove(key, out _); + if (_cacheSpan.TryRemove(key, out _)) + { + _hasPendingChanges = true; + } + return; + } + + bool setValue = true; + if (_cacheSpan.TryGetValue(key, out var existingValue)) + { + if (!Bytes.AreEqual(existingValue, value)) + { + setValue = false; + } } - else + + if (setValue) { - _cache.AddOrUpdate(key.ToArray(), newValue => Add(value), (x, oldValue) => Update(oldValue, value)); + _cacheSpan[key] = value; + _hasPendingChanges = true; } } @@ -77,8 +92,10 @@ public void Set(ReadOnlySpan key, byte[]? value, WriteFlags flags = WriteF public void Remove(ReadOnlySpan key) { - _hasPendingChanges = true; - _cacheSpan.TryRemove(key, out _); + if (_cacheSpan.TryRemove(key, out _)) + { + _hasPendingChanges = true; + } } public bool KeyExists(ReadOnlySpan key) diff --git a/src/Nethermind/Nethermind.Network.Discovery/DiscoveryManager.cs b/src/Nethermind/Nethermind.Network.Discovery/DiscoveryManager.cs index 1b05e402ecd..fbce6b08f62 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/DiscoveryManager.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/DiscoveryManager.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using Nethermind.Config; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -25,6 +26,8 @@ public class DiscoveryManager : IDiscoveryManager private readonly INetworkStorage _discoveryStorage; private readonly ConcurrentDictionary> _waitingEvents = new(); + private readonly Func _createNodeLifecycleManager; + private readonly Func _createNodeLifecycleManagerPersisted; private IMsgSender? _msgSender; public DiscoveryManager( @@ -41,6 +44,24 @@ public DiscoveryManager( _discoveryStorage = discoveryStorage ?? throw new ArgumentNullException(nameof(discoveryStorage)); _nodeLifecycleManagerFactory.DiscoveryManager = this; _outgoingMessageRateLimiter = new RateLimiter(discoveryConfig.MaxOutgoingMessagePerSecond); + _createNodeLifecycleManager = GetLifecycleManagerFunc(isPersisted: false); + _createNodeLifecycleManagerPersisted = GetLifecycleManagerFunc(isPersisted: true); + } + + private Func GetLifecycleManagerFunc(bool isPersisted) + { + return (_, node) => + { + Interlocked.Increment(ref _managersCreated); + INodeLifecycleManager manager = _nodeLifecycleManagerFactory.CreateNodeLifecycleManager(node); + manager.OnStateChanged += ManagerOnOnStateChanged; + if (!isPersisted) + { + _discoveryStorage.UpdateNodes(new[] { new NetworkNode(manager.ManagedNode.Id, manager.ManagedNode.Host, manager.ManagedNode.Port, manager.NodeStats.NewPersistedNodeReputation(DateTime.UtcNow)) }); + } + + return manager; + }; } public IMsgSender MsgSender @@ -120,18 +141,7 @@ public void OnIncomingMsg(DiscoveryMsg msg) return null; } - return _nodeLifecycleManagers.GetOrAdd(node.IdHash, _ => - { - Interlocked.Increment(ref _managersCreated); - INodeLifecycleManager manager = _nodeLifecycleManagerFactory.CreateNodeLifecycleManager(node); - manager.OnStateChanged += ManagerOnOnStateChanged; - if (!isPersisted) - { - _discoveryStorage.UpdateNodes(new[] { new NetworkNode(manager.ManagedNode.Id, manager.ManagedNode.Host, manager.ManagedNode.Port, manager.NodeStats.NewPersistedNodeReputation(DateTime.UtcNow)) }); - } - - return manager; - }); + return _nodeLifecycleManagers.GetOrAdd(node.IdHash, isPersisted ? _createNodeLifecycleManagerPersisted : _createNodeLifecycleManager, node); } private void ManagerOnOnStateChanged(object? sender, NodeLifecycleState e) @@ -168,7 +178,8 @@ public async Task SendMessageAsync(DiscoveryMsg discoveryMsg) } } - public async Task WasMessageReceived(Hash256 senderIdHash, MsgType msgType, int timeout) + [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))] + public async ValueTask WasMessageReceived(Hash256 senderIdHash, MsgType msgType, int timeout) { TaskCompletionSource completionSource = GetCompletionSource(senderIdHash, (int)msgType); CancellationTokenSource delayCancellation = new(); diff --git a/src/Nethermind/Nethermind.Network.Discovery/IDiscoveryManager.cs b/src/Nethermind/Nethermind.Network.Discovery/IDiscoveryManager.cs index d33ce988471..26f8502ca7a 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/IDiscoveryManager.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/IDiscoveryManager.cs @@ -14,7 +14,7 @@ public interface IDiscoveryManager : IDiscoveryMsgListener INodeLifecycleManager? GetNodeLifecycleManager(Node node, bool isPersisted = false); void SendMessage(DiscoveryMsg discoveryMsg); Task SendMessageAsync(DiscoveryMsg discoveryMsg); - Task WasMessageReceived(Hash256 senderIdHash, MsgType msgType, int timeout); + ValueTask WasMessageReceived(Hash256 senderIdHash, MsgType msgType, int timeout); event EventHandler NodeDiscovered; IReadOnlyCollection GetNodeLifecycleManagers(); diff --git a/src/Nethermind/Nethermind.Network.Discovery/NettyDiscoveryHandler.cs b/src/Nethermind/Nethermind.Network.Discovery/NettyDiscoveryHandler.cs index ed470dcd1ae..a0dfb7afedf 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/NettyDiscoveryHandler.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/NettyDiscoveryHandler.cs @@ -97,14 +97,14 @@ public async Task SendMsg(DiscoveryMsg discoveryMsg) } IAddressedEnvelope packet = new DatagramPacket(msgBuffer, discoveryMsg.FarAddress); - - await _channel.WriteAndFlushAsync(packet).ContinueWith(t => + try { - if (t.IsFaulted) - { - if (_logger.IsTrace) _logger.Trace($"Error when sending a discovery message Msg: {discoveryMsg} ,Exp: {t.Exception}"); - } - }); + await _channel.WriteAndFlushAsync(packet); + } + catch (Exception e) + { + if (_logger.IsTrace) _logger.Trace($"Error when sending a discovery message Msg: {discoveryMsg} ,Exp: {e}"); + } Interlocked.Add(ref Metrics.DiscoveryBytesSent, size); } diff --git a/src/Nethermind/Nethermind.Network.Discovery/Serializers/NeighborsMsgSerializer.cs b/src/Nethermind/Nethermind.Network.Discovery/Serializers/NeighborsMsgSerializer.cs index 3b439a16f25..ea3f8820f68 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/Serializers/NeighborsMsgSerializer.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/Serializers/NeighborsMsgSerializer.cs @@ -13,6 +13,22 @@ namespace Nethermind.Network.Discovery.Serializers; public class NeighborsMsgSerializer : DiscoveryMsgSerializerBase, IZeroInnerMessageSerializer { + private static readonly Func _decodeItem = static ctx => + { + int lastPosition = ctx.ReadSequenceLength() + ctx.Position; + int count = ctx.PeekNumberOfItemsRemaining(lastPosition); + + ReadOnlySpan ip = ctx.DecodeByteArraySpan(); + IPEndPoint address = GetAddress(ip, ctx.DecodeInt()); + if (count > 3) + { + ctx.DecodeInt(); + } + + ReadOnlySpan id = ctx.DecodeByteArraySpan(); + return new Node(new PublicKey(id), address); + }; + public NeighborsMsgSerializer(IEcdsa ecdsa, IPrivateKeyGenerator nodeKey, INodeIdResolver nodeIdResolver) : base(ecdsa, nodeKey, nodeIdResolver) @@ -53,30 +69,16 @@ public NeighborsMsg Deserialize(IByteBuffer msgBytes) NettyRlpStream rlp = new(Data); rlp.ReadSequenceLength(); - Node[] nodes = DeserializeNodes(rlp) as Node[]; + Node[] nodes = DeserializeNodes(rlp); long expirationTime = rlp.DecodeLong(); NeighborsMsg msg = new(FarPublicKey, expirationTime, nodes); return msg; } - private static Node?[] DeserializeNodes(RlpStream rlpStream) + private static Node[] DeserializeNodes(RlpStream rlpStream) { - return rlpStream.DecodeArray(ctx => - { - int lastPosition = ctx.ReadSequenceLength() + ctx.Position; - int count = ctx.PeekNumberOfItemsRemaining(lastPosition); - - ReadOnlySpan ip = ctx.DecodeByteArraySpan(); - IPEndPoint address = GetAddress(ip, ctx.DecodeInt()); - if (count > 3) - { - ctx.DecodeInt(); - } - - ReadOnlySpan id = ctx.DecodeByteArraySpan(); - return new Node(new PublicKey(id), address); - }); + return rlpStream.DecodeArray(_decodeItem); } private static int GetNodesLength(Node[] nodes, out int contentLength) diff --git a/src/Nethermind/Nethermind.Network.Test/ProtocolsManagerTests.cs b/src/Nethermind/Nethermind.Network.Test/ProtocolsManagerTests.cs index 3f10c542571..140e661af22 100644 --- a/src/Nethermind/Nethermind.Network.Test/ProtocolsManagerTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/ProtocolsManagerTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Numerics; -using System.Threading; using DotNetty.Buffers; using DotNetty.Transport.Channels; using Nethermind.Blockchain; @@ -184,12 +183,6 @@ public Context ReceiveDisconnect() return this; } - public Context Wait(int i) - { - Thread.Sleep(i); - return this; - } - public Context VerifyInitialized() { Assert.That(_currentSession.State, Is.EqualTo(SessionState.Initialized)); diff --git a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs index b05f4e9df4a..a17a31b947b 100644 --- a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/P2PProtocolHandler.cs @@ -79,13 +79,7 @@ public override void Init() // We are expecting to receive Hello message anytime from the handshake completion, // irrespective of sending Hello from our side - CheckProtocolInitTimeout().ContinueWith(x => - { - if (x.IsFaulted && Logger.IsError) - { - Logger.Error("Error during p2pProtocol handler timeout logic", x.Exception); - } - }); + _ = CheckProtocolInitTimeout(); } public override void HandleMessage(Packet msg) diff --git a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/ProtocolHandlerBase.cs b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/ProtocolHandlerBase.cs index e4eb0a2c2a7..339ff752abc 100644 --- a/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/ProtocolHandlerBase.cs +++ b/src/Nethermind/Nethermind.Network/P2P/ProtocolHandlers/ProtocolHandlerBase.cs @@ -93,22 +93,32 @@ protected internal void Send(T message) where T : P2PMessage protected async Task CheckProtocolInitTimeout() { - Task receivedInitMsgTask = _initCompletionSource.Task; - CancellationTokenSource delayCancellation = new(); - Task firstTask = await Task.WhenAny(receivedInitMsgTask, Task.Delay(InitTimeout, delayCancellation.Token)); - - if (firstTask != receivedInitMsgTask) + try { - if (Logger.IsTrace) + Task receivedInitMsgTask = _initCompletionSource.Task; + CancellationTokenSource delayCancellation = new(); + Task firstTask = await Task.WhenAny(receivedInitMsgTask, Task.Delay(InitTimeout, delayCancellation.Token)); + + if (firstTask != receivedInitMsgTask) { - Logger.Trace($"Disconnecting due to timeout for protocol init message ({Name}): {Session.RemoteNodeId}"); - } + if (Logger.IsTrace) + { + Logger.Trace($"Disconnecting due to timeout for protocol init message ({Name}): {Session.RemoteNodeId}"); + } - Session.InitiateDisconnect(DisconnectReason.ProtocolInitTimeout, "protocol init timeout"); + Session.InitiateDisconnect(DisconnectReason.ProtocolInitTimeout, "protocol init timeout"); + } + else + { + delayCancellation.Cancel(); + } } - else + catch (Exception e) { - delayCancellation.Cancel(); + if (Logger.IsError) + { + Logger.Error("Error during p2pProtocol handler timeout logic", e); + } } } diff --git a/src/Nethermind/Nethermind.Network/P2P/Session.cs b/src/Nethermind/Nethermind.Network/P2P/Session.cs index 21d6dda9254..67abb2122f8 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Session.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Session.cs @@ -487,33 +487,7 @@ public void MarkDisconnected(DisconnectReason disconnectReason, DisconnectType d Disconnecting?.Invoke(this, new DisconnectEventArgs(disconnectReason, disconnectType, details)); - //Possible in case of disconnect before p2p initialization - if (_context is null) - { - //in case pipeline did not get to p2p - no disconnect delay - _channel.DisconnectAsync().ContinueWith(x => - { - if (x.IsFaulted && _logger.IsTrace) - _logger.Trace($"Error while disconnecting on channel on {this} : {x.Exception}"); - }); - } - else - { - Task delayTask = - disconnectType == DisconnectType.Local - ? Task.Delay(Timeouts.Disconnection) - : Task.CompletedTask; - delayTask.ContinueWith(t => - { - if (_logger.IsTrace) - _logger.Trace($"{this} disconnecting now after {Timeouts.Disconnection.TotalMilliseconds} milliseconds"); - _context.DisconnectAsync().ContinueWith(x => - { - if (x.IsFaulted && _logger.IsTrace) - _logger.Trace($"Error while disconnecting on context on {this} : {x.Exception}"); - }); - }); - } + _ = DisconnectAsync(disconnectType); lock (_sessionStateLock) { @@ -530,6 +504,41 @@ public void MarkDisconnected(DisconnectReason disconnectReason, DisconnectType d _logger.Error($"DEBUG/ERROR No subscriptions for session disconnected event on {this}"); } + private async Task DisconnectAsync(DisconnectType disconnectType) + { + //Possible in case of disconnect before p2p initialization + if (_context is null) + { + //in case pipeline did not get to p2p - no disconnect delay + try + { + await _channel.DisconnectAsync(); + } + catch (Exception e) + { + if (_logger.IsTrace) + _logger.Trace($"Error while disconnecting on context on {this} : {e}"); + } + } + else + { + if (disconnectType == DisconnectType.Local) + { + await Task.Delay(Timeouts.Disconnection); + } + + try + { + await _context.DisconnectAsync(); + } + catch (Exception e) + { + if (_logger.IsTrace) + _logger.Trace($"Error while disconnecting on context on {this} : {e}"); + } + } + } + public event EventHandler Disconnecting; public event EventHandler Disconnected; public event EventHandler HandshakeComplete; diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs index fb5c330b1b7..db427262f5f 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs @@ -33,6 +33,7 @@ public class Eth62ProtocolHandler : SyncPeerProtocolHandlerBase, IZeroProtocolHa private readonly ITxGossipPolicy _txGossipPolicy; private LruKeyCache? _lastBlockNotificationCache; private LruKeyCache LastBlockNotificationCache => _lastBlockNotificationCache ??= new(10, "LastBlockNotificationCache"); + private readonly Func<(IOwnedReadOnlyList txs, int startIndex), CancellationToken, ValueTask> _handleSlow; public Eth62ProtocolHandler(ISession session, IMessageSerializationService serializer, @@ -49,6 +50,7 @@ public Eth62ProtocolHandler(ISession session, _txPool = txPool ?? throw new ArgumentNullException(nameof(txPool)); _gossipPolicy = gossipPolicy ?? throw new ArgumentNullException(nameof(gossipPolicy)); _txGossipPolicy = transactionsGossipPolicy ?? TxPool.ShouldGossip.Instance; + _handleSlow = HandleSlow; EnsureGossipPolicy(); } @@ -253,7 +255,7 @@ protected void Handle(TransactionsMessage msg) { IOwnedReadOnlyList iList = msg.Transactions; - BackgroundTaskScheduler.ScheduleBackgroundTask((iList, 0), HandleSlow); + BackgroundTaskScheduler.ScheduleBackgroundTask((iList, 0), _handleSlow); } private ValueTask HandleSlow((IOwnedReadOnlyList txs, int startIndex) request, CancellationToken cancellationToken) diff --git a/src/Nethermind/Nethermind.Network/Rlpx/NettyHandshakeHandler.cs b/src/Nethermind/Nethermind.Network/Rlpx/NettyHandshakeHandler.cs index f5186f4b2a8..88571b3d5c6 100644 --- a/src/Nethermind/Nethermind.Network/Rlpx/NettyHandshakeHandler.cs +++ b/src/Nethermind/Nethermind.Network/Rlpx/NettyHandshakeHandler.cs @@ -75,13 +75,7 @@ public override void ChannelActive(IChannelHandlerContext context) _session.RemotePort = ((IPEndPoint)context.Channel.RemoteAddress).Port; } - CheckHandshakeInitTimeout().ContinueWith(x => - { - if (x.IsFaulted && _logger.IsError) - { - _logger.Error("Error during handshake timeout logic", x.Exception); - } - }); + _ = CheckHandshakeInitTimeout(); } public override void ChannelInactive(IChannelHandlerContext context) @@ -203,20 +197,31 @@ public override void HandlerRemoved(IChannelHandlerContext context) private async Task CheckHandshakeInitTimeout() { - Task receivedInitMsgTask = _initCompletionSource.Task; - CancellationTokenSource delayCancellation = new(); - Task firstTask = await Task.WhenAny(receivedInitMsgTask, Task.Delay(Timeouts.Handshake, delayCancellation.Token)); - - if (firstTask != receivedInitMsgTask) + try { - Metrics.HandshakeTimeouts++; - if (_logger.IsTrace) _logger.Trace($"Disconnecting due to timeout for handshake: {_session.RemoteNodeId}@{_session.RemoteHost}:{_session.RemotePort}"); - //It will trigger channel.CloseCompletion which will trigger DisconnectAsync on the session - await _channel.DisconnectAsync(); + Task receivedInitMsgTask = _initCompletionSource.Task; + CancellationTokenSource delayCancellation = new(); + Task firstTask = await Task.WhenAny(receivedInitMsgTask, Task.Delay(Timeouts.Handshake, delayCancellation.Token)); + + if (firstTask != receivedInitMsgTask) + { + Metrics.HandshakeTimeouts++; + if (_logger.IsTrace) _logger.Trace($"Disconnecting due to timeout for handshake: {_session.RemoteNodeId}@{_session.RemoteHost}:{_session.RemotePort}"); + //It will trigger channel.CloseCompletion which will trigger DisconnectAsync on the session + await _channel.DisconnectAsync(); + } + else + { + delayCancellation.Cancel(); + } } - else + catch (Exception ex) { - delayCancellation.Cancel(); + + if (_logger.IsError) + { + _logger.Error("Error during handshake timeout logic", ex); + } } } } diff --git a/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs b/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs index 403d7b6b60b..c287dd81f5b 100644 --- a/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StateReaderTests.cs @@ -316,7 +316,7 @@ public void IsInvalidContractSender_AccountHasCodeButDelegateReturnsTrue_Returns sut.Commit(MuirGlacier.Instance); sut.CommitTree(0); - bool result = sut.IsInvalidContractSender(releaseSpec, TestItem.AddressA, static () => true); + bool result = sut.IsInvalidContractSender(releaseSpec, TestItem.AddressA, static (_) => true); Assert.That(result, Is.False); } diff --git a/src/Nethermind/Nethermind.State/IReadOnlyStateProviderExtensions.cs b/src/Nethermind/Nethermind.State/IReadOnlyStateProviderExtensions.cs index 83f39b0c6c9..5101b3abf8c 100644 --- a/src/Nethermind/Nethermind.State/IReadOnlyStateProviderExtensions.cs +++ b/src/Nethermind/Nethermind.State/IReadOnlyStateProviderExtensions.cs @@ -27,11 +27,11 @@ public static bool IsInvalidContractSender( this IReadOnlyStateProvider stateProvider, IReleaseSpec spec, Address sender, - Func? isDelegatedCode = null) => + Func? isDelegatedCode = null) => spec.IsEip3607Enabled && stateProvider.HasCode(sender) && (!spec.IsEip7702Enabled - || (!isDelegatedCode?.Invoke() ?? !Eip7702Constants.IsDelegatedCode(GetCode(stateProvider, sender)))); + || (!isDelegatedCode?.Invoke(sender) ?? !Eip7702Constants.IsDelegatedCode(GetCode(stateProvider, sender)))); } } diff --git a/src/Nethermind/Nethermind.TxPool/Filters/DeployedCodeFilter.cs b/src/Nethermind/Nethermind.TxPool/Filters/DeployedCodeFilter.cs index 1eb06f8dcc8..3d18504e468 100644 --- a/src/Nethermind/Nethermind.TxPool/Filters/DeployedCodeFilter.cs +++ b/src/Nethermind/Nethermind.TxPool/Filters/DeployedCodeFilter.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; using Nethermind.Core.Specs; using Nethermind.Evm; @@ -13,11 +14,12 @@ namespace Nethermind.TxPool.Filters /// internal sealed class DeployedCodeFilter(IReadOnlyStateProvider worldState, ICodeInfoRepository codeInfoRepository, IChainHeadSpecProvider specProvider) : IIncomingTxFilter { + private readonly Func _isDelegatedCode = (sender) => codeInfoRepository.TryGetDelegation(worldState, sender, out _); public AcceptTxResult Accept(Transaction tx, ref TxFilteringState state, TxHandlingOptions txHandlingOptions) { return worldState.IsInvalidContractSender(specProvider.GetCurrentHeadSpec(), tx.SenderAddress!, - () => codeInfoRepository.TryGetDelegation(worldState, tx.SenderAddress!, out _)) + _isDelegatedCode) ? AcceptTxResult.SenderIsContract : AcceptTxResult.Accepted; }