/// <summary> /// This method permit to get back the real ip behind a proxy and check the list of banned IP. /// </summary> private bool GetAndCheckForwardedIp(string packet) { var splitPacket = packet.Split(new[] { "\n" }, StringSplitOptions.None); foreach (var packetEach in splitPacket) { if (packetEach != null) { if (!string.IsNullOrEmpty(packetEach)) { if (packetEach.ToLower().Contains("x-forwarded-for: ")) { _ip = packetEach.ToLower().Replace("x-forwarded-for: ", ""); ClassLog.ConsoleWriteLog("HTTP/HTTPS API - X-Forwarded-For ip of the client is: " + _ip, ClassLogEnumeration.IndexPoolApiLog, ClassLogEnumeration.IndexPoolApiErrorLog); if (ClassFilteringMiner.CheckMinerIsBannedByIP(_ip)) { return(false); } } } } } return(true); }
/// <summary> /// Initialization of the mining pool. /// </summary> /// <returns></returns> private static bool InitializeMiningPool() { ClassLog.ConsoleWriteLog("Initialize Log system..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); if (ClassLog.LogInitialization()) { ClassLog.ConsoleWriteLog("Initialize pool settings..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); if (MiningPoolSettingInitialization.InitializationPoolSettingFile()) { ClassLog.ConsoleWriteLog("Pool settings initialized.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); ClassLog.ConsoleWriteLog("Intialize pool databases..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); if (ClassMiningPoolDatabase.InitializationMiningPoolDatabases()) { ClassMiningPoolDatabase.AutoSaveMiningPoolDatabases(); ClassLog.ConsoleWriteLog("Pool databases initialized.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); ClassLog.ConsoleWriteLog("Log System initialized.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); ThreadNetworkBlockchain = new Thread(async delegate() { ClassLog.ConsoleWriteLog("Connect Pool to the network for retrieve current blocktemplate..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); bool notConnected = true; while (notConnected) { Certificate = ClassUtils.GenerateCertificate(); while (!await ClassNetworkBlockchain.ConnectToBlockchainAsync()) { Thread.Sleep(5000); ClassLog.ConsoleWriteLog("Can't connect Pool to the network, retry in 5 seconds.. (Press CTRL+C to cancel and close the pool.)", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } Certificate = ClassUtils.GenerateCertificate(); ClassLog.ConsoleWriteLog("Certificate generate, send to the network..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); if (!await ClassNetworkBlockchain.SendPacketToNetworkBlockchain(Certificate, false)) { ClassLog.ConsoleWriteLog("Can't send certificate, reconnect now..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } else { ClassLog.ConsoleWriteLog("Certificate sent, start to login..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); ClassNetworkBlockchain.ListenBlockchain(); Thread.Sleep(1000); if (!await ClassNetworkBlockchain.SendPacketToNetworkBlockchain(ClassConnectorSettingEnumeration.MinerLoginType + "|" + MiningPoolSetting.MiningPoolWalletAddress, true)) { ClassLog.ConsoleWriteLog("Can't login to the network, reconnect now.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } else { ClassLog.ConsoleWriteLog("Login successfully sent, waiting confirmation..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); notConnected = false; } } if (notConnected) { ClassLog.ConsoleWriteLog("Can't long Pool to the network, retry in 5 seconds.. (Press CTRL+C to cancel and close the pool.)", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); Thread.Sleep(5000); } else { break; } } }) { IsBackground = true }; ThreadNetworkBlockchain.Start(); if (MiningPoolSetting.MiningPoolEnableFiltering) { ClassLog.ConsoleWriteLog("Enable Filtering Miner System..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); ClassFilteringMiner.EnableFilteringMiner(); } if (MiningPoolSetting.MiningPoolEnableCheckMinerStats) { ClassLog.ConsoleWriteLog("Enable Check Miner Stats System..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); ClassMinerStats.EnableCheckMinerStats(); } if (MiningPoolSetting.MiningPoolEnableTrustedShare) { ClassLog.ConsoleWriteLog("Enable Trusted Share System..", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); ClassMinerStats.EnableCheckTrustedMinerStats(); } if (MiningPoolSetting.MiningPoolEnablePayment) { ClassPayment.EnableAutoPaymentSystem(); } if (MiningPoolSetting.MiningPoolMiningPort.Count > 0) { foreach (var miningPoolPort in MiningPoolSetting.MiningPoolMiningPort) { var miningPoolObject = new ClassMiningPool(miningPoolPort.Key, miningPoolPort.Value); miningPoolObject.StartMiningPool(); ListMiningPool.Add(miningPoolPort.Key, miningPoolObject); } ClassApi.StartApiHttpServer(); EnableMiningPoolCommandLine(); } else { ClassLog.ConsoleWriteLog("Cannot start mining pool, their is any ports on the setting.", ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); return(false); } } else { return(false); } } else { return(false); } } else { return(false); } return(true); }
/// <summary> /// Enable mining pool command line. /// </summary> private static void EnableMiningPoolCommandLine() { ThreadMiningPoolCommandLines = new Thread(delegate() { while (!Exit) { string commandLine = Console.ReadLine(); try { var splitCommandLine = commandLine.Split(new char[0], StringSplitOptions.None); switch (splitCommandLine[0].ToLower()) { case MiningPoolCommandLinesEnumeration.MiningPoolCommandLineHelp: ClassLog.ConsoleWriteLog(MiningPoolCommandLinesEnumeration.MiningPoolCommandLineHelp + " - Command line to get list of commands details.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog(MiningPoolCommandLinesEnumeration.MiningPoolCommandLineStats + " - Show mining pool stats.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog(MiningPoolCommandLinesEnumeration.MiningPoolCommandLineBanMiner + " - ban a miner wallet address, syntax: " + MiningPoolCommandLinesEnumeration.MiningPoolCommandLineBanMiner + " wallet_address time", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog(MiningPoolCommandLinesEnumeration.MiningPoolCommandLineBanMinerList + " - Show the list of miner wallet address banned.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog(MiningPoolCommandLinesEnumeration.MiningPoolCommandLineUnBanMiner + " - Permit to unban a wallet address, syntax: " + MiningPoolCommandLinesEnumeration.MiningPoolCommandLineUnBanMiner + " wallet_address", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog(MiningPoolCommandLinesEnumeration.MiningPoolCommandLineExit + " - Stop mining pool, save and exit.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); break; case MiningPoolCommandLinesEnumeration.MiningPoolCommandLineStats: ClassLog.ConsoleWriteLog("Mining Pool Stats: ", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog("Total miners connected: " + ClassMiningPoolGlobalStats.TotalWorkerConnected, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog("Total blocks found: " + ClassMiningPoolGlobalStats.TotalBlockFound, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog("Total miners hashrate: " + ClassMiningPoolGlobalStats.TotalMinerHashrate.ToString("F2"), ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog("Pool Wallet Total Balance: " + ClassMiningPoolGlobalStats.PoolCurrentBalance + " " + ClassConnectorSetting.CoinNameMin, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); ClassLog.ConsoleWriteLog("Pool Wallet Total Balance in Pending: " + ClassMiningPoolGlobalStats.PoolPendingBalance + " " + ClassConnectorSetting.CoinNameMin, ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); if (ClassNetworkBlockchain.IsConnected) { ClassLog.ConsoleWriteLog("Mining pool is connected to retrieve last blocktemplate.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleMagentaLog, true); } else { ClassLog.ConsoleWriteLog("Mining pool is not connected to retrieve last blocktemplate.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } break; case MiningPoolCommandLinesEnumeration.MiningPoolCommandLineBanMiner: string walletAddress = splitCommandLine[1]; if (!ClassMinerStats.ManualBanWalletAddress(walletAddress, int.Parse(splitCommandLine[2]))) { ClassLog.ConsoleWriteLog("Cannot ban wallet address: " + walletAddress + " because this one not exist.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } else { ClassLog.ConsoleWriteLog("Wallet address: " + walletAddress + " is banned successfully pending " + splitCommandLine[2] + " second(s).", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } break; case MiningPoolCommandLinesEnumeration.MiningPoolCommandLineBanMinerList: if (ClassMinerStats.DictionaryMinerStats.Count > 0) { int totalBanned = 0; foreach (var minerStats in ClassMinerStats.DictionaryMinerStats) { if (minerStats.Value.IsBanned) { long minerBanTime = minerStats.Value.DateOfBan - DateTimeOffset.Now.ToUnixTimeSeconds(); ClassLog.ConsoleWriteLog("Wallet address: " + minerStats.Key + " is banned pending: " + minerBanTime + " second(s).", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); totalBanned++; } else { if (minerStats.Value.TotalBan > MiningPoolSetting.MiningPoolMaxTotalBanMiner) { ClassLog.ConsoleWriteLog("Wallet address: " + minerStats.Key + " is banned forever (until to restart the pool or manual unban).", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); totalBanned++; } } } if (totalBanned == 0) { ClassLog.ConsoleWriteLog("Their is any miner(s) banned.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); } } break; case MiningPoolCommandLinesEnumeration.MiningPoolCommandLineUnBanMiner: if (ClassMinerStats.DictionaryMinerStats.Count > 0) { if (ClassMinerStats.DictionaryMinerStats.ContainsKey(splitCommandLine[1])) { ClassMinerStats.DictionaryMinerStats[splitCommandLine[1]].DateOfBan = 0; ClassMinerStats.DictionaryMinerStats[splitCommandLine[1]].IsBanned = false; ClassMinerStats.DictionaryMinerStats[splitCommandLine[1]].TotalBan = 0; ClassLog.ConsoleWriteLog("Miner wallet address: " + splitCommandLine[1] + " is unbanned.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleGreenLog, true); } else { ClassLog.ConsoleWriteLog("Miner wallet address: " + splitCommandLine[1] + " not exist.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); } } else { ClassLog.ConsoleWriteLog("Miner wallet address: " + splitCommandLine[1] + " not exist.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleYellowLog, true); } break; case MiningPoolCommandLinesEnumeration.MiningPoolCommandLineExit: if (ClassPayment.PoolOnSendingTransaction) { ClassLog.ConsoleWriteLog("Can't close mining pool, the pool is currently on sending transaction(s).", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } else { if (ClassPayment.PoolOnProceedBlockReward) { ClassLog.ConsoleWriteLog("Can't close mining pool, the pool is currently on proceed block reward(s).", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } else { Exit = true; new Thread(delegate() { if (ListMiningPool.Count > 0) { foreach (var miningPool in ListMiningPool) { miningPool.Value.StopMiningPool(); } } ClassApi.StopApiHttpServer(); ClassMinerStats.StopCheckMinerStats(); ClassPayment.StopAutoPaymentSystem(); ClassFilteringMiner.StopFileringMiner(); ClassMiningPoolDatabase.StopAutoSaveMiningPoolDatabases(); ClassLog.ConsoleWriteLog("Mining pool stopped.", ClassLogEnumeration.IndexPoolGeneralLog, ClassLogConsoleEnumeration.IndexPoolConsoleBlueLog, true); ClassLog.StopLogSystem(); if (ThreadMiningPoolCommandLines != null && (ThreadMiningPoolCommandLines.IsAlive || ThreadMiningPoolCommandLines != null)) { ThreadMiningPoolCommandLines.Abort(); GC.SuppressFinalize(ThreadMiningPoolCommandLines); } }).Start(); } } break; } } catch (Exception error) { ClassLog.ConsoleWriteLog("Error on command line: " + commandLine + " exception: " + error.Message, ClassLogEnumeration.IndexPoolGeneralErrorLog, ClassLogConsoleEnumeration.IndexPoolConsoleRedLog, true); } } }); ThreadMiningPoolCommandLines.Start(); }
/// <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.Run(() => MaxKeepAliveFunctionAsync()).ConfigureAwait(false); try { while (_clientStatus) { try { using (CancellationTokenSource cancellationPacket = new CancellationTokenSource(1000)) { 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(); }