private void ProcessSubmitQueue() { foreach (var item in this.submissionQueue.GetConsumingEnumerable()) { StratumWork work = item.Item1; IMiningDevice device = item.Item2; string nonce = item.Item3; if (this.connection == null || !this.connection.Connected) { LogHelper.ConsoleLogError("Attempting to submit share to disconnected pool."); return; } if (!this._allowOldWork && (this.latestWork == null || work.JobId != this.latestWork.JobId)) { if (LogHelper.ShouldDisplay(LogVerbosity.Verbose)) { LogHelper.ConsoleLog(string.Format("Discarding share for old job {0}.", work.JobId), ConsoleColor.Magenta, LogVerbosity.Verbose); } return; } if (WorkSubmitQueue != null) { try { long requestId = this.RequestId; this.RequestId++; string[] param = { this.Username, work.JobId, work.Extranonce2, work.Timestamp, nonce }; StratumSendCommand command = new StratumSendCommand(requestId, StratumSendCommand.SubmitCommandString, param); WorkSubmitQueue.Enqueue(new Tuple <StratumSendCommand, StratumWork, IMiningDevice>(command, work, device)); if (this.connection != null && this.connection.Connected) { MemoryStream memStream = new MemoryStream(); command.Serialize(memStream); this.SendData(memStream); } } catch (Exception e) { LogHelper.LogErrorSecondary(e); if ((this.connection == null || !this.connection.Connected) && this.Running) { Task.Factory.StartNew(() => { this.Stop(); this.OnDisconnect(); }); } } } } }
private void Connect() { try { if (connection != null) { this.Stop(); connection = null; } WorkSubmitQueue = Queue.Synchronized(new Queue()); this.Running = true; this.IsAlive = false; this._allowOldWork = true; this.latestWork = null; string[] splitAddress = Url.Split(':'); if (splitAddress.Length != 3) { Exception e = new StratumConnectionFailureException(string.Format("Incorrect pool address: {0}", Url)); LogHelper.LogErrorSecondary(e); throw e; } string hostName = splitAddress[1].Replace("/", "").Trim(); int port; if (!int.TryParse(splitAddress[2], out port)) { Exception e = new StratumConnectionFailureException(string.Format("Incorrect port format: {0}", splitAddress[1])); LogHelper.LogErrorSecondary(e); throw e; } try { connection = new TcpClient(hostName, port); } catch (SocketException e) { throw new StratumConnectionFailureException(e); } this.IsConnecting = false; if (!connection.Connected) { Exception e = new StratumConnectionFailureException("Unknown connection failure."); LogHelper.LogErrorSecondary(e); throw e; } StratumSendCommand subscribeCommand = StratumSendCommand.SubscribeCommand; subscribeCommand.Id = this.RequestId; MemoryStream memStream = new MemoryStream(); subscribeCommand.Serialize(memStream); this.SendData(memStream); StratumResponse response = this.waitForResponse(); Object[] data = (response != null ? response.Data as Object[] : null); if (data == null) { throw new StratumConnectionFailureException("Recieved null response from server subscription command."); } this.Extranonce1 = data[1] as string; this.Extranonce2Size = (int)data[2]; if (Extranonce2Size == 0) { Extranonce2Size = DefaultExtraNonce2Size; } if (LogHelper.ShouldDisplay(LogVerbosity.Normal)) { LogHelper.ConsoleLog(string.Format("Successfully connected to pool {0}", this.Url)); } LogHelper.DebugConsoleLog(new Object[] { string.Format("Extranonce1: {0}", data[1]), string.Format("Extranonce2_size: {0}", data[2]) }, LogVerbosity.Verbose); string[] param = { this.Username, (!string.IsNullOrEmpty(this.Password) ? this.Password : "******") }; StratumSendCommand command = new StratumSendCommand(this.RequestId, StratumSendCommand.AuthorizationCommandString, param); memStream = new MemoryStream(); command.Serialize(memStream); this.SendData(memStream); StratumResponse successResponse = this.waitForResponse(); if (connection.Connected) { this.IsAlive = true; } // If we recieved work before we started the device manager, give the work to the device manager now if (pendingWork != null) { StratumWork work = new StratumWork(pendingWork.CommandArray, this.Extranonce1, this.Extranonce2Size, "00000000", this.Diff); pendingWork = null; this.OnNewWorkRecieved(work, true); } if (successResponse.Data == null || !successResponse.Data.Equals(true)) { this.IsAlive = false; LogHelper.ConsoleLogError(string.Format("Pool Username or Password rejected with: {0}", successResponse.Error)); throw new StratumConnectionFailureException(string.Format("Pool Username or Password rejected with: {0}", successResponse.Error)); } this.ListenerThread = new Thread(new ThreadStart(this.ProcessIncomingData)); this.ListenerThread.Start(); this.SubmissionQueueThread = new Thread(new ThreadStart(this.ProcessSubmitQueue)); this.SubmissionQueueThread.Priority = ThreadPriority.Highest; this.SubmissionQueueThread.Start(); } catch (Exception e) { this.IsConnecting = false; LogHelper.LogErrorSecondary(e); this.Stop(); this.OnDisconnect(); } if (this.Connected != null) { this.Connected(this); } }