/// <summary> /// Handle get request received from client. /// </summary> /// <param name="packet"></param> /// <returns></returns> private async Task HandlePacketHttpAsync(string packet) { long selectedIndex = 0; string selectedHash = string.Empty; if (packet.Contains("=")) { var splitPacket = packet.Split(new[] { "=" }, StringSplitOptions.None); if (!long.TryParse(splitPacket[1], out selectedIndex)) { selectedHash = splitPacket[1]; // Hash } packet = splitPacket[0]; } switch (packet) { case ClassApiHttpRequestEnumeration.GetCoinName: await BuildAndSendHttpPacketAsync(ClassConnectorSetting.CoinName); break; case ClassApiHttpRequestEnumeration.GetCoinMinName: await BuildAndSendHttpPacketAsync(ClassConnectorSetting.CoinNameMin); break; case ClassApiHttpRequestEnumeration.GetCoinMaxSupply: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CoinMaxSupply); break; case ClassApiHttpRequestEnumeration.GetCoinCirculating: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CoinCirculating); break; case ClassApiHttpRequestEnumeration.GetCoinTotalFee: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentTotalFee); break; case ClassApiHttpRequestEnumeration.GetCoinTotalMined: await BuildAndSendHttpPacketAsync("" + (ClassRemoteNodeSync.ListOfBlock.Count * 10)); break; case ClassApiHttpRequestEnumeration.GetCoinBlockchainHeight: await BuildAndSendHttpPacketAsync("" + (ClassRemoteNodeSync.ListOfBlock.Count + 1)); break; case ClassApiHttpRequestEnumeration.GetCoinTotalBlockMined: await BuildAndSendHttpPacketAsync("" + (ClassRemoteNodeSync.ListOfBlock.Count)); break; case ClassApiHttpRequestEnumeration.GetCoinTotalBlockLeft: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentBlockLeft); break; case ClassApiHttpRequestEnumeration.GetCoinNetworkDifficulty: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentDifficulty); break; case ClassApiHttpRequestEnumeration.GetCoinNetworkHashrate: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentHashrate); break; case ClassApiHttpRequestEnumeration.GetCoinBlockPerId: if (selectedIndex > 0) { selectedIndex -= 1; if (ClassRemoteNodeSync.ListOfBlock.Count - 1 >= selectedIndex) { if (ClassRemoteNodeSync.ListOfBlock.ContainsKey((int)selectedIndex)) { var splitBlock = ClassRemoteNodeSync.ListOfBlock[(int)selectedIndex].Split(new[] { "#" }, StringSplitOptions.None); Dictionary <string, string> blockContent = new Dictionary <string, string> { { "block_id", splitBlock[0] }, { "block_hash", splitBlock[1] }, { "block_transaction_hash", splitBlock[2] }, { "block_timestamp_create", splitBlock[3] }, { "block_timestamp_found", splitBlock[4] }, { "block_difficulty", splitBlock[5] }, { "block_reward", splitBlock[6] } }; await BuildAndSendHttpPacketAsync(null, true, blockContent); blockContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinBlockPerHash: if (selectedHash != string.Empty) { int selectedBlockIndex = ClassRemoteNodeSync.ListOfBlockHash.GetBlockIdFromHash(selectedHash); if (selectedBlockIndex != -1) { var splitBlock = ClassRemoteNodeSync.ListOfBlock[selectedBlockIndex].Split(new[] { "#" }, StringSplitOptions.None); Dictionary <string, string> blockContent = new Dictionary <string, string> { { "block_id", splitBlock[0] }, { "block_hash", splitBlock[1] }, { "block_transaction_hash", splitBlock[2] }, { "block_timestamp_create", splitBlock[3] }, { "block_timestamp_found", splitBlock[4] }, { "block_difficulty", splitBlock[5] }, { "block_reward", splitBlock[6] } }; await BuildAndSendHttpPacketAsync(null, true, blockContent); blockContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinTransactionPerId: if (selectedIndex > 0) { selectedIndex -= 1; if (ClassRemoteNodeSync.ListOfTransaction.Count - 1 >= selectedIndex) { if (ClassRemoteNodeSync.ListOfTransaction.ContainsKey(selectedIndex)) { var splitTransaction = ClassRemoteNodeSync.ListOfTransaction.GetTransaction(selectedIndex).Split(new[] { "-" }, StringSplitOptions.None); Dictionary <string, string> transactionContent = new Dictionary <string, string> { { "transaction_id", "" + (selectedIndex + 1) }, { "transaction_id_sender", splitTransaction[0] }, { "transaction_fake_amount", splitTransaction[1] }, { "transaction_fake_fee", splitTransaction[2] }, { "transaction_id_receiver", splitTransaction[3] }, { "transaction_timestamp_sended", splitTransaction[4] }, { "transaction_hash", splitTransaction[5] }, { "transaction_timestamp_received", splitTransaction[6] } }; await BuildAndSendHttpPacketAsync(null, true, transactionContent); transactionContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinTransactionPerHash: if (selectedHash != string.Empty) { long transactionIndex = ClassRemoteNodeSync.ListOfTransactionHash.ContainsKey(selectedHash); if (transactionIndex != -1) { var splitTransaction = ClassRemoteNodeSync.ListOfTransaction.GetTransaction(transactionIndex).Split(new[] { "-" }, StringSplitOptions.None); Dictionary <string, string> transactionContent = new Dictionary <string, string> { { "transaction_id", "" + (transactionIndex + 1) }, { "transaction_id_sender", splitTransaction[0] }, { "transaction_fake_amount", splitTransaction[1] }, { "transaction_fake_fee", splitTransaction[2] }, { "transaction_id_receiver", splitTransaction[3] }, { "transaction_timestamp_sended", splitTransaction[4] }, { "transaction_hash", splitTransaction[5] }, { "transaction_timestamp_received", splitTransaction[6] } }; await BuildAndSendHttpPacketAsync(null, true, transactionContent); transactionContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinNetworkFullStats: Dictionary <string, string> networkStatsContent = new Dictionary <string, string> { { "coin_name", ClassConnectorSetting.CoinName }, { "coin_min_name", ClassConnectorSetting.CoinNameMin }, { "coin_max_supply", ClassRemoteNodeSync.CoinMaxSupply }, { "coin_circulating", decimal.Parse(ClassRemoteNodeSync.CoinCirculating, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_total_fee", decimal.Parse(ClassRemoteNodeSync.CurrentTotalFee, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_total_mined", (ClassRemoteNodeSync.ListOfBlock.Count * ClassConnectorSetting.ConstantBlockReward).ToString() }, { "coin_blockchain_height", "" + (ClassRemoteNodeSync.ListOfBlock.Count + 1) }, { "coin_total_block_mined", "" + ClassRemoteNodeSync.ListOfBlock.Count }, { "coin_total_block_left", ClassRemoteNodeSync.CurrentBlockLeft }, { "coin_network_difficulty", decimal.Parse(ClassRemoteNodeSync.CurrentDifficulty, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_network_hashrate", decimal.Parse(ClassRemoteNodeSync.CurrentHashrate, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_total_transaction", "" + ClassRemoteNodeSync.ListOfTransaction.Count } }; await BuildAndSendHttpPacketAsync(null, true, networkStatsContent); networkStatsContent.Clear(); break; case ClassApiHttpRequestEnumeration.PacketFavicon: ClassLog.Log("HTTP API - packet received from IP: " + _ip + " - favicon request detected and ignored.", 6, 2); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); break; default: ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); break; } }
private static void CheckBlockchainConnection() { _lastPacketReceivedFromBlockchain = DateTimeOffset.Now.ToUnixTimeSeconds(); var threadCheckConnection = new Thread(async delegate() { while (true) { Thread.Sleep(1000); if (!IsConnected || !classSeedNodeConnector.ReturnStatus()) { if (ThreadListenBlockchain != null && (ThreadListenBlockchain.IsAlive || ThreadListenBlockchain != null)) { ThreadListenBlockchain.Abort(); GC.SuppressFinalize(ThreadListenBlockchain); } if (ThreadAskMiningMethod != null && (ThreadAskMiningMethod.IsAlive || ThreadAskMiningMethod != null)) { ThreadAskMiningMethod.Abort(); GC.SuppressFinalize(ThreadAskMiningMethod); } ClassMiningPoolGlobalStats.CurrentBlockTemplate = string.Empty; ClassMiningPoolGlobalStats.CurrentBlockId = string.Empty; IsConnected = false; LoginAccepted = false; while (!await ConnectToBlockchainAsync()) { ClassLog.ConsoleWriteLog("Can't connect to the network, retry in 5 seconds..", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); Thread.Sleep(5000); } ClassLog.ConsoleWriteLog("Connection success, generate dynamic certificate for the network.", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); Program.Certificate = ClassUtils.GenerateCertificate(); ClassLog.ConsoleWriteLog("Certificate generate, send to the network..", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); if (!await SendPacketToNetworkBlockchain(Program.Certificate, false)) { ClassLog.ConsoleWriteLog("Can't send certificate, reconnect now..", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); IsConnected = false; } else { Thread.Sleep(1000); ClassLog.ConsoleWriteLog("Certificate sent, start to login..", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); ListenBlockchain(); if (!await SendPacketToNetworkBlockchain(ClassConnectorSettingEnumeration.MinerLoginType + "|" + MiningPoolSetting.MiningPoolWalletAddress, true)) { ClassLog.ConsoleWriteLog("Can't login to the network, reconnect now.", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); IsConnected = false; } else { ClassLog.ConsoleWriteLog("Login successfully sent, waiting confirmation.. (Wait 5 seconds maximum.)", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); IsConnected = true; Thread.Sleep(ClassConnectorSetting.MaxTimeoutConnect); if (!LoginAccepted) { IsConnected = false; } } } } } }); threadCheckConnection.Start(); }
/// <summary> /// Start to listen incoming client. /// </summary> /// <returns></returns> public async Task StartHandleClientHttpAsync() { try { _ip = ((IPEndPoint)(_client.Client.RemoteEndPoint)).Address.ToString(); } catch { CloseClientConnection(); return; } var checkBanResult = true; if (_ip != "127.0.0.1") // Do not check localhost ip. { checkBanResult = ClassApiBan.FilterCheckIp(_ip); } int totalWhile = 0; if (checkBanResult) { if (_ip != "127.0.0.1") { ClassApiBan.FilterInsertIp(_ip); } try { while (_clientStatus) { try { byte[] buffer = new byte[ClassConnectorSetting.MaxNetworkPacketSize]; using (NetworkStream clientHttpReader = new NetworkStream(_client.Client)) { using (var bufferedStreamNetwork = new BufferedStream(clientHttpReader, ClassConnectorSetting.MaxNetworkPacketSize)) { int received = await bufferedStreamNetwork.ReadAsync(buffer, 0, buffer.Length); if (received > 0) { string packet = Encoding.UTF8.GetString(buffer, 0, received); try { if (!GetAndCheckForwardedIp(packet)) { break; } } catch { } packet = ClassUtilsNode.GetStringBetween(packet, "GET", "HTTP"); packet = packet.Replace("/", ""); packet = packet.Replace(" ", ""); ClassLog.Log("HTTP API - packet received from IP: " + _ip + " - " + packet, 6, 2); await HandlePacketHttpAsync(packet); break; } else { totalWhile++; } if (totalWhile >= 8) { break; } } } } catch { break; } } } catch { } CloseClientConnection(); } }
/// <summary> /// Handle packet received from the network. /// </summary> /// <param name="packet"></param> private static async Task HandlePacketNetworkAsync(string packet) { packet = packet.Replace("*", ""); var packetSplit = packet.Split(new[] { "|" }, StringSplitOptions.None); switch (packetSplit[0]) { case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendLoginAccepted: LoginAccepted = true; ClassLog.ConsoleWriteLog("Mining pool logged successfully to the blockchain network.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); AskMiningMethod(); break; case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendListBlockMethod: var methodList = packetSplit[1]; if (methodList.Contains("#")) { var splitMethodList = methodList.Split(new[] { "#" }, StringSplitOptions.None); if (ListOfMiningMethodName.Count > 1) { foreach (var methodName in splitMethodList) { if (!string.IsNullOrEmpty(methodName)) { if (ListOfMiningMethodName.Contains(methodName) == false) { ListOfMiningMethodName.Add(methodName); } if (!await SendPacketToNetworkBlockchain(ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ReceiveAskContentBlockMethod + "|" + methodName, true).ConfigureAwait(false)) { IsConnected = false; break; } await Task.Delay(1000); } } } else { foreach (var methodName in splitMethodList) { if (!string.IsNullOrEmpty(methodName)) { if (ListOfMiningMethodName.Contains(methodName) == false) { ListOfMiningMethodName.Add(methodName); } if (!await SendPacketToNetworkBlockchain(ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ReceiveAskContentBlockMethod + "|" + methodName, true).ConfigureAwait(false)) { IsConnected = false; break; } await Task.Delay(1000); } } } } else { if (ListOfMiningMethodName.Contains(methodList) == false) { ListOfMiningMethodName.Add(methodList); } if (!await SendPacketToNetworkBlockchain(ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ReceiveAskContentBlockMethod + "|" + methodList, true).ConfigureAwait(false)) { IsConnected = false; } } break; case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendContentBlockMethod: if (ListOfMiningMethodContent.Count == 0) { ListOfMiningMethodContent.Add(packetSplit[1]); } else { ListOfMiningMethodContent[0] = packetSplit[1]; } break; case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendCurrentBlockMining: if (packetSplit[1] != ClassMiningPoolGlobalStats.CurrentBlockTemplate) { var splitBlockContent = packetSplit[1].Split(new[] { "&" }, StringSplitOptions.None); if (splitBlockContent[0].Replace("ID=", "") != "" && splitBlockContent[0].Replace("ID=", "").Length > 0) { if (splitBlockContent[0].Replace("ID=", "") != ClassMiningPoolGlobalStats.CurrentBlockId) { ClassMiningPoolGlobalStats.CurrentBlockId = splitBlockContent[0].Replace("ID=", ""); ClassMiningPoolGlobalStats.CurrentBlockHash = splitBlockContent[1].Replace("HASH=", ""); ClassMiningPoolGlobalStats.CurrentBlockAlgorithm = splitBlockContent[2].Replace("ALGORITHM=", ""); ClassMiningPoolGlobalStats.CurrentBlockSize = splitBlockContent[3].Replace("SIZE=", ""); ClassMiningPoolGlobalStats.CurrentBlockMethod = splitBlockContent[4].Replace("METHOD=", ""); ClassMiningPoolGlobalStats.CurrentBlockKey = splitBlockContent[5].Replace("KEY=", ""); ClassMiningPoolGlobalStats.CurrentBlockJob = splitBlockContent[6].Replace("JOB=", ""); ClassMiningPoolGlobalStats.CurrentBlockJobMinRange = decimal.Parse(ClassMiningPoolGlobalStats.CurrentBlockJob.Split(new[] { ";" }, StringSplitOptions.None)[0]); ClassMiningPoolGlobalStats.CurrentBlockJobMaxRange = decimal.Parse(ClassMiningPoolGlobalStats.CurrentBlockJob.Split(new[] { ";" }, StringSplitOptions.None)[1]); ClassMiningPoolGlobalStats.CurrentBlockReward = splitBlockContent[7].Replace("REWARD=", ""); ClassMiningPoolGlobalStats.CurrentBlockDifficulty = splitBlockContent[8].Replace("DIFFICULTY=", ""); ClassMiningPoolGlobalStats.CurrentBlockTimestampCreate = splitBlockContent[9].Replace("TIMESTAMP=", ""); ClassMiningPoolGlobalStats.CurrentBlockIndication = splitBlockContent[10].Replace("INDICATION=", ""); ClassMiningPoolGlobalStats.CurrentBlockTemplate = packetSplit[1]; int idMethod = 0; if (ListOfMiningMethodName.Count > 0) { for (int i = 0; i < ListOfMiningMethodName.Count; i++) { if (i < ListOfMiningMethodName.Count) { if (ListOfMiningMethodName[i] == ClassMiningPoolGlobalStats.CurrentBlockMethod) { idMethod = i; } } } } var splitMethod = ListOfMiningMethodContent[idMethod].Split(new[] { "#" }, StringSplitOptions.None); ClassMiningPoolGlobalStats.CurrentRoundAesRound = int.Parse(splitMethod[0]); ClassMiningPoolGlobalStats.CurrentRoundAesSize = int.Parse(splitMethod[1]); ClassMiningPoolGlobalStats.CurrentRoundAesKey = splitMethod[2]; ClassMiningPoolGlobalStats.CurrentRoundXorKey = int.Parse(splitMethod[3]); if (ClassMinerStats.DictionaryMinerStats.Count > 0) { foreach (var miner in ClassMinerStats.DictionaryMinerStats) { if (miner.Value.ListOfMinerTcpObject.Count > 0) { for (int i = 0; i < miner.Value.ListOfMinerTcpObject.Count; i++) { if (i < miner.Value.ListOfMinerTcpObject.Count) { if (miner.Value.ListOfMinerTcpObject[i] != null) { if (miner.Value.ListOfMinerTcpObject[i].IsLogged) { miner.Value.ListOfMinerTcpObject[i].MiningPoolSendJobAsync(miner.Value.ListOfMinerTcpObject[i].CurrentMiningJobDifficulty); } } } } } } } ClassLog.ConsoleWriteLog("New block to mining id: " + ClassMiningPoolGlobalStats.CurrentBlockId + " difficulty: " + ClassMiningPoolGlobalStats.CurrentBlockDifficulty + " hash: " + ClassMiningPoolGlobalStats.CurrentBlockHash, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleBlueLog, true); ClassLog.ConsoleWriteLog("Current Mining Method: " + ClassMiningPoolGlobalStats.CurrentBlockMethod + " = AES ROUND: " + ClassMiningPoolGlobalStats.CurrentRoundAesRound + " AES SIZE: " + ClassMiningPoolGlobalStats.CurrentRoundAesSize + " AES BYTE KEY: " + ClassMiningPoolGlobalStats.CurrentRoundAesKey + " XOR KEY: " + ClassMiningPoolGlobalStats.CurrentRoundXorKey, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleBlueLog, true); } else { if (splitBlockContent[1].Replace("HASH=", "") != ClassMiningPoolGlobalStats.CurrentBlockHash) { ClassMiningPoolGlobalStats.CurrentBlockId = splitBlockContent[0].Replace("ID=", ""); ClassMiningPoolGlobalStats.CurrentBlockHash = splitBlockContent[1].Replace("HASH=", ""); ClassMiningPoolGlobalStats.CurrentBlockAlgorithm = splitBlockContent[2].Replace("ALGORITHM=", ""); ClassMiningPoolGlobalStats.CurrentBlockSize = splitBlockContent[3].Replace("SIZE=", ""); ClassMiningPoolGlobalStats.CurrentBlockMethod = splitBlockContent[4].Replace("METHOD=", ""); ClassMiningPoolGlobalStats.CurrentBlockKey = splitBlockContent[5].Replace("KEY=", ""); ClassMiningPoolGlobalStats.CurrentBlockJob = splitBlockContent[6].Replace("JOB=", ""); ClassMiningPoolGlobalStats.CurrentBlockJobMinRange = decimal.Parse(ClassMiningPoolGlobalStats.CurrentBlockJob.Split(new[] { ";" }, StringSplitOptions.None)[0]); ClassMiningPoolGlobalStats.CurrentBlockJobMaxRange = decimal.Parse(ClassMiningPoolGlobalStats.CurrentBlockJob.Split(new[] { ";" }, StringSplitOptions.None)[1]); ClassMiningPoolGlobalStats.CurrentBlockReward = splitBlockContent[7].Replace("REWARD=", ""); ClassMiningPoolGlobalStats.CurrentBlockDifficulty = splitBlockContent[8].Replace("DIFFICULTY=", ""); ClassMiningPoolGlobalStats.CurrentBlockTimestampCreate = splitBlockContent[9].Replace("TIMESTAMP=", ""); ClassMiningPoolGlobalStats.CurrentBlockIndication = splitBlockContent[10].Replace("INDICATION=", ""); ClassMiningPoolGlobalStats.CurrentBlockTemplate = packetSplit[1]; int idMethod = 0; if (ListOfMiningMethodName.Count > 0) { for (int i = 0; i < ListOfMiningMethodName.Count; i++) { if (i < ListOfMiningMethodName.Count) { if (ListOfMiningMethodName[i] == ClassMiningPoolGlobalStats.CurrentBlockMethod) { idMethod = i; } } } } var splitMethod = ListOfMiningMethodContent[idMethod].Split(new[] { "#" }, StringSplitOptions.None); ClassMiningPoolGlobalStats.CurrentRoundAesRound = int.Parse(splitMethod[0]); ClassMiningPoolGlobalStats.CurrentRoundAesSize = int.Parse(splitMethod[1]); ClassMiningPoolGlobalStats.CurrentRoundAesKey = splitMethod[2]; ClassMiningPoolGlobalStats.CurrentRoundXorKey = int.Parse(splitMethod[3]); if (ClassMinerStats.DictionaryMinerStats.Count > 0) { foreach (var miner in ClassMinerStats.DictionaryMinerStats) { if (miner.Value.ListOfMinerTcpObject.Count > 0) { for (int i = 0; i < miner.Value.ListOfMinerTcpObject.Count; i++) { if (i < miner.Value.ListOfMinerTcpObject.Count) { if (miner.Value.ListOfMinerTcpObject[i] != null) { if (miner.Value.ListOfMinerTcpObject[i].IsLogged) { miner.Value.ListOfMinerTcpObject[i].MiningPoolSendJobAsync(miner.Value.ListOfMinerTcpObject[i].CurrentMiningJobDifficulty); } } } } } } } ClassLog.ConsoleWriteLog("Renewed block to mining id: " + ClassMiningPoolGlobalStats.CurrentBlockId + " difficulty: " + ClassMiningPoolGlobalStats.CurrentBlockDifficulty + " hash: " + ClassMiningPoolGlobalStats.CurrentBlockHash, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleBlueLog, true); ClassLog.ConsoleWriteLog("Current Mining Method: " + ClassMiningPoolGlobalStats.CurrentBlockMethod + " = AES ROUND: " + ClassMiningPoolGlobalStats.CurrentRoundAesRound + " AES SIZE: " + ClassMiningPoolGlobalStats.CurrentRoundAesSize + " AES BYTE KEY: " + ClassMiningPoolGlobalStats.CurrentRoundAesKey + " XOR KEY: " + ClassMiningPoolGlobalStats.CurrentRoundXorKey, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleBlueLog, true); } } } } break; case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendJobStatus: switch (packetSplit[1]) { case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.ShareUnlock: ClassLog.ConsoleWriteLog("Block ID: " + packetSplit[2] + " has been successfully found and accepted by Blockchain !", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); ClassMiningPoolGlobalStats.ListBlockFound.Add(ClassMiningPoolGlobalStats.ListBlockFound.Count, int.Parse(packetSplit[2]) + "|" + ClassUtility.GetCurrentDateInSecond()); await Task.Factory.StartNew(() => ClassPayment.ProceedMiningScoreRewardAsync(packetSplit[2]), CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Current).ConfigureAwait(false); break; case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.ShareBad: ClassLog.ConsoleWriteLog("Block ID: " + packetSplit[2] + " has been found by someone else before the pool or the share sent is invalid.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); break; case ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.ShareAleady: ClassLog.ConsoleWriteLog("Block ID: " + packetSplit[2] + " is already found by someone else.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); break; } break; } }
static void Main(string[] args) { EnableCatchUnexpectedException(); Console.CancelKeyPress += Console_CancelKeyPress; Thread.CurrentThread.Name = Path.GetFileName(Environment.GetCommandLineArgs()[0]); GlobalCultureInfo = new CultureInfo("fr-FR"); ClassLog.LogInitialization(); ServicePointManager.DefaultConnectionLimit = 65535; ClassConsole.ConsoleWriteLine(ClassConnectorSetting.CoinName + " RPC Wallet - " + Assembly.GetExecutingAssembly().GetName().Version + "R", ClassConsoleColorEnumeration.IndexConsoleBlueLog, LogLevel); if (ClassRpcSetting.InitializeRpcWalletSetting()) { ClassConsole.ConsoleWriteLine("Please write your rpc wallet password for decrypt your databases of wallet (Input keys are hidden): ", ClassConsoleColorEnumeration.IndexConsoleYellowLog, LogLevel); ClassRpcDatabase.SetRpcDatabasePassword(ClassUtility.GetHiddenConsoleInput()); ClassConsole.ConsoleWriteLine("RPC Wallet Database loading..", ClassConsoleColorEnumeration.IndexConsoleYellowLog, LogLevel); if (ClassRpcDatabase.LoadRpcDatabaseFile()) { ClassConsole.ConsoleWriteLine("RPC Wallet Database successfully loaded.", ClassConsoleColorEnumeration.IndexConsoleGreenLog, LogLevel); ClassConsole.ConsoleWriteLine("RPC Sync Database loading..", ClassConsoleColorEnumeration.IndexConsoleYellowLog, LogLevel); if (ClassSyncDatabase.InitializeSyncDatabase()) { ClassConsole.ConsoleWriteLine("RPC Sync Database successfully loaded.", ClassConsoleColorEnumeration.IndexConsoleGreenLog, LogLevel); if (ClassRpcSetting.WalletEnableAutoUpdateWallet) { ClassConsole.ConsoleWriteLine("Enable Auto Update Wallet System..", ClassConsoleColorEnumeration.IndexConsoleYellowLog, LogLevel); ClassWalletUpdater.EnableAutoUpdateWallet(); ClassConsole.ConsoleWriteLine("Enable Auto Update Wallet System done.", ClassConsoleColorEnumeration.IndexConsoleGreenLog, LogLevel); } ClassConsole.ConsoleWriteLine("Start RPC Wallet API Server..", ClassConsoleColorEnumeration.IndexConsoleYellowLog, LogLevel); ClassApi.StartApiHttpServer(); ClassConsole.ConsoleWriteLine("Start RPC Wallet API Server sucessfully started.", ClassConsoleColorEnumeration.IndexConsoleGreenLog, LogLevel); if (ClassRpcSetting.RpcWalletEnableRemoteNodeSync && ClassRpcSetting.RpcWalletRemoteNodeHost != string.Empty && ClassRpcSetting.RpcWalletRemoteNodePort != 0) { ClassConsole.ConsoleWriteLine("RPC Remote Node Sync system loading..", ClassConsoleColorEnumeration.IndexConsoleYellowLog, LogLevel); ThreadRemoteNodeSync = new Thread(async() => await ClassRemoteSync.ConnectRpcWalletToRemoteNodeSyncAsync()); ThreadRemoteNodeSync.Start(); } ClassConsole.ConsoleWriteLine("Enable Command Line system.", ClassConsoleColorEnumeration.IndexConsoleGreenLog, LogLevel); ClassConsoleCommandLine.EnableConsoleCommandLine(); } else { ClassConsole.ConsoleWriteLine("Cannot read RPC Sync Database, the database is maybe corrupted.", ClassConsoleColorEnumeration.IndexConsoleRedLog, LogLevel); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); Environment.Exit(0); } } else { ClassConsole.ConsoleWriteLine("Cannot read RPC Wallet Database, the database is maybe corrupted.", ClassConsoleColorEnumeration.IndexConsoleRedLog, LogLevel); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); Environment.Exit(0); } } else { ClassConsole.ConsoleWriteLine("Cannot read RPC Wallet setting, the setting is maybe corrupted, you can delete your setting file to build another one.", ClassConsoleColorEnumeration.IndexConsoleRedLog, LogLevel); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); Environment.Exit(0); } }
public static bool CommandLine(string command) { var splitCommand = command.Split(new char[0], StringSplitOptions.None); try { switch (splitCommand[0]) { case ClassCommandLineEnumeration.CommandLineHelp: Console.WriteLine("Command list: "); Console.WriteLine(ClassCommandLineEnumeration.CommandLineStatus + " -> Get Network status of your node"); Console.WriteLine(ClassCommandLineEnumeration.CommandLineTransaction + " -> Get the number of transaction(s) sync."); Console.WriteLine(ClassCommandLineEnumeration.CommandLineBlock + " -> Get the number of block(s) sync."); Console.WriteLine(ClassCommandLineEnumeration.CommandLineLog + " -> Can set level of log to show: (default) log 0 max level 4"); Console.WriteLine(ClassCommandLineEnumeration.CommandLineClearSync + " -> Clear the sync of the remote node."); Console.WriteLine(ClassCommandLineEnumeration.CommandLineFilterList + " -> show every incoming connections ip's and their status."); Console.WriteLine(ClassCommandLineEnumeration.CommandLineBanList + " -> show every incoming connections ip's banned."); Console.WriteLine(ClassCommandLineEnumeration.CommandLineSave + " -> Save sync."); Console.WriteLine(ClassCommandLineEnumeration.CommandLineExit + " -> Save sync and Exit the node."); break; case ClassCommandLineEnumeration.CommandLineStatus: Console.WriteLine("Total Transaction Sync: " + (ClassRemoteNodeSync.ListOfTransaction.Count)); Console.WriteLine("Total Transaction in the Blockchain: " + ClassRemoteNodeSync.TotalTransaction); long totalTransactionSortedPerWallet = ClassRemoteNodeSync.ListTransactionPerWallet.Count; Console.WriteLine("Total Transaction Sorted for Wallet(s): " + totalTransactionSortedPerWallet); Console.WriteLine("Total Block(s) Sync: " + (ClassRemoteNodeSync.ListOfBlock.Count)); Console.WriteLine("Total Block(s) mined in the Blockchain: " + ClassRemoteNodeSync.TotalBlockMined); Console.WriteLine("Total Block(s) left to mining: " + ClassRemoteNodeSync.CurrentBlockLeft); Console.WriteLine("Total pending transaction in the network: " + ClassRemoteNodeSync.TotalPendingTransaction); Console.WriteLine("Total Fee in the network: " + ClassRemoteNodeSync.CurrentTotalFee, Program.GlobalCultureInfo); Console.WriteLine("Current Mining Difficulty: " + ClassRemoteNodeSync.CurrentDifficulty); if (ClassRemoteNodeSync.CurrentHashrate != null) { Console.WriteLine("Current Mining Hashrate: " + ClassUtils.GetTranslateHashrate(ClassRemoteNodeSync.CurrentHashrate.Replace(".", ","), 2).Replace(",", "."), Program.GlobalCultureInfo); } Console.WriteLine("Total Coin Max Supply: " + ClassRemoteNodeSync.CoinMaxSupply, Program.GlobalCultureInfo); Console.WriteLine("Total Coin Circulating: " + ClassRemoteNodeSync.CoinCirculating, Program.GlobalCultureInfo); if (ClassRemoteNodeSync.WantToBePublicNode) { string publicNodes = string.Empty; for (int i = 0; i < ClassRemoteNodeSync.ListOfPublicNodes.Count; i++) { if (i < ClassRemoteNodeSync.ListOfPublicNodes.Count) { publicNodes += ClassRemoteNodeSync.ListOfPublicNodes[i] + " "; } } Console.WriteLine("List of Public Remote Node: " + publicNodes); string status = "NOT LISTED"; if (ClassRemoteNodeSync.ImPublicNode) { status = "LISTED"; } Console.WriteLine("Public Status of the Remote Node: " + status); } Console.WriteLine("Trusted Key: " + ClassRemoteNodeSync.TrustedKey); Console.WriteLine("Hash Transaction Key: " + ClassRemoteNodeSync.HashTransactionList); Console.WriteLine("Hash Block Key: " + ClassRemoteNodeSync.HashBlockList); break; case ClassCommandLineEnumeration.CommandLineTransaction: Console.WriteLine("Total Transaction Sync: " + (ClassRemoteNodeSync.ListOfTransaction.Count)); Console.WriteLine("Total Transaction in the Blockchain: " + ClassRemoteNodeSync.TotalTransaction); break; case ClassCommandLineEnumeration.CommandLineBlock: Console.WriteLine("Total Block(s) Sync: " + (ClassRemoteNodeSync.ListOfBlock.Count)); Console.WriteLine("Total Block(s) mined in the Blockchain: " + ClassRemoteNodeSync.TotalBlockMined); Console.WriteLine("Total Block(s) left to mining: " + ClassRemoteNodeSync.CurrentBlockLeft); break; case ClassCommandLineEnumeration.CommandLineLog: if (!string.IsNullOrEmpty(splitCommand[1])) { if (int.TryParse(splitCommand[1], out var logLevel)) { if (logLevel < 0) { logLevel = 0; } if (logLevel > 7) { logLevel = 7; } Console.WriteLine("Log Level " + Program.LogLevel + " -> " + logLevel); Program.LogLevel = logLevel; } else { Console.WriteLine("Wrong argument: " + splitCommand[1] + " should be a number."); } } else { Console.WriteLine("Empty/Missing argument."); } break; case ClassCommandLineEnumeration.CommandLineClearSync: if (Program.RemoteNodeObjectTransaction.RemoteNodeObjectInSyncTransaction || Program.RemoteNodeObjectBlock.RemoteNodeObjectInSyncBlock) { Console.WriteLine("Cannot clean remote node sync, your remote node is currently on sync."); Console.WriteLine("If you absolutly want to clear your sync, close the remote node, remove the Blockchain folder and restart."); } else { ClassRemoteNodeSync.ListOfTransaction.Clear(); ClassRemoteNodeSync.ListOfTransactionHash.Clear(); ClassRemoteNodeSync.ListTransactionPerWallet.Clear(); ClassRemoteNodeSync.ListOfBlock.Clear(); ClassRemoteNodeSync.ListOfBlockHash.Clear(); ClassRemoteNodeSave.ClearBlockSyncSave(); ClassRemoteNodeSave.ClearTransactionSyncSave(); ClassRemoteNodeKey.DataBlockRead = string.Empty; ClassRemoteNodeKey.DataTransactionRead = string.Empty; ClassRemoteNodeSave.TotalBlockSaved = 0; ClassRemoteNodeSave.TotalTransactionSaved = 0; ClassRemoteNodeSave.DataTransactionSaved = string.Empty; ClassRemoteNodeSave.DataBlockSaved = string.Empty; Console.WriteLine("Clear finish, restart sync.."); ClassRemoteNodeKey.StartUpdateHashTransactionList(); ClassRemoteNodeKey.StartUpdateHashBlockList(); ClassRemoteNodeKey.StartUpdateTrustedKey(); } break; case ClassCommandLineEnumeration.CommandLineFilterList: if (ClassApiBan.ListFilterObjects.Count > 0) { foreach (var objectBan in ClassApiBan.ListFilterObjects) { if (objectBan.Value.Banned) { long banDelay = objectBan.Value.LastBanDate - DateTimeOffset.Now.ToUnixTimeSeconds(); Console.WriteLine("IP: " + objectBan.Value.Ip + " Total Invalid Packet:" + objectBan.Value.TotalInvalidPacket + " banned pending: " + banDelay + " second(s)."); } else { Console.WriteLine("IP: " + objectBan.Value.Ip + " Total Invalid Packet:" + objectBan.Value.TotalInvalidPacket + " not banned."); } } } else { Console.WriteLine("Their is any incoming ip on the list."); } break; case ClassCommandLineEnumeration.CommandLineBanList: if (ClassApiBan.ListFilterObjects.Count > 0) { foreach (var objectBan in ClassApiBan.ListFilterObjects) { if (objectBan.Value.Banned) { long banDelay = objectBan.Value.LastBanDate - DateTimeOffset.Now.ToUnixTimeSeconds(); Console.WriteLine("IP: " + objectBan.Value.Ip + " Total Invalid Packet:" + objectBan.Value.TotalInvalidPacket + " banned pending: " + banDelay + " second(s)."); } } } else { Console.WriteLine("Their is any incoming ip on the list."); } break; case ClassCommandLineEnumeration.CommandLineSave: Console.WriteLine("Stop auto save system. Start manual save sync.."); while (ClassRemoteNodeSave.InSaveTransactionDatabase) { Thread.Sleep(1000); } ClassRemoteNodeSave.TotalTransactionSaved = 0; ClassRemoteNodeSave.DataTransactionSaved = string.Empty; ClassRemoteNodeSave.SaveTransaction(false); while (ClassRemoteNodeSave.InSaveBlockDatabase) { Thread.Sleep(1000); } ClassRemoteNodeSave.TotalBlockSaved = 0; ClassRemoteNodeSave.DataBlockSaved = string.Empty; ClassRemoteNodeSave.SaveBlock(false); Console.WriteLine("Sync saved."); Console.WriteLine("Restart auto save system."); ClassRemoteNodeSave.SaveTransaction(); ClassRemoteNodeSave.SaveBlock(); break; case ClassCommandLineEnumeration.CommandLineExit: Program.Closed = true; Console.WriteLine("Disable auto reconnect remote node.."); ClassCheckRemoteNodeSync.DisableCheckRemoteNodeSync(); Thread.Sleep(1000); Console.WriteLine("Stop each connection of the remote node."); Program.RemoteNodeObjectBlock.StopConnection(); Program.RemoteNodeObjectTransaction.StopConnection(); Program.RemoteNodeObjectTotalTransaction.StopConnection(); Program.RemoteNodeObjectCoinCirculating.StopConnection(); Program.RemoteNodeObjectCoinMaxSupply.StopConnection(); Program.RemoteNodeObjectCurrentDifficulty.StopConnection(); Program.RemoteNodeObjectCurrentRate.StopConnection(); Program.RemoteNodeObjectTotalBlockMined.StopConnection(); Program.RemoteNodeObjectTotalFee.StopConnection(); Program.RemoteNodeObjectTotalPendingTransaction.StopConnection(); ClassLog.StopWriteLog(); Thread.Sleep(1000); Console.WriteLine("Stop api.."); ClassApi.StopApi(); Console.WriteLine("Starting save sync.."); while (ClassRemoteNodeSave.InSaveTransactionDatabase) { Thread.Sleep(1000); } ClassRemoteNodeSave.TotalTransactionSaved = 0; ClassRemoteNodeSave.DataTransactionSaved = string.Empty; ClassRemoteNodeSave.SaveTransaction(false); while (ClassRemoteNodeSave.InSaveBlockDatabase) { Thread.Sleep(1000); } ClassRemoteNodeSave.TotalBlockSaved = 0; ClassRemoteNodeSave.DataBlockSaved = string.Empty; ClassRemoteNodeSave.SaveBlock(false); Console.WriteLine("Sync saved."); Process.GetCurrentProcess().Kill(); return(false); } } catch (Exception error) { Console.WriteLine("Command line error: " + error.Message); } return(true); }
/// <summary> /// Handle get request received from client. /// </summary> /// <param name="packet"></param> /// <returns></returns> private async Task HandlePacketHttpAsync(string packet) { if (packet.Contains("|")) { var splitPacket = packet.Split(new[] { "|" }, StringSplitOptions.None); switch (splitPacket[0]) { case ClassApiEnumeration.GetPoolPaymentById: if (int.TryParse(splitPacket[1], out var paymentId)) { if (paymentId > 0) { paymentId--; } if (ClassMinerStats.DictionaryPoolTransaction.ContainsKey(paymentId)) { var payment = ClassMinerStats.DictionaryPoolTransaction[paymentId].Split(new[] { "|" }, StringSplitOptions.None); string hash = payment[0]; string amount = payment[1]; string fee = payment[2]; string timeSent = payment[3]; Dictionary <string, string> paymentContent = new Dictionary <string, string>() { { "payment_id", splitPacket[1] }, { "payment_hash", hash }, { "payment_amount", ClassUtility.FormatMaxDecimalPlace(amount) }, { "payment_fee", ClassUtility.FormatMaxDecimalPlace(fee) }, { "payment_date_sent", timeSent } }; await BuildAndSendHttpPacketAsync(string.Empty, true, paymentContent); break; } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.IndexNotExist); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } break; case ClassApiEnumeration.GetPoolBlockById: if (int.TryParse(splitPacket[1], out var blockId)) { if (blockId > 0) { blockId--; } if (ClassMiningPoolGlobalStats.ListBlockFound.ContainsKey(blockId)) { var blockFound = ClassMiningPoolGlobalStats.ListBlockFound[blockId]; var splitBlock = blockFound.Split(new[] { "|" }, StringSplitOptions.None); var blockResult = await ClassRemoteApi.GetBlockInformation(splitBlock[0]); if (blockResult != null) { try { JObject jObjectBlock = JObject.Parse(blockResult); if (jObjectBlock.ContainsKey("result")) // Usually showed has not exist when the remote node don't have finish to sync blocks mined. { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.IndexNotExist); } else { await BuildAndSendHttpPacketAsync(blockResult, false, null, true); // Send already jsonfyed request. } } catch (Exception error) { ClassLog.ConsoleWriteLog("Pool API - Remote Node HTTP API packet exception: " + error.Message + " packet received: " + blockResult, ClassLogEnumeration.IndexPoolApiErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog); await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } } else { ClassLog.ConsoleWriteLog("Pool API - Warning, your Remote Node HTTP API seems to not respond !", ClassLogEnumeration.IndexPoolApiErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } break; } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.IndexNotExist); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } break; case ClassApiEnumeration.GetWalletPaymentById: if (splitPacket.Length > 1) { if (ClassMinerStats.DictionaryMinerStats.ContainsKey(splitPacket[1])) { if (ClassMinerStats.DictionaryMinerTransaction.ContainsKey(splitPacket[1])) { if (int.TryParse(splitPacket[2], out var walletPaymentId)) { if (walletPaymentId > 0) { walletPaymentId--; } if (ClassMinerStats.DictionaryMinerTransaction[splitPacket[1]].Count > walletPaymentId) { var paymentSplit = ClassMinerStats.DictionaryMinerTransaction[splitPacket[1]][walletPaymentId].Split(new[] { "|" }, StringSplitOptions.None); string transactionHash = paymentSplit[0]; string transactionAmount = paymentSplit[1]; string transactionFee = paymentSplit[2]; string transactionDateSent = paymentSplit[3]; Dictionary <string, string> paymentContent = new Dictionary <string, string>() { { "payment_hash", transactionHash }, { "payment_amount", ClassUtility.FormatMaxDecimalPlace(transactionAmount) }, { "payment_fee", ClassUtility.FormatMaxDecimalPlace(transactionFee) }, { "payment_date_sent", transactionDateSent } }; await BuildAndSendHttpPacketAsync(string.Empty, true, paymentContent); } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.WalletPaymentIndexNotExist); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.WalletNoPaymentExist); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.WalletNotExist); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } break; case ClassApiEnumeration.GetWalletStats: if (splitPacket.Length > 1) { if (ClassMinerStats.DictionaryMinerStats.ContainsKey(splitPacket[1])) { int totalPayment = 0; long totalGoodShare = 0; float totalInvalidShare = 0; string totalBalance = "0"; string totalPaid = "0"; decimal totalHashrate = 0; decimal totalMiningScore = 0; decimal totalMiningScorePool = 0; decimal customMinimumPayment = 0; long lastShareReceived = 0; if (ClassMinerStats.DictionaryMinerTransaction.ContainsKey(splitPacket[1])) { totalPayment = ClassMinerStats.DictionaryMinerTransaction[splitPacket[1]].Count; } totalGoodShare = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].TotalGoodShare; totalInvalidShare = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].TotalInvalidShare; totalBalance = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].TotalBalance.ToString("F" + ClassConnectorSetting.MaxDecimalPlace); totalPaid = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].TotalPaid.ToString("F" + ClassConnectorSetting.MaxDecimalPlace); totalHashrate = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].CurrentTotalHashrate; totalMiningScore = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].TotalMiningScore; customMinimumPayment = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].CustomMinimumPayment; lastShareReceived = ClassMinerStats.DictionaryMinerStats[splitPacket[1]].DateOfLastGoodShare; foreach (var minerStats in ClassMinerStats.DictionaryMinerStats) { if (minerStats.Value.TotalBan <= MiningPoolSetting.MiningPoolMaxTotalBanMiner) { if (minerStats.Value.TotalMiningScore > 0) { totalMiningScorePool += minerStats.Value.TotalMiningScore; } } } Dictionary <string, string> minerStatsContent = new Dictionary <string, string>() { { "wallet_address", splitPacket[1] }, { "wallet_total_hashrate", "" + totalHashrate }, { "wallet_total_good_share", "" + totalGoodShare }, { "wallet_total_invalid_share", "" + totalInvalidShare }, { "wallet_total_balance", totalBalance }, { "wallet_total_paid", totalPaid }, { "wallet_total_payment", "" + totalPayment }, { "wallet_total_mining_score", totalMiningScore.ToString("F0") }, { "wallet_total_pool_mining_score", totalMiningScorePool.ToString("F0") }, { "wallet_custom_minimum_payment", "" + customMinimumPayment }, { "wallet_last_share_received", "" + lastShareReceived } }; await BuildAndSendHttpPacketAsync(string.Empty, true, minerStatsContent); break; } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.WalletNotExist); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } break; case ClassApiEnumeration.SetWalletCustomMinimumPayment: if (splitPacket.Length > 2) { if (ClassMinerStats.DictionaryMinerStats.ContainsKey(splitPacket[1])) { var customMinimumPaymentString = ClassUtility.FormatMaxDecimalPlace(splitPacket[2].Replace(".", ",")).Replace(".", ","); if (decimal.TryParse(customMinimumPaymentString, NumberStyles.Currency, Program.GlobalCultureInfo, out var customMinimumPayment)) { if (customMinimumPayment >= MiningPoolSetting.MiningPoolMinimumBalancePayment) { ClassMinerStats.DictionaryMinerStats[splitPacket[1]].CustomMinimumPayment = customMinimumPayment; await BuildAndSendHttpPacketAsync(ClassApiEnumeration.CustomMinimumPaymentChanged); } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.CustomMinimumPaymentTooLowest); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.CustomMinimumPaymentNotValid); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.WalletNotExist); } } else { await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } break; default: await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketNotExist); break; } } else { switch (packet) { case ClassApiEnumeration.GetPoolStats: decimal networkHashrate = 0; string networkInformation = await ClassRemoteApi.GetNetworkInformation(); if (networkInformation != null) { var networkInformationObject = JObject.Parse(networkInformation); networkHashrate = decimal.Parse(networkInformationObject["coin_network_hashrate"].ToString()); string lastBlockFoundDate = "0"; if (ClassMiningPoolGlobalStats.ListBlockFound.Count > 0) { lastBlockFoundDate = ClassMiningPoolGlobalStats.ListBlockFound[ClassMiningPoolGlobalStats.ListBlockFound.Count - 1].Split(new[] { "|" }, StringSplitOptions.None)[1]; } var lastBlockFound = int.Parse(ClassMiningPoolGlobalStats.CurrentBlockId) - 1; string blockHash = string.Empty; string blockTimestampFound = "0"; string blockReward = "0"; if (ClassApi.DictionaryBlockHashCache.ContainsKey(lastBlockFound)) { blockHash = ClassApi.DictionaryBlockHashCache[lastBlockFound]; blockTimestampFound = ClassApi.DictionaryBlockDateFoundCache[lastBlockFound]; blockReward = ClassApi.DictionaryBlockRewardCache[lastBlockFound]; } else { var blockResult = await ClassRemoteApi.GetBlockInformation("" + lastBlockFound); if (blockResult != null) { JObject blockJson = JObject.Parse(blockResult); blockHash = blockJson["block_hash"].ToString(); blockTimestampFound = blockJson["block_timestamp_found"].ToString(); blockReward = blockJson["block_reward"].ToString(); try { ClassApi.DictionaryBlockHashCache.Add(lastBlockFound, blockHash); } catch { } try { ClassApi.DictionaryBlockDateFoundCache.Add(lastBlockFound, blockTimestampFound); } catch { } try { ClassApi.DictionaryBlockRewardCache.Add(lastBlockFound, blockReward); } catch { } } else { ClassLog.ConsoleWriteLog("Pool API - Warning, your Remote Node HTTP API seems to not respond !", ClassLogEnumeration.IndexPoolApiErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } } string miningPortInfo = string.Empty; if (MiningPoolSetting.MiningPoolMiningPort.Count > 0) { int counter = 0; foreach (var miningPort in MiningPoolSetting.MiningPoolMiningPort) { counter++; if (counter < MiningPoolSetting.MiningPoolMiningPort.Count) { miningPortInfo += miningPort.Key + "|" + miningPort.Value + ";"; // Mining port + mining difficulty; } else { miningPortInfo += miningPort.Key + "|" + miningPort.Value; // Mining port + mining difficulty; } } } Dictionary <string, string> poolStatsContent = new Dictionary <string, string>() { { "pool_hashrate", ClassMiningPoolGlobalStats.TotalMinerHashrate.ToString() }, { "pool_total_miner_connected", ClassMiningPoolGlobalStats.TotalMinerConnected.ToString() }, { "pool_total_worker_connected", ClassMiningPoolGlobalStats.TotalWorkerConnected.ToString() }, { "pool_total_payment", ClassMinerStats.DictionaryPoolTransaction.Count.ToString() }, { "pool_total_paid", ClassMiningPoolGlobalStats.PoolTotalPaid.ToString("F" + ClassConnectorSetting.MaxDecimalPlace) }, { "pool_total_block_found", ClassMiningPoolGlobalStats.ListBlockFound.Count.ToString() }, { "pool_fee", MiningPoolSetting.MiningPoolFee.ToString() }, { "pool_last_block_found_date", lastBlockFoundDate }, { "pool_mining_port_and_difficulty", miningPortInfo }, { "pool_minimum_payment", "" + MiningPoolSetting.MiningPoolMinimumBalancePayment }, { "network_height", ClassMiningPoolGlobalStats.CurrentBlockId }, { "network_difficulty", ClassMiningPoolGlobalStats.CurrentBlockDifficulty }, { "network_hashrate", networkHashrate.ToString() }, { "network_last_block_hash", blockHash }, { "network_last_block_found_timestamp", blockTimestampFound }, { "network_last_block_reward", blockReward } }; await BuildAndSendHttpPacketAsync(string.Empty, true, poolStatsContent); } else { ClassLog.ConsoleWriteLog("Pool API - Warning, your Remote Node HTTP API seems to not respond !", ClassLogEnumeration.IndexPoolApiErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketError); } break; default: await BuildAndSendHttpPacketAsync(ClassApiEnumeration.PacketNotExist); break; } } }
/// <summary> /// Start to listen incoming client. /// </summary> /// <returns></returns> public async Task StartHandleClientHttpAsync() { var isWhitelisted = true; if (ClassFilteringMiner.CheckMinerIsBannedByIP(_ip)) { isWhitelisted = false; } int totalWhile = 0; if (isWhitelisted) { await Task.Factory.StartNew(() => MaxKeepAliveFunctionAsync(), CancellationListen.Token, TaskCreationOptions.DenyChildAttach, TaskScheduler.Current).ConfigureAwait(false); try { while (_clientStatus) { try { using (NetworkStream clientHttpReader = new NetworkStream(_client.Client)) { using (BufferedStream bufferedStreamNetwork = new BufferedStream(clientHttpReader, ClassConnectorSetting.MaxNetworkPacketSize)) { byte[] buffer = new byte[ClassConnectorSetting.MaxNetworkPacketSize]; int received = await bufferedStreamNetwork.ReadAsync(buffer, 0, buffer.Length); if (received > 0) { string packet = Encoding.UTF8.GetString(buffer, 0, received); try { if (!GetAndCheckForwardedIp(packet)) { break; } } catch { } packet = ClassUtility.GetStringBetween(packet, "GET /", "HTTP"); packet = packet.Replace("%7C", "|"); // Translate special character | packet = packet.Replace(" ", ""); // Remove empty,space characters ClassLog.ConsoleWriteLog("HTTP API - packet received from IP: " + _ip + " - " + packet, ClassLogEnumeration.IndexPoolApiLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog); await HandlePacketHttpAsync(packet); break; } else { totalWhile++; } if (totalWhile >= 8) { break; } } } } catch (Exception error) { ClassLog.ConsoleWriteLog("HTTP API - exception error: " + error.Message, ClassLogEnumeration.IndexPoolApiErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog); break; } } } catch { } } CloseClientConnection(); }