private PeerStatistics GetPeerStatistics(IPEndPoint peerEndPoint)
        {
            if (!this.peersStatistics.TryGetValue(peerEndPoint, out PeerStatistics statistics))
            {
                // ensures no other threads have created already an entry between existence check and lock acquisition.
                if (!this.peersStatistics.TryGetValue(peerEndPoint, out statistics))
                {
                    statistics = new PeerStatistics(this.diagnosticSettings.MaxPeerLoggedEvents, peerEndPoint);
                    this.peersStatistics.Add(peerEndPoint, statistics);
                }
            }

            return(statistics);
        }
        private Task UpdatePeerStatistics(Event.PeerEventBase peerEvent, CancellationToken cancellation)
        {
            PeerStatistics statistics = GetPeerStatistics(peerEvent.PeerEndPoint);

            switch (peerEvent)
            {
            case Event.PeerConnected @event:
                statistics.Inbound = @event.Inbound;
                statistics.LogEvent($"Peer Connected");
                break;

            case Event.PeerConnectionAttempt @event:
                statistics.Inbound = @event.Inbound;
                statistics.LogEvent($"Attempting Connection");
                break;

            case Event.PeerConnectionAttemptFailed @event:
                statistics.Inbound = @event.Inbound;
                statistics.LogEvent($"Connection attempt FAILED. Reason: {@event.Reason}.");
                break;

            case Event.PeerDisconnected @event:
                statistics.Inbound = @event.Inbound;
                statistics.LogEvent($"Disconnected. Reason: {@event.Reason}. Exception: {@event.Exception?.ToString()}");
                break;

            case Event.PeerMessageReceived @event:
                statistics.ReceivedMessages++;
                statistics.BytesReceived += @event.MessageSize;
                statistics.LogEvent($"Message Received: {@event.Message.Payload.Command}");
                break;

            case Event.PeerMessageSent @event:
                statistics.SentMessages++;
                statistics.BytesSent += @event.Size;
                statistics.LogEvent($"Message Sent: {@event.Message.Payload.Command}");
                break;

            case Event.PeerMessageSendFailure @event:
                statistics.LogEvent($"Message Send Failure: {@event.Message?.Payload.Command}. Exception: {@event.Exception?.ToString()}");
                break;
            }

            return(Task.CompletedTask);
        }