Пример #1
0
        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);
            });
        }
Пример #2
0
        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();
                            });
                        }
                    }
                }
            }
        }
Пример #3
0
        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));
            }
        }
Пример #4
0
 private void OnNewWorkRecieved(StratumWork work, bool forceRestart)
 {
     if (NewWorkRecieved != null)
     {
         Task.Factory.StartNew(() =>
         {
             NewWorkRecieved(this, work, forceRestart);
         });
     }
 }
Пример #5
0
 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);
         }
     }
 }
Пример #6
0
 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);
         }
     }
 }
Пример #7
0
        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;
            }
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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;
        }