public static PoolConnection CreatePoolConnection(Client client, string url, int port, string login, string password) { string credential = url + port.ToString() + login + password; PoolConnection lpc, mypc = null; int batchCounter = 0; while (Connections.TryGetValue(credential + batchCounter.ToString(), out lpc)) { if (lpc.WebClients.Count > MainClass.BatchSize) { batchCounter++; } else { mypc = lpc; break; } } credential += batchCounter.ToString(); if (mypc == null) { CConsole.ColorInfo(() => { Console.WriteLine("{0}: initiated new pool connection", client.WebSocket.ConnectionInfo.Id); Console.WriteLine("{0} {1} {2}", login, password, url); }); mypc = new PoolConnection(); mypc.Credentials = credential; mypc.LastSender = client; mypc.TcpClient = new TcpClient(); Fleck.SocketExtensions.SetKeepAlive(mypc.TcpClient.Client, 60000, 1000); mypc.TcpClient.Client.ReceiveBufferSize = 4096 * 2; mypc.Login = login; mypc.Password = password; mypc.Port = port; mypc.Url = url; mypc.WebClients.TryAdd(client); Connections.TryAdd(credential, mypc); try { mypc.TcpClient.Client.BeginConnect(url, port, new AsyncCallback(ConnectCallback), mypc); } catch { } } else { Console.WriteLine("{0}: reusing pool connection", client.WebSocket.ConnectionInfo.Id); mypc.WebClients.TryAdd(client); if (mypc.LastJob != null) { ReceiveJob(client, mypc.LastJob, mypc.LastSolved); } else { Console.WriteLine("{0} no job yet.", client.WebSocket.ConnectionInfo.Id); } } client.PoolConnection = mypc; return(mypc); }
private static void ReceiveCallback(IAsyncResult result) { PoolConnection mypc = result.AsyncState as PoolConnection; TcpClient client = mypc.TcpClient; if (mypc.Closed || !client.Connected) { return; } NetworkStream networkStream; try { networkStream = client.GetStream(); } catch { return; } int bytesread = 0; try { bytesread = networkStream.EndRead(result); } catch { return; } string json = string.Empty; try { if (bytesread == 0) // disconnected { // slow that down a bit to avoid negative feedback loop Task.Run(async delegate { await Task.Delay(TimeSpan.FromSeconds(4)); List <Client> cllist = new List <Client>(mypc.WebClients.Values); foreach (Client ev in cllist) { Disconnect(ev, "lost pool connection."); } }); return; } json = Encoding.ASCII.GetString(mypc.ReceiveBuffer, 0, bytesread); networkStream.BeginRead(mypc.ReceiveBuffer, 0, mypc.ReceiveBuffer.Length, new AsyncCallback(ReceiveCallback), mypc); } catch { return; } if (bytesread == 0 || string.IsNullOrEmpty(json)) { return; //?! } var msg = json.FromJson <JsonData>(); if (msg == null) { return; } if (string.IsNullOrEmpty(mypc.PoolId)) { // this "protocol" is strange if (!msg.ContainsKey("result")) { string additionalInfo = "none"; // try to get the error if (msg.ContainsKey("error")) { msg = msg["error"] as JsonData; if (msg != null && msg.ContainsKey("message")) { additionalInfo = msg["message"].GetString(); } } List <Client> cllist = new List <Client>(mypc.WebClients.Values); foreach (Client ev in cllist) { Disconnect(ev, "can not connect. additional information: " + additionalInfo); } return; } msg = msg["result"] as JsonData; if (msg == null) { return; } if (!msg.ContainsKey("id")) { return; } if (!msg.ContainsKey("job")) { return; } mypc.PoolId = msg["id"].GetString(); var lastjob = msg["job"] as JsonData; if (!VerifyJob(lastjob)) { CConsole.ColorWarning(() => Console.WriteLine("Failed to verify job: {0}", json)); return; } // extended stratum if (!lastjob.ContainsKey("variant")) { lastjob.Add("variant", mypc.DefaultVariant); } if (!lastjob.ContainsKey("algo")) { lastjob.Add("algo", mypc.DefaultAlgorithm); } AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob); mypc.LastJob = lastjob; mypc.LastInteraction = DateTime.Now; mypc.LastSolved = new CcHashset <string>(); List <Client> cllist2 = new List <Client>(mypc.WebClients.Values); foreach (Client ev in cllist2) { ReceiveJob(ev, mypc.LastJob, mypc.LastSolved); } } else if (msg.ContainsKey("method") && msg["method"].GetString() == "job") { if (!msg.ContainsKey("params")) { return; } var lastjob = msg["params"] as JsonData; if (!VerifyJob(lastjob)) { CConsole.ColorWarning(() => Console.WriteLine("Failed to verify job: {0}", json)); return; } // extended stratum if (!lastjob.ContainsKey("variant")) { lastjob.Add("variant", mypc.DefaultVariant); } if (!lastjob.ContainsKey("algo")) { lastjob.Add("algo", mypc.DefaultAlgorithm); } AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob); mypc.LastJob = lastjob; mypc.LastInteraction = DateTime.Now; mypc.LastSolved = new CcHashset <string>(); List <Client> cllist2 = new List <Client>(mypc.WebClients.Values); Console.WriteLine("Sending job to {0} client(s)!", cllist2.Count); foreach (Client ev in cllist2) { ReceiveJob(ev, mypc.LastJob, mypc.LastSolved); } } else { if (msg.ContainsKey("error")) { // who knows? ReceiveError(mypc.LastSender, msg); } else { CConsole.ColorWarning(() => Console.WriteLine("Pool is sending nonsense.")); } } }