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 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(); }); } } } } }
public void SubmitWork(IPoolWork work, IMiningDevice device, string nonce) { StratumWork stratumWork = work as StratumWork; if (stratumWork != null && device != null && nonce != null && this.submissionQueue != null) { this.submissionQueue.Add(new Tuple <StratumWork, IMiningDevice, string>(stratumWork, device, nonce)); } }
private void OnNewWorkRecieved(StratumWork work, bool forceRestart) { if (NewWorkRecieved != null) { Task.Factory.StartNew(() => { NewWorkRecieved(this, work, forceRestart); }); } }
private void OnWorkRejected(StratumWork work, IMiningDevice device, IShareResponse response, bool async = true) { if (this.WorkRejected != null) { if (async) { Task.Factory.StartNew(() => { this.WorkRejected(this, work, device, response); }); } else { this.WorkRejected(this, work, device, response); } } }
private void OnWorkAccepted(StratumWork work, IMiningDevice device, bool async = true) { if (this.WorkAccepted != null) { if (async) { Task.Factory.StartNew(() => { this.WorkAccepted(this, work, device); }); } else { this.WorkAccepted(this, work, device); } } }
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 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); } }
public void Stop() { if (this.WorkSubmitQueue != null) { this.WorkSubmitQueue.Clear(); } this.Running = false; if (this.threadStopping != null) { this.threadStopping.Cancel(); } try { if (this.ListenerThread != null) { this.ListenerThread.Join(200); this.ListenerThread.Abort(); } } finally { this.ListenerThread = null; } try { if (this.SubmissionQueueThread != null) { if (this.submissionQueue != null) { this.submissionQueue.CompleteAdding(); } this.SubmissionQueueThread.Join(200); this.SubmissionQueueThread.Abort(); } } finally { this.submissionQueue = null; this.SubmissionQueueThread = null; } if (connection != null) { connection.Close(); } connection = null; latestWork = null; this.IsConnecting = false; this.IsAlive = false; _allowOldWork = true; latestWork = null; pendingWork = null; this.Diff = 0; this.RequestId = 0; this.Extranonce1 = null; this.Extranonce2Size = 4; this.partialData = null; WorkSubmitQueue = null; }