/// <summary> /// Disconnect the miner. /// </summary> /// <param name="tcpMiner"></param> public void DisconnectMiner() { if (MinerInitialized) { if (NetworkProxy.TotalConnectedMiner > 0) { NetworkProxy.TotalConnectedMiner--; } } MinerConnected = false; MinerInitialized = false; tcpMiner?.Close(); tcpMiner?.Dispose(); if (NetworkBlockchain.ListMinerStats.ContainsKey(MinerName)) { NetworkBlockchain.ListMinerStats[MinerName].MinerConnectionStatus = false; if (NetworkBlockchain.ListMinerStats[MinerName].MinerDifficultyEnd == 0 && NetworkBlockchain.ListMinerStats[MinerName].MinerDifficultyStart == 0) { NetworkBlockchain.SpreadJobAsync(); } } }
/// <summary> /// Handle packet received from miner. /// </summary> /// <param name="packet"></param> /// <param name="tcpMiner"></param> private async void HandlePacketMinerAsync(string packet) { try { var splitPacket = packet.Split(new[] { "|" }, StringSplitOptions.None); switch (splitPacket[0]) { case "MINER": // For Login. MinerName = splitPacket[1]; var MinerDifficulty = int.Parse(splitPacket[2]); var MinerDifficultyPosition = int.Parse(splitPacket[3]); if (MinerDifficulty > 100 || MinerDifficultyPosition > 100 || MinerDifficulty < 0 || MinerDifficultyPosition < 0) { MinerDifficulty = 0; MinerDifficultyPosition = 0; } if (MinerDifficultyPosition > MinerDifficulty) { MinerDifficulty = 0; MinerDifficultyPosition = 0; } if (splitPacket.Length > 4) { MinerVersion = splitPacket[4]; } if (NetworkBlockchain.ListMinerStats.ContainsKey(MinerName)) { NetworkBlockchain.ListMinerStats[MinerName].MinerConnectionStatus = true; NetworkBlockchain.ListMinerStats[MinerName].MinerVersion = MinerVersion; NetworkBlockchain.ListMinerStats[MinerName].MinerDifficultyStart = MinerDifficultyPosition; NetworkBlockchain.ListMinerStats[MinerName].MinerDifficultyEnd = MinerDifficulty; NetworkBlockchain.ListMinerStats[MinerName].MinerIp = MinerIp; } else { NetworkBlockchain.ListMinerStats.Add(MinerName, new ClassMinerStats() { MinerConnectionStatus = true, MinerTotalGoodShare = 0, MinerVersion = MinerVersion, MinerDifficultyStart = MinerDifficultyPosition, MinerDifficultyEnd = MinerDifficulty, MinerIp = MinerIp, MinerName = MinerName }); } if (!await SendPacketAsync(ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendLoginAccepted + "|NO").ConfigureAwait(false)) { DisconnectMiner(); } break; case ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ReceiveAskContentBlockMethod: // Receive ask to know content of selected mining method. string dataMethod = null; bool methodExist = false; if (NetworkBlockchain.ListOfMiningMethodName.Count > 0) { for (int i = 0; i < NetworkBlockchain.ListOfMiningMethodName.Count; i++) { if (i < NetworkBlockchain.ListOfMiningMethodName.Count) { if (NetworkBlockchain.ListOfMiningMethodName[i] == splitPacket[1]) { methodExist = true; dataMethod = NetworkBlockchain.ListOfMiningMethodContent[i]; } } } } else { if (NetworkBlockchain.ListOfMiningMethodName[0] == splitPacket[1]) { methodExist = true; dataMethod = NetworkBlockchain.ListOfMiningMethodContent[0]; } } if (methodExist) { if (!await SendPacketAsync(ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendContentBlockMethod + "|" + dataMethod).ConfigureAwait(false)) { DisconnectMiner(); } } break; case ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ReceiveAskListBlockMethod: // Receive ask to know list of mining method. string dateListMethod = ""; if (NetworkBlockchain.ListOfMiningMethodName.Count == 1) { dateListMethod = NetworkBlockchain.ListOfMiningMethodName[0]; } else { for (int i = 0; i < NetworkBlockchain.ListOfMiningMethodName.Count; i++) { if (i < NetworkBlockchain.ListOfMiningMethodName.Count) { if (i < NetworkBlockchain.ListOfMiningMethodName.Count - 1) { dateListMethod += NetworkBlockchain.ListOfMiningMethodName[i] + "#"; } else { dateListMethod += NetworkBlockchain.ListOfMiningMethodName[i]; } } } } if (!await SendPacketAsync(ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendListBlockMethod + "|" + dateListMethod).ConfigureAwait(false)) { DisconnectMiner(); } break; case ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ReceiveAskCurrentBlockMining: MinerInitialized = true; NetworkBlockchain.SpreadJobAsync(MinerId); break; case ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ShareHashrate: if (NetworkBlockchain.ListMinerStats.ContainsKey(MinerName)) { NetworkBlockchain.ListMinerStats[MinerName].MinerHashrateExpected = splitPacket[1]; var currentBlockId = 0; if (int.TryParse(NetworkBlockchain.CurrentBlockId, out currentBlockId)) { var differenceBlockId = (decimal)currentBlockId - NetworkBlockchain.FirstBlockId; if (differenceBlockId > 0) { var hashrateCalculated = Math.Round(((NetworkBlockchain.ListMinerStats[MinerName].MinerTotalGoodShare / differenceBlockId * 100) * 1024), 0); NetworkBlockchain.ListMinerStats[MinerName].MinerHashrateCalculated = "" + hashrateCalculated; } else { NetworkBlockchain.ListMinerStats[MinerName].MinerHashrateCalculated = "0"; } } } break; case ClassSoloMiningPacketEnumeration.SoloMiningSendPacketEnumeration.ReceiveJob: NetworkBlockchain.ListMinerStats[MinerName].MinerTotalShare++; var encryptedShare = splitPacket[1]; var hashShare = splitPacket[4]; if (NetworkBlockchain.CurrentBlockIndication == Utils.ConvertToSha512(encryptedShare)) { NetworkBlockchain.ListMinerStats[MinerName].MinerTotalGoodShare++; if (!await NetworkBlockchain.SendPacketAsync(packet, true).ConfigureAwait(false)) { DisconnectMiner(); } } else { NetworkBlockchain.ListMinerStats[MinerName].MinerTotalInvalidShare++; if (!await SendPacketAsync(ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.SendJobStatus + "|" + ClassSoloMiningPacketEnumeration.SoloMiningRecvPacketEnumeration.ShareBad).ConfigureAwait(false)) { DisconnectMiner(); } } break; } } catch { try { DisconnectMiner(); } catch { } } }