Exemple #1
0
        /// <summary>
        /// Sets the current mining mission.
        /// </summary>
        /// <param name="wp">The work package we wish to be mining.</param>
        public void SetWork(WorkPackage wp)
        {
            if (_currentWp.Epoch != wp.Epoch)
            {
                //var ec = Ethash.GetGlobalEpochContext(wp.Epoch);
                //_currentEc.EpochNumber = wp.Epoch;
                //_currentEc.LightNumItems = ec.LightCacheNumItems;
                //_currentEc.LightSize = Ethash.GetLightCacheSize(ec.LightCacheNumItems);
                //_currentEc.DagNumItems = ec.FullDatasetNumItems;
                //_currentEc.DagSize = Ethash.GetFullDatasetSize(ec.FullDatasetNumItems);
                //_currentEc.LightCache = ec.LightCcache;
                foreach (var miner in _miners)
                {
                    miner.SetEpoch(_currentEc);
                }
            }

            _currentWp = wp;

            // Check if we need to shuffle per work (ergodicity == 2)
            if (_options.Ergodicity == 2 && _currentWp.ExSizeBytes == 0)
            {
                Shuffle();
            }

            ulong startNonce;

            if (_currentWp.ExSizeBytes > 0)
            {
                // Equally divide the residual segment among miners
                startNonce         = _currentWp.StartNonce;
                _nonceSegmentWidth = (int)Math.Log(Math.Pow(2, 64 - (_currentWp.ExSizeBytes * 4)) / _miners.Count, 2);
            }
            // Get the randomly selected nonce
            else
            {
                startNonce = _nonceScrambler;
            }

            for (var i = 0; i < _miners.Count; i++)
            {
                _currentWp.StartNonce = startNonce + ((ulong)i << _nonceSegmentWidth);
                _miners[i].SetWork(_currentWp);
            }
        }
Exemple #2
0
 public void SetWork(WorkPackage currentWp)
 {
     throw new NotImplementedException();
 }
Exemple #3
0
        void SetClientHandlers()
        {
            _client.OnConnected((f, c) =>
            {
                var connection = c.Connection;
                // If HostName is already an IP address no need to append the effective ip address.
                if ((connection.HostNameType == UriHostNameType.Dns || connection.HostNameType == UriHostNameType.Basic) && !string.IsNullOrEmpty(c.ActiveEndPoint))
                {
                    _selectedHost = connection.Host + c.ActiveEndPoint;
                }

                Console.WriteLine($"Established connection to {_selectedHost}");
                _connectionAttempt = 0;

                // Reset current WorkPackage
                _currentWp.Job    = null;
                _currentWp.Header = H256.Empty;

                // Shuffle if needed
                if (f.Ergodicity == 1U)
                {
                    f.Shuffle();
                }

                // Rough implementation to return to primary pool after specified amount of time
                _failoverTimer = _activeConnectionIdx != 0 && _options.PoolFailoverTimeout != 0
                    ? new Timer(FailoverTimer_Elapsed, null, new TimeSpan(0, _options.PoolFailoverTimeout, 0), new TimeSpan(0, 0, -1))
                    : null;

                if (!f.IsMining)
                {
                    Console.WriteLine("Spinning up miners...");
                    f.Start();
                }
                else if (f.Paused)
                {
                    Console.WriteLine("Resume mining ...");
                    f.Resume();
                }

                // Activate timing for HR submission
                _submithrTimer = _options.ReportHashrate
                    ? new Timer(SubmithrTimer_Elapsed, null, new TimeSpan(0, 0, _options.HashRateInterval), new TimeSpan(0, 0, -1))
                    : null;

                // Signal async operations have completed
                _asyncPending = 0; //: atomic
            });

            _client.OnDisconnected((f, c) =>
            {
                Console.WriteLine($"Disconnected from {_selectedHost}");

                // Clear current connection
                c.UnsetConnection();
                _currentWp.Header = H256.Empty;

                // Stop timing actors
                _failoverTimer?.Dispose(); _failoverTimer = null;
                _submithrTimer?.Dispose(); _submithrTimer = null;

                if (_stopping != 0) //: atomic
                {
                    if (f.IsMining)
                    {
                        Console.WriteLine("Shutting down miners...");
                        f.Stop();
                    }
                    _running = 0; //: atomic
                }
                else
                {
                    // Signal we will reconnect async
                    _asyncPending = 1; //: atomic

                    // Suspend mining and submit new connection request
                    Console.WriteLine("No connection. Suspend mining ...");
                    f.Pause();
                    Task.Run(() => RotateConnect());
                }
            });

            _client.OnWorkReceived((f, c, wp) =>
            {
                // Should not happen !
                if (wp == null)
                {
                    return;
                }

                var _currentEpoch = _currentWp.Epoch;
                var newEpoch      = _currentEpoch == -1;
                // In EthereumStratum/2.0.0 epoch number is set in session
                if (!newEpoch)
                {
                    newEpoch = c.Connection.GetStratumMode() == StratumVersion.EthereumStratum2
                        ? wp.Epoch != _currentWp.Epoch
                        : wp.Seed != _currentWp.Seed;
                }
                var newDiff = wp.Boundary != _currentWp.Boundary;
                _currentWp  = wp;

                if (newEpoch)
                {
                    Interlocked.Add(ref _epochChanges, 1);
                    // If epoch is valued in workpackage take it
                    if (wp.Epoch == -1)
                    {
                        _currentWp.Epoch = _currentWp.Block >= 0
                            ? _currentWp.Block / 30000
                            : Ethash.FindEpochNumber(Ethash.Hash256FromBytes(_currentWp.Seed.Data));
                    }
                }
                else
                {
                    _currentWp.Epoch = _currentEpoch;
                }

                if (newDiff || newEpoch)
                {
                    ShowMiningAt();
                }

                Console.WriteLine($"Job: {Ansi.White}{_currentWp.Header.Abridged}{(_currentWp.Block != -1 ? $" block {_currentWp.Block}" : null)}{Ansi.Reset} {_selectedHost}");
                f.SetWork(_currentWp);
            });

            _client.OnSolutionAccepted((f, c, responseDelay, minerIdx, asStale) =>
            {
                Console.WriteLine($"{Ansi.Lime}**Accepted{(asStale ? " stale" : null)}{Ansi.Reset}{responseDelay,4} ms. {_selectedHost}");
                f.AccountSolution(minerIdx, SolutionAccounting.Accepted);
            });

            _client.OnSolutionRejected((f, c, responseDelay, minerIdx) =>
            {
                Console.WriteLine($"{Ansi.Red}**Rejected{Ansi.Reset}{responseDelay,4} ms. {_selectedHost}");
                f.AccountSolution(minerIdx, SolutionAccounting.Rejected);
            });
        }