private void DisplaySubmissionResponse(bool accepted, StratumResponse response) { if ((int)LogHelper.Verbosity >= (int)LogVerbosity.Normal) { lock (submissionDisplayLock) { Object[][] format = (accepted ? acceptedSubmissionFormat : rejectedSubmissionFormat); format[3][0] = this.Accepted; format[5][0] = this.Rejected; format[7][0] = this.HardwareErrors; format[10][0] = MegaHashDisplayString(this.AcceptedHashRate); format[12][0] = MegaHashDisplayString(this.RejectedHashRate); format[14][0] = MegaHashDisplayString(this.DiscardedHashRate); if (accepted) { LogHelper.ConsoleLog(acceptedSubmissionFormat); } else { format[0][0] = string.Format("Rejected with {0}", response.RejectReason); LogHelper.ConsoleLog(rejectedSubmissionFormat); } } } }
private StratumResponse <T> Invoke <T>(StratumRequest stratumReq) { // Serialize stratumReq into JSON string var reqJSON = JsonConvert.SerializeObject(stratumReq) + '\n'; // Send JSON data to the remote device. Send(client, reqJSON); // Wait for response gotResponse.WaitOne(); var strResponse = string.Empty; lock (responsesLock) { // Deserialize the response strResponse = responses[stratumReq.Id]; responses.Remove(stratumReq.Id); } // Deserialize response into new instance of StratumResponse<T> StratumResponse <T> responseObj = JsonConvert.DeserializeObject <StratumResponse <T> >(strResponse); // Reset the state gotResponse.Reset(); if (responseObj == null) { try { JObject jResponseObj = JsonConvert.DeserializeObject(strResponse) as JObject; throw new Exception(jResponseObj["Error"].ToString()); } catch (JsonSerializationException) { throw new Exception("Inconsistent or empty response"); } } return(responseObj); }
private StratumResponse waitForResponse() { // TODO: handle null connection StratumResponse response = null; string responseStr = ""; // TODO: Make this not an infinate loop while (response == null && connection != null && connection.Connected) { responseStr = this.listenForData(); string[] responses = responseStr.Split('\n'); response = this.processCommands(responses, this.RequestId); if (response != null) { this.RequestId++; } } return(response); }
private void processWorkAcceptCommand(StratumWork work, IMiningDevice device, StratumResponse response, bool error = false) { if (error) { LogHelper.DebugConsoleLogError("Error. Unknown work result. Mismatch in work queue ID and recieved response ID."); return; } bool accepted = response.Data != null && response.Data.Equals(true); if (accepted) { Accepted++; AcceptedWorkUnits += work.Diff; } else { Rejected++; RejectedWorkUnits += work.Diff; } Task.Factory.StartNew(() => { if (accepted) { this.OnWorkAccepted(work, device, false); } else { this.OnWorkRejected(work, device, response, false); } DisplaySubmissionResponse(accepted, response); }); }
private StratumResponse processCommands(string[] commands, long id = -1) { StratumResponse result = null; foreach (string s in commands) { LogHelper.DebugLogToFileAsync(new Object[] { string.Format("Got Command from {0}: ", this.Url), s }, NetworkTrafficLogFile); if (!string.IsNullOrWhiteSpace(s)) { if (!s.Trim().EndsWith("}")) { LogHelper.LogErrorSecondary( new Object[] { string.Format("Partial command recieved from {0}", this.Url), s }); partialData = s; continue; } LogHelper.DebugConsoleLog(new Object[] { string.Format("Recieved data from {0}:", this.Url), s }, LogVerbosity.Verbose); if (!string.IsNullOrEmpty(s.Trim())) { string str = s; MemoryStream memStream = new MemoryStream(Encoding.ASCII.GetBytes(str)); if (str.Contains("\"result\"")) { StratumResponse response = null; try { try { response = StratumResponse.Deserialize(memStream); } catch { if (str.Contains('[')) { LogHelper.DebugConsoleLog(string.Format("Falling back to manual parsing. Could not parse response: {0}", str)); str = JsonParsingHelper.ConvertToMonoFriendlyJSON(str); memStream = new MemoryStream(Encoding.ASCII.GetBytes(str)); response = StratumResponse.Deserialize(memStream); } else { throw; } } } catch (Exception e) { Exception exception = new InvalidDataException(string.Format("Error parsing response {0}", str), e); LogHelper.LogErrorSecondary(exception); throw exception; } // This is the response we're looking for if (response.Id == id) { result = response; } else // This should be a work submit response. We expect these to come back in order { if (WorkSubmitQueue != null) { if (WorkSubmitQueue.Count > 0) { Tuple <StratumSendCommand, StratumWork, IMiningDevice> workItem = WorkSubmitQueue.Peek() as Tuple <StratumSendCommand, StratumWork, IMiningDevice>; if (response.Id == workItem.Item1.Id) { processWorkAcceptCommand(workItem.Item2, workItem.Item3, response); WorkSubmitQueue.Dequeue(); } else if (response.Id > workItem.Item1.Id) // Something odd happened, we probably missed some responses or the server decided not to send them { workItem = WorkSubmitQueue.Peek() as Tuple <StratumSendCommand, StratumWork, IMiningDevice>; while (WorkSubmitQueue.Count > 0 && response.Id > workItem.Item1.Id) { // Get rid of the old stuff WorkSubmitQueue.Dequeue(); workItem = WorkSubmitQueue.Peek() as Tuple <StratumSendCommand, StratumWork, IMiningDevice>; } if (WorkSubmitQueue.Count > 0 && response.Id == ((Tuple <StratumSendCommand, StratumWork, IMiningDevice>)WorkSubmitQueue.Peek()).Item1.Id) { workItem = WorkSubmitQueue.Dequeue() as Tuple <StratumSendCommand, StratumWork, IMiningDevice>; processWorkAcceptCommand(workItem.Item2, workItem.Item3, response); } } } } } } else // This is a command from the server { StratumRecieveCommand command = null; try { try { command = StratumRecieveCommand.Deserialize(memStream); } catch { if (str.Contains('[')) { LogHelper.DebugConsoleLog(string.Format("Falling back to manual parsing. Could not parse command: {0}", str)); str = JsonParsingHelper.ConvertToMonoFriendlyJSON(str); memStream = new MemoryStream(Encoding.ASCII.GetBytes(str)); command = StratumRecieveCommand.Deserialize(memStream); } else { throw; } } } catch (Exception e) { Exception exception = new InvalidDataException(string.Format("Error parsing command {0}", str), e); LogHelper.LogErrorSecondary(exception); throw exception; } processCommand(command); } } } } return(result); }
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); } }