Gav Wood
10 years ago
11 changed files with 650 additions and 456 deletions
@ -0,0 +1,119 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file EthashCPUMiner.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* |
|||
* Determines the PoW algorithm. |
|||
*/ |
|||
|
|||
#include "EthashCPUMiner.h" |
|||
#include <thread> |
|||
#include <chrono> |
|||
#include <boost/algorithm/string.hpp> |
|||
#if ETH_CPUID || !ETH_TRUE |
|||
#define HAVE_STDINT_H |
|||
#include <libcpuid/libcpuid.h> |
|||
#endif |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace eth; |
|||
|
|||
unsigned EthashCPUMiner::s_numInstances = 0; |
|||
|
|||
static string jsonEncode(map<string, string> const& _m) |
|||
{ |
|||
string ret = "{"; |
|||
|
|||
for (auto const& i: _m) |
|||
{ |
|||
string k = boost::replace_all_copy(boost::replace_all_copy(i.first, "\\", "\\\\"), "'", "\\'"); |
|||
string v = boost::replace_all_copy(boost::replace_all_copy(i.second, "\\", "\\\\"), "'", "\\'"); |
|||
if (ret.size() > 1) |
|||
ret += ", "; |
|||
ret += "\"" + k + "\":\"" + v + "\""; |
|||
} |
|||
|
|||
return ret + "}"; |
|||
} |
|||
|
|||
void EthashCPUMiner::workLoop() |
|||
{ |
|||
auto tid = std::this_thread::get_id(); |
|||
static std::mt19937_64 s_eng((time(0) + std::hash<decltype(tid)>()(tid))); |
|||
|
|||
uint64_t tryNonce = (uint64_t)(u64)Nonce::random(s_eng); |
|||
ethash_return_value ethashReturn; |
|||
|
|||
WorkPackage w = work(); |
|||
|
|||
EthashAux::FullType dag; |
|||
while (!shouldStop() && !dag) |
|||
{ |
|||
while (!shouldStop() && EthashAux::computeFull(w.seedHash, true) != 100) |
|||
this_thread::sleep_for(chrono::milliseconds(500)); |
|||
dag = EthashAux::full(w.seedHash, false); |
|||
} |
|||
|
|||
h256 boundary = w.boundary; |
|||
unsigned hashCount = 1; |
|||
for (; !shouldStop(); tryNonce++, hashCount++) |
|||
{ |
|||
ethashReturn = ethash_full_compute(dag->full, *(ethash_h256_t*)w.headerHash.data(), tryNonce); |
|||
h256 value = h256((uint8_t*)ðashReturn.result, h256::ConstructFromPointer); |
|||
if (value <= boundary && submitProof(EthashProofOfWork::Solution{(h64)(u64)tryNonce, h256((uint8_t*)ðashReturn.mix_hash, h256::ConstructFromPointer)})) |
|||
break; |
|||
if (!(hashCount % 100)) |
|||
accumulateHashes(100); |
|||
} |
|||
} |
|||
|
|||
std::string EthashCPUMiner::platformInfo() |
|||
{ |
|||
string baseline = toString(std::thread::hardware_concurrency()) + "-thread CPU"; |
|||
#if ETH_CPUID || !ETH_TRUE |
|||
if (!cpuid_present()) |
|||
return baseline; |
|||
struct cpu_raw_data_t raw; |
|||
struct cpu_id_t data; |
|||
if (cpuid_get_raw_data(&raw) < 0) |
|||
return baseline; |
|||
if (cpu_identify(&raw, &data) < 0) |
|||
return baseline; |
|||
map<string, string> m; |
|||
m["vendor"] = data.vendor_str; |
|||
m["codename"] = data.cpu_codename; |
|||
m["brand"] = data.brand_str; |
|||
m["L1 cache"] = toString(data.l1_data_cache); |
|||
m["L2 cache"] = toString(data.l2_cache); |
|||
m["L3 cache"] = toString(data.l3_cache); |
|||
m["cores"] = toString(data.num_cores); |
|||
m["threads"] = toString(data.num_logical_cpus); |
|||
m["clocknominal"] = toString(cpu_clock_by_os()); |
|||
m["clocktested"] = toString(cpu_clock_measure(200, 0)); |
|||
/*
|
|||
printf(" MMX : %s\n", data.flags[CPU_FEATURE_MMX] ? "present" : "absent"); |
|||
printf(" MMX-extended: %s\n", data.flags[CPU_FEATURE_MMXEXT] ? "present" : "absent"); |
|||
printf(" SSE : %s\n", data.flags[CPU_FEATURE_SSE] ? "present" : "absent"); |
|||
printf(" SSE2 : %s\n", data.flags[CPU_FEATURE_SSE2] ? "present" : "absent"); |
|||
printf(" 3DNow! : %s\n", data.flags[CPU_FEATURE_3DNOW] ? "present" : "absent"); |
|||
*/ |
|||
return jsonEncode(m); |
|||
#else |
|||
return baseline; |
|||
#endif |
|||
} |
@ -0,0 +1,61 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file EthashCPUMiner.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* |
|||
* Determines the PoW algorithm. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "libdevcore/Worker.h" |
|||
#include "EthashAux.h" |
|||
#include "Miner.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
class EthashCPUMiner: public GenericMiner<EthashProofOfWork>, Worker |
|||
{ |
|||
public: |
|||
EthashCPUMiner(GenericMiner<EthashProofOfWork>::ConstructionInfo const& _ci): GenericMiner<EthashProofOfWork>(_ci), Worker("miner" + toString(index())) {} |
|||
|
|||
static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); } |
|||
static std::string platformInfo(); |
|||
static void listDevices() {} |
|||
static bool configureGPU(unsigned, unsigned, unsigned, unsigned, unsigned, bool, unsigned, uint64_t) { return false; } |
|||
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); } |
|||
|
|||
protected: |
|||
void kickOff() override |
|||
{ |
|||
stopWorking(); |
|||
startWorking(); |
|||
} |
|||
|
|||
void pause() override { stopWorking(); } |
|||
|
|||
private: |
|||
void workLoop() override; |
|||
static unsigned s_numInstances; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,239 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file EthashGPUMiner.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* |
|||
* Determines the PoW algorithm. |
|||
*/ |
|||
|
|||
#if ETH_ETHASHCL || !ETH_TRUE |
|||
|
|||
#include "EthashGPUMiner.h" |
|||
#include <thread> |
|||
#include <chrono> |
|||
#include <cpuid.h> |
|||
#include <libethash-cl/ethash_cl_miner.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace eth; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
class EthashCLHook: public ethash_cl_miner::search_hook |
|||
{ |
|||
public: |
|||
EthashCLHook(EthashGPUMiner* _owner): m_owner(_owner) {} |
|||
EthashCLHook(EthashCLHook const&) = delete; |
|||
|
|||
void abort() |
|||
{ |
|||
{ |
|||
UniqueGuard l(x_all); |
|||
if (m_aborted) |
|||
return; |
|||
// cdebug << "Attempting to abort";
|
|||
|
|||
m_abort = true; |
|||
} |
|||
// m_abort is true so now searched()/found() will return true to abort the search.
|
|||
// we hang around on this thread waiting for them to point out that they have aborted since
|
|||
// otherwise we may end up deleting this object prior to searched()/found() being called.
|
|||
m_aborted.wait(true); |
|||
// for (unsigned timeout = 0; timeout < 100 && !m_aborted; ++timeout)
|
|||
// std::this_thread::sleep_for(chrono::milliseconds(30));
|
|||
// if (!m_aborted)
|
|||
// cwarn << "Couldn't abort. Abandoning OpenCL process.";
|
|||
} |
|||
|
|||
void reset() |
|||
{ |
|||
UniqueGuard l(x_all); |
|||
m_aborted = m_abort = false; |
|||
} |
|||
|
|||
protected: |
|||
virtual bool found(uint64_t const* _nonces, uint32_t _count) override |
|||
{ |
|||
// dev::operator <<(std::cerr << "Found nonces: ", vector<uint64_t>(_nonces, _nonces + _count)) << std::endl;
|
|||
for (uint32_t i = 0; i < _count; ++i) |
|||
if (m_owner->report(_nonces[i])) |
|||
return (m_aborted = true); |
|||
return m_owner->shouldStop(); |
|||
} |
|||
|
|||
virtual bool searched(uint64_t _startNonce, uint32_t _count) override |
|||
{ |
|||
UniqueGuard l(x_all); |
|||
// std::cerr << "Searched " << _count << " from " << _startNonce << std::endl;
|
|||
m_owner->accumulateHashes(_count); |
|||
m_last = _startNonce + _count; |
|||
if (m_abort || m_owner->shouldStop()) |
|||
return (m_aborted = true); |
|||
return false; |
|||
} |
|||
|
|||
private: |
|||
Mutex x_all; |
|||
uint64_t m_last; |
|||
bool m_abort = false; |
|||
Notified<bool> m_aborted = {true}; |
|||
EthashGPUMiner* m_owner = nullptr; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
unsigned EthashGPUMiner::s_platformId = 0; |
|||
unsigned EthashGPUMiner::s_deviceId = 0; |
|||
unsigned EthashGPUMiner::s_numInstances = 0; |
|||
|
|||
EthashGPUMiner::EthashGPUMiner(ConstructionInfo const& _ci): |
|||
GenericMiner<EthashProofOfWork>(_ci), |
|||
Worker("gpuminer" + toString(index())), |
|||
m_hook(new EthashCLHook(this)) |
|||
{ |
|||
} |
|||
|
|||
EthashGPUMiner::~EthashGPUMiner() |
|||
{ |
|||
pause(); |
|||
delete m_miner; |
|||
delete m_hook; |
|||
} |
|||
|
|||
bool EthashGPUMiner::report(uint64_t _nonce) |
|||
{ |
|||
Nonce n = (Nonce)(u64)_nonce; |
|||
EthashProofOfWork::Result r = EthashAux::eval(work().seedHash, work().headerHash, n); |
|||
if (r.value < work().boundary) |
|||
return submitProof(Solution{n, r.mixHash}); |
|||
return false; |
|||
} |
|||
|
|||
void EthashGPUMiner::kickOff() |
|||
{ |
|||
m_hook->reset(); |
|||
startWorking(); |
|||
} |
|||
|
|||
void EthashGPUMiner::workLoop() |
|||
{ |
|||
// take local copy of work since it may end up being overwritten by kickOff/pause.
|
|||
try { |
|||
WorkPackage w = work(); |
|||
cnote << "workLoop" << !!m_miner << m_minerSeed << w.seedHash; |
|||
if (!m_miner || m_minerSeed != w.seedHash) |
|||
{ |
|||
cnote << "Initialising miner..."; |
|||
m_minerSeed = w.seedHash; |
|||
|
|||
delete m_miner; |
|||
m_miner = new ethash_cl_miner; |
|||
|
|||
unsigned device = instances() > 1 ? index() : s_deviceId; |
|||
|
|||
EthashAux::FullType dag; |
|||
while (true) |
|||
{ |
|||
if ((dag = EthashAux::full(w.seedHash, true))) |
|||
break; |
|||
if (shouldStop()) |
|||
{ |
|||
delete m_miner; |
|||
m_miner = nullptr; |
|||
return; |
|||
} |
|||
cnote << "Awaiting DAG"; |
|||
this_thread::sleep_for(chrono::milliseconds(500)); |
|||
} |
|||
bytesConstRef dagData = dag->data(); |
|||
m_miner->init(dagData.data(), dagData.size(), s_platformId, device); |
|||
} |
|||
|
|||
uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); |
|||
m_miner->search(w.headerHash.data(), upper64OfBoundary, *m_hook); |
|||
} |
|||
catch (cl::Error const& _e) |
|||
{ |
|||
delete m_miner; |
|||
m_miner = nullptr; |
|||
cwarn << "Error GPU mining: " << _e.what() << "(" << _e.err() << ")"; |
|||
} |
|||
} |
|||
|
|||
void EthashGPUMiner::pause() |
|||
{ |
|||
m_hook->abort(); |
|||
stopWorking(); |
|||
} |
|||
|
|||
std::string EthashGPUMiner::platformInfo() |
|||
{ |
|||
return ethash_cl_miner::platform_info(s_platformId, s_deviceId); |
|||
} |
|||
|
|||
unsigned EthashGPUMiner::getNumDevices() |
|||
{ |
|||
return ethash_cl_miner::getNumDevices(s_platformId); |
|||
} |
|||
|
|||
void EthashGPUMiner::listDevices() |
|||
{ |
|||
return ethash_cl_miner::listDevices(); |
|||
} |
|||
|
|||
bool EthashGPUMiner::configureGPU( |
|||
unsigned _localWorkSize, |
|||
unsigned _globalWorkSizeMultiplier, |
|||
unsigned _msPerBatch, |
|||
unsigned _platformId, |
|||
unsigned _deviceId, |
|||
bool _allowCPU, |
|||
unsigned _extraGPUMemory, |
|||
uint64_t _currentBlock |
|||
) |
|||
{ |
|||
s_platformId = _platformId; |
|||
s_deviceId = _deviceId; |
|||
|
|||
if (_localWorkSize != 32 && _localWorkSize != 64 && _localWorkSize != 128) |
|||
{ |
|||
cout << "Given localWorkSize of " << toString(_localWorkSize) << "is invalid. Must be either 32,64, or 128" << endl; |
|||
return false; |
|||
} |
|||
|
|||
if (!ethash_cl_miner::configureGPU( |
|||
_platformId, |
|||
_localWorkSize, |
|||
_globalWorkSizeMultiplier * _localWorkSize, |
|||
_msPerBatch, |
|||
_allowCPU, |
|||
_extraGPUMemory, |
|||
_currentBlock) |
|||
) |
|||
{ |
|||
cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl; |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,82 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file EthashGPUMiner.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* |
|||
* Determines the PoW algorithm. |
|||
*/ |
|||
|
|||
#pragma once |
|||
#if ETH_ETHASHCL || !ETH_TRUE |
|||
|
|||
#include "libdevcore/Worker.h" |
|||
#include "EthashAux.h" |
|||
#include "Miner.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
class EthashGPUMiner: public GenericMiner<EthashProofOfWork>, Worker |
|||
{ |
|||
friend class dev::eth::EthashCLHook; |
|||
|
|||
public: |
|||
EthashGPUMiner(ConstructionInfo const& _ci); |
|||
~EthashGPUMiner(); |
|||
|
|||
static unsigned instances() { return s_numInstances > 0 ? s_numInstances : 1; } |
|||
static std::string platformInfo(); |
|||
static unsigned getNumDevices(); |
|||
static void listDevices(); |
|||
static bool configureGPU( |
|||
unsigned _localWorkSize, |
|||
unsigned _globalWorkSizeMultiplier, |
|||
unsigned _msPerBatch, |
|||
unsigned _platformId, |
|||
unsigned _deviceId, |
|||
bool _allowCPU, |
|||
unsigned _extraGPUMemory, |
|||
uint64_t _currentBlock |
|||
); |
|||
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, getNumDevices()); } |
|||
|
|||
protected: |
|||
void kickOff() override; |
|||
void pause() override; |
|||
|
|||
private: |
|||
void workLoop() override; |
|||
bool report(uint64_t _nonce); |
|||
|
|||
using GenericMiner<EthashProofOfWork>::accumulateHashes; |
|||
|
|||
EthashCLHook* m_hook = nullptr; |
|||
ethash_cl_miner* m_miner = nullptr; |
|||
|
|||
h256 m_minerSeed; ///< Last seed in m_miner
|
|||
static unsigned s_platformId; |
|||
static unsigned s_deviceId; |
|||
static unsigned s_numInstances; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,72 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file EthashSealEngine.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* |
|||
* Determines the PoW algorithm. |
|||
*/ |
|||
|
|||
#include "EthashSealEngine.h" |
|||
#include "EthashCPUMiner.h" |
|||
#include "EthashGPUMiner.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace eth; |
|||
|
|||
EthashSealEngine::EthashSealEngine() |
|||
{ |
|||
map<string, GenericFarm<EthashProofOfWork>::SealerDescriptor> sealers; |
|||
sealers["cpu"] = GenericFarm<EthashProofOfWork>::SealerDescriptor{&EthashCPUMiner::instances, [](GenericMiner<EthashProofOfWork>::ConstructionInfo ci){ return new EthashCPUMiner(ci); }}; |
|||
#if ETH_ETHASHCL |
|||
sealers["opencl"] = GenericFarm<EthashProofOfWork>::SealerDescriptor{&EthashGPUMiner::instances, [](GenericMiner<EthashProofOfWork>::ConstructionInfo ci){ return new EthashGPUMiner(ci); }}; |
|||
#endif |
|||
m_farm.setSealers(sealers); |
|||
} |
|||
|
|||
strings EthashSealEngine::sealers() const |
|||
{ |
|||
return { |
|||
"cpu" |
|||
#if ETH_ETHASHCL |
|||
, "opencl" |
|||
#endif |
|||
}; |
|||
} |
|||
|
|||
void EthashSealEngine::generateSeal(BlockInfo const& _bi) |
|||
{ |
|||
m_sealing = Ethash::BlockHeader(_bi); |
|||
m_farm.setWork(m_sealing); |
|||
m_farm.start(m_sealer); |
|||
m_farm.setWork(m_sealing); // TODO: take out one before or one after...
|
|||
Ethash::ensurePrecomputed((unsigned)_bi.number()); |
|||
} |
|||
|
|||
void EthashSealEngine::onSealGenerated(std::function<void(bytes const&)> const& _f) |
|||
{ |
|||
m_farm.onSolutionFound([=](EthashProofOfWork::Solution const& sol) |
|||
{ |
|||
cdebug << m_farm.work().seedHash << m_farm.work().headerHash << sol.nonce << EthashAux::eval(m_farm.work().seedHash, m_farm.work().headerHash, sol.nonce).value; |
|||
m_sealing.m_mixHash = sol.mixHash; |
|||
m_sealing.m_nonce = sol.nonce; |
|||
RLPStream ret; |
|||
m_sealing.streamRLP(ret); |
|||
_f(ret.out()); |
|||
return true; |
|||
}); |
|||
} |
@ -0,0 +1,56 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file EthashSealEngine.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* |
|||
* Determines the PoW algorithm. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "Sealer.h" |
|||
#include "Ethash.h" |
|||
#include "EthashAux.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
class EthashSealEngine: public SealEngineBase<Ethash> |
|||
{ |
|||
friend class Ethash; |
|||
|
|||
public: |
|||
EthashSealEngine(); |
|||
|
|||
strings sealers() const override; |
|||
void setSealer(std::string const& _sealer) override { m_sealer = _sealer; } |
|||
void cancelGeneration() override { m_farm.stop(); } |
|||
void generateSeal(BlockInfo const& _bi) override; |
|||
void onSealGenerated(std::function<void(bytes const&)> const& _f) override; |
|||
|
|||
private: |
|||
bool m_opencl = false; |
|||
eth::GenericFarm<EthashProofOfWork> m_farm; |
|||
std::string m_sealer = "cpu"; |
|||
Ethash::BlockHeader m_sealing; |
|||
}; |
|||
|
|||
} |
|||
} |
Loading…
Reference in new issue