private async Task UpdatePeersAsync(xServerPeers xServerPeerList)
        {
            foreach (var peer in xServerPeerList.GetPeers())
            {
                string xServerURL       = Utils.GetServerUrl(peer.NetworkProtocol, peer.NetworkAddress, peer.NetworkPort);
                var    client           = new RestClient(xServerURL);
                var    pingRequest      = new RestRequest("/ping/", Method.GET);
                var    pingResponseTime = Stopwatch.StartNew();
                var    pingResult       = await client.ExecuteAsync <PingResult>(pingRequest).ConfigureAwait(false);

                pingResponseTime.Stop();
                if (pingResult.StatusCode == HttpStatusCode.OK)
                {
                    var pingData = pingResult.Data;
                    peer.Version      = pingData.Version;
                    peer.ResponseTime = pingResponseTime.ElapsedMilliseconds;
                    peer.Tier         = pingData.Tier;
                    SyncPeerToPeersList(xServerPeerList, peer);
                }
                else
                {
                    SyncPeerToPeersList(xServerPeerList, peer, removePeer: true);
                }
            }
        }
        private void SyncPeerToPeersList(xServerPeers xServerPeerList, xServerPeer peer, bool seedCheck = false, bool removePeer = false)
        {
            var peersList = xServerPeerList.GetPeers();
            int peerIndex = peersList.FindIndex(p => p.NetworkAddress == peer.NetworkAddress);

            if (removePeer)
            {
                peersList.Remove(peer);
            }
            else if (seedCheck)
            {
                if (peerIndex == -1)
                {
                    peersList.Add(peer);
                }
            }
            else
            {
                if (peerIndex >= 0)
                {
                    peersList[peerIndex] = peer;
                }
                else
                {
                    peersList.Add(peer);
                }
            }
            lock (this.xServerPeersLock)
            {
                xServerPeerList.ReplacePeers(peersList);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="xServerFeature"/> class with the xServers.
        /// </summary>
        /// <param name="loggerFactory">The logger factory.</param>
        /// <param name="dataFolders">The data folders of the system.</param>
        /// <param name="asyncProvider">The async loop factory.</param>
        /// <param name="nodeLifetime">The managment of the node process.</param>
        /// <param name="network">The network managment.</param>
        public xServerManager(
            ILoggerFactory loggerFactory,
            DataFolder dataFolders,
            IAsyncProvider asyncProvider,
            INodeLifetime nodeLifetime,
            xServerSettings xServerSettings,
            Network network)
        {
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(dataFolders, nameof(dataFolders));
            Guard.NotNull(asyncProvider, nameof(asyncProvider));
            Guard.NotNull(nodeLifetime, nameof(nodeLifetime));
            Guard.NotNull(xServerSettings, nameof(xServerSettings));

            this.logger          = loggerFactory.CreateLogger(this.GetType().FullName);
            this.dataFolders     = dataFolders;
            this.asyncProvider   = asyncProvider;
            this.nodeLifetime    = nodeLifetime;
            this.xServerSettings = xServerSettings;
            this.network         = network;

            string path = Path.Combine(this.dataFolders.xServerAppsPath, xServerPeersFileName);

            this.xServerPeerList = new xServerPeers(path);

            this.xServerPeersLock = new object();
        }
        private async Task XServerDiscoveryAsync(xServerPeers xServerPeerList)
        {
            var seedList  = new ConcurrentBag <NetworkXServer>();
            int topResult = 10;

            await this.xServerSettings.RetrieveNodes().ForEachAsync(10, this.nodeLifetime.ApplicationStopping, async(peer, cancellation) =>
            {
                if (this.nodeLifetime.ApplicationStopping.IsCancellationRequested)
                {
                    return;
                }

                string xServerURL = Utils.GetServerUrl(peer.NetworkProtocol, peer.NetworkAddress, peer.NetworkPort);

                this.logger.LogDebug($"Attempting connection to {xServerURL}.");

                var client             = new RestClient(xServerURL);
                var topXServersRequest = new RestRequest("/gettop/", Method.GET);
                topXServersRequest.AddParameter("top", topResult);
                var topXServerResult = await client.ExecuteAsync <TopResult>(topXServersRequest, cancellation).ConfigureAwait(false);
                if (topXServerResult.StatusCode == HttpStatusCode.OK)
                {
                    seedList.Add(peer);
                    if (topXServerResult.Data?.XServers?.Count > 0)
                    {
                        var xServers = topXServerResult.Data.XServers;
                        foreach (var xServer in xServers)
                        {
                            xServerURL           = Utils.GetServerUrl(xServer.NetworkProtocol, xServer.NetworkAddress, xServer.NetworkPort);
                            client               = new RestClient(xServerURL);
                            var pingRequest      = new RestRequest("/ping/", Method.GET);
                            var pingResponseTime = Stopwatch.StartNew();
                            var pingResult       = await client.ExecuteAsync <PingResult>(pingRequest, cancellation).ConfigureAwait(false);
                            pingResponseTime.Stop();
                            if (pingResult.StatusCode == HttpStatusCode.OK)
                            {
                                var ping    = pingResult.Data;
                                var newPeer = new xServerPeer()
                                {
                                    Name            = xServer.Name,
                                    NetworkProtocol = xServer.NetworkProtocol,
                                    NetworkAddress  = xServer.NetworkAddress,
                                    NetworkPort     = xServer.NetworkPort,
                                    Priority        = xServer.Priotiry,
                                    Version         = ping.Version,
                                    ResponseTime    = pingResponseTime.ElapsedMilliseconds,
                                    Tier            = ping.Tier
                                };
                                SyncPeerToPeersList(xServerPeerList, newPeer);
                            }
                        }
                    }
                }

                SyncSeedsToPeersList(xServerPeerList, seedList);
            }).ConfigureAwait(false);
        }
 private void SyncSeedsToPeersList(xServerPeers xServerPeerList, ConcurrentBag <NetworkXServer> seedList)
 {
     foreach (var networkAddress in seedList)
     {
         var seedPeer = new xServerPeer()
         {
             Name            = "Public Seed",
             NetworkProtocol = networkAddress.NetworkProtocol,
             NetworkAddress  = networkAddress.NetworkAddress,
             NetworkPort     = networkAddress.NetworkPort,
             Priority        = -1,
             Version         = "N/A",
             ResponseTime    = 99999999,
             Tier            = (int)TierLevel.Seed
         };
         SyncPeerToPeersList(xServerPeerList, seedPeer, seedCheck: true);
     }
 }