From 0fe8512012a77dc01668c77b3300cf6d7230ac4e Mon Sep 17 00:00:00 2001 From: wmpadmin Date: Tue, 26 Feb 2019 14:05:29 +0100 Subject: [PATCH] cnv4 protocol changes --- SDK/miner_raw/mine.html | 4 +- SDK/miner_raw/miner/miner.js | 1 + server/Server/AlgorithmHelper.cs | 10 +- server/Server/Fleck/WebSocketConnection.cs | 523 +++++++++++---------- server/Server/PoolConnection.cs | 5 +- server/Server/Program.cs | 36 +- 6 files changed, 307 insertions(+), 272 deletions(-) diff --git a/SDK/miner_raw/mine.html b/SDK/miner_raw/mine.html index 4d222b2..6ec98c7 100644 --- a/SDK/miner_raw/mine.html +++ b/SDK/miner_raw/mine.html @@ -24,8 +24,8 @@ /* start mining, use a local server */ server = "ws://localhost:8181"; - startMining("moneroocean.stream", - "422QQNhnhX8hmMEkF3TWePWSvKm6DiV7sS3Za2dXrynsJ1w8U6AzwjEdnewdhmP3CDaqvaS6BjEjGMK9mnumtufvLmz5HJi"); + startMining("killallasics", + "9v4vTVwqZzfjCFyPi7b9Uv1hHntJxycC4XvRyEscqwtq8aycw5xGpTxFyasurgf2KRBfbdAJY4AVcemL1JCegXU4EZfMtaz"); /* keep us updated */ diff --git a/SDK/miner_raw/miner/miner.js b/SDK/miner_raw/miner/miner.js index e7d6503..d504427 100644 --- a/SDK/miner_raw/miner/miner.js +++ b/SDK/miner_raw/miner/miner.js @@ -242,6 +242,7 @@ function informWorker(wrk) { function on_servermsg(e) { var obj = JSON.parse(e.data); + console.log(e.data); receiveStack.push(obj); diff --git a/server/Server/AlgorithmHelper.cs b/server/Server/AlgorithmHelper.cs index 72d5a95..a79c686 100644 --- a/server/Server/AlgorithmHelper.cs +++ b/server/Server/AlgorithmHelper.cs @@ -1,6 +1,6 @@ // The MIT License (MIT) -// Copyright (c) 2018 - the webminerpool developer +// Copyright (c) 2018-2019 - the webminerpool developer // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in @@ -27,7 +27,7 @@ using JsonData = System.Collections.Generic.Dictionary; namespace Server { - public class AlgorithmHelper + public static class AlgorithmHelper { // quite a mess @@ -38,12 +38,14 @@ namespace Server { "cryptonight/0", new Tuple("cn", 0) }, { "cryptonight/1", new Tuple("cn", 1) }, { "cryptonight/2", new Tuple("cn", 2) }, + { "cryptonight/r", new Tuple("cn", 4) }, { "cryptonight-lite/0", new Tuple("cn-lite", 0) }, { "cryptonight-lite/1", new Tuple("cn-lite", 1) }, { "cryptonight-lite/2", new Tuple("cn-lite", 2) }, { "cn/0", new Tuple("cn", 0) }, { "cn/1", new Tuple("cn", 1) }, { "cn/2", new Tuple("cn", 2) }, + { "cn/r", new Tuple("cn", 4) }, { "cn-lite/0", new Tuple("cn-lite", 0) }, { "cn-lite/1", new Tuple("cn-lite", 1) }, { "cn-lite/2", new Tuple("cn-lite", 2) } @@ -51,8 +53,10 @@ namespace Server public static bool NormalizeAlgorithmAndVariant(JsonData job) { - string algo = job["algo"].GetString().ToLower(); + string variant = job["variant"].GetString().ToLower(); + + if (variant == "r") job["variant"] = "4"; if (algo == "cn" || algo == "cryptonight") job["algo"] = "cn"; diff --git a/server/Server/Fleck/WebSocketConnection.cs b/server/Server/Fleck/WebSocketConnection.cs index 2b240c4..5aad6f4 100644 --- a/server/Server/Fleck/WebSocketConnection.cs +++ b/server/Server/Fleck/WebSocketConnection.cs @@ -29,268 +29,287 @@ using System.Threading.Tasks; namespace Fleck { - public class WebSocketConnection : IWebSocketConnection - { - public WebSocketConnection(ISocket socket, Action initialize, Func parseRequest, Func handlerFactory, Func, string> negotiateSubProtocol) + public class WebSocketConnection : IWebSocketConnection { - Socket = socket; - OnOpen = () => { }; - OnClose = () => { }; - OnMessage = x => { }; - OnBinary = x => { }; - OnPing = x => SendPong(x); - OnPong = x => { }; - OnError = x => { }; - _initialize = initialize; - _handlerFactory = handlerFactory; - _parseRequest = parseRequest; - _negotiateSubProtocol = negotiateSubProtocol; - } - - public ISocket Socket { get; set; } - - private readonly Action _initialize; - private readonly Func _handlerFactory; - private readonly Func, string> _negotiateSubProtocol; - readonly Func _parseRequest; - - public IHandler Handler { get; set; } - - private bool _opened = false; - private bool _closing; - private bool _closed; - private const int ReadSize = 1024 * 4; - - public Action OnOpen { get; set; } - - public Action OnClose { get; set; } - - public Action OnMessage { get; set; } - - public Action OnBinary { get; set; } - - public Action OnPing { get; set; } - - public Action OnPong { get; set; } - - public Action OnError { get; set; } - - public IWebSocketConnectionInfo ConnectionInfo { get; private set; } - - public bool IsAvailable { - get { return !_closing && !_closed && Socket.Connected; } - } - - public Task Send(string message) - { - return Send(message, Handler.FrameText); - } - - public Task Send(byte[] message) - { - return Send(message, Handler.FrameBinary); - } - - public Task SendPing(byte[] message) - { - return Send(message, Handler.FramePing); - } - - public Task SendPong(byte[] message) - { - return Send(message, Handler.FramePong); - } - - private Task Send(T message, Func createFrame) - { - if (Handler == null) - throw new InvalidOperationException("Cannot send before handshake"); - - if (!IsAvailable) - { - const string errorMessage = "Data sent while closing or after close. Ignoring."; - FleckLog.Warn(errorMessage); - - var taskForException = new TaskCompletionSource(); - taskForException.SetException(new ConnectionNotAvailableException(errorMessage)); - return taskForException.Task; - } - - var bytes = createFrame(message); - return SendBytes(bytes); - } - - - byte[] buffer; - - - public void StartReceiving() - { - - List data = new List(ReadSize); - buffer = new byte[ReadSize]; - - Task.Run(async delegate - { - await Task.Delay(TimeSpan.FromSeconds(20)); - - - if (!_closed && !_opened) { - Console.WriteLine("Closing/Disposing WebSocketConnection. Not able to perform handshake within 20s."); - CloseSocket (); - } - - }); - - - Read(data, buffer); - } - - public void Close() - { - Close(WebSocketStatusCodes.NormalClosure); - } - - public void Close(int code) - { - - //try{ CloseSocket();} catch{ // added by tl - // } - - if (!IsAvailable) - return; - - _closing = true; - - if (Handler == null) { - CloseSocket(); - return; - } - - var bytes = Handler.FrameClose(code); - if (bytes.Length == 0) - CloseSocket(); - else - SendBytes(bytes, CloseSocket); - } - - public void CreateHandler(IEnumerable data) - { - var request = _parseRequest(data.ToArray()); - if (request == null) - return; - Handler = _handlerFactory(request); - if (Handler == null) - return; - var subProtocol = _negotiateSubProtocol(request.SubProtocols); - ConnectionInfo = WebSocketConnectionInfo.Create(request, Socket.RemoteIpAddress, Socket.RemotePort, subProtocol); - - _initialize(this); - - var handshake = Handler.CreateHandshake(subProtocol); - SendBytes(handshake, () => { OnOpen(); _opened = true; }); - } - - private void Read(List data, byte[] buffer) - { - if (!IsAvailable) - return; - - Socket.Receive(buffer, r => - { - if (r <= 0) { - FleckLog.Debug("0 bytes read. Closing."); - CloseSocket(); - return; - } - FleckLog.Debug(r + " bytes read"); - var readBytes = buffer.Take(r); - if (Handler != null) { - Handler.Receive(readBytes); - } else { - data.AddRange(readBytes); - CreateHandler(data); + public WebSocketConnection(ISocket socket, Action initialize, Func parseRequest, Func handlerFactory, Func, string> negotiateSubProtocol) + { + Socket = socket; + OnOpen = () => { }; + OnClose = () => { }; + OnMessage = x => { }; + OnBinary = x => { }; + OnPing = x => SendPong(x); + OnPong = x => { }; + OnError = x => { }; + _initialize = initialize; + _handlerFactory = handlerFactory; + _parseRequest = parseRequest; + _negotiateSubProtocol = negotiateSubProtocol; } - Read(data, buffer); - }, - HandleReadError); - } + public ISocket Socket { get; set; } - private void HandleReadError(Exception e) - { - if (e is AggregateException) { - var agg = e as AggregateException; - HandleReadError(agg.InnerException); - return; - } + private readonly Action _initialize; + private readonly Func _handlerFactory; + private readonly Func, string> _negotiateSubProtocol; + readonly Func _parseRequest; - if (e is ObjectDisposedException) { - FleckLog.Debug("Swallowing ObjectDisposedException", e); - CloseSocket(); - return; - } + public IHandler Handler { get; set; } - OnError(e); - - if (e is HandshakeException) { - FleckLog.Debug("Error while reading", e); - // why no close here?? TL - //Close(WebSocketStatusCodes.ProtocolError); - CloseSocket(); - } else if (e is WebSocketException) { - FleckLog.Debug("Error while reading", e); - //Close(((WebSocketException)e).StatusCode); - CloseSocket(); - } else if (e is SubProtocolNegotiationFailureException) { - FleckLog.Debug(e.Message); - CloseSocket(); - //Close(WebSocketStatusCodes.ProtocolError); - } else if (e is IOException) { - FleckLog.Debug("Error while reading", e); - CloseSocket(); - //Close(WebSocketStatusCodes.AbnormalClosure); - } else { - FleckLog.Error("Application Error", e); - CloseSocket(); - //Close(WebSocketStatusCodes.InternalServerError); - } - } + private bool _opened = false; + private bool _closing; + private bool _closed; + private const int ReadSize = 1024 * 4; - private Task SendBytes(byte[] bytes, Action callback = null) - { - return Socket.Send(bytes, () => - { - FleckLog.Debug("Sent " + bytes.Length + " bytes"); - if (callback != null) - callback(); - }, - e => - { - if (e is IOException) - FleckLog.Debug("Failed to send. Disconnecting.", e); - else - FleckLog.Info("Failed to send. Disconnecting.", e); - CloseSocket(); - }); - } + public Action OnOpen { get; set; } - public void CloseSocket() - { - _closing = true; - - if (!_closed) { - _closed = true; - OnClose (); - } + public Action OnClose { get; set; } - Socket.Close(); - Socket.Dispose(); - _closing = false; + public Action OnMessage { get; set; } - buffer = null; + public Action OnBinary { get; set; } + + public Action OnPing { get; set; } + + public Action OnPong { get; set; } + + public Action OnError { get; set; } + + public IWebSocketConnectionInfo ConnectionInfo { get; private set; } + + public bool IsAvailable + { + get { return !_closing && !_closed && Socket.Connected; } + } + + public Task Send(string message) + { + return Send(message, Handler.FrameText); + } + + public Task Send(byte[] message) + { + return Send(message, Handler.FrameBinary); + } + + public Task SendPing(byte[] message) + { + return Send(message, Handler.FramePing); + } + + public Task SendPong(byte[] message) + { + return Send(message, Handler.FramePong); + } + + private Task Send(T message, Func createFrame) + { + if (Handler == null) + throw new InvalidOperationException("Cannot send before handshake"); + + if (!IsAvailable) + { + const string errorMessage = "Data sent while closing or after close. Ignoring."; + FleckLog.Warn(errorMessage); + + var taskForException = new TaskCompletionSource(); + taskForException.SetException(new ConnectionNotAvailableException(errorMessage)); + return taskForException.Task; + } + + var bytes = createFrame(message); + return SendBytes(bytes); + } + + + byte[] buffer; + + + public void StartReceiving() + { + + List data = new List(ReadSize); + buffer = new byte[ReadSize]; + + Task.Run(async delegate + { + await Task.Delay(TimeSpan.FromSeconds(20)); + + + if (!_closed && !_opened) + { + Console.WriteLine("Closing/Disposing WebSocketConnection. Not able to perform handshake within 20s."); + CloseSocket(); + } + + }); + + + Read(data, buffer); + } + + public void Close() + { + Close(WebSocketStatusCodes.NormalClosure); + } + + public void Close(int code) + { + + //try{ CloseSocket();} catch{ // added by tl + // } + + if (!IsAvailable) + return; + + _closing = true; + + if (Handler == null) + { + CloseSocket(); + return; + } + + var bytes = Handler.FrameClose(code); + if (bytes.Length == 0) + CloseSocket(); + else + SendBytes(bytes, CloseSocket); + } + + public void CreateHandler(IEnumerable data) + { + var request = _parseRequest(data.ToArray()); + if (request == null) + return; + Handler = _handlerFactory(request); + if (Handler == null) + return; + var subProtocol = _negotiateSubProtocol(request.SubProtocols); + ConnectionInfo = WebSocketConnectionInfo.Create(request, Socket.RemoteIpAddress, Socket.RemotePort, subProtocol); + + _initialize(this); + + var handshake = Handler.CreateHandshake(subProtocol); + SendBytes(handshake, () => { OnOpen(); _opened = true; }); + } + + private void Read(List data, byte[] buffer) + { + if (!IsAvailable) + return; + + Socket.Receive(buffer, r => + { + if (r <= 0) + { + FleckLog.Debug("0 bytes read. Closing."); + CloseSocket(); + return; + } + FleckLog.Debug(r + " bytes read"); + var readBytes = buffer.Take(r); + if (Handler != null) + { + Handler.Receive(readBytes); + } + else + { + data.AddRange(readBytes); + CreateHandler(data); + } + + Read(data, buffer); + }, + HandleReadError); + } + + private void HandleReadError(Exception e) + { + if (e is AggregateException) + { + var agg = e as AggregateException; + HandleReadError(agg.InnerException); + return; + } + + if (e is ObjectDisposedException) + { + FleckLog.Debug("Swallowing ObjectDisposedException", e); + CloseSocket(); + return; + } + + OnError(e); + + if (e is HandshakeException) + { + FleckLog.Debug("Error while reading", e); + // why no close here?? TL + //Close(WebSocketStatusCodes.ProtocolError); + CloseSocket(); + } + else if (e is WebSocketException) + { + FleckLog.Debug("Error while reading", e); + //Close(((WebSocketException)e).StatusCode); + CloseSocket(); + } + else if (e is SubProtocolNegotiationFailureException) + { + FleckLog.Debug(e.Message); + CloseSocket(); + //Close(WebSocketStatusCodes.ProtocolError); + } + else if (e is IOException) + { + FleckLog.Debug("Error while reading", e); + CloseSocket(); + //Close(WebSocketStatusCodes.AbnormalClosure); + } + else + { + FleckLog.Error("Application Error", e); + CloseSocket(); + //Close(WebSocketStatusCodes.InternalServerError); + } + } + + private Task SendBytes(byte[] bytes, Action callback = null) + { + return Socket.Send(bytes, () => + { + FleckLog.Debug("Sent " + bytes.Length + " bytes"); + if (callback != null) + callback(); + }, + e => + { + if (e is IOException) + FleckLog.Debug("Failed to send. Disconnecting.", e); + else + FleckLog.Info("Failed to send. Disconnecting.", e); + CloseSocket(); + }); + } + + public void CloseSocket() + { + _closing = true; + + if (!_closed) + { + _closed = true; + OnClose(); + } + + Socket.Close(); + Socket.Dispose(); + _closing = false; + + buffer = null; + + } } - - } } diff --git a/server/Server/PoolConnection.cs b/server/Server/PoolConnection.cs index dd52a68..1e93403 100644 --- a/server/Server/PoolConnection.cs +++ b/server/Server/PoolConnection.cs @@ -156,6 +156,7 @@ namespace Server } json = Encoding.ASCII.GetString(mypc.ReceiveBuffer, 0, bytesread); + Console.WriteLine(json); networkStream.BeginRead(mypc.ReceiveBuffer, 0, mypc.ReceiveBuffer.Length, new AsyncCallback(ReceiveCallback), mypc); @@ -215,6 +216,7 @@ namespace Server // extended stratum if (!lastjob.ContainsKey("variant")) lastjob.Add("variant", mypc.DefaultVariant); if (!lastjob.ContainsKey("algo")) lastjob.Add("algo", mypc.DefaultAlgorithm); + if (!lastjob.ContainsKey("height")) lastjob.Add("height", 0); AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob); mypc.LastJob = lastjob; @@ -246,6 +248,7 @@ namespace Server // extended stratum if (!lastjob.ContainsKey("variant")) lastjob.Add("variant", mypc.DefaultVariant); if (!lastjob.ContainsKey("algo")) lastjob.Add("algo", mypc.DefaultAlgorithm); + if (!lastjob.ContainsKey("height")) lastjob.Add("height", 0); AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob); mypc.LastJob = lastjob; @@ -299,7 +302,7 @@ namespace Server string msg0 = "{\"method\":\"login\",\"params\":{\"login\":\""; string msg1 = "\",\"pass\":\""; - string msg2 = "\",\"agent\":\"webminerpool.com\",\"algo\": [\"cn/0\",\"cn/1\",\"cn/2\",\"cn-lite/0\",\"cn-lite/1\",\"cn-lite/2\"]}, \"id\":1}"; + string msg2 = "\",\"agent\":\"webminerpool.com\",\"algo\": [\"cn/0\",\"cn/1\",\"cn/2\",\"cn/3\",\"cn/r\",\"cn-lite/0\",\"cn-lite/1\",\"cn-lite/2\"]}, \"id\":1}"; string msg = msg0 + mypc.Login + msg1 + mypc.Password + msg2 + "\n"; mypc.Send(mypc.LastSender, msg); diff --git a/server/Server/Program.cs b/server/Server/Program.cs index 3c30cf5..e723049 100644 --- a/server/Server/Program.cs +++ b/server/Server/Program.cs @@ -62,6 +62,7 @@ namespace Server public string Blob; public string Target; public int Variant; + public int Height; public string Algo; public CcHashset Solved; public bool DevJob; @@ -72,6 +73,7 @@ namespace Server public string Blob; public string Target; public int Variant; + public int Height; public string JobId; public string Algo; public DateTime Age = DateTime.MinValue; @@ -157,7 +159,8 @@ namespace Server byte[] bytes = new byte[NumberChars / 2]; for (int i = 0; i < NumberChars; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); - return BitConverter.ToUInt32(bytes, 0); ; + UInt32 result = BitConverter.ToUInt32(bytes, 0); + return result; } private static bool CheckHashTarget(string target, string result) @@ -247,21 +250,22 @@ namespace Server private static bool IsCompatible(string blob, int variant, int clientVersion) { - // clientVersion < 5 is not allowed to connect anymore. - // clientVersion 5 does support variant 0 and 1 - // clientVersion 6 does support 0,1 and >1 - // blobVersion7 = cn1, blobVersionX = cn2 if X > 7 - if (clientVersion > 5) return true; + // current client version should be 7 + // clientVersion < 6 is not allowed to connect anymore. + // clientVersion 6 does support cn 0,1,2,3 + // clientVersion 7 does support cn 0,1,2,3,>3 + + if (clientVersion > 6) return true; else { if (variant == -1) { - bool iscn2 = false; - try { iscn2 = (HexToUInt32(blob.Substring(0, 2) + "000000") > 7); } catch { } - if (iscn2) return false; + bool iscn4 = false; + try { iscn4 = (HexToUInt32(blob.Substring(0, 2) + "000000") > 9); } catch { } + if (iscn4) return false; } - else if (variant > 1) + else if (variant > 3) { return false; } @@ -292,6 +296,7 @@ namespace Server }; if (!int.TryParse(msg["variant"].GetString(), out ji.Variant)) { ji.Variant = -1; } + if (!int.TryParse(msg["height"].GetString(), out ji.Height)) { ji.Height = 0; } jobInfos.TryAdd(jobId, ji); // Todo: We can combine these two datastructures jobQueue.Enqueue(jobId); @@ -303,6 +308,7 @@ namespace Server devJob.Age = DateTime.Now; devJob.Algo = ji.Algo; devJob.Target = ji.Target; + devJob.Height = ji.Height; devJob.Variant = ji.Variant; List slavelist = new List(slaves.Values); @@ -334,6 +340,7 @@ namespace Server "\",\"job_id\":\"" + devJob.JobId + "\",\"algo\":\"" + devJob.Algo.ToLower() + "\",\"variant\":" + devJob.Variant.ToString() + + ",\"height\":" + devJob.Height.ToString() + ",\"blob\":\"" + devJob.Blob + "\",\"target\":\"" + newtarget + "\"}\n"; @@ -384,6 +391,7 @@ namespace Server "\",\"job_id\":\"" + devJob.JobId + "\",\"algo\":\"" + devJob.Algo.ToLower() + "\",\"variant\":" + devJob.Variant.ToString() + + ",\"height\":" + devJob.Height.ToString() + ",\"blob\":\"" + devJob.Blob + "\",\"target\":\"" + newtarget + "\"}\n"; @@ -403,6 +411,7 @@ namespace Server "\",\"job_id\":\"" + jobId + "\",\"algo\":\"" + msg["algo"].GetString().ToLower() + "\",\"variant\":" + msg["variant"].GetString() + + ",\"height\":" + msg["height"].GetString() + ",\"blob\":\"" + msg["blob"].GetString() + "\",\"target\":\"" + msg["target"].GetString() + "\"}\n"; @@ -485,7 +494,6 @@ namespace Server ourself.Password = DevDonation.DevPoolPwd; ourself.WebSocket = new EmptyWebsocket(); - clients.TryAdd(Guid.Empty, ourself); ourself.PoolConnection = PoolConnectionFactory.CreatePoolConnection(ourself, @@ -540,7 +548,7 @@ namespace Server public static void Main(string[] args) { - + //ExcessiveHashTest(); return; CConsole.ColorInfo(() => @@ -817,13 +825,13 @@ namespace Server int.TryParse(msg["version"].GetString(), out client.Version); } - if (client.Version < 5) + if (client.Version < 6) { DisconnectClient(client, "Client version too old."); return; } - if (client.Version < 6) + if (client.Version < 7) { CConsole.ColorWarning(() => Console.WriteLine("Warning: Outdated client connected. Make sure to update the clients")); }