From 38e985e808ef28868d82a3af810062d4ef84c57a Mon Sep 17 00:00:00 2001 From: Alexandre Van de Sande Date: Fri, 10 Apr 2015 17:56:31 -0300 Subject: [PATCH 1/9] created a frame for the step action buttons --- mix/qml/Debugger.qml | 34 +++++----- mix/qml/StepActionImage.qml | 122 ++++++++++++++++++++++++++++++------ 2 files changed, 116 insertions(+), 40 deletions(-) diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index ef83ef390..3b8a87e8a 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -4,6 +4,7 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import Qt.labs.settings 1.0 +import QtGraphicalEffects 1.0 import "js/Debugger.js" as Debugger import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "." @@ -231,9 +232,9 @@ Rectangle { id: playAction enabledStateImg: "qrc:/qml/img/play_button.png" disableStateImg: "qrc:/qml/img/play_button.png" + buttonLeft: true onClicked: projectModel.stateListModel.runState(transactionLog.selectedStateIndex) - width: 30 - height: 30 + width: 23 buttonShortcut: "Ctrl+Shift+F8" buttonTooltip: qsTr("Start Debugging") visible: true @@ -246,8 +247,7 @@ Rectangle { enabledStateImg: "qrc:/qml/img/stop_button2x.png" disableStateImg: "qrc:/qml/img/stop_button2x.png" onClicked: Debugger.init(null); - width: 30 - height: 30 + width: 23 buttonShortcut: "Ctrl+Shift+F9" buttonTooltip: qsTr("Stop Debugging") visible: true @@ -259,8 +259,7 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpoutback.png" disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png" onClicked: Debugger.runBack() - width: 30 - height: 30 + width: 23 buttonShortcut: "Ctrl+Shift+F5" buttonTooltip: qsTr("Run Back") visible: false @@ -272,8 +271,7 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpoutback.png" disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png" onClicked: Debugger.stepOutBack() - width: 30 - height: 30 + width: 23 buttonShortcut: "Ctrl+Shift+F11" buttonTooltip: qsTr("Step Out Back") } @@ -284,8 +282,7 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpintoback.png" disableStateImg: "qrc:/qml/img/jumpintobackdisabled.png" onClicked: Debugger.stepIntoBack() - width: 30 - height: 30 + width: 23 buttonShortcut: "Ctrl+F11" buttonTooltip: qsTr("Step Into Back") } @@ -296,8 +293,7 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpoverback.png" disableStateImg: "qrc:/qml/img/jumpoverbackdisabled.png" onClicked: Debugger.stepOverBack() - width: 30 - height: 30 + width: 23 buttonShortcut: "Ctrl+F10" buttonTooltip: qsTr("Step Over Back") } @@ -308,8 +304,7 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpoverforward.png" disableStateImg: "qrc:/qml/img/jumpoverforwarddisabled.png" onClicked: Debugger.stepOverForward() - width: 30 - height: 30 + width: 23 buttonShortcut: "F10" buttonTooltip: qsTr("Step Over Forward") } @@ -320,8 +315,7 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpintoforward.png" disableStateImg: "qrc:/qml/img/jumpintoforwarddisabled.png" onClicked: Debugger.stepIntoForward() - width: 30 - height: 30 + width: 23 buttonShortcut: "F11" buttonTooltip: qsTr("Step Into Forward") } @@ -332,10 +326,10 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpoutforward.png" disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png" onClicked: Debugger.stepOutForward() - width: 30 - height: 30 + width: 45 buttonShortcut: "Shift+F11" buttonTooltip: qsTr("Step Out Forward") + buttonRight: true } StepActionImage @@ -344,11 +338,11 @@ Rectangle { enabledStateImg: "qrc:/qml/img/jumpoutforward.png" disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png" onClicked: Debugger.runForward() - width: 30 - height: 30 + width: 45 buttonShortcut: "Ctrl+F5" buttonTooltip: qsTr("Run Forward") visible: false + buttonRight: true } Rectangle { diff --git a/mix/qml/StepActionImage.qml b/mix/qml/StepActionImage.qml index 262c99def..a8c800b64 100644 --- a/mix/qml/StepActionImage.qml +++ b/mix/qml/StepActionImage.qml @@ -4,15 +4,22 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 + Rectangle { id: buttonActionContainer - color: "transparent" property string disableStateImg property string enabledStateImg property string buttonTooltip property string buttonShortcut + property bool buttonLeft + property bool buttonRight signal clicked + + color: "transparent" + width: 35 + height: 24 + function enabled(state) { buttonAction.enabled = state; @@ -22,29 +29,104 @@ Rectangle { debugImage.source = disableStateImg; } - Button - { - anchors.fill: parent - id: debugImg -/* iconSource: enabledStateImg -*/ action: buttonAction + Rectangle { + color: "#DCDADA" + width: 10 + height: 24 + radius: 4 + x: 0 + visible: buttonLeft + + Rectangle { + anchors { + left: parent.left + right: parent.right + top: parent.top + bottom: parent.bottom + bottomMargin:debugImg.pressed? 0 : 1; + topMargin:debugImg.pressed? 1 : 0; + } + color: "#FCFBFC" + radius: 3 + } } - Image { - id: debugImage - source: enabledStateImg - anchors.centerIn: parent - fillMode: Image.PreserveAspectFit - width: 15 - height: 15 + Rectangle { + color: "#DCDADA" + width: 10 + height: 24 + radius: 4 + x: 25 + visible: buttonRight + + Rectangle { + anchors { + left: parent.left + right: parent.right + top: parent.top + bottom: parent.bottom + bottomMargin:debugImg.pressed? 0 : 1; + topMargin:debugImg.pressed? 1 : 0; + } + color: "#FCFBFC" + radius: 3 + } } - Action { - tooltip: buttonTooltip - id: buttonAction - shortcut: buttonShortcut - onTriggered: { - buttonActionContainer.clicked(); + + Rectangle { + id: contentRectangle + width: 25 + height: 24 + color: "#DCDADA" + x: 5 + + Rectangle { + anchors { + left: parent.left + right: parent.right + top: parent.top + bottom: parent.bottom + bottomMargin:debugImg.pressed? 0 : 1; + topMargin:debugImg.pressed? 1 : 0; + } + color: "#FCFBFC" + + Image { + id: debugImage + source: enabledStateImg + anchors.centerIn: parent + anchors.topMargin: debugImg.pressed? 1 : 0; + + fillMode: Image.PreserveAspectFit + width: 15 + height: 15 + } + + } + + + Button { + anchors.fill: parent + id: debugImg + action: buttonAction + style: Rectangle { + color: "transparent" + } + } + + + Action { + tooltip: buttonTooltip + id: buttonAction + shortcut: buttonShortcut + onTriggered: { + // contentRectangle.anchors.bottomMargin = 0 + // contentRectangle.anchors.topMargin = 1 + buttonActionContainer.clicked(); + } } } + + } From 89dbad3bf85f854657de05e543be13a7ed4fd09d Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Apr 2015 23:12:51 +0200 Subject: [PATCH 2/9] Working GPU miner. --- libethcore/ProofOfWork.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp index e24b2087c..a97baca94 100644 --- a/libethcore/ProofOfWork.cpp +++ b/libethcore/ProofOfWork.cpp @@ -207,10 +207,10 @@ std::pair EthashCL::mine(BlockInfo const& _header, unsi { m_hook->abort(); static std::random_device s_eng; - uint64_t tryNonce = (uint64_t)(u64)(m_last = Nonce::random(s_eng)); auto hh = _header.headerHash(WithoutNonce); - cdebug << "Mining with headerhash" << hh << "from nonce" << m_last << "with boundary" << _header.boundary(); - m_miner->search(hh.data(), tryNonce, *m_hook); + uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)_header.boundary() >> 192); + cdebug << "Mining with headerhash" << hh << "from nonce" << m_last << "with boundary" << _header.boundary() << " (" << upper64OfBoundary << ")"; + m_miner->search(hh.data(), upper64OfBoundary, *m_hook); } m_lastHeader = _header; From 6e78287401e219750e260512cdf385890a95ee46 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Apr 2015 00:45:21 +0200 Subject: [PATCH 3/9] Ability to switch GPU/CPU mining on the fly. --- CMakeLists.txt | 2 ++ alethzero/Main.ui | 18 +++++------ alethzero/MainWin.cpp | 3 ++ eth/main.cpp | 4 --- libethcore/ProofOfWork.cpp | 20 +++--------- libethcore/ProofOfWork.h | 34 ++++++++++----------- libethereum/Client.cpp | 16 +++++++--- libethereum/Client.h | 20 ++++++------ libethereum/ClientBase.h | 3 +- libethereum/Interface.h | 4 ++- libethereum/Miner.cpp | 4 ++- libethereum/Miner.h | 13 ++++---- libethereum/State.cpp | 25 ++------------- libethereum/State.h | 22 +++++++++++-- libweb3jsonrpc/WebThreeStubServerBase.cpp | 5 +++ libweb3jsonrpc/WebThreeStubServerBase.h | 1 + libweb3jsonrpc/abstractwebthreestubserver.h | 7 +++++ libweb3jsonrpc/spec.json | 5 +-- mix/MixClient.cpp | 10 ++++-- mix/MixClient.h | 3 +- test/blockchain.cpp | 7 +++-- test/stateOriginal.cpp | 5 +-- test/webthreestubclient.h | 10 ++++++ 23 files changed, 138 insertions(+), 103 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 100ef9139..e6a906b59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,8 @@ function(configureProject) if (GUI) add_definitions(-DETH_GUI) endif() + + add_definitions(-DETH_TRUE) endfunction() set(CPPETHEREUM 1) diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 6c01f57f9..3f3d1e237 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -150,6 +150,7 @@ &Tools + @@ -176,7 +177,6 @@ - @@ -1608,14 +1608,6 @@ font-size: 14pt &Enable LLL Optimizer - - - true - - - &Reserved Debug 1 - - true @@ -1679,6 +1671,14 @@ font-size: 14pt &NatSpec Enabled + + + true + + + &GPU Mining + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index bbacaf539..374829a61 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -707,6 +707,7 @@ void Main::writeSettings() s.setValue("upnp", ui->upnp->isChecked()); s.setValue("forceAddress", ui->forcePublicIP->text()); s.setValue("forceMining", ui->forceMining->isChecked()); + s.setValue("turboMining", ui->turboMining->isChecked()); s.setValue("paranoia", ui->paranoia->isChecked()); s.setValue("natSpec", ui->natSpec->isChecked()); s.setValue("showAll", ui->showAll->isChecked()); @@ -777,6 +778,8 @@ void Main::readSettings(bool _skipGeometry) ui->dropPeers->setChecked(false); ui->forceMining->setChecked(s.value("forceMining", false).toBool()); on_forceMining_triggered(); + ui->turboMining->setChecked(s.value("turboMining", false).toBool()); + on_turboMining_triggered(); ui->paranoia->setChecked(s.value("paranoia", false).toBool()); ui->natSpec->setChecked(s.value("natSpec", true).toBool()); ui->showAll->setChecked(s.value("showAll", false).toBool()); diff --git a/eth/main.cpp b/eth/main.cpp index c83332c20..e9af192f9 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -273,7 +273,6 @@ int main(int argc, char** argv) unsigned mining = ~(unsigned)0; int miners = -1; bool forceMining = false; - bool turboMining = false; KeyPair us = KeyPair::create(); Address coinbase = us.address(); @@ -466,8 +465,6 @@ int main(int argc, char** argv) bootstrap = true; else if (arg == "-f" || arg == "--force-mining") forceMining = true; - else if (arg == "-T" || arg == "--turbo-mining") - turboMining = true; else if (arg == "-i" || arg == "--interactive") interactive = true; #if ETH_JSONRPC @@ -632,7 +629,6 @@ int main(int argc, char** argv) { c->setGasPricer(gasPricer); c->setForceMining(forceMining); - c->setTurboMining(turboMining); c->setAddress(coinbase); } diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp index a97baca94..f7cf4944b 100644 --- a/libethcore/ProofOfWork.cpp +++ b/libethcore/ProofOfWork.cpp @@ -45,12 +45,12 @@ namespace dev namespace eth { -bool EthashCPU::verify(BlockInfo const& _header) +bool EthashPoW::verify(BlockInfo const& _header) { return Ethasher::verify(_header); } -std::pair EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) +std::pair EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue) { Ethasher::Miner m(_header); @@ -67,8 +67,6 @@ std::pair EthashCPU::mine(BlockInfo const& _header, // // evaluate until we run out of time auto startTime = std::chrono::steady_clock::now(); - if (!_turbo) - std::this_thread::sleep_for(std::chrono::milliseconds(_msTimeout * 90 / 100)); double best = 1e99; // high enough to be effectively infinity :) Proof result; unsigned hashCount = 0; @@ -102,7 +100,7 @@ std::pair EthashCPU::mine(BlockInfo const& _header, return ret; } -#if ETH_ETHASHCL +#if ETH_ETHASHCL || !ETH_TRUE /* class ethash_cl_miner @@ -186,12 +184,7 @@ EthashCL::~EthashCL() { } -bool EthashCL::verify(BlockInfo const& _header) -{ - return Ethasher::verify(_header); -} - -std::pair EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool) +std::pair EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool) { if (!m_lastHeader || m_lastHeader.seedHash() != _header.seedHash()) { @@ -201,7 +194,7 @@ std::pair EthashCL::mine(BlockInfo const& _header, unsi auto cb = [&](void* d) { Ethasher::get()->readFull(_header, d); }; - m_miner->init(Ethasher::params(_header), cb); + m_miner->init(Ethasher::params(_header), cb, 32); } if (m_lastHeader != _header) { @@ -209,7 +202,6 @@ std::pair EthashCL::mine(BlockInfo const& _header, unsi static std::random_device s_eng; auto hh = _header.headerHash(WithoutNonce); uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)_header.boundary() >> 192); - cdebug << "Mining with headerhash" << hh << "from nonce" << m_last << "with boundary" << _header.boundary() << " (" << upper64OfBoundary << ")"; m_miner->search(hh.data(), upper64OfBoundary, *m_hook); } m_lastHeader = _header; @@ -221,11 +213,9 @@ std::pair EthashCL::mine(BlockInfo const& _header, unsi for (auto const& n: found) { auto result = Ethasher::eval(_header, n); - cdebug << "Got nonce " << n << "gives result" << result.value; if (result.value < _header.boundary()) return std::make_pair(MineInfo(true), EthashCL::Proof{n, result.mixHash}); } - assert(false); } return std::make_pair(MineInfo(false), EthashCL::Proof()); } diff --git a/libethcore/ProofOfWork.h b/libethcore/ProofOfWork.h index 48d52049a..2e04e842c 100644 --- a/libethcore/ProofOfWork.h +++ b/libethcore/ProofOfWork.h @@ -51,7 +51,7 @@ struct MineInfo bool completed = false; }; -class EthashCPU +class EthashPoW { public: struct Proof @@ -61,31 +61,32 @@ public: }; static bool verify(BlockInfo const& _header); - std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } + virtual unsigned defaultTimeout() const { return 100; } + virtual std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) = 0; +}; + +class EthashCPU: public EthashPoW +{ +public: + std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) override; + protected: Nonce m_last; }; -#if ETH_ETHASHCL +#if ETH_ETHASHCL || !ETH_TRUE class EthashCLHook; -class EthashCL +class EthashCL: public EthashPoW { public: - struct Proof - { - Nonce nonce; - h256 mixHash; - }; - EthashCL(); ~EthashCL(); - static bool verify(BlockInfo const& _header); - std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); - static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } + std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) override; + unsigned defaultTimeout() const override { return 500; } protected: Nonce m_last; @@ -107,8 +108,9 @@ public: using Proof = Nonce; static bool verify(BlockInfo const& _header) { return (bigint)(u256)Evaluator::eval(_header.headerHash(WithoutNonce), _header.nonce) <= (bigint(1) << 256) / _header.difficulty; } - inline std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); + inline std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true); static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r; } + unsigned defaultTimeout() const { return 100; } protected: Nonce m_last; @@ -125,7 +127,7 @@ using SHA3ProofOfWork = ProofOfWorkEngine; using ProofOfWork = Ethash; template -std::pair::Proof> ProofOfWorkEngine::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) +std::pair::Proof> ProofOfWorkEngine::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue) { auto headerHashWithoutNonce = _header.headerHash(WithoutNonce); auto difficulty = _header.difficulty; @@ -142,8 +144,6 @@ std::pair::Proof> ProofOfWorkEng // // evaluate until we run out of time auto startTime = std::chrono::steady_clock::now(); - if (!_turbo) - std::this_thread::sleep_for(std::chrono::milliseconds(_msTimeout * 90 / 100)); double best = 1e99; // high enough to be effectively infinity :) ProofOfWorkEngine::Proof solution; unsigned h = 0; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 8c2d2b4fa..4b197797f 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -345,11 +345,10 @@ void Client::setForceMining(bool _enable) void Client::setMiningThreads(unsigned _threads) { stopMining(); -#if ETH_ETHASHCL - (void)_threads; - unsigned t = 1; -#else auto t = _threads ? _threads : thread::hardware_concurrency(); +#if ETH_ETHASHCL || !ETH_TRUE + if (m_turboMining) + t = 1; #endif WriteGuard l(x_localMiners); m_localMiners.clear(); @@ -368,6 +367,15 @@ MineProgress Client::miningProgress() const return ret; } +uint64_t Client::hashrate() const +{ + uint64_t ret; + ReadGuard l(x_localMiners); + for (LocalMiner const& m: m_localMiners) + ret += m.miningProgress().hashes / m.miningProgress().ms; + return ret / 1000; +} + std::list Client::miningHistory() { std::list ret; diff --git a/libethereum/Client.h b/libethereum/Client.h index 57fe0d9de..cc51f9747 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -188,25 +188,27 @@ public: bool forceMining() const { return m_forceMining; } /// Enable/disable forcing of mining to happen, even without transactions. void setForceMining(bool _enable); - /// Are we mining as fast as we can? + /// Are we allowed to GPU mine? bool turboMining() const { return m_turboMining; } - /// Enable/disable fast mining. - void setTurboMining(bool _enable = true) { m_turboMining = _enable; } + /// Enable/disable GPU mining. + void setTurboMining(bool _enable = true) { bool was = isMining(); stopMining(); m_turboMining = _enable; setMiningThreads(0); if (was) startMining(); } /// Stops mining and sets the number of mining threads (0 for automatic). - virtual void setMiningThreads(unsigned _threads = 0); + void setMiningThreads(unsigned _threads = 0) override; /// Get the effective number of mining threads. - virtual unsigned miningThreads() const { ReadGuard l(x_localMiners); return m_localMiners.size(); } + unsigned miningThreads() const override { ReadGuard l(x_localMiners); return m_localMiners.size(); } /// Start mining. /// NOT thread-safe - call it & stopMining only from a single thread - virtual void startMining() { startWorking(); { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); } } + void startMining() override { startWorking(); { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); } } /// Stop mining. /// NOT thread-safe - virtual void stopMining() { { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); } } + void stopMining() override { { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); } } /// Are we mining now? - virtual bool isMining() { { ReadGuard l(x_localMiners); if (!m_localMiners.empty() && m_localMiners[0].isRunning()) return true; } return false; } + bool isMining() const override { { ReadGuard l(x_localMiners); if (!m_localMiners.empty() && m_localMiners[0].isRunning()) return true; } return false; } + /// Are we mining now? + uint64_t hashrate() const override; /// Check the progress of the mining. - virtual MineProgress miningProgress() const; + MineProgress miningProgress() const override; /// Get and clear the mining history. std::list miningHistory(); diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 00bb02ed4..ddfbf1176 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -146,7 +146,8 @@ public: virtual unsigned miningThreads() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::miningThreads")); } virtual void startMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::startMining")); } virtual void stopMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::stopMining")); } - virtual bool isMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::isMining")); } + virtual bool isMining() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::isMining")); } + virtual uint64_t hashrate() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::hashrate")); } virtual eth::MineProgress miningProgress() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::miningProgress")); } virtual std::pair getWork() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::getWork")); } virtual bool submitWork(eth::ProofOfWork::Proof const&) override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::submitWork")); } diff --git a/libethereum/Interface.h b/libethereum/Interface.h index ac41b0ec1..02833743e 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -183,7 +183,9 @@ public: /// NOT thread-safe virtual void stopMining() = 0; /// Are we mining now? - virtual bool isMining() = 0; + virtual bool isMining() const = 0; + /// Current hash rate. + virtual uint64_t hashrate() const = 0; /// Get hash of the current block to be mined minus the nonce (the 'work hash'). virtual std::pair getWork() = 0; diff --git a/libethereum/Miner.cpp b/libethereum/Miner.cpp index 08bc426dc..b3a65f081 100644 --- a/libethereum/Miner.cpp +++ b/libethereum/Miner.cpp @@ -34,12 +34,14 @@ LocalMiner::LocalMiner(MinerHost* _host, unsigned _id): AsyncMiner(_host, _id), Worker("miner-" + toString(_id)) { + m_pow.reset(_host->turbo() ? new Ethash : (Ethash*)new EthashCPU); } void LocalMiner::setup(MinerHost* _host, unsigned _id) { AsyncMiner::setup(_host, _id); setName("miner-" + toString(m_id)); + m_pow.reset(_host->turbo() ? new Ethash : (Ethash*)new EthashCPU); } void LocalMiner::doWork() @@ -66,7 +68,7 @@ void LocalMiner::doWork() if (m_miningStatus == Mining) { // Mine for a while. - MineInfo mineInfo = m_mineState.mine(100, m_host->turbo()); + MineInfo mineInfo = m_mineState.mine(m_pow.get()); { Guard l(x_mineInfo); diff --git a/libethereum/Miner.h b/libethereum/Miner.h index 7c4f7e767..8c2fc4bb4 100644 --- a/libethereum/Miner.h +++ b/libethereum/Miner.h @@ -60,8 +60,8 @@ public: virtual void setupState(State& _s) = 0; ///< Reset the given State object to the one that should be being mined. virtual void onProgressed() {} ///< Called once some progress has been made. virtual void onComplete() {} ///< Called once a block is found. - virtual bool turbo() const = 0; ///< @returns true iff the Miner should mine as fast as possible. virtual bool force() const = 0; ///< @returns true iff the Miner should mine regardless of the number of transactions. + virtual bool turbo() const = 0; ///< @returns true iff the Miner should use GPU if possible. }; class Miner @@ -93,7 +93,7 @@ public: virtual void stop() {} /// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force(). - virtual bool isRunning() { return false; } + virtual bool isRunning() const { return false; } protected: MinerHost* m_host = nullptr; ///< Our host. @@ -122,10 +122,10 @@ public: LocalMiner(MinerHost* _host, unsigned _id = 0); /// Move-constructor. - LocalMiner(LocalMiner&& _m): Worker((Worker&&)_m) { std::swap(m_host, _m.m_host); } + LocalMiner(LocalMiner&& _m): Worker((Worker&&)_m) { std::swap(m_host, _m.m_host); std::swap(m_pow, _m.m_pow); } /// Move-assignment. - LocalMiner& operator=(LocalMiner&& _m) { Worker::operator=((Worker&&)_m); std::swap(m_host, _m.m_host); return *this; } + LocalMiner& operator=(LocalMiner&& _m) { Worker::operator=((Worker&&)_m); std::swap(m_host, _m.m_host); std::swap(m_pow, _m.m_pow); return *this; } /// Destructor. Stops miner. ~LocalMiner() { stop(); } @@ -143,7 +143,7 @@ public: virtual void noteStateChange() override { m_miningStatus = Preparing; } /// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force(). - bool isRunning() { return isWorking(); } + bool isRunning() const override { return isWorking(); } /// @returns true if mining is complete. virtual bool isComplete() const override { return m_miningStatus == Mined; } @@ -167,8 +167,9 @@ private: enum MiningStatus { Waiting, Preparing, Mining, Mined, Stopping, Stopped }; MiningStatus m_miningStatus = Waiting; ///< TODO: consider mutex/atomic variable. State m_mineState; ///< The state on which we are mining, generally equivalent to m_postMine. + std::unique_ptr m_pow; ///< Our miner. - mutable std::mutex x_mineInfo; ///< Lock for the mining progress & history. + mutable Mutex x_mineInfo; ///< Lock for the mining progress & history. MineProgress m_mineProgress; ///< What's our progress? std::list m_mineHistory; ///< What the history of our mining? }; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 5631ffe28..c1beee787 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -856,33 +856,12 @@ void State::commitToMine(BlockChain const& _bc) m_committedToMine = true; } -MineInfo State::mine(unsigned _msTimeout, bool _turbo) -{ - // Update difficulty according to timestamp. - m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock); - - MineInfo ret; - // TODO: Miner class that keeps dagger between mine calls (or just non-polling mining). - ProofOfWork::Proof r; - tie(ret, r) = m_pow.mine(m_currentBlock, _msTimeout, true, _turbo); - - if (!ret.completed) - m_currentBytes.clear(); - else - { - ProofOfWork::assignResult(r, m_currentBlock); - cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock); - } - - return ret; -} - bool State::completeMine(ProofOfWork::Proof const& _nonce) { ProofOfWork::assignResult(_nonce, m_currentBlock); - if (!m_pow.verify(m_currentBlock)) - return false; +// if (!m_pow.verify(m_currentBlock)) +// return false; cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock); diff --git a/libethereum/State.h b/libethereum/State.h index 336c58b1a..1b71038b4 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -168,7 +168,25 @@ public: /// This function is thread-safe. You can safely have other interactions with this object while it is happening. /// @param _msTimeout Timeout before return in milliseconds. /// @returns Information on the mining. - MineInfo mine(unsigned _msTimeout = 1000, bool _turbo = false); + template MineInfo mine(ProofOfWork* _pow) + { + // Update difficulty according to timestamp. + m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock); + + MineInfo ret; + typename ProofOfWork::Proof r; + std::tie(ret, r) = _pow->mine(m_currentBlock, _pow->defaultTimeout(), true); + + if (!ret.completed) + m_currentBytes.clear(); + else + { + ProofOfWork::assignResult(r, m_currentBlock); + cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock); + } + + return ret; + } /** Commit to DB and build the final block if the previous call to mine()'s result is completion. * Typically looks like: @@ -371,8 +389,6 @@ private: Address m_ourAddress; ///< Our address (i.e. the address to which fees go). - ProofOfWork m_pow; ///< The PoW mining class. - u256 m_blockReward; static std::string c_defaultPath; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index c86274b15..04bbe7345 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -296,6 +296,11 @@ string WebThreeStubServerBase::eth_coinbase() return toJS(client()->address()); } +string WebThreeStubServerBase::eth_hashrate() +{ + return toJS(client()->hashrate()); +} + bool WebThreeStubServerBase::eth_mining() { return client()->isMining(); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index b57a54c87..22a31a762 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -78,6 +78,7 @@ public: virtual bool net_listening(); virtual std::string eth_protocolVersion(); + virtual std::string eth_hashrate(); virtual std::string eth_coinbase(); virtual bool eth_mining(); virtual std::string eth_gasPrice(); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 6cc5de3e6..0860ecaee 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -18,6 +18,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("net_peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::net_peerCountI); this->bindAndAddMethod(jsonrpc::Procedure("net_listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::net_listeningI); this->bindAndAddMethod(jsonrpc::Procedure("eth_protocolVersion", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_protocolVersionI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_hashrate", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_hashrateI); this->bindAndAddMethod(jsonrpc::Procedure("eth_coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_coinbaseI); this->bindAndAddMethod(jsonrpc::Procedure("eth_mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_miningI); this->bindAndAddMethod(jsonrpc::Procedure("eth_gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_gasPriceI); @@ -98,6 +99,11 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_protocolVersion(); } + inline virtual void eth_hashrateI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_hashrate(); + } inline virtual void eth_coinbaseI(const Json::Value &request, Json::Value &response) { (void)request; @@ -309,6 +315,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer getWork() override { return std::pair(); } bool submitWork(eth::ProofOfWork::Proof const&) override { return false; } diff --git a/test/blockchain.cpp b/test/blockchain.cpp index ab01df5a5..15cda8037 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -192,7 +192,8 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) state.sync(bc, txs, gp); state.commitToMine(bc); MineInfo info; - for (info.completed = false; !info.completed; info = state.mine()) {} + ProofOfWork pow; + for (info.completed = false; !info.completed; info = state.mine(&pow)) {} state.completeMine(); } catch (Exception const& _e) @@ -577,7 +578,7 @@ void overwriteBlockHeader(BlockInfo& _currentBlockHeader, mObject& _blObj) std::pair ret; while (!ProofOfWork::verify(_currentBlockHeader)) { - ret = pow.mine(_currentBlockHeader, 1000, true, true); + ret = pow.mine(_currentBlockHeader, 1000, true); Ethash::assignResult(ret.second, _currentBlockHeader); } } @@ -623,7 +624,7 @@ void updatePoW(BlockInfo& _bi) std::pair ret; while (!ProofOfWork::verify(_bi)) { - ret = pow.mine(_bi, 10000, true, true); + ret = pow.mine(_bi, 10000, true); Ethash::assignResult(ret.second, _bi); } _bi.noteDirty(); diff --git a/test/stateOriginal.cpp b/test/stateOriginal.cpp index 572e84dcf..40f759434 100644 --- a/test/stateOriginal.cpp +++ b/test/stateOriginal.cpp @@ -68,7 +68,8 @@ BOOST_AUTO_TEST_CASE(Complex) // Mine to get some ether! s.commitToMine(bc); - while (!s.mine(100, true).completed) {} + ProofOfWork pow; + while (!s.mine(&pow).completed) {} s.completeMine(); bc.attemptImport(s.blockData(), stateDB); @@ -88,7 +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(100, true).completed) {} + while (!s.mine(&pow).completed) {} s.completeMine(); bc.attemptImport(s.blockData(), stateDB); diff --git a/test/webthreestubclient.h b/test/webthreestubclient.h index a460ddda4..c1fdc3411 100644 --- a/test/webthreestubclient.h +++ b/test/webthreestubclient.h @@ -72,6 +72,16 @@ class WebThreeStubClient : public jsonrpc::Client else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } + std::string eth_hashrate() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_hashrate",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } std::string eth_coinbase() throw (jsonrpc::JsonRpcException) { Json::Value p; From 71c83172c5bd55f9297113a8007f79e70bd040c5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 12 Apr 2015 12:15:56 +0200 Subject: [PATCH 4/9] Fixes #1597 --- libethereum/State.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index c1beee787..6d3301cd7 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -451,7 +451,7 @@ bool State::cull(TransactionQueue& _tq) const { try { - if (i.second.nonce() <= transactionsFrom(i.second.sender())) + if (i.second.nonce() < transactionsFrom(i.second.sender())) { _tq.drop(i.first); ret = true; From 927989907fbd3c1af1f30ab8f441d0e846e709ef Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 12 Apr 2015 12:17:28 +0200 Subject: [PATCH 5/9] Avoid ethashcl in exp. Fixes #1594 --- exp/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 7e670cfaa..d2a0e9ead 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -23,10 +23,11 @@ endif() target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} p2p) +if (ETHASHCL) target_link_libraries(${EXECUTABLE} ethash-cl) target_link_libraries(${EXECUTABLE} ethash) target_link_libraries(${EXECUTABLE} OpenCL) - +endif() install( TARGETS ${EXECUTABLE} DESTINATION bin) From 07f780fa30d827950dbabf67caa86c24c0de092a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 12 Apr 2015 12:22:45 +0200 Subject: [PATCH 6/9] Fixes #1573 --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 04bbe7345..9f765935b 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -607,10 +607,10 @@ Json::Value WebThreeStubServerBase::eth_getCompilers() { Json::Value ret(Json::arrayValue); ret.append("lll"); -#if SOLIDITY +#if ETH_SOLIDITY || !TRUE ret.append("solidity"); #endif -#if SERPENT +#if ETH_SERPENT || !TRUE ret.append("serpent"); #endif return ret; @@ -632,7 +632,7 @@ string WebThreeStubServerBase::eth_compileSerpent(string const& _code) // TODO throw here jsonrpc errors string res; (void)_code; -#if SERPENT +#if ETH_SERPENT || !TRUE try { res = toJS(dev::asBytes(::compile(_code))); @@ -654,7 +654,7 @@ string WebThreeStubServerBase::eth_compileSolidity(string const& _code) // TOOD throw here jsonrpc errors (void)_code; string res; -#if SOLIDITY +#if ETH_SOLIDITY || !TRUE dev::solidity::CompilerStack compiler; try { From 2eab7a7c22883cfda35f341609f6af53b05ebc72 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 12 Apr 2015 16:34:35 +0200 Subject: [PATCH 7/9] Fixes some build issues. --- libethereum/Client.cpp | 2 +- libweb3jsonrpc/WebThreeStubServerBase.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 4b197797f..87eff7f08 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -369,7 +369,7 @@ MineProgress Client::miningProgress() const uint64_t Client::hashrate() const { - uint64_t ret; + uint64_t ret = 0; ReadGuard l(x_localMiners); for (LocalMiner const& m: m_localMiners) ret += m.miningProgress().hashes / m.miningProgress().ms; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 9f765935b..5b6c833bc 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -26,7 +26,7 @@ #include #include -#if ETH_SOLIDITY +#if ETH_SOLIDITY || !ETH_TRUE #include #include #include @@ -38,7 +38,7 @@ #include #include #include -#if ETH_SERPENT +#if ETH_SERPENT || !ETH_TRUE #include #endif #include "WebThreeStubServerBase.h" @@ -632,7 +632,7 @@ string WebThreeStubServerBase::eth_compileSerpent(string const& _code) // TODO throw here jsonrpc errors string res; (void)_code; -#if ETH_SERPENT || !TRUE +#if ETH_SERPENT || !ETH_TRUE try { res = toJS(dev::asBytes(::compile(_code))); @@ -654,7 +654,7 @@ string WebThreeStubServerBase::eth_compileSolidity(string const& _code) // TOOD throw here jsonrpc errors (void)_code; string res; -#if ETH_SOLIDITY || !TRUE +#if ETH_SOLIDITY || !ETH_TRUE dev::solidity::CompilerStack compiler; try { From 97a18e33feb60d72630ee26837cde4a775313dd9 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 12 Apr 2015 16:36:11 +0200 Subject: [PATCH 8/9] Avoid llvm warning. --- libethereum/Client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 87eff7f08..d8723430d 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -264,7 +264,7 @@ static string filtersToString(T const& _fs) { stringstream ret; ret << "{"; - bool i = false; + unsigned i = 0; for (h256 const& f: _fs) ret << (i++ ? ", " : "") << (f == PendingChangedFilter ? "pending" : f == ChainChangedFilter ? "chain" : f.abridged()); ret << "}"; From 1a67af3115eb16383f1e5b806426f37e7ea4d818 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 12 Apr 2015 23:25:20 +0200 Subject: [PATCH 9/9] Fix configuraion issues. --- CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e6a906b59..05862d9f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,7 +136,6 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") endif () createDefaultCacheConfig() -configureProject() # Force chromium. set (ETH_HAVE_WEBENGINE 1) @@ -263,6 +262,8 @@ elseif (BUNDLE STREQUAL "user") set(TESTS OFF) endif () +configureProject() + # Default CMAKE_BUILD_TYPE to "Release". set(CMAKE_BUILD_TYPE CACHE STRING "Release") if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x") @@ -272,7 +273,11 @@ endif () # Default TARGET_PLATFORM to "linux". set(TARGET_PLATFORM CACHE STRING "linux") if ("x${TARGET_PLATFORM}" STREQUAL "x") - set(TARGET_PLATFORM "linux") + if (WIN32) + set(TARGET_PLATFORM "windows") + else () + set(TARGET_PLATFORM "linux") + endif () endif () message("------------------------------------------------------------------------") @@ -308,7 +313,7 @@ include(EthCompilerSettings) message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}") -# this must be an include, as a function it would messs up with variable scope! +# this must be an include, as a function it would mess up with variable scope! include(EthDependencies) include(EthExecutableHelper)