|
|
@ -30,6 +30,9 @@ |
|
|
|
#include <libdevcrypto/CryptoPP.h> |
|
|
|
#include <libdevcrypto/FileSystem.h> |
|
|
|
#include <libdevcore/Common.h> |
|
|
|
#if ETH_ETHASHCL |
|
|
|
#include <libethash-cl/ethash_cl_miner.h> |
|
|
|
#endif |
|
|
|
#include "BlockInfo.h" |
|
|
|
#include "Ethasher.h" |
|
|
|
#include "ProofOfWork.h" |
|
|
@ -41,12 +44,12 @@ namespace dev |
|
|
|
namespace eth |
|
|
|
{ |
|
|
|
|
|
|
|
bool Ethash::verify(BlockInfo const& _header) |
|
|
|
bool EthashCPU::verify(BlockInfo const& _header) |
|
|
|
{ |
|
|
|
return Ethasher::verify(_header); |
|
|
|
} |
|
|
|
|
|
|
|
std::pair<MineInfo, Ethash::Proof> Ethash::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) |
|
|
|
std::pair<MineInfo, EthashCPU::Proof> EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) |
|
|
|
{ |
|
|
|
Ethasher::Miner m(_header); |
|
|
|
|
|
|
@ -93,5 +96,113 @@ std::pair<MineInfo, Ethash::Proof> Ethash::mine(BlockInfo const& _header, unsign |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
#if ETH_ETHASHCL |
|
|
|
|
|
|
|
/*
|
|
|
|
struct ethash_cl_search_hook |
|
|
|
{ |
|
|
|
// reports progress, return true to abort
|
|
|
|
virtual bool found(uint64_t const* nonces, uint32_t count) = 0; |
|
|
|
virtual bool searched(uint64_t start_nonce, uint32_t count) = 0; |
|
|
|
}; |
|
|
|
|
|
|
|
class ethash_cl_miner |
|
|
|
{ |
|
|
|
public: |
|
|
|
ethash_cl_miner(); |
|
|
|
|
|
|
|
bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64); |
|
|
|
|
|
|
|
void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count); |
|
|
|
void search(uint8_t const* header, uint64_t target, search_hook& hook); |
|
|
|
}; |
|
|
|
*/ |
|
|
|
|
|
|
|
struct EthashCLHook: public ethash_cl_search_hook |
|
|
|
{ |
|
|
|
virtual bool found(uint64_t const* _nonces, uint32_t _count) |
|
|
|
{ |
|
|
|
Guard l(x_all); |
|
|
|
for (unsigned i = 0; i < _count; ++i) |
|
|
|
found.push_back((Nonce)(u64)_nonces[i]); |
|
|
|
if (abort) |
|
|
|
{ |
|
|
|
aborted = true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
virtual bool searched(uint64_t _startNonce, uint32_t _count) |
|
|
|
{ |
|
|
|
Guard l(x_all); |
|
|
|
total += _count; |
|
|
|
last = _startNonce + _count; |
|
|
|
if (abort) |
|
|
|
{ |
|
|
|
aborted = true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
vector<Nonce> fetchFound() { vector<Nonce> ret; Guard l(x_all); std::swap(ret, found); return ret; } |
|
|
|
uint64_t fetchTotal() { Guard l(x_all); auto ret = total; total = 0; return ret; } |
|
|
|
|
|
|
|
Mutex x_all; |
|
|
|
vector<Nonce> found; |
|
|
|
uint64_t total; |
|
|
|
uint64_t last; |
|
|
|
bool abort = false; |
|
|
|
bool aborted = false; |
|
|
|
}; |
|
|
|
|
|
|
|
EthashCL::EthashCL(): |
|
|
|
m_miner(new ethash_cl_miner), |
|
|
|
m_hook(new EthashCLHook) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
EthashCL::~EthashCL() |
|
|
|
{ |
|
|
|
m_hook->abort = true; |
|
|
|
for (unsigned timeout = 0; timeout < 100 && !m_hook->aborted; ++timeout) |
|
|
|
std::this_thread::sleep_for(chrono::milliseconds(30)); |
|
|
|
if (!m_hook->aborted) |
|
|
|
cwarn << "Couldn't abort. Abandoning OpenCL process."; |
|
|
|
} |
|
|
|
|
|
|
|
bool EthashCL::verify(BlockInfo const& _header) |
|
|
|
{ |
|
|
|
return Ethasher::verify(_header); |
|
|
|
} |
|
|
|
|
|
|
|
std::pair<MineInfo, Ethash::Proof> EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool) |
|
|
|
{ |
|
|
|
if (m_lastHeader.seedHash() != _header.seedHash()) |
|
|
|
{ |
|
|
|
m_miner->init(Ethasher::params(_header), _header.seedHash().data()); |
|
|
|
// TODO: reinit probably won't work when seed changes.
|
|
|
|
} |
|
|
|
if (m_lastHeader != _header) |
|
|
|
{ |
|
|
|
static std::random_device s_eng; |
|
|
|
uint64_t tryNonce = (uint64_t)(u64)(m_last = Nonce::random(s_eng)); |
|
|
|
m_miner->search(_header.headerHash(WithoutNonce).data(), tryNonce, *m_hook); |
|
|
|
} |
|
|
|
m_lastHeader = _header; |
|
|
|
|
|
|
|
std::this_thread::sleep_for(chrono::milliseconds(_msTimeout)); |
|
|
|
auto found = m_hook->fetchFound(); |
|
|
|
if (!found.empty()) |
|
|
|
{ |
|
|
|
h256 mixHash; // ?????
|
|
|
|
return std::make_pair(MineInfo{0.0, 1e99, 0, true}, EthashCL::Proof((Nonce)(u64)found[0], mixHash)); |
|
|
|
} |
|
|
|
return std::make_pair(MineInfo{0.0, 1e99, 0, false}, EthashCL::Proof()); |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|