/// <summary> /// Permit to check new remote node host. /// </summary> /// <param name="ip"></param> public static async System.Threading.Tasks.Task <string> CheckNewRemoteNodeHostAsync(string ip) { InCheckingNewRemoteNode = true; var statusPing = CheckPing.CheckPingHost(ip); if (statusPing != -1) { #if DEBUG Console.WriteLine("From Xiropht-Connector-All: ping status: " + ip + " " + statusPing + " ms."); #endif var statusTcp = await CheckTcp.CheckTcpClientAsync(ip, ClassConnectorSetting.RemoteNodePort); if (statusTcp) { if (ListRemoteNodeChecked.Count > 0) { var exist = false; for (var i = 0; i < ListRemoteNodeChecked.Count - 1; i++) { if (ListRemoteNodeChecked[i].Item1 == ip) { exist = true; } } if (!exist) { ListRemoteNodeChecked.Add(new Tuple <string, int>(ip, statusPing)); return(ClassRemoteNodeStatus.StatusNew); } return(ClassRemoteNodeStatus.StatusAlive); } ListRemoteNodeChecked.Add(new Tuple <string, int>(ip, statusPing)); return(ClassRemoteNodeStatus.StatusNew); } } InCheckingNewRemoteNode = false; return(ClassRemoteNodeStatus.StatusDead); }
/// <summary> /// Check if the wallet address exist on the network. /// </summary> /// <param name="walletAddress"></param> /// <returns></returns> public static async Task <bool> CheckWalletAddressExistAsync(string walletAddress) { if (Program.DictionaryWalletAddressCache.ContainsKey(walletAddress)) { return(true); } Dictionary <string, int> listOfSeedNodesSpeed = new Dictionary <string, int>(); foreach (var seedNode in ClassConnectorSetting.SeedNodeIp) { try { int seedNodeResponseTime = -1; Task taskCheckSeedNode = Task.Run(() => seedNodeResponseTime = CheckPing.CheckPingHost(seedNode.Key, true)); taskCheckSeedNode.Wait(ClassConnectorSetting.MaxPingDelay); if (seedNodeResponseTime == -1) { seedNodeResponseTime = ClassConnectorSetting.MaxSeedNodeTimeoutConnect; } listOfSeedNodesSpeed.Add(seedNode.Key, seedNodeResponseTime); } catch { listOfSeedNodesSpeed.Add(seedNode.Key, ClassConnectorSetting.MaxSeedNodeTimeoutConnect); // Max delay. } } listOfSeedNodesSpeed = listOfSeedNodesSpeed.OrderBy(u => u.Value).ToDictionary(z => z.Key, y => y.Value); foreach (var seedNode in listOfSeedNodesSpeed) { try { string randomSeedNode = seedNode.Key; string request = ClassConnectorSettingEnumeration.WalletTokenType + ClassConnectorSetting.PacketContentSeperator + ClassRpcWalletCommand.TokenCheckWalletAddressExist + ClassConnectorSetting.PacketContentSeperator + walletAddress; string result = await ProceedHttpRequest("http://" + randomSeedNode + ":" + ClassConnectorSetting.SeedNodeTokenPort + "/", request); if (result != string.Empty && result != PacketNotExist) { JObject resultJson = JObject.Parse(result); if (resultJson.ContainsKey(PacketResult)) { string resultCheckWalletAddress = resultJson[PacketResult].ToString(); if (resultCheckWalletAddress.Contains(ClassConnectorSetting.PacketContentSeperator)) { var splitResultCheckWalletAddress = resultCheckWalletAddress.Split(new[] { ClassConnectorSetting.PacketContentSeperator }, StringSplitOptions.None); if (splitResultCheckWalletAddress[0] == ClassRpcWalletCommand.SendTokenCheckWalletAddressValid) { Program.SaveWalletAddressCache(walletAddress); return(true); } } } } } catch { } } return(false); }
/// <summary> /// Start to connect on the seed node. /// </summary> /// <returns></returns> public async Task <bool> StartConnectToSeedAsync(string host, int port = ClassConnectorSetting.SeedNodePort, bool isLinux = false) { MalformedPacket = string.Empty; if (!string.IsNullOrEmpty(host)) { #if DEBUG Console.WriteLine("Host target: " + host); #endif try { _connector = new TcpClient(); await _connector.ConnectAsync(host, port); } catch (Exception error) { #if DEBUG Console.WriteLine("Error to connect on manual host node: " + error.Message); #endif _isConnected = false; return(false); } _isConnected = true; _currentSeedNodeHost = host; _connector.SetSocketKeepAliveValues(20 * 60 * 1000, 30 * 1000); return(true); } else { Dictionary <string, int> ListOfSeedNodesSpeed = new Dictionary <string, int>(); foreach (var seedNode in ClassConnectorSetting.SeedNodeIp) { try { int seedNodeResponseTime = -1; Task taskCheckSeedNode = Task.Run(() => seedNodeResponseTime = CheckPing.CheckPingHost(seedNode.Key, true)); taskCheckSeedNode.Wait(ClassConnectorSetting.MaxPingDelay); if (seedNodeResponseTime == -1) { seedNodeResponseTime = ClassConnectorSetting.MaxSeedNodeTimeoutConnect; } #if DEBUG Console.WriteLine(seedNode.Key + " response time: " + seedNodeResponseTime + " ms."); #endif ListOfSeedNodesSpeed.Add(seedNode.Key, seedNodeResponseTime); } catch { ListOfSeedNodesSpeed.Add(seedNode.Key, ClassConnectorSetting.MaxSeedNodeTimeoutConnect); // Max delay. } } ListOfSeedNodesSpeed = ListOfSeedNodesSpeed.OrderBy(u => u.Value).ToDictionary(z => z.Key, y => y.Value); var success = false; var seedNodeTested = false; foreach (var seedNode in ListOfSeedNodesSpeed) { #if DEBUG Console.WriteLine("Seed Node Host target: " + seedNode.Key); #endif try { if (ClassConnectorSetting.SeedNodeDisconnectScore.ContainsKey(seedNode.Key)) { int totalDisconnection = ClassConnectorSetting.SeedNodeDisconnectScore[seedNode.Key].Item1; long lastDisconnection = ClassConnectorSetting.SeedNodeDisconnectScore[seedNode.Key].Item2; if (lastDisconnection + ClassConnectorSetting.SeedNodeMaxKeepAliveDisconnection < ClassUtils.DateUnixTimeNowSecond()) { totalDisconnection = 0; ClassConnectorSetting.SeedNodeDisconnectScore[seedNode.Key] = new Tuple <int, long>(totalDisconnection, lastDisconnection); } if (totalDisconnection < ClassConnectorSetting.SeedNodeMaxDisconnection) { seedNodeTested = true; int maxRetry = 0; while (maxRetry < ClassConnectorSetting.SeedNodeMaxRetry || success) { _connector = new TcpClient(); var connectTask = _connector.ConnectAsync(seedNode.Key, port); var connectTaskDelay = Task.Delay(ClassConnectorSetting.MaxSeedNodeTimeoutConnect); var completedConnectTask = await Task.WhenAny(connectTask, connectTaskDelay); if (completedConnectTask == connectTask) { #if DEBUG Console.WriteLine("Successfully connected to Seed Node: " + seedNode.Key); #endif success = true; _isConnected = true; _currentSeedNodeHost = seedNode.Key; maxRetry = ClassConnectorSetting.SeedNodeMaxRetry; _connector.SetSocketKeepAliveValues(20 * 60 * 1000, 30 * 1000); await Task.Factory.StartNew(() => EnableCheckConnectionAsync(), CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false); return(true); } else { #if DEBUG Console.WriteLine("Failed to connect to Seed Node: " + seedNode.Key); #endif if (maxRetry >= ClassConnectorSetting.SeedNodeMaxRetry) { ClassConnectorSetting.SeedNodeDisconnectScore[seedNode.Key] = new Tuple <int, long>(totalDisconnection + 1, ClassUtils.DateUnixTimeNowSecond()); } } try { _connector?.Close(); _connector?.Dispose(); } catch { } maxRetry++; } } else { #if DEBUG Console.WriteLine("Max disconnection is reach for seed node: " + seedNode.Key); #endif } } } catch (Exception error) { #if DEBUG Console.WriteLine("Error to connect on seed node: " + error.Message); #endif } } if (!seedNodeTested) // Clean up just in case if every seed node return too much disconnection saved in their counter. { foreach (var seednode in ClassConnectorSetting.SeedNodeIp) { if (ClassConnectorSetting.SeedNodeDisconnectScore.ContainsKey(seednode.Key)) { ClassConnectorSetting.SeedNodeDisconnectScore[seednode.Key] = new Tuple <int, long>(0, 0); } } } } return(false); }