10 changed files with 22 additions and 297 deletions
@ -1,94 +0,0 @@ |
|||
/*
|
|||
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 Miner.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @author Giacomo Tazzari |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "Miner.h" |
|||
|
|||
#include <libdevcore/CommonIO.h> |
|||
#include "State.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
OldMiner::~OldMiner() {} |
|||
|
|||
LocalMiner::LocalMiner(MinerHost* _host, unsigned _id) |
|||
{ |
|||
setup(_host, _id); |
|||
} |
|||
|
|||
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() |
|||
{ |
|||
// Do some mining.
|
|||
if (m_miningStatus != Waiting && m_miningStatus != Mined) |
|||
{ |
|||
if (m_miningStatus == Preparing) |
|||
{ |
|||
m_host->setupState(m_mineState); |
|||
if (m_host->force() || m_mineState.pending().size()) |
|||
m_miningStatus = Mining; |
|||
else |
|||
m_miningStatus = Waiting; |
|||
|
|||
{ |
|||
Guard l(x_mineInfo); |
|||
m_mineProgress.best = (double)-1; |
|||
m_mineProgress.hashes = 0; |
|||
m_mineProgress.ms = 0; |
|||
} |
|||
} |
|||
|
|||
if (m_miningStatus == Mining) |
|||
{ |
|||
// Mine for a while.
|
|||
MineInfo mineInfo = m_mineState.mine(m_pow.get()); |
|||
|
|||
{ |
|||
Guard l(x_mineInfo); |
|||
m_mineProgress.best = min(m_mineProgress.best, mineInfo.best); |
|||
m_mineProgress.current = mineInfo.best; |
|||
m_mineProgress.requirement = mineInfo.requirement; |
|||
m_mineProgress.ms += 100; |
|||
m_mineProgress.hashes += mineInfo.hashes; |
|||
m_mineHistory.push_back(mineInfo); |
|||
} |
|||
if (mineInfo.completed) |
|||
{ |
|||
m_mineState.completeMine(); |
|||
m_host->onComplete(); |
|||
m_miningStatus = Mined; |
|||
} |
|||
else |
|||
m_host->onProgressed(); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
this_thread::sleep_for(chrono::milliseconds(100)); |
|||
} |
|||
} |
@ -1,166 +0,0 @@ |
|||
/*
|
|||
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 Miner.h
|
|||
* @author Alex Leverington <nessence@gmail.com> |
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <thread> |
|||
#include <list> |
|||
#include <atomic> |
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/Worker.h> |
|||
#include <libethcore/Common.h> |
|||
#include <libethcore/Miner.h> |
|||
#include "State.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth |
|||
{ |
|||
|
|||
/**
|
|||
* @brief Class for hosting one or more Miners. |
|||
* @warning Must be implemented in a threadsafe manner since it will be called from multiple |
|||
* miner threads. |
|||
*/ |
|||
class MinerHost |
|||
{ |
|||
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 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 OldMiner |
|||
{ |
|||
public: |
|||
virtual ~OldMiner(); |
|||
|
|||
virtual void noteStateChange() = 0; |
|||
virtual bool isComplete() const = 0; |
|||
virtual bytes const& blockData() const = 0; |
|||
}; |
|||
|
|||
class AsyncMiner: public OldMiner |
|||
{ |
|||
public: |
|||
/// Null constructor.
|
|||
AsyncMiner(): m_host(nullptr) {} |
|||
|
|||
/// Constructor.
|
|||
AsyncMiner(MinerHost* _host, unsigned _id = 0): m_host(_host), m_id(_id) {} |
|||
|
|||
/// Setup its basics.
|
|||
void setup(MinerHost* _host, unsigned _id = 0) { m_host = _host; m_id = _id; } |
|||
|
|||
/// Start mining.
|
|||
virtual void start() {} |
|||
|
|||
/// Stop mining.
|
|||
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() const { return false; } |
|||
|
|||
protected: |
|||
MinerHost* m_host = nullptr; ///< Our host.
|
|||
unsigned m_id = 0; ///< Our unique id.
|
|||
}; |
|||
|
|||
/**
|
|||
* @brief Implements Miner. |
|||
* To begin mining, use start() & stop(). noteStateChange() can be used to reset the mining and set up the |
|||
* State object according to the host. Use isRunning() to determine if the miner has been start()ed. |
|||
* Use isComplete() to determine if the miner has finished mining. |
|||
* |
|||
* blockData() can be used to retrieve the complete block, ready for insertion into the BlockChain. |
|||
* |
|||
* Information on the mining can be queried through miningProgress() and miningHistory(). |
|||
* @threadsafe |
|||
* @todo Signal Miner to restart once with condition variables. |
|||
*/ |
|||
class LocalMiner: public AsyncMiner, Worker |
|||
{ |
|||
public: |
|||
/// Null constructor.
|
|||
LocalMiner() {} |
|||
|
|||
/// Constructor.
|
|||
LocalMiner(MinerHost* _host, unsigned _id = 0); |
|||
|
|||
/// Move-constructor.
|
|||
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); std::swap(m_pow, _m.m_pow); return *this; } |
|||
|
|||
/// Destructor. Stops miner.
|
|||
~LocalMiner() { stop(); } |
|||
|
|||
/// Setup its basics.
|
|||
void setup(MinerHost* _host, unsigned _id = 0); |
|||
|
|||
/// Start mining.
|
|||
void start() { startWorking(); } |
|||
|
|||
/// Stop mining.
|
|||
void stop() { stopWorking(); } |
|||
|
|||
/// Call to notify Miner of a state change.
|
|||
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() const override { return isWorking(); } |
|||
|
|||
/// @returns true if mining is complete.
|
|||
virtual bool isComplete() const override { return m_miningStatus == Mined; } |
|||
|
|||
/// @returns the internal State object.
|
|||
virtual bytes const& blockData() const override { return m_mineState.blockData(); } |
|||
|
|||
/// Check the progress of the mining.
|
|||
MineProgress miningProgress() const { Guard l(x_mineInfo); return m_mineProgress; } |
|||
|
|||
/// Get and clear the mining history.
|
|||
std::list<MineInfo> miningHistory() { Guard l(x_mineInfo); auto ret = m_mineHistory; m_mineHistory.clear(); return ret; } |
|||
|
|||
/// @returns the state on which we mined.
|
|||
State const& state() const { return m_mineState; } |
|||
|
|||
private: |
|||
/// Do some work on the mining.
|
|||
virtual void doWork(); |
|||
|
|||
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<EthashPoW> m_pow; ///< Our miner.
|
|||
|
|||
mutable Mutex x_mineInfo; ///< Lock for the mining progress & history.
|
|||
MineProgress m_mineProgress; ///< What's our progress?
|
|||
std::list<MineInfo> m_mineHistory; ///< What the history of our mining?
|
|||
}; |
|||
|
|||
} |
|||
} |
Loading…
Reference in new issue