private void processCommand(StratumRecieveCommand command) { if (LogHelper.ShouldDisplay(LogVerbosity.Verbose)) { LogHelper.DebugConsoleLog(string.Format("Command: {0}", command.Method), LogVerbosity.Verbose); } object[] _params = command.Params; switch (command.Method.Trim()) { case StratumCommand.NotifyCommandString: if (_params == null || _params.Length < 9) { LogHelper.LogErrorSecondary(string.Format("Recieved invalid notification command from {0}", this.Url)); throw new InvalidDataException(string.Format("Recieved invalid notification command from {0}", this.Url)); } if (LogHelper.ShouldDisplay(LogVerbosity.Verbose)) { LogHelper.ConsoleLog(string.Format("Got Work from {0}!", this.Url), LogVerbosity.Verbose); } if (_params != null && _params.Length >= 9 && _params[8] != null && _params[8].Equals(true)) { this.NewBlocks++; if (LogHelper.ShouldDisplay(LogVerbosity.Verbose)) { LogHelper.ConsoleLog(string.Format("New block! ({0})", this.NewBlocks), ConsoleColor.DarkYellow, LogVerbosity.Verbose); } } StratumWork work = new StratumWork(_params, this.Extranonce1, this.Extranonce2Size, "00000000", this.Diff); LogHelper.DebugLogToFileAsync(new Object[] { "Server Work:", string.Format(" nonce1: {0}", work.Extranonce1), string.Format(" nonce2: {0}", work.Extranonce2), string.Format(" nonce2_size: {0}", work.ExtraNonce2Size), string.Format(" diff: {0}", work.Diff), string.Format(" id: {0}", work.JobId), string.Format(" prevHash: {0}", work.PreviousHash), string.Format(" coinb1: {0}", work.Coinbase1), string.Format(" coinb2: {0}", work.Coinbase2), string.Format(" version: {0}", work.Version), string.Format(" nbits: {0}", work.NetworkDiff), string.Format(" ntime: {0}", work.Timestamp) }, ServerWorkLogFile); latestWork = work; if (this.IsAlive && this.NewWorkRecieved != null && !string.IsNullOrEmpty(this.Extranonce1)) { bool forceRestart = (_params != null && _params.Length >= 9 && _params[8] != null && _params[8] is bool?_params[8].Equals(true) : true); this.OnNewWorkRecieved(work, forceRestart); } else { #if DEBUG if (string.IsNullOrEmpty(this.Extranonce1)) { LogHelper.LogError("Got work with while Extranonce1 is null."); } #endif pendingWork = work; } break; case StratumCommand.SetDifficlutyCommandString: if (_params == null || _params.Length < 1) { LogHelper.LogErrorSecondary(string.Format("Recieved invalid difficulty command from {0}", this.Url)); throw new InvalidDataException(string.Format("Recieved invalid difficulty command from {0}", this.Url)); } if (LogHelper.ShouldDisplay(LogVerbosity.Verbose)) { LogHelper.ConsoleLog(string.Format("Got Diff: {0} from {1}", _params[0], this.Url), LogVerbosity.Verbose); } LogHelper.DebugConsoleLog(string.Format("Diff Change {0} => {1}", this.Diff, _params[0]), ConsoleColor.Magenta); if (_params[0] is int) { this.Diff = (int)_params[0]; } else if (_params[0] is double || _params[0] is float || _params[0] is decimal) { double d = (_params[0] is decimal ? decimal.ToDouble((decimal)_params[0]) : (double)_params[0]); this.Diff = (int)Math.Ceiling(d); } else { if (_params[0] is string) { int i; int.TryParse((string)_params[0], out i); this.Diff = i; } else if (_params.Length > 1 && _params.Count(obj => obj is int) > 0) { foreach (int i in _params) { this.Diff = i; break; } } else { if (_params.Length == 1) { LogHelper.LogError(string.Format("Unknown diff command object: {0} of type {1}", _params[0], _params[0].GetType().ToString())); } else { StringBuilder sb = new StringBuilder(); sb.Append("[ "); bool first = true; foreach (object obj in _params) { if (!first) { sb.Append(", "); } else { first = false; } sb.Append(obj.ToString()); } sb.Append(" ]"); LogHelper.LogError(string.Format("Unknown diff command params: {0}", sb.ToString())); } } } break; default: LogHelper.ConsoleLogError(string.Format("Unrecognized command: {0}", command.Method)); break; } }
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); }