protected override Task WorkAction()
{
if (this.localClient.Type == ChainType.Regtest)
return Task.CompletedTask;
foreach (var peer in this.connectedPeers)
{
// clear out any disconnected peers
if (!peer.IsConnected)
DisconnectPeer(peer, null);
if (this.connectedPeers.Count < 3)
break;
// disconnect seed peers, once enough peers are connected
if (peer.IsSeed)
DisconnectPeer(peer, null);
// disconnect slow peers
if (peer.BlockMissCount >= 5)
{
logger.Info($"Disconnecting slow peer: {peer.RemoteEndPoint}");
DisconnectPeer(peer, null);
}
}
// get peer counts
var connectedCount = this.connectedPeers.Count;
var pendingCount = this.pendingPeers.Count;
var maxConnections = ConnectedMax; // Math.Max(CONNECTED_MAX + 20, PENDING_MAX);
// if there aren't enough peers connected and there is a pending connection slot available, make another connection
if (connectedCount < ConnectedMax
&& pendingCount < PendingMax
&& (connectedCount + pendingCount) < maxConnections)
{
// get number of connections to attempt
var connectCount = maxConnections - (connectedCount + pendingCount);
// take a selection of unconnected peers, ordered by time
var unconnectedPeersLocal = this.unconnectedPeersLock.Do(() =>
this.unconnectedPeers.Values.Take(connectCount).ToArray());
var connectTasks = new List<Task>();
foreach (var candidatePeer in unconnectedPeersLocal)
{
// cooperative loop
this.ThrowIfCancelled();
// connect to peer
connectTasks.Add(ConnectToPeer(candidatePeer.IPEndPoint, candidatePeer.IsSeed));
}
// wait for pending connection attempts to complete
//Task.WaitAll(connectTasks.ToArray(), this.shutdownToken.Token);
}
// check if there are too many peers connected
var overConnected = this.connectedPeers.Count - ConnectedMax;
if (overConnected > 0)
{
foreach (var peer in this.connectedPeers.Take(overConnected))
{
// cooperative loop
this.ThrowIfCancelled();
logger.Debug($"Too many peers connected ({overConnected}), disconnecting {peer}");
DisconnectPeer(peer, null);
}
}
return Task.CompletedTask;
}