public static (H256 value, H256 mixHash) Eval(int epoch, H256 headerHash, ulong nonce) { var hash = Ethash.Hash256FromBytes(headerHash.Data); var context = Ethash.GetGlobalEpochContext(epoch); var result = Ethash.Hash(context, hash, nonce); //H256 mix { reinterpret_cast<byte*>(result.mix_hash.bytes), H256.ConstructFromPointer}; //H256 final { reinterpret_cast<byte*>(result.final_hash.bytes), H256.ConstructFromPointer}; //return { final, mix}; throw new NotImplementedException(); }
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); }); }