override protected void Authorize() { try { mMutex.WaitOne(5000); } catch (Exception) { } mJsonRPCMessageID = 1; WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(new Dictionary <string, Object> { { "id", mJsonRPCMessageID++ }, { "method", "mining.subscribe" }, { "params", new List <string> { Program.appName + "/" + Program.appVersion, "EthereumStratum/1.0.0" } } })); Dictionary <String, Object> response; try { response = JsonConvert.DeserializeObject <Dictionary <string, Object> >(ReadLine()); mSubsciptionID = (string)(((JArray)(((JArray)(response["result"]))[0]))[1]); mPoolExtranonce = (string)(((JArray)(response["result"]))[1]); } catch (Exception) { throw this.UnrecoverableException = new AuthorizationFailedException(); } // mining.extranonce.subscribe WriteLine(JsonConvert.SerializeObject(new Dictionary <string, Object> { { "id", mJsonRPCMessageID++ }, { "method", "mining.extranonce.subscribe" }, { "params", new List <string> { } } })); response = JsonConvert.DeserializeObject <Dictionary <string, Object> >(ReadLine()); //Program.Logger("mining.extranonce.subscribe: " + response["result"]); // TODO WriteLine(JsonConvert.SerializeObject(new Dictionary <string, Object> { { "id", mJsonRPCMessageID++ }, { "method", "mining.authorize" }, { "params", new List <string> { Username, Password } } })); response = JsonConvert.DeserializeObject <Dictionary <string, Object> >(ReadLine()); if (!(bool)response["result"]) { try { mMutex.ReleaseMutex(); } catch (Exception) { } throw (UnrecoverableException = new UnrecoverableException("Authorization failed.")); } try { mMutex.ReleaseMutex(); } catch (Exception) { } }
protected override void ProcessLine(String line) { //Program.Logger("line: " + line); Dictionary <String, Object> response = JsonConvert.DeserializeObject <Dictionary <string, Object> >(line); if (response.ContainsKey("method") && response.ContainsKey("params")) { string method = (string)response["method"]; JArray parameters = (JArray)response["params"]; if (method.Equals("mining.set_difficulty")) { lock (thisLock) { mDifficulty = (double)parameters[0]; } Program.Logger("Difficulty set to " + (double)parameters[0] + "."); UInt64 target = (UInt64)((double)0xffff0000UL / (mDifficulty / 256)); Program.Logger("target : " + String.Format("0x{0:X16}", target)); } else if (method.Equals("mining.notify")) { bool jobChanged = (mJob == null || mJob.ID != (string)parameters[0]); lock (thisLock) { mJob = (new Job(this, (string)parameters[0], (string)parameters[1], (string)parameters[2], (string)parameters[3], Array.ConvertAll(((JArray)parameters[4]).ToArray(), item => (string)item), (string)parameters[5], (string)parameters[6], (string)parameters[7])); } if (!SilentMode && jobChanged) { Program.Logger("Received new job: " + parameters[0]); } } else if (method.Equals("mining.set_extranonce")) { lock (thisLock) { mPoolExtranonce = (String)parameters[0]; } Program.Logger("Received new extranonce: " + parameters[0]); } else if (method.Equals("client.reconnect")) { throw new Exception("client.reconnect"); } else { Program.Logger("Unknown stratum method: " + line); } } else if (response.ContainsKey("id") && response.ContainsKey("result")) { var ID = response["id"].ToString(); bool result = (response["result"] == null) ? false : (bool)response["result"]; if (ID == "3" && !result) { throw (UnrecoverableException = new UnrecoverableException("Authorization failed.")); } else if ((ID != "1" && ID != "2" && ID != "3") && result) { ReportAcceptedShare(); } else if ((ID != "1" && ID != "2" && ID != "3") && !result) { ReportRejectedShare((String)(((JArray)response["error"])[1])); } } else { Program.Logger("Unknown JSON message: " + line); } }
private void StreamReaderThread() { Thread.CurrentThread.Priority = ThreadPriority.Normal; do { int errorCount = 0; UnrecoverableException = null; do { Program.Logger("TOP OF MAIN STRATUM SERVER THREAD DO LOOP"); try { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); Program.Logger("TOP OF MAIN STRATUM SERVER THREAD DO LOOP - A "); try { mMutex.WaitOne(5000); } catch (Exception) { } Program.Logger("TOP OF MAIN STRATUM SERVER THREAD DO LOOP - B "); mClient = new TcpClient(ServerAddress, ServerPort); mStream = mClient.GetStream(); mStreamReader = new StreamReader(mStream, System.Text.Encoding.ASCII, false, 65536); mStreamWriter = new StreamWriter(mStream, System.Text.Encoding.ASCII, 65536); mStreamReader.BaseStream.ReadTimeout = 3 * 60 * 1000; mStreamWriter.BaseStream.WriteTimeout = 10 * 1000; mReconnectionRequested = false; Program.Logger("TOP OF MAIN STRATUM SERVER THREAD DO LOOP - C "); try { mMutex.ReleaseMutex(); } catch (Exception) { } Program.Logger("TOP OF MAIN STRATUM SERVER THREAD DO LOOP - D "); Authorize(); Program.Logger("TOP OF MAIN STRATUM SERVER THREAD DO LOOP - E "); while (!Stopped && !mReconnectionRequested) { string line; try { line = mStreamReader.ReadLine(); } catch (Exception) { throw new StratumServerUnavailableException(); } if (line == null) { throw new StratumServerUnavailableException(); } if (Stopped) { break; } if (line != "") { ProcessLine(line); } if (sw.ElapsedMilliseconds >= 60 * 60 * 1000) { mReconnectionRequested = true; } } } catch (UnrecoverableException ex) { this.UnrecoverableException = ex; } catch (Exception ex) { Program.Logger("Exception in Stratum.StreamReaderThread(): " + ex.ToString()); if (UnrecoverableException.IsUnrecoverableException(ex)) { this.UnrecoverableException = new UnrecoverableException(ex.Message); } else if (++errorCount < 4) { Program.Logger("Reconnecting to the server..."); System.Threading.Thread.Sleep(5000); } else { this.UnrecoverableException = new StratumServerUnavailableException(); } } try { mClient.Close(); mClient = null; } catch (Exception) { } } while (!Stopped && UnrecoverableException == null); if (Stopped) { Program.Logger("STRATUM SERVER STOPPED"); break; } Program.Logger("STRATUM SERVER BAIL OUT - UnrecoverableException : "); Program.Logger(" " + UnrecoverableException.ToString()); Program.Logger("Restarting in 10 seconds "); System.Threading.Thread.Sleep(10000); }while (true); }
protected override void ProcessLine(String line) { //Program.Logger("line: " + line); Dictionary <String, Object> response = JsonConvert.DeserializeObject <Dictionary <string, Object> >(line); if (response.ContainsKey("method") && response.ContainsKey("params")) { string method = (string)response["method"]; JArray parameters = (JArray)response["params"]; if (method.Equals("mining.set_difficulty")) { try { mMutex.WaitOne(5000); } catch (Exception) { } mDifficulty = (double)parameters[0]; try { mMutex.ReleaseMutex(); } catch (Exception) { } Program.Logger("Difficulty set to " + (double)parameters[0] + "."); } else if (method.Equals("mining.notify")) { bool jobChanged = (mJob == null || mJob.ID != (string)parameters[0]); try { mMutex.WaitOne(5000); } catch (Exception) { } mJob = (new Job(this, (string)parameters[0], (string)parameters[2], (string)parameters[3], (string)parameters[7])); try { mMutex.ReleaseMutex(); } catch (Exception) { } if (!SilentMode && jobChanged) { Program.Logger("Received new job: " + parameters[0]); } } else if (method.Equals("mining.set_extranonce")) { try { mMutex.WaitOne(5000); } catch (Exception) { } mPoolExtranonce = (String)parameters[0]; try { mMutex.ReleaseMutex(); } catch (Exception) { } Program.Logger("Received new extranonce: " + parameters[0]); } else if (method.Equals("client.reconnect")) { throw new Exception("client.reconnect"); } else { Program.Logger("Unknown stratum method: " + line); } } else if (response.ContainsKey("id") && response.ContainsKey("result")) { var ID = response["id"].ToString(); bool result = (response["result"] == null) ? false : (bool)response["result"]; if (ID == "3" && !result) { throw (UnrecoverableException = new UnrecoverableException("Authorization failed.")); } else if ((ID != "1" && ID != "2" && ID != "3") && result) { ReportAcceptedShare(); } else if ((ID != "1" && ID != "2" && ID != "3") && !result) { ReportRejectedShare((String)(((JArray)response["error"])[1])); } } else { Program.Logger("Unknown JSON message: " + line); } }