From cd4478e4cf87963ca488590072b4b26f385a7d22 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 13 Apr 2015 18:12:05 +0200 Subject: [PATCH] Various fixes for mining. --- alethzero/DownloadView.h | 1 - alethzero/MainWin.cpp | 10 ++-- alethzero/MiningView.cpp | 11 ++-- alethzero/MiningView.h | 4 +- eth/main.cpp | 17 +++--- exp/main.cpp | 54 +++++++++++++++---- libdevcore/Worker.h | 3 ++ libethcore/Ethash.cpp | 52 +++++++++--------- libethcore/Ethash.h | 22 +++++--- libethcore/Miner.h | 35 ++++++------ libethereum/Farm.h | 45 ++++++++++++---- mix/MixClient.cpp | 23 +++++--- mix/MixClient.h | 4 +- neth/main.cpp | 10 +--- test/TestHelper.cpp | 31 +++++++++++ test/TestHelper.h | 5 +- test/blockchain.cpp | 111 ++++++++++++++------------------------- test/dagger.cpp | 12 ++--- test/stateOriginal.cpp | 11 ++-- third/MainWin.cpp | 2 +- 20 files changed, 269 insertions(+), 194 deletions(-) diff --git a/alethzero/DownloadView.h b/alethzero/DownloadView.h index 22a11651c..d0fc445f8 100644 --- a/alethzero/DownloadView.h +++ b/alethzero/DownloadView.h @@ -32,7 +32,6 @@ #endif namespace dev { namespace eth { -struct MineInfo; class DownloadMan; }} diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 03d216a17..2e4478594 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -45,7 +45,7 @@ #endif #include #include -#include +#include #include #include #include @@ -164,7 +164,7 @@ Main::Main(QWidget *parent) : statusBar()->addPermanentWidget(ui->chainStatus); statusBar()->addPermanentWidget(ui->blockCount); - ui->blockCount->setText(QString("PV%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(c_databaseVersion).arg(ProofOfWork::name()).arg(ProofOfWork::revision()).arg(dev::Version)); + ui->blockCount->setText(QString("PV%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); @@ -952,7 +952,7 @@ void Main::on_preview_triggered() void Main::refreshMining() { - MineProgress p = ethereum()->miningProgress(); + MiningProgress p = ethereum()->miningProgress(); ui->mineStatus->setText(ethereum()->isMining() ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Not mining"); if (!ui->miningView->isVisible()) return; @@ -1481,7 +1481,7 @@ void Main::on_blocks_currentItemChanged() s << "
Difficulty: " << info.difficulty << "" << "
"; if (info.number) { - auto e = Ethasher::eval(info); + auto e = EthashAux::eval(info); s << "
Proof-of-Work: " << e.value << " <= " << (h256)u256((bigint(1) << 256) / info.difficulty) << " (mixhash: " << e.mixHash.abridged() << ")" << "
"; s << "
Parent: " << info.parentHash << "" << "
"; } @@ -1510,7 +1510,7 @@ void Main::on_blocks_currentItemChanged() s << line << "Nonce: " << uncle.nonce << "" << ""; s << line << "Hash w/o nonce: " << uncle.headerHash(WithoutNonce) << "" << ""; s << line << "Difficulty: " << uncle.difficulty << "" << ""; - auto e = Ethasher::eval(uncle); + auto e = EthashAux::eval(uncle); s << line << "Proof-of-Work: " << e.value << " <= " << (h256)u256((bigint(1) << 256) / uncle.difficulty) << " (mixhash: " << e.mixHash.abridged() << ")" << ""; } if (info.parentHash) diff --git a/alethzero/MiningView.cpp b/alethzero/MiningView.cpp index 63d1fcf99..e020408ea 100644 --- a/alethzero/MiningView.cpp +++ b/alethzero/MiningView.cpp @@ -36,7 +36,7 @@ using namespace dev::eth; // types using dev::eth::MineInfo; -using dev::eth::MineProgress; +using dev::eth::MiningProgress; // functions using dev::toString; @@ -50,12 +50,13 @@ MiningView::MiningView(QWidget* _p): QWidget(_p) { } -void MiningView::appendStats(list const& _i, MineProgress const& _p) +void MiningView::appendStats(list const& _i, MiningProgress const& _p) { + (void)_p; if (_i.empty()) return; - unsigned o = m_values.size(); +/* unsigned o = m_values.size(); for (MineInfo const& i: _i) { m_values.push_back(i.best); @@ -91,7 +92,7 @@ void MiningView::appendStats(list const& _i, MineProgress const& _p) m_completes.erase(remove_if(m_completes.begin(), m_completes.end(), [](int i){return i < 0;}), m_completes.end()); m_progress = _p; - update(); + update();*/ } void MiningView::resetStats() @@ -101,6 +102,7 @@ void MiningView::resetStats() void MiningView::paintEvent(QPaintEvent*) { + /* Grapher g; QPainter p(this); @@ -115,4 +117,5 @@ void MiningView::paintEvent(QPaintEvent*) g.ruleY(r - 1, QColor(128, 128, 128)); for (auto r: m_completes) g.ruleY(r, QColor(192, 64, 64)); + */ } diff --git a/alethzero/MiningView.h b/alethzero/MiningView.h index 8f3135f75..65b9f2ec9 100644 --- a/alethzero/MiningView.h +++ b/alethzero/MiningView.h @@ -42,14 +42,14 @@ class MiningView: public QWidget public: MiningView(QWidget* _p = nullptr); - void appendStats(std::list const& _l, dev::eth::MineProgress const& _p); + void appendStats(std::list const& _l, dev::eth::MiningProgress const& _p); void resetStats(); protected: virtual void paintEvent(QPaintEvent*); private: - dev::eth::MineProgress m_progress; + dev::eth::MiningProgress m_progress; unsigned m_duration = 300; std::vector m_values; std::vector m_bests; diff --git a/eth/main.cpp b/eth/main.cpp index 66abefd54..24bf839aa 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -126,13 +126,16 @@ void help() #if ETH_JSONRPC << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl +#endif +#if ETH_EVMJIT + << " -J,--jit Enable EVM JIT (default: off)." << endl #endif << " -K,--kill First kill the blockchain." << endl << " --listen-ip Listen on the given port for incoming connections (default: 30303)." << endl << " -l,--listen Listen on the given IP for incoming connections (default: 0.0.0.0)." << endl << " -u,--public-ip Force public ip to given (default: auto)." << endl << " -m,--mining Enable mining, optionally for a specified number of blocks (Default: off)" << endl - << " -n,--upnp Use upnp for NAT (default: on)." << endl + << " -n,-u,--upnp Use upnp for NAT (default: on)." << endl << " -o,--mode Start a full node or a peer node (Default: full)." << endl << " -p,--port Connect to remote port (default: 30303)." << endl << " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl @@ -140,7 +143,6 @@ void help() << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl << " -S,--temporary-secret Set the secret key for use with send command, for this session only." << endl - << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (Default: 8)." << endl << " -x,--peers Attempt to connect to given number of peers (Default: 5)." << endl << " -V,--version Show the version and exit." << endl @@ -336,7 +338,7 @@ int main(int argc, char** argv) exportFrom = argv[++i]; else if (arg == "--only" && i + 1 < argc) exportTo = exportFrom = argv[++i]; - else if ((arg == "-n" || arg == "--upnp") && i + 1 < argc) + else if ((arg == "-n" || arg == "-u" || arg == "--upnp") && i + 1 < argc) { string m = argv[++i]; if (isTrue(m)) @@ -490,15 +492,12 @@ int main(int argc, char** argv) return -1; } } - else if (arg == "--jit") - { #if ETH_EVMJIT + else if (arg == "-J" || arg == "--jit") + { jit = true; -#else - cerr << "EVM JIT not enabled" << endl; - return -1; -#endif } +#endif else if (arg == "-h" || arg == "--help") help(); else if (arg == "-V" || arg == "--version") diff --git a/exp/main.cpp b/exp/main.cpp index 88f1075a9..933fda1a6 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -34,9 +34,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -109,18 +109,50 @@ int main() #else int main() { -#if ETH_ETHASHCL - EthashCL ecl; + GenericFarm f; BlockInfo genesis = CanonBlockChain::genesis(); genesis.difficulty = 1 << 18; - cdebug << (h256)u256((bigint(1) << 256) / genesis.difficulty); - std::pair r; - while (!r.first.completed) - r = ecl.mine(genesis, 1000); - cdebug << r.second.mixHash << r.second.nonce; - EthashCL::assignResult(r.second, genesis); - assert(EthashCPU::verify(genesis)); -#endif + cdebug << genesis.boundary(); + + auto mine = [](GenericFarm& f, BlockInfo const& g, unsigned timeout) { + BlockInfo bi = g; + bool completed = false; + f.onSolutionFound([&](ProofOfWork::Solution sol) + { + ProofOfWork::assignResult(sol, bi); + return completed = true; + }); + f.setWork(bi); + for (unsigned i = 0; !completed && i < timeout * 10; ++i, cout << f.miningProgress() << "\r" << flush) + this_thread::sleep_for(chrono::milliseconds(100)); + cdebug << bi.mixHash << bi.nonce << (Ethash::verify(bi) ? "GOOD" : "bad"); + }; + + f.startCPU(); + mine(f, genesis, 10); + mine(f, genesis, 10); + f.startGPU(); + + cdebug << "Good:"; + genesis.difficulty = 1 << 18; + genesis.noteDirty(); + mine(f, genesis, 3); + + cdebug << "Bad:"; + genesis.difficulty = (u256(1) << 40); + genesis.noteDirty(); + mine(f, genesis, 3); + + cdebug << "Good:"; + genesis.difficulty = 1 << 18; + genesis.noteDirty(); + mine(f, genesis, 3); + + cdebug << "Bad:"; + genesis.difficulty = (u256(1) << 40); + genesis.noteDirty(); + mine(f, genesis, 3); + return 0; } #endif diff --git a/libdevcore/Worker.h b/libdevcore/Worker.h index 6a35d6c4c..24ff4cc15 100644 --- a/libdevcore/Worker.h +++ b/libdevcore/Worker.h @@ -66,6 +66,9 @@ protected: /// Called when is to be stopped, just prior to thread being joined. virtual void doneWorking() {} + /// Blocks caller into worker thread has finished. + void join() const { Guard l(x_work); try { if (m_work) m_work->join(); } catch (...) {} } + private: std::string m_name; unsigned m_idleWaitMs = 0; diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 03c7a3654..f66188976 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -63,7 +63,7 @@ Ethash::WorkPackage Ethash::package(BlockInfo const& _bi) { WorkPackage ret; ret.boundary = _bi.boundary(); - ret.headerHash = _bi.headerHash(WithNonce); + ret.headerHash = _bi.headerHash(WithoutNonce); ret.seedHash = _bi.seedHash(); return ret; } @@ -95,9 +95,8 @@ bool Ethash::verify(BlockInfo const& _header) return false; #endif - h256 boundary = u256((bigint(1) << 256) / _header.difficulty); auto result = EthashAux::eval(_header); - bool slow = result.value <= boundary && result.mixHash == _header.mixHash; + bool slow = result.value <= _header.boundary() && result.mixHash == _header.mixHash; #if ETH_DEBUG || !ETH_TRUE if (!pre && slow) @@ -107,7 +106,7 @@ bool Ethash::verify(BlockInfo const& _header) cwarn << "nonce:" << _header.nonce; cwarn << "mixHash:" << _header.mixHash; cwarn << "difficulty:" << _header.difficulty; - cwarn << "boundary:" << boundary; + cwarn << "boundary:" << _header.boundary(); cwarn << "result.value:" << result.value; cwarn << "result.mixHash:" << result.mixHash; } @@ -125,16 +124,18 @@ void Ethash::CPUMiner::workLoop() ethash_return_value ethashReturn; auto p = EthashAux::params(m_work.seedHash); - void const* dagPointer = EthashAux::full(m_work.headerHash).data(); + void const* dagPointer = EthashAux::full(m_work.seedHash).data(); uint8_t const* headerHashPointer = m_work.headerHash.data(); h256 boundary = m_work.boundary; - unsigned hashCount = 0; + unsigned hashCount = 1; for (; !shouldStop(); tryNonce++, hashCount++) { ethash_compute_full(ðashReturn, dagPointer, &p, headerHashPointer, tryNonce); h256 value = h256(ethashReturn.result, h256::ConstructFromPointer); if (value <= boundary && submitProof(Solution{(Nonce)(u64)tryNonce, h256(ethashReturn.mix_hash, h256::ConstructFromPointer)})) break; + if (!(hashCount % 1000)) + accumulateHashes(1000); } } @@ -148,6 +149,7 @@ public: void abort() { Guard l(x_all); + m_owner->m_work.headerHash = h256(); if (m_aborted) return; // cdebug << "Attempting to abort"; @@ -159,8 +161,6 @@ public: m_aborted = m_abort = false; } - uint64_t fetchTotal() { Guard l(x_all); auto ret = m_total; m_total = 0; return ret; } - protected: virtual bool found(uint64_t const* _nonces, uint32_t _count) override { @@ -180,7 +180,7 @@ protected: { Guard l(x_all); // cdebug << "Searched" << _count << "from" << _startNonce; - m_total += _count; + m_owner->accumulateHashes(_count); m_last = _startNonce + _count; if (m_abort) { @@ -192,7 +192,6 @@ protected: private: Mutex x_all; - uint64_t m_total; uint64_t m_last; bool m_abort = false; bool m_aborted = true; @@ -214,38 +213,43 @@ Ethash::GPUMiner::~GPUMiner() bool Ethash::GPUMiner::report(uint64_t _nonce) { Nonce n = (Nonce)(u64)_nonce; - Result r = EthashAux::eval(m_lastWork.seedHash, m_lastWork.headerHash, n); - if (r.value < m_lastWork.boundary) + Result r = EthashAux::eval(m_work.seedHash, m_work.headerHash, n); + if (r.value < m_work.boundary) return submitProof(Solution{n, r.mixHash}); return false; } void Ethash::GPUMiner::kickOff(WorkPackage const& _work) { - if (!m_miner || m_minerSeed != _work.seedHash) + m_work = _work; + startWorking(); +} + +void Ethash::GPUMiner::workLoop() +{ + // take local copy of work since it may end up being overwritten by kickOff/pause. + WorkPackage w = m_work; + if (!m_miner || m_minerSeed != w.seedHash) { - if (m_miner) - m_hook->abort(); + m_minerSeed = w.seedHash; delete m_miner; m_miner = new ethash_cl_miner; - auto p = EthashAux::params(_work.seedHash); - auto cb = [&](void* d) { EthashAux::full(_work.seedHash, bytesRef((byte*)d, p.full_size)); }; + auto p = EthashAux::params(m_minerSeed); + auto cb = [&](void* d) { EthashAux::full(m_minerSeed, bytesRef((byte*)d, p.full_size)); }; m_miner->init(p, cb, 32); } - if (m_lastWork.headerHash != _work.headerHash) - { - m_hook->abort(); - uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)_work.boundary >> 192); - m_miner->search(_work.headerHash.data(), upper64OfBoundary, *m_hook); - } - m_lastWork = _work; + + uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); + m_miner->search(w.headerHash.data(), upper64OfBoundary, *m_hook); } void Ethash::GPUMiner::pause() { m_hook->abort(); + stopWorking(); + m_work.headerHash = h256(); } #endif diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h index 1a7d82149..8f1ba3eb3 100644 --- a/libethcore/Ethash.h +++ b/libethcore/Ethash.h @@ -59,6 +59,11 @@ public: struct WorkPackage { + WorkPackage() = default; + + void reset() { headerHash = h256(); } + operator bool() const { return headerHash != h256(); } + h256 boundary; h256 headerHash; ///< When h256() means "pause until notified a new work package is available". h256 seedHash; @@ -89,17 +94,16 @@ public: startWorking(); } - void pause() override { stopWorking(); } + void pause() override { stopWorking(); m_work.reset(); } private: void workLoop() override; WorkPackage m_work; - MineInfo m_info; }; #if ETH_ETHASHCL || !ETH_TRUE - class GPUMiner: public Miner + class GPUMiner: public Miner, Worker { friend class dev::eth::EthashCLHook; @@ -114,14 +118,16 @@ public: void pause() override; private: + void workLoop() override; bool report(uint64_t _nonce); - EthashCLHook* m_hook; - ethash_cl_miner* m_miner; + using Miner::accumulateHashes; + + EthashCLHook* m_hook = nullptr; + ethash_cl_miner* m_miner = nullptr; - h256 m_minerSeed; - WorkPackage m_lastWork; ///< Work loaded into m_miner. - MineInfo m_info; + h256 m_minerSeed; ///< Last seed in m_miner + WorkPackage m_work; ///< Work to be done by GPU, set with kickOff and picked up in workLoop. }; #else using GPUMiner = CPUMiner; diff --git a/libethcore/Miner.h b/libethcore/Miner.h index 9372c06b1..ea51b0eb5 100644 --- a/libethcore/Miner.h +++ b/libethcore/Miner.h @@ -34,30 +34,24 @@ namespace dev namespace eth { -struct MineInfo -{ - MineInfo() = default; - MineInfo(bool _completed): completed(_completed) {} - void combine(MineInfo const& _m) { requirement = std::max(requirement, _m.requirement); best = std::min(best, _m.best); hashes += _m.hashes; completed = completed || _m.completed; } - double requirement = 0; - double best = 1e99; - unsigned hashes = 0; - bool completed = false; -}; - /** * @brief Describes the progress of a mining operation. */ struct MiningProgress { - void combine(MiningProgress const& _m) { requirement = std::max(requirement, _m.requirement); best = std::min(best, _m.best); current = std::max(current, _m.current); hashes += _m.hashes; ms = std::max(ms, _m.ms); } - double requirement = 0; ///< The PoW requirement - as the second logarithm of the minimum acceptable hash. - double best = 1e99; ///< The PoW achievement - as the second logarithm of the minimum found hash. - double current = 0; ///< The most recent PoW achievement - as the second logarithm of the presently found hash. +// MiningProgress& operator+=(MiningProgress const& _mp) { hashes += _mp.hashes; ms = std::max(ms, _mp.ms); return *this; } unsigned hashes = 0; ///< Total number of hashes computed. unsigned ms = 0; ///< Total number of milliseconds of mining thus far. }; +struct MineInfo: public MiningProgress {}; + +inline std::ostream& operator<<(std::ostream& _out, MiningProgress const& _p) +{ + _out << (_p.hashes * 1000 / _p.ms) << "H/s = " << _p.hashes << " hashes / " << (double(_p.ms) / 1000) << "s"; + return _out; +} + template class GenericMiner; /** @@ -103,13 +97,18 @@ public: void setWork(WorkPackage const& _work = WorkPackage()) { Guard l(x_work); + if (_work.headerHash == m_work.headerHash) + return; if (_work.headerHash != h256()) - kickOff(m_work); + kickOff(_work); else if (m_work.headerHash == h256() && _work.headerHash != h256()) pause(); m_work = _work; + m_hashCount = 0; } + unsigned hashCount() { return m_hashCount; } + unsigned index() const { return m_index; } protected: @@ -146,12 +145,16 @@ protected: WorkPackage const& work() const { return m_work; } + void accumulateHashes(unsigned _n) { m_hashCount += _n; } + private: FarmFace* m_farm = nullptr; unsigned m_index; Mutex x_work; WorkPackage m_work; + + unsigned m_hashCount = 0; }; } diff --git a/libethereum/Farm.h b/libethereum/Farm.h index 09c7f0e78..c20c27e6d 100644 --- a/libethereum/Farm.h +++ b/libethereum/Farm.h @@ -56,16 +56,16 @@ public: */ void setWork(BlockInfo const& _bi) { - WorkPackage w; - { - WriteGuard l(x_work); - m_header = _bi; - w = m_work = PoW::package(m_header); - } - + WriteGuard l(x_work); ReadGuard l2(x_miners); + m_header = _bi; + auto p = PoW::package(m_header); + if (p.headerHash == m_work.headerHash) + return; + m_work = p; for (auto const& m: m_miners) m->setWork(m_work); + resetTimer(); } /** @@ -99,7 +99,19 @@ public: * @brief Get information on the progress of mining this work package. * @return The progress with mining so far. */ - MiningProgress const& miningProgress() const { ReadGuard l(x_progress); return m_progress; } + MiningProgress const& miningProgress() const + { + MiningProgress p; + p.ms = std::chrono::duration_cast(std::chrono::steady_clock::now() - m_lastStart).count(); + { + ReadGuard l2(x_miners); + for (auto const& i: m_miners) + p.hashes += i->hashCount(); + } + ReadGuard l(x_progress); + m_progress = p; + return m_progress; + } using SolutionFound = std::function; @@ -110,6 +122,8 @@ public: */ void onSolutionFound(SolutionFound const& _handler) { m_onSolutionFound = _handler; } + WorkPackage work() const { ReadGuard l(x_work); return m_work; } + private: /** * @brief Called from a Miner to note a WorkPackage has a solution. @@ -140,21 +154,32 @@ private: template bool start() { - WriteGuard l(x_miners); + ReadGuard l(x_work); + WriteGuard l2(x_miners); if (!m_miners.empty() && !!std::dynamic_pointer_cast(m_miners[0])) return true; m_miners.clear(); m_miners.reserve(MinerType::instances()); for (unsigned i = 0; i < MinerType::instances(); ++i) + { m_miners.push_back(std::shared_ptr(new MinerType(std::make_pair(this, i)))); + m_miners.back()->setWork(m_work); + } + resetTimer(); return true; } + void resetTimer() + { + m_lastStart = std::chrono::steady_clock::now(); + } + mutable SharedMutex x_miners; std::vector> m_miners; mutable SharedMutex x_progress; - MiningProgress m_progress; + mutable MiningProgress m_progress; + std::chrono::steady_clock::time_point m_lastStart; mutable SharedMutex x_work; WorkPackage m_work; diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 2e8bd5384..76552fb06 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -20,6 +20,7 @@ * Ethereum IDE client. */ +#include "MixClient.h" #include #include #include @@ -28,10 +29,8 @@ #include #include #include - #include "Exceptions.h" -#include "MixClient.h" - +using namespace std; using namespace dev; using namespace dev::eth; @@ -250,9 +249,17 @@ void MixClient::mine() { WriteGuard l(x_state); m_state.commitToMine(bc()); - ProofOfWork pow; - while (!m_state.mine(&pow).completed) {} - m_state.completeMine(); + GenericFarm f; + bool completed = false; + f.onSolutionFound([&](ProofOfWork::Solution sol) + { + return completed = m_state.completeMine(sol); + }); + f.setWork(m_state.info()); + f.startCPU(); + while (!completed) + this_thread::sleep_for(chrono::milliseconds(20)); + bc().import(m_state.blockData(), m_stateDB); m_state.sync(bc()); m_startState = m_state; @@ -392,9 +399,9 @@ uint64_t MixClient::hashrate() const return 0; } -eth::MineProgress MixClient::miningProgress() const +eth::MiningProgress MixClient::miningProgress() const { - return eth::MineProgress(); + return eth::MiningProgress(); } } diff --git a/mix/MixClient.h b/mix/MixClient.h index 649c7694f..c496df754 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -67,8 +67,8 @@ public: void stopMining() override; bool isMining() const override; uint64_t hashrate() const override; - eth::MineProgress miningProgress() const override; - std::pair getWork() override { return std::pair(); } + eth::MiningProgress miningProgress() const override; + eth::ProofOfWork::WorkPackage getWork() override { return eth::ProofOfWork::WorkPackage(); } bool submitWork(eth::ProofOfWork::Solution const&) override { return false; } virtual void flushTransactions() override {} diff --git a/neth/main.cpp b/neth/main.cpp index fd3d3f403..4c38da0a4 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -40,7 +40,6 @@ #include #include #endif -#include #include "BuildInfo.h" #undef KEY_EVENT // from windows.h @@ -332,7 +331,6 @@ int main(int argc, char** argv) unsigned mining = ~(unsigned)0; NodeMode mode = NodeMode::Full; unsigned peers = 5; - int miners = -1; #if ETH_JSONRPC int jsonrpc = 8080; #endif @@ -502,8 +500,6 @@ int main(int argc, char** argv) g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) peers = atoi(argv[++i]); - else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) - miners = atoi(argv[++i]); else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) { string m = argv[++i]; @@ -553,9 +549,7 @@ int main(int argc, char** argv) killChain ? WithExisting::Kill : WithExisting::Trust, mode == NodeMode::Full ? set{"eth", "shh"} : set(), netPrefs, - &nodesState, - miners - ); + &nodesState); web3.setIdealPeerCount(peers); std::shared_ptr gasPricer = make_shared(u256(double(ether / 1000) / etherPrice), u256(blockFees * 1000)); @@ -1253,7 +1247,7 @@ int main(int argc, char** argv) if (c && c->isMining()) { mvwprintw(consolewin, qheight - 1, width / 4 - 11, "Mining ON"); - dev::eth::MineProgress p = c->miningProgress(); + dev::eth::MiningProgress p = c->miningProgress(); auto speed = boost::format("%2% kH/s @ %1%s") % (p.ms / 1000) % (p.ms ? p.hashes / p.ms : 0); mvwprintw(consolewin, qheight - 2, width / 4 - speed.str().length() - 2, speed.str().c_str()); } diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 45fe55b07..93c564e62 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -62,6 +62,37 @@ void connectClients(Client& c1, Client& c2) c2.connect("127.0.0.1", c1Port); #endif } + +void mine(State& s, BlockChain const& _bc) +{ + s.commitToMine(_bc); + GenericFarm f; + bool completed = false; + f.onSolutionFound([&](ProofOfWork::Solution sol) + { + return completed = s.completeMine(sol); + }); + f.setWork(s.info()); + f.startCPU(); + while (!completed) + this_thread::sleep_for(chrono::milliseconds(20)); +} + +void mine(BlockInfo& _bi) +{ + GenericFarm f; + bool completed = false; + f.onSolutionFound([&](ProofOfWork::Solution sol) + { + ProofOfWork::assignResult(sol, _bi); + return completed = true; + }); + f.setWork(_bi); + f.startCPU(); + while (!completed) + this_thread::sleep_for(chrono::milliseconds(20)); +} + } namespace test diff --git a/test/TestHelper.h b/test/TestHelper.h index 04ca95be4..92745bc36 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -36,9 +36,12 @@ namespace eth { class Client; +class State; void mine(Client& c, int numBlocks); void connectClients(Client& c1, Client& c2); +void mine(State& _s, BlockChain const& _bc); +void mine(BlockInfo& _bi); } @@ -225,7 +228,5 @@ public: }; }; - - } } diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 8f5605898..4aa70c63a 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -191,11 +191,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) { state.sync(bc); state.sync(bc, txs, gp); - state.commitToMine(bc); - MineInfo info; - ProofOfWork pow; - for (info.completed = false; !info.completed; info = state.mine(&pow)) {} - state.completeMine(); + mine(state, bc); } catch (Exception const& _e) { @@ -531,76 +527,55 @@ bytes createBlockRLPFromFields(mObject& _tObj) return rlpStream.out(); } -void overwriteBlockHeader(BlockInfo& _currentBlockHeader, mObject& _blObj) +void overwriteBlockHeader(BlockInfo& _header, mObject& _blObj) { - if (_blObj["blockHeader"].get_obj().size() != 14) + auto ho = _blObj["blockHeader"].get_obj(); + if (ho.size() != 14) { - - BlockInfo tmp = _currentBlockHeader; - - if (_blObj["blockHeader"].get_obj().count("parentHash")) - tmp.parentHash = h256(_blObj["blockHeader"].get_obj()["parentHash"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("uncleHash")) - tmp.sha3Uncles = h256(_blObj["blockHeader"].get_obj()["uncleHash"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("coinbase")) - tmp.coinbaseAddress = Address(_blObj["blockHeader"].get_obj()["coinbase"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("stateRoot")) - tmp.stateRoot = h256(_blObj["blockHeader"].get_obj()["stateRoot"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("transactionsTrie")) - tmp.transactionsRoot = h256(_blObj["blockHeader"].get_obj()["transactionsTrie"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("receiptTrie")) - tmp.receiptsRoot = h256(_blObj["blockHeader"].get_obj()["receiptTrie"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("bloom")) - tmp.logBloom = LogBloom(_blObj["blockHeader"].get_obj()["bloom"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("difficulty")) - tmp.difficulty = toInt(_blObj["blockHeader"].get_obj()["difficulty"]); - - if (_blObj["blockHeader"].get_obj().count("number")) - tmp.number = toInt(_blObj["blockHeader"].get_obj()["number"]); - - if (_blObj["blockHeader"].get_obj().count("gasLimit")) - tmp.gasLimit = toInt(_blObj["blockHeader"].get_obj()["gasLimit"]); - - if (_blObj["blockHeader"].get_obj().count("gasUsed")) - tmp.gasUsed = toInt(_blObj["blockHeader"].get_obj()["gasUsed"]); - - if (_blObj["blockHeader"].get_obj().count("timestamp")) - tmp.timestamp = toInt(_blObj["blockHeader"].get_obj()["timestamp"]); - - if (_blObj["blockHeader"].get_obj().count("extraData")) - tmp.extraData = importByteArray(_blObj["blockHeader"].get_obj()["extraData"].get_str()); - - if (_blObj["blockHeader"].get_obj().count("mixHash")) - tmp.mixHash = h256(_blObj["blockHeader"].get_obj()["mixHash"].get_str()); + BlockInfo tmp = _header; + if (ho.count("parentHash")) + tmp.parentHash = h256(ho["parentHash"].get_str()); + if (ho.count("uncleHash")) + tmp.sha3Uncles = h256(ho["uncleHash"].get_str()); + if (ho.count("coinbase")) + tmp.coinbaseAddress = Address(ho["coinbase"].get_str()); + if (ho.count("stateRoot")) + tmp.stateRoot = h256(ho["stateRoot"].get_str()); + if (ho.count("transactionsTrie")) + tmp.transactionsRoot = h256(ho["transactionsTrie"].get_str()); + if (ho.count("receiptTrie")) + tmp.receiptsRoot = h256(ho["receiptTrie"].get_str()); + if (ho.count("bloom")) + tmp.logBloom = LogBloom(ho["bloom"].get_str()); + if (ho.count("difficulty")) + tmp.difficulty = toInt(ho["difficulty"]); + if (ho.count("number")) + tmp.number = toInt(ho["number"]); + if (ho.count("gasLimit")) + tmp.gasLimit = toInt(ho["gasLimit"]); + if (ho.count("gasUsed")) + tmp.gasUsed = toInt(ho["gasUsed"]); + if (ho.count("timestamp")) + tmp.timestamp = toInt(ho["timestamp"]); + if (ho.count("extraData")) + tmp.extraData = importByteArray(ho["extraData"].get_str()); + if (ho.count("mixHash")) + tmp.mixHash = h256(ho["mixHash"].get_str()); + tmp.noteDirty(); // find new valid nonce - - if (tmp != _currentBlockHeader) + if (tmp != _header) { - _currentBlockHeader = tmp; - - ProofOfWork pow; - std::pair ret; - while (!ProofOfWork::verify(_currentBlockHeader)) - { - ret = pow.mine(_currentBlockHeader, 1000, true); - Ethash::assignResult(ret.second, _currentBlockHeader); - } + mine(tmp); + _header = tmp; } } else { // take the blockheader as is - const bytes c_blockRLP = createBlockRLPFromFields(_blObj["blockHeader"].get_obj()); + const bytes c_blockRLP = createBlockRLPFromFields(ho); const RLP c_bRLP(c_blockRLP); - _currentBlockHeader.populateFromHeader(c_bRLP, IgnoreNonce); + _header.populateFromHeader(c_bRLP, IgnoreNonce); } } @@ -631,13 +606,7 @@ BlockInfo constructBlock(mObject& _o) void updatePoW(BlockInfo& _bi) { - ProofOfWork pow; - std::pair ret; - while (!ProofOfWork::verify(_bi)) - { - ret = pow.mine(_bi, 10000, true); - Ethash::assignResult(ret.second, _bi); - } + mine(_bi); _bi.noteDirty(); } diff --git a/test/dagger.cpp b/test/dagger.cpp index 4abba5090..367c422ad 100644 --- a/test/dagger.cpp +++ b/test/dagger.cpp @@ -25,7 +25,7 @@ #include "JsonSpiritHeaders.h" #include #include -#include +#include #include #include "TestHelper.h" @@ -63,18 +63,18 @@ BOOST_AUTO_TEST_CASE(basic_test) unsigned cacheSize(o["cache_size"].get_int()); h256 cacheHash(o["cache_hash"].get_str()); - BOOST_REQUIRE_EQUAL(Ethasher::get()->params(header).cache_size, cacheSize); - BOOST_REQUIRE_EQUAL(sha3(bytesConstRef((byte const*)Ethasher::get()->light(header), cacheSize)), cacheHash); + BOOST_REQUIRE_EQUAL(EthashAux::get()->params(header).cache_size, cacheSize); + BOOST_REQUIRE_EQUAL(sha3(bytesConstRef((byte const*)EthashAux::get()->light(header), cacheSize)), cacheHash); #if TEST_FULL unsigned fullSize(o["full_size"].get_int()); h256 fullHash(o["full_hash"].get_str()); - BOOST_REQUIRE_EQUAL(Ethasher::get()->full(header).size(), fullSize); - BOOST_REQUIRE_EQUAL(sha3(Ethasher::get()->full(header)), fullHash); + BOOST_REQUIRE_EQUAL(EthashAux::get()->full(header).size(), fullSize); + BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->full(header)), fullHash); #endif h256 result(o["result"].get_str()); - Ethasher::Result r = Ethasher::eval(header); + Ethash::Result r = EthashAux::eval(header); BOOST_REQUIRE_EQUAL(r.value, result); BOOST_REQUIRE_EQUAL(r.mixHash, header.mixHash); } diff --git a/test/stateOriginal.cpp b/test/stateOriginal.cpp index 40f759434..e1a3c7c4a 100644 --- a/test/stateOriginal.cpp +++ b/test/stateOriginal.cpp @@ -25,7 +25,9 @@ #include #include #include +#include #include +#include "TestHelper.h" using namespace std; using namespace dev; using namespace dev::eth; @@ -67,10 +69,8 @@ BOOST_AUTO_TEST_CASE(Complex) cout << s; // Mine to get some ether! - s.commitToMine(bc); - ProofOfWork pow; - while (!s.mine(&pow).completed) {} - s.completeMine(); + mine(s, bc); + bc.attemptImport(s.blockData(), stateDB); cout << bc; @@ -89,8 +89,7 @@ BOOST_AUTO_TEST_CASE(Complex) // Mine to get some ether and set in stone. s.commitToMine(bc); s.commitToMine(bc); - while (!s.mine(&pow).completed) {} - s.completeMine(); + mine(s, bc); bc.attemptImport(s.blockData(), stateDB); cout << bc; diff --git a/third/MainWin.cpp b/third/MainWin.cpp index b03723131..12625ffbc 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -465,7 +465,7 @@ void Main::on_urlEdit_returnPressed() void Main::refreshMining() { - dev::eth::MineProgress p = ethereum()->miningProgress(); + dev::eth::MiningProgress p = ethereum()->miningProgress(); ui->mineStatus->setText(ethereum()->isMining() ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Not mining"); }