You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.0 KiB

/*
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 Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include <thread>
#include <list>
#include <atomic>
#include <libdevcore/Common.h>
#include <libdevcore/Worker.h>
#include <libethcore/Common.h>
namespace dev
{
namespace eth
{
/**
* @brief Describes the progress of a mining operation.
*/
struct MiningProgress
{
// 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;
}
10 years ago
template <class PoW> class GenericMiner;
/**
* @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.
*/
10 years ago
template <class PoW> class GenericFarmFace
{
public:
using WorkPackage = typename PoW::WorkPackage;
using Solution = typename PoW::Solution;
10 years ago
using Miner = GenericMiner<PoW>;
/**
* @brief Called from a Miner to note a WorkPackage has a solution.
* @param _p The solution.
* @param _wp The WorkPackage that the Solution is for.
* @param _finder The miner that found it.
* @return true iff the solution was good (implying that mining should be .
*/
virtual bool submitProof(Solution const& _p, WorkPackage const& _wp, Miner* _finder) = 0;
};
/**
* @brief A miner - a member and adoptee of the Farm.
*/
10 years ago
template <class PoW> class GenericMiner
{
public:
using WorkPackage = typename PoW::WorkPackage;
using Solution = typename PoW::Solution;
10 years ago
using FarmFace = GenericFarmFace<PoW>;
using ConstructionInfo = std::pair<FarmFace*, unsigned>;
10 years ago
GenericMiner(ConstructionInfo const& _ci):
m_farm(_ci.first),
m_index(_ci.second)
{}
// API FOR THE FARM TO CALL IN WITH
void setWork(WorkPackage const& _work = WorkPackage())
{
Guard l(x_work);
if (_work.headerHash == m_work.headerHash)
return;
if (_work.headerHash != h256())
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:
// REQUIRED TO BE REIMPLEMENTED BY A SUBCLASS:
/**
* @brief Begin working on a given work package, discarding any previous work.
* @param _work The package for which to find a solution.
*/
virtual void kickOff(WorkPackage const& _work) = 0;
/**
* @brief No work left to be done. Pause until told to kickOff().
*/
virtual void pause() = 0;
// AVAILABLE FOR A SUBCLASS TO CALL:
/**
* @brief Notes that the Miner found a solution.
* @param _s The solution.
* @return true if the solution was correct and that the miner should pause.
*/
bool submitProof(Solution const& _s)
{
if (m_farm)
{
Guard l(x_work);
return m_farm->submitProof(_s, m_work, this);
}
return true;
}
10 years ago
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;
};
}
}