/// <summary> /// waiting for messages from stream and reading them /// </summary> public void Listen() { if (shouldPrint()) { Logger.Log(LogLevel.DEBUG, $"begin listen for sc id {id} from thread {Environment.CurrentManagedThreadId}"); } try { while (client.Connected) { if (terminated) { break; } if ((DateTime.Now - lastComm) > TimeSpan.FromMinutes(30) || BadPacketCnt > 10) { break; } string message = reader.ReadLine(); if (string.IsNullOrWhiteSpace(message)) { try { Logger.Log(LogLevel.DEBUG, $"(sc id {id}): Epmty read from reader, client:{client.Client.Connected}, liger state: {client.LingerState}, stream.CanRead: {stream.CanRead}, stream.DataAvailable: {stream.DataAvailable}, stream.readTimeout:{stream.ReadTimeout}, stream.length:{stream.Length} "); } catch (Exception ex) { Logger.Log(LogLevel.DEBUG, $"(sc id {id}): Epmty read from reader, Exception {ex.Message}"); Logger.Log(LogLevel.DEBUG, $"stream is null? {stream == null}, tcpclient is null? {client == null}"); } BadPacketCnt++; continue; } Console.ForegroundColor = ConsoleColor.Green; //Console.WriteLine(); if (shouldPrint()) { Logger.Log(LogLevel.DEBUG, $"(sc id {id}):TCP IN: {message} {Environment.NewLine}"); } Console.ResetColor(); try { JObject msg = JsonConvert.DeserializeObject(message, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }) as JObject; var method = ((JObject)msg)["method"].ToString(); string para = ""; if (msg.ContainsKey("params")) { para = msg["params"].ToString() /*.Replace("\\", "")*/; } BadPacketCnt = 0; switch (method) { case "getjobtemplate": if (msg.ContainsKey("result")) { PrevJob = CurrentJob ?? null; CurrentJob = new Job(JsonConvert.DeserializeObject <JobTemplate>(msg["result"].ToString(), new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore })); CurrentJob.origin = GetJobOrigine(); //CurrentJob.type = type; currentHeight = (int)CurrentJob.height; if (CurrentJob != null && CurrentJob.pre_pow != null && CurrentJob.pre_pow != "") { lastComm = DateTime.Now; if (jobs != null) { jobs.Enqueue(message); } else if (ConnectionManager.IsConnectionCurrent(id)) { PushJobToWorkers(); } Console.ForegroundColor = ConsoleColor.Green; Logger.Log(LogLevel.INFO, $"({ConnectionManager.solutionCounter}) New Job: sc id {id}, job {CurrentJob.jobID}, dificulty {CurrentJob.difficulty}, height {CurrentJob.height}"); Console.ResetColor(); } } break; case "job": PrevJob = CurrentJob ?? null; CurrentJob = new Job(JsonConvert.DeserializeObject <JobTemplate>(para, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore })); CurrentJob.origin = GetJobOrigine(); //CurrentJob.type = type; currentHeight = (int)CurrentJob.height; if (CurrentJob != null && CurrentJob.pre_pow != null && CurrentJob.pre_pow != "") { if (CurrentJob.scale != 1) { lastComm = DateTime.Now; if (jobs != null) { jobs.Enqueue(message); } else if (ConnectionManager.IsConnectionCurrent(id)) { PushJobToWorkers(); } } else { Logger.Log(LogLevel.WARNING, $"Incorrect pre_pow: {CurrentJob.pre_pow}"); } } break; case "submit": if (msg.ContainsKey("result") && msg["result"].ToString() == "ok") { Console.ForegroundColor = ConsoleColor.Cyan; Logger.Log(LogLevel.INFO, $"(sc id {id}):Share accepted"); sharesAccepted++; Console.ResetColor(); } else if (msg.ContainsKey("result") && msg["result"].ToString().StartsWith("blockfound")) { Console.ForegroundColor = ConsoleColor.Cyan; //Console.WriteLine("###################################"); Logger.Log(LogLevel.INFO, "###### Block mined! #" + (++mined).ToString("D4") + " ######"); // 8 chars //Console.WriteLine("###################################"); Console.ResetColor(); //statistics.mined++; sharesAccepted++; } if (msg.ContainsKey("error")) { //phooton -32501, "Share rejected due to low difficulty" and -32504 "Shares rejected: duplicates" would that be okay for you try { var code = (int)msg["error"]["code"]; switch (code) { case -32503: if (shouldPrint()) { Logger.Log(LogLevel.WARNING, "Solution submitted too late"); } sharesTooLate++; break; case -32502: if (shouldPrint()) { Logger.Log(LogLevel.WARNING, "Failed to validate solution"); } sharesRejected++; break; case -32501: if (shouldPrint()) { Logger.Log(LogLevel.WARNING, "Share rejected due to low difficulty"); } sharesRejected++; break; default: if (shouldPrint()) { Logger.Log(LogLevel.WARNING, "Stratum " + (string)msg["error"]["message"]); } break; } } catch { } } break; case "message": if (msg.ContainsKey("result")) { Console.ForegroundColor = ConsoleColor.Yellow; Logger.Log(LogLevel.INFO, $"(sc id {id}):{msg["result"].ToString()}"); Console.ResetColor(); } break; case "login": //{"id":"Stratum","jsonrpc":"2.0","method":"login","error":{"code":-32501,"message":"invalid login format"}} //"error":{"code":-32500,"message":"login first"}} if (msg.ContainsKey("error")) { try { var errormsg = (string)msg["error"]["message"]; if (!string.IsNullOrEmpty(errormsg)) { Logger.Log(LogLevel.ERROR, $"Stratum {ip}:{port} " + errormsg); } } catch { } try { var code = (int)msg["error"]["code"]; if (code == -32501) { terminated = true; IsConnected = false; hasInvalidLogin = true; StratumClose(); Logger.Log(LogLevel.ERROR, "STRATUM INVALID LOGIN ERROR, CLOSING CONNECTION"); Task.Run(() => Task.Delay(2000).ContinueWith(_ => ReconnectAction())); } if (code == -32500) /// login first { //terminate (so wathdot doest trigger reconnect from CM), close and reconnect.. //terminated = true; //Task.Delay(200).Wait(); //IsConnected = false; //StratumClose(); //WaitForLoginConfirm = true; //Connect(); //SendLogin(); } } catch { } } //{"id":"Stratum","jsonrpc":"2.0","method":"login","result":"ok","error":null} if ((msg.ContainsKey("result") && msg["result"].ToString() == "ok")) { if (shouldPrint()) { Logger.Log(LogLevel.INFO, $"Stratum {ip}:{port} login ok"); } _IsLoginConfirmed = true; } break; default: if (method != "keepalive" && !string.IsNullOrEmpty(para)) { if (shouldPrint()) { Logger.Log(LogLevel.INFO, para); } } if (msg.ContainsKey("error")) { try { var errormsg = (string)msg["error"]["message"]; if (!string.IsNullOrEmpty(errormsg)) { Logger.Log(LogLevel.WARNING, "Stratum " + errormsg); } } catch { } } break; } } catch (System.IO.IOException ex) { Logger.Log(LogLevel.DEBUG, "Catched Socket exeption in listener msg parsing lopp: " + ex.Message); } catch (System.Net.Sockets.SocketException ex) { Logger.Log(LogLevel.DEBUG, "Catched Socket exeption in listener msg parsing loop: " + ex.Message); } catch (Exception ex) { Logger.Log(ex); } } IsConnected = false; //more like "IsListening" Logger.Log(LogLevel.DEBUG, $"Listener dropped for stratum connection id {id} on thread {Environment.CurrentManagedThreadId}"); //listenerCancel.ThrowIfCancellationRequested(); } catch (System.Net.Sockets.SocketException ex) { IsConnected = false; Logger.Log(LogLevel.DEBUG, $"(sc id {id}):Catched Socket exeption in listener: " + ex.Message); } catch (System.IO.IOException ex) { if (IsConnected == false) { Logger.Log(LogLevel.DEBUG, "Catched Socket exeption in listener: " + ex.Message); } else { IsConnected = false; if (ex.InnerException != null && ex.InnerException is SocketException) { var errc1 = ((SocketException)ex.InnerException).ErrorCode; //var errc2 = ((SocketException)ex.InnerException).NativeErrorCode; //var errc3 = ((SocketException)ex.InnerException).SocketErrorCode; // https://docs.microsoft.com/en-us/windows/desktop/winsock/windows-sockets-error-codes-2 if (errc1 == 10053) //WSAECONNABORTED - happens when ssl and port combination not supported by pool { Logger.Log(LogLevel.ERROR, "Check that your stratum connection details are correct. Ssl (true/false) and port must be supported by pool in this combination."); } } } } catch (Exception ex) { IsConnected = false; Logger.Log(ex); } }
/// <summary> /// waiting for messages from stream and reading them /// </summary> public void Listen() { Logger.Log(LogLevel.DEBUG, $"begin listen for sc id {id} from thread {Environment.CurrentManagedThreadId}"); try { while (client.Connected) { if (terminated) { break; } if ((DateTime.Now - lastComm) > TimeSpan.FromMinutes(30) || BadPacketCnt > 10) { break; } string message = reader.ReadLine(); if (string.IsNullOrWhiteSpace(message)) { Logger.Log(LogLevel.DEBUG, $"(sc id {id}): Epmty read from reader"); BadPacketCnt++; continue; } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(); Logger.Log(LogLevel.DEBUG, $"(sc id {id}):TCP IN: {message} {Environment.NewLine}"); Console.ResetColor(); try { JObject msg = JsonConvert.DeserializeObject(message, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }) as JObject; var method = ((JObject)msg)["method"].ToString(); string para = ""; if (msg.ContainsKey("params")) { para = msg["params"].ToString() /*.Replace("\\", "")*/; } BadPacketCnt = 0; switch (method) { case "getjobtemplate": if (msg.ContainsKey("result")) { PrevJob = CurrentJob ?? null; CurrentJob = new Job(JsonConvert.DeserializeObject <JobTemplate>(msg["result"].ToString(), new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore })); CurrentJob.origin = GetJobOrigine(); if (CurrentJob != null && CurrentJob.pre_pow != null && CurrentJob.pre_pow != "") { lastComm = DateTime.Now; if (ConnectionManager.IsConnectionCurrent(id)) { PushJobToWorkers(); } } } break; case "job": PrevJob = CurrentJob ?? null; CurrentJob = new Job(JsonConvert.DeserializeObject <JobTemplate>(para, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore })); CurrentJob.origin = GetJobOrigine(); if (CurrentJob != null && CurrentJob.pre_pow != null && CurrentJob.pre_pow != "") { if (CurrentJob.scale != 1) { lastComm = DateTime.Now; if (ConnectionManager.IsConnectionCurrent(id)) { PushJobToWorkers(); } } else { Logger.Log(LogLevel.WARNING, $"Incorrect pre_pow: {CurrentJob.pre_pow}"); } } break; case "submit": if (msg.ContainsKey("result") && msg["result"].ToString() == "ok") { Console.ForegroundColor = ConsoleColor.Cyan; Logger.Log(LogLevel.INFO, $"(sc id {id}):Share accepted"); sharesAccepted++; Console.ResetColor(); } else if (msg.ContainsKey("result") && msg["result"].ToString().StartsWith("blockfound")) { Console.ForegroundColor = ConsoleColor.Cyan; //Console.WriteLine("###################################"); Logger.Log(LogLevel.INFO, "###### Block mined! #" + (++mined).ToString("D4") + " ######"); // 8 chars //Console.WriteLine("###################################"); Console.ResetColor(); statistics.mined++; sharesAccepted++; } if (msg.ContainsKey("error")) { //phooton -32501, "Share rejected due to low difficulty" and -32504 "Shares rejected: duplicates" would that be okay for you try { var code = (int)msg["error"]["code"]; switch (code) { case -32503: Logger.Log(LogLevel.WARNING, "Solution submitted too late"); sharesTooLate++; break; case -32502: Logger.Log(LogLevel.WARNING, "Failed to validate solution"); sharesRejected++; break; case -32501: Logger.Log(LogLevel.WARNING, "Share rejected due to low difficulty"); sharesRejected++; break; default: Logger.Log(LogLevel.WARNING, "Stratum " + (string)msg["error"]["message"]); break; } } catch { } } break; case "login": //{"id":"Stratum","jsonrpc":"2.0","method":"login","error":{"code":-32501,"message":"invalid login format"}} if (msg.ContainsKey("error")) { try { var errormsg = (string)msg["error"]["message"]; if (!string.IsNullOrEmpty(errormsg)) { Logger.Log(LogLevel.ERROR, $"Stratum {ip}:{port} " + errormsg); } } catch { } try { var code = (int)msg["error"]["code"]; if (code == -32501) { terminated = true; IsConnected = false; hasInvalidLogin = true; StratumClose(); Logger.Log(LogLevel.ERROR, "STRATUM INVALID LOGIN ERROR, CLOSING CONNECTION"); Task.Run(() => Task.Delay(2000).ContinueWith(_ => ReconnectAction())); } } catch { } } //{"id":"Stratum","jsonrpc":"2.0","method":"login","result":"ok","error":null} if (msg.ContainsKey("result") && msg["result"].ToString() == "ok") { Logger.Log(LogLevel.INFO, $"Stratum {ip}:{port} login ok"); } break; default: if (method != "keepalive" && !string.IsNullOrEmpty(para)) { Logger.Log(LogLevel.INFO, para); } if (msg.ContainsKey("error")) { try { var errormsg = (string)msg["error"]["message"]; if (!string.IsNullOrEmpty(errormsg)) { Logger.Log(LogLevel.WARNING, "Stratum " + errormsg); } } catch { } } break; } } catch (System.IO.IOException ex) { Logger.Log(LogLevel.DEBUG, "Catched Socket exeption in listener: " + ex.Message); } catch (System.Net.Sockets.SocketException ex) { Logger.Log(LogLevel.DEBUG, "Catched Socket exeption in listener: " + ex.Message); } catch (Exception ex) { Logger.Log(ex); } } IsConnected = false; //more like "IsListening" Logger.Log(LogLevel.DEBUG, $"Listener dropped for stratum connection id {id} on thread {Environment.CurrentManagedThreadId}"); //listenerCancel.ThrowIfCancellationRequested(); } catch (System.IO.IOException ex) { Logger.Log(LogLevel.DEBUG, "Catched Socket exeption in listener: " + ex.Message); } catch (System.Net.Sockets.SocketException ex) { Logger.Log(LogLevel.DEBUG, $"(sc id {id}):Catched Socket exeption in listener: " + ex.Message); } catch (Exception ex) { IsConnected = false; Logger.Log(ex); } }