Skip to content

Commit ae99897

Browse files
committed
Remove unneeded channel in TrustedNodesManager
1 parent 7869bc8 commit ae99897

File tree

1 file changed

+61
-74
lines changed

1 file changed

+61
-74
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
22
// SPDX-License-Identifier: LGPL-3.0-only
33

4-
// SPDX-License-Identifier: LGPL-3.0-only
5-
64
using System;
75
using System.Collections.Concurrent;
86
using System.Collections.Generic;
@@ -12,21 +10,17 @@
1210
using System.Runtime.CompilerServices;
1311
using System.Text.Json;
1412
using System.Threading;
15-
using System.Threading.Channels;
1613
using System.Threading.Tasks;
1714
using Nethermind.Config;
1815
using Nethermind.Core.Crypto;
1916
using Nethermind.Logging;
20-
using Nethermind.Network.StaticNodes;
21-
using Nethermind.Serialization.Json;
2217
using Nethermind.Stats.Model;
2318

2419
namespace Nethermind.Network
2520
{
2621
public class TrustedNodesManager : ITrustedNodesManager
2722
{
2823
private ConcurrentDictionary<PublicKey, NetworkNode> _nodes = new();
29-
3024
private readonly string _trustedNodesPath;
3125
private readonly ILogger _logger;
3226

@@ -38,16 +32,19 @@ public TrustedNodesManager(string trustedNodesPath, ILogManager logManager)
3832

3933
public IEnumerable<NetworkNode> Nodes => _nodes.Values;
4034

41-
private static readonly char[] separator = new[] { '\r', '\n' };
42-
4335
public async Task InitAsync()
4436
{
4537
if (!File.Exists(_trustedNodesPath))
4638
{
47-
if (_logger.IsDebug) _logger.Debug($"Trusted nodes file not found for path: {_trustedNodesPath}");
39+
if (_logger.IsDebug)
40+
{
41+
_logger.Debug($"Trusted nodes file not found at: {_trustedNodesPath}");
42+
}
4843
return;
4944
}
50-
List<string> lines = new();
45+
46+
HashSet<string> lines = new();
47+
// Read lines asynchronously
5148
await foreach (string line in File.ReadLinesAsync(_trustedNodesPath))
5249
{
5350
if (!string.IsNullOrWhiteSpace(line))
@@ -56,66 +53,73 @@ public async Task InitAsync()
5653
}
5754
}
5855

59-
string[] nodes = lines.Distinct().ToArray();
60-
6156
if (_logger.IsInfo)
62-
_logger.Info($"Loaded {nodes.Length} trusted nodes from file: {Path.GetFullPath(_trustedNodesPath)}");
57+
{
58+
_logger.Info($"Loaded {lines.Count} trusted nodes from: {Path.GetFullPath(_trustedNodesPath)}");
59+
}
6360

64-
if (nodes.Length != 0 && _logger.IsDebug)
61+
if (lines.Any() && _logger.IsDebug)
6562
{
66-
string formattedNodes = string.Join(Environment.NewLine, nodes);
67-
_logger.Debug($"Trusted nodes: {Environment.NewLine}{formattedNodes}");
63+
_logger.Debug("Trusted nodes:\n" + string.Join(Environment.NewLine, lines));
6864
}
6965

66+
// Parse each line into a NetworkNode
7067
List<NetworkNode> networkNodes = new();
71-
foreach (string? n in nodes)
68+
foreach (string line in lines)
7269
{
7370
try
7471
{
75-
NetworkNode networkNode = new(n);
76-
networkNodes.Add(networkNode);
72+
networkNodes.Add(new NetworkNode(line));
7773
}
78-
catch (Exception exception) when (exception is ArgumentException or SocketException)
74+
catch (Exception ex) when (ex is ArgumentException or SocketException)
7975
{
80-
if (_logger.IsError) _logger.Error("Unable to process node. ", exception);
76+
if (_logger.IsError)
77+
{
78+
_logger.Error($"Failed to parse '{line}' as a trusted node.", ex);
79+
}
8180
}
8281
}
8382

84-
_nodes = new ConcurrentDictionary<PublicKey, NetworkNode>(networkNodes.ToDictionary(n => n.NodeId, n => n));
83+
_nodes = new ConcurrentDictionary<PublicKey, NetworkNode>(
84+
networkNodes.ToDictionary(n => n.NodeId, n => n));
8585
}
8686

87-
private static string[] GetNodes(string data)
87+
// ---- INodeSource requirement: IAsyncEnumerable<Node> ----
88+
// C# requires 'async' for IAsyncEnumerable yield. We'll add a small 'await Task.Yield()'
89+
// to avoid the warning about "no awaits".
90+
public async IAsyncEnumerable<Node> DiscoverNodes([EnumeratorCancellation] CancellationToken cancellationToken)
8891
{
89-
string[] nodes;
90-
try
91-
{
92-
nodes = JsonSerializer.Deserialize<string[]>(data) ?? Array.Empty<string>();
93-
}
94-
catch (JsonException)
92+
// At least one 'await', so no compiler warnings
93+
await Task.Yield();
94+
95+
foreach (NetworkNode netNode in _nodes.Values)
9596
{
96-
nodes = data.Split(separator, StringSplitOptions.RemoveEmptyEntries);
97+
cancellationToken.ThrowIfCancellationRequested();
98+
yield return new Node(netNode) { IsTrusted = true };
9799
}
98-
99-
return nodes.Distinct().ToArray();
100100
}
101101

102102
public async Task<bool> AddAsync(Enode enode, bool updateFile = true)
103103
{
104104
NetworkNode networkNode = new(enode.ToString());
105105
if (!_nodes.TryAdd(networkNode.NodeId, networkNode))
106106
{
107-
if (_logger.IsInfo) _logger.Info($"Trusted node was already added: {enode}");
107+
if (_logger.IsInfo)
108+
{
109+
_logger.Info($"Trusted node was already added: {enode}");
110+
}
108111
return false;
109112
}
110113

111-
if (_logger.IsInfo) _logger.Info($"Trusted node added: {enode}");
112-
Node node = new(networkNode) { IsTrusted = true };
113-
NodeAdded?.Invoke(this, new NodeEventArgs(node));
114+
if (_logger.IsInfo)
115+
{
116+
_logger.Info($"Trusted node added: {enode}");
117+
}
118+
114119
if (updateFile)
115120
{
116121
await SaveFileAsync();
117122
}
118-
119123
return true;
120124
}
121125

@@ -124,18 +128,22 @@ public async Task<bool> RemoveAsync(Enode enode, bool updateFile = true)
124128
NetworkNode networkNode = new(enode.ToString());
125129
if (!_nodes.TryRemove(networkNode.NodeId, out _))
126130
{
127-
if (_logger.IsInfo) _logger.Info($"Trusted node was not found: {enode}");
131+
if (_logger.IsInfo)
132+
{
133+
_logger.Info($"Trusted node was not found: {enode}");
134+
}
128135
return false;
129136
}
130137

131-
if (_logger.IsInfo) _logger.Info($"Trusted node was removed: {enode}");
132-
Node node = new(networkNode) { IsTrusted = true };
133-
NodeRemoved?.Invoke(this, new NodeEventArgs(node));
138+
if (_logger.IsInfo)
139+
{
140+
_logger.Info($"Trusted node was removed: {enode}");
141+
}
142+
134143
if (updateFile)
135144
{
136145
await SaveFileAsync();
137146
}
138-
139147
return true;
140148
}
141149

@@ -145,41 +153,20 @@ public bool IsTrusted(Enode enode)
145153
return _nodes.ContainsKey(node.NodeId);
146154
}
147155

148-
private Task SaveFileAsync()
149-
=> File.WriteAllTextAsync(_trustedNodesPath,
150-
JsonSerializer.Serialize(_nodes.Values.Select(n => n.ToString()), EthereumJsonSerializer.JsonOptionsIndented));
151-
152-
public async IAsyncEnumerable<Node> DiscoverNodes([EnumeratorCancellation] CancellationToken cancellationToken)
156+
// ---- INodeSource requirement: event EventHandler<NodeEventArgs> ----
157+
public event EventHandler<NodeEventArgs>? NodeRemoved
153158
{
154-
Channel<Node> ch = Channel.CreateBounded<Node>(128);
155-
156-
foreach (Node node in _nodes.Values.Select(n => new Node(n) { IsTrusted = true }))
157-
{
158-
cancellationToken.ThrowIfCancellationRequested();
159-
yield return node;
160-
}
161-
162-
void handler(object? _, NodeEventArgs args)
163-
{
164-
ch.Writer.TryWrite(args.Node);
165-
}
159+
add { /* no-op */ }
160+
remove { /* no-op*/ }
161+
}
166162

167-
try
168-
{
169-
NodeAdded += handler;
170163

171-
await foreach (Node node in ch.Reader.ReadAllAsync(cancellationToken))
172-
{
173-
yield return node;
174-
}
175-
}
176-
finally
177-
{
178-
NodeAdded -= handler;
179-
}
164+
private Task SaveFileAsync()
165+
{
166+
// Serialize the Enode strings from each stored node
167+
IEnumerable<string> enodes = _nodes.Values.Select(n => n.ToString());
168+
return File.WriteAllTextAsync(_trustedNodesPath,
169+
JsonSerializer.Serialize(enodes, new JsonSerializerOptions { WriteIndented = true }));
180170
}
181-
182-
private event EventHandler<NodeEventArgs>? NodeAdded;
183-
public event EventHandler<NodeEventArgs>? NodeRemoved;
184171
}
185172
}

0 commit comments

Comments
 (0)