diff --git a/libdevcore/Worker.cpp b/libdevcore/Worker.cpp
index 175323620..bc8fe97f2 100644
--- a/libdevcore/Worker.cpp
+++ b/libdevcore/Worker.cpp
@@ -39,12 +39,7 @@ void Worker::startWorking()
{
setThreadName(m_name.c_str());
startedWorking();
- while (!m_stop)
- {
- if (m_idleWaitMs)
- this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs));
- doWork();
- }
+ workLoop();
cnote << "Finishing up worker thread";
doneWorking();
}));
@@ -63,3 +58,12 @@ void Worker::stopWorking()
cnote << "Stopped" << m_name;
}
+void Worker::workLoop()
+{
+ while (!m_stop)
+ {
+ if (m_idleWaitMs)
+ this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs));
+ doWork();
+ }
+}
diff --git a/libdevcore/Worker.h b/libdevcore/Worker.h
index 40bc118aa..6a35d6c4c 100644
--- a/libdevcore/Worker.h
+++ b/libdevcore/Worker.h
@@ -57,7 +57,11 @@ protected:
virtual void startedWorking() {}
/// Called continuously following sleep for m_idleWaitMs.
- virtual void doWork() = 0;
+ virtual void doWork() {}
+
+ /// Overrides doWork(); should call shouldStop() often and exit when true.
+ virtual void workLoop();
+ bool shouldStop() const { return m_stop; }
/// Called when is to be stopped, just prior to thread being joined.
virtual void doneWorking() {}
diff --git a/libethcore/Miner.cpp b/libethcore/Miner.cpp
new file mode 100644
index 000000000..d6f15866f
--- /dev/null
+++ b/libethcore/Miner.cpp
@@ -0,0 +1,12 @@
+#include "Miner.h"
+
+Miner::Miner()
+{
+
+}
+
+Miner::~Miner()
+{
+
+}
+
diff --git a/libethcore/Miner.h b/libethcore/Miner.h
new file mode 100644
index 000000000..a7f17e565
--- /dev/null
+++ b/libethcore/Miner.h
@@ -0,0 +1,146 @@
+/*
+ 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 .
+ */
+/** @file Miner.h
+ * @author Alex Leverington
+ * @author Gav Wood
+ * @date 2014
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "State.h"
+
+namespace dev
+{
+
+namespace eth
+{
+
+struct WorkPackage
+{
+ h256 boundary;
+ h256 headerHash; ///< When h256() means "pause until notified a new work package is available".
+ h256 seedHash;
+};
+
+static const WorkPackage NullWorkPackage;
+
+/**
+ * @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.
+ unsigned hashes = 0; ///< Total number of hashes computed.
+ unsigned ms = 0; ///< Total number of milliseconds of mining thus far.
+};
+
+/**
+ * @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 FarmFace
+{
+public:
+ /**
+ * @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.
+ * @return true iff the solution was good (implying that mining should be .
+ */
+ virtual bool submitProof(ProofOfWork::Solution const& _p, WorkPackage const& _wp) = 0;
+};
+
+/**
+ * @brief A miner - a member and adoptee of the Farm.
+ */
+class Miner
+{
+public:
+ using ConstructionInfo = std::pair;
+
+ Miner(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 != h256())
+ kickOff(m_work);
+ else if (m_work.headerHash == h256() && _work.headerHash != h256())
+ pause();
+ m_work = _work;
+ }
+
+ 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(ProofOfWork::Solution const& _s)
+ {
+ if (m_farm)
+ {
+ Guard l(x_work);
+ return m_farm->submitProof(_s, m_work, this);
+ }
+ return true;
+ }
+
+private:
+ FarmFace* m_farm = nullptr;
+ unsigned m_index;
+
+ Mutex x_work;
+ WorkPackage m_work;
+};
+
+}
+}
diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp
index ffa787e3e..1b3b55f4d 100644
--- a/libethcore/ProofOfWork.cpp
+++ b/libethcore/ProofOfWork.cpp
@@ -45,13 +45,38 @@ namespace dev
namespace eth
{
-bool EthashPoW::verify(BlockInfo const& _header)
+void Ethash::CPUMiner::workLoop()
{
- return Ethasher::verify(_header);
-}
+ Solution solution;
+
+ class Miner
+ {
+ public:
+ Miner(BlockInfo const& _header):
+ m_headerHash(_header.headerHash(WithoutNonce)),
+ m_params(Ethasher::params(_header)),
+ m_datasetPointer(Ethasher::get()->full(_header).data())
+ {}
+
+ inline h256 mine(uint64_t _nonce)
+ {
+ ethash_compute_full(&m_ethashReturn, m_datasetPointer, &m_params, m_headerHash.data(), _nonce);
+// cdebug << "Ethasher::mine hh:" << m_headerHash << "nonce:" << (Nonce)(u64)_nonce << " => " << h256(m_ethashReturn.result, h256::ConstructFromPointer);
+ return h256(m_ethashReturn.result, h256::ConstructFromPointer);
+ }
+
+ inline h256 lastMixHash() const
+ {
+ return h256(m_ethashReturn.mix_hash, h256::ConstructFromPointer);
+ }
+
+ private:
+ ethash_return_value m_ethashReturn;
+ h256 m_headerHash;
+ ethash_params m_params;
+ void const* m_datasetPointer;
+ };
-std::pair EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue)
-{
Ethasher::Miner m(_header);
std::pair ret;
@@ -70,34 +95,21 @@ std::pair EthashCPU::mine(BlockInfo const& _heade
double best = 1e99; // high enough to be effectively infinity :)
Solution result;
unsigned hashCount = 0;
- for (; (std::chrono::steady_clock::now() - startTime) < std::chrono::milliseconds(_msTimeout) && _continue; tryNonce++, hashCount++)
+ for (; !shouldStop(); tryNonce++, hashCount++)
{
h256 val(m.mine(tryNonce));
best = std::min(best, log2((double)(u256)val));
if (val <= boundary)
{
- ret.first.completed = true;
- assert(Ethasher::eval(_header, (Nonce)(u64)tryNonce).value == val);
- result.mixHash = m.lastMixHash();
- result.nonce = u64(tryNonce);
- BlockInfo test = _header;
- assignResult(result, test);
- assert(verify(test));
- break;
+ if (submitProof(solution))
+ return;
}
}
ret.first.hashes = hashCount;
ret.first.best = best;
ret.second = result;
- if (ret.first.completed)
- {
- BlockInfo test = _header;
- assignResult(result, test);
- assert(verify(test));
- }
-
- return ret;
+ return;
}
#if ETH_ETHASHCL || !ETH_TRUE
diff --git a/libethcore/ProofOfWork.h b/libethcore/ProofOfWork.h
index bd8ab58db..3ea177a9a 100644
--- a/libethcore/ProofOfWork.h
+++ b/libethcore/ProofOfWork.h
@@ -29,6 +29,7 @@
#include
#include "Common.h"
#include "BlockInfo.h"
+#include "Miner.h"
#define FAKE_DAGGER 1
@@ -51,39 +52,56 @@ struct MineInfo
bool completed = false;
};
-class EthashPoW
+class EthashCLHook;
+
+class Ethash
{
-public:
- struct Solution
- {
- Nonce nonce;
- h256 mixHash;
- };
- static bool verify(BlockInfo const& _header);
- static void assignResult(Solution const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
+public:
- virtual unsigned defaultTimeout() const { return 100; }
- virtual std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) = 0;
+struct Solution
+{
+ Nonce nonce;
+ h256 mixHash;
};
-class EthashCPU: public EthashPoW
+static bool verify(BlockInfo const& _header);
+static void assignResult(Solution const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
+
+class CPUMiner: public Miner, Worker
{
public:
- std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) override;
+ CPUMiner(ConstructionInfo const& _ci): Miner(_ci), Worker("miner" + toString(index())) {}
-protected:
- Nonce m_last;
+ static unsigned instances() { return thread::hardware_concurrency(); }
+
+ void kickOff(WorkPackage const& _work) override
+ {
+ stopWorking();
+ m_work = _work;
+ startWorking();
+ }
+
+ void pause() override { stopWorking(); }
+
+private:
+ void workLoop() override;
+
+ WorkPackage m_work;
+ MineInfo m_info;
};
#if ETH_ETHASHCL || !ETH_TRUE
-class EthashCLHook;
-class EthashCL: public EthashPoW
+class GPUMiner: public NewMiner
{
public:
- EthashCL();
- ~EthashCL();
+ GPUMiner(ConstructionInfo const& _ci): NewMiner(_ci)
+ {
+
+ }
+
+ static unsigned instances() { return 1; }
std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true) override;
unsigned defaultTimeout() const override { return 500; }
@@ -96,81 +114,15 @@ protected:
std::unique_ptr m_hook;
};
-using Ethash = EthashCL;
#else
-using Ethash = EthashCPU;
-#endif
-template
-class ProofOfWorkEngine: public Evaluator
-{
-public:
- using Solution = Nonce;
+using GPUMiner = CPUMiner;
- 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);
- static void assignResult(Solution const& _r, BlockInfo& _header) { _header.nonce = _r; }
- unsigned defaultTimeout() const { return 100; }
-
-protected:
- Nonce m_last;
-};
+#endif
-class SHA3Evaluator
-{
-public:
- static h256 eval(h256 const& _root, Nonce const& _nonce) { h256 b[2] = { _root, h256(_nonce) }; return sha3(bytesConstRef((byte const*)&b[0], 64)); }
};
-using SHA3ProofOfWork = ProofOfWorkEngine;
-
using ProofOfWork = Ethash;
-template
-std::pair::Solution> ProofOfWorkEngine::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue)
-{
- auto headerHashWithoutNonce = _header.headerHash(WithoutNonce);
- auto difficulty = _header.difficulty;
-
- std::pair ret;
- static std::mt19937_64 s_eng((time(0) + *reinterpret_cast(m_last.data())));
- Nonce::Arith s = (m_last = Nonce::random(s_eng));
-
- bigint d = (bigint(1) << 256) / difficulty;
- ret.first.requirement = log2((double)d);
-
- // 2^ 0 32 64 128 256
- // [--------*-------------------------]
- //
- // evaluate until we run out of time
- auto startTime = std::chrono::steady_clock::now();
- double best = 1e99; // high enough to be effectively infinity :)
- ProofOfWorkEngine::Solution solution;
- unsigned h = 0;
- for (; (std::chrono::steady_clock::now() - startTime) < std::chrono::milliseconds(_msTimeout) && _continue; s++, h++)
- {
- solution = (ProofOfWorkEngine::Solution)s;
- auto e = (bigint)(u256)Evaluator::eval(headerHashWithoutNonce, solution);
- best = std::min(best, log2((double)e));
- if (e <= d)
- {
- ret.first.completed = true;
- break;
- }
- }
- ret.first.hashes = h;
- ret.first.best = best;
- ret.second = solution;
-
- if (ret.first.completed)
- {
- BlockInfo test = _header;
- assignResult(solution, test);
- assert(verify(test));
- }
-
- return ret;
-}
-
}
}
diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp
index b2f5ff63c..e7c91c03f 100644
--- a/libethereum/Client.cpp
+++ b/libethereum/Client.cpp
@@ -467,7 +467,7 @@ void Client::doWork()
cworkin << "WORK";
h256Set changeds;
- auto maintainMiner = [&](Miner& m)
+ auto maintainMiner = [&](OldMiner& m)
{
if (m.isComplete())
{
diff --git a/libethereum/Client.h b/libethereum/Client.h
index ec852afd2..9af501f74 100644
--- a/libethereum/Client.h
+++ b/libethereum/Client.h
@@ -72,7 +72,7 @@ private:
std::string m_path;
};
-class RemoteMiner: public Miner
+class RemoteMiner: public OldMiner
{
public:
RemoteMiner() {}
@@ -124,7 +124,7 @@ struct ClientDetail: public LogChannel { static const char* name() { return " C
*/
class Client: public MinerHost, public ClientBase, Worker
{
- friend class Miner;
+ friend class OldMiner;
public:
/// New-style Constructor.
diff --git a/libethereum/Farm.cpp b/libethereum/Farm.cpp
new file mode 100644
index 000000000..639e4efcf
--- /dev/null
+++ b/libethereum/Farm.cpp
@@ -0,0 +1,12 @@
+#include "Farm.h"
+
+Farm::Farm()
+{
+
+}
+
+Farm::~Farm()
+{
+
+}
+
diff --git a/libethereum/Farm.h b/libethereum/Farm.h
new file mode 100644
index 000000000..a49038f0d
--- /dev/null
+++ b/libethereum/Farm.h
@@ -0,0 +1,153 @@
+/*
+ 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 .
+ */
+/** @file Miner.h
+ * @author Alex Leverington
+ * @author Gav Wood
+ * @date 2014
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "Miner.h"
+
+namespace dev
+{
+
+namespace eth
+{
+
+/**
+ * @brief A collective of Miners.
+ * Miners ask for work, then submit proofs
+ * @threadsafe
+ */
+template
+class Farm: public FarmFace
+{
+public:
+ /**
+ * @brief Sets the current mining mission.
+ * @param _bi The block (header) we wish to be mining.
+ */
+ void setWork(BlockInfo const& _bi)
+ {
+ WriteGuard l(x_work);
+ m_header = _bi;
+ m_work.boundary = _bi.boundary();
+ m_work.headerHash = _bi.headerHash(WithNonce);
+ m_work.seedHash = _bi.seedHash();
+ ReadGuard l(x_miners);
+ for (auto const& m: miners)
+ m->setWork(m_work);
+ }
+
+ /**
+ * @brief (Re)start miners for CPU only.
+ * @returns true if started properly.
+ */
+ bool startCPU() { return start(); }
+
+ /**
+ * @brief (Re)start miners for GPU only.
+ * @returns true if started properly.
+ */
+ bool startGPU() { start(); }
+
+ /**
+ * @brief Stop all mining activities.
+ */
+ void stop()
+ {
+ WriteGuard l(x_miners);
+ m_miners.clear();
+ }
+
+ /**
+ * @brief Get information on the progress of mining this work package.
+ * @return The progress with mining so far.
+ */
+ MineProgress const& mineProgress() const { ReadGuard l(x_progress); return m_progress; }
+
+protected:
+ // TO BE REIMPLEMENTED BY THE SUBCLASS
+ /**
+ * @brief Provides a valid header based upon that received previously with setWork().
+ * @param _bi The now-valid header.
+ * @return true if the header was good and that the Farm should pause until more work is submitted.
+ */
+ virtual bool submitHeader(BlockInfo const& _bi) = 0;
+
+private:
+ /**
+ * @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.
+ * @return true iff the solution was good (implying that mining should be .
+ */
+ bool submitProof(ProofOfWork::Solution const& _p, WorkPackage const& _wp, NewMiner* _m) override
+ {
+ if (_wp.headerHash != m_work.headerHash)
+ return false;
+
+ ProofOfWork::assignResult(_p, m_header);
+ if (submitHeader(m_header))
+ {
+ ReadGuard l(x_miners);
+ for (std::shared_ptr const& m: m_miners)
+ if (m.get() != _m)
+ m->pause();
+ m_work.headerHash = h256();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @brief Start a number of miners.
+ */
+ template
+ bool start()
+ {
+ WriteGuard l(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(new MinerType(std::make_pair(this, i)));
+ return true;
+ }
+
+ mutable SharedMutex x_miners;
+ std::vector> m_miners;
+
+ mutable SharedMutex x_progress;
+ MineProgress m_progress;
+
+ mutable SharedMutex x_work;
+ WorkPackage m_work;
+ BlockInfo m_header;
+};
+
+}
+}
diff --git a/libethereum/Miner.cpp b/libethereum/Miner.cpp
index dc3d9bd9e..b386fe868 100644
--- a/libethereum/Miner.cpp
+++ b/libethereum/Miner.cpp
@@ -28,7 +28,7 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
-Miner::~Miner() {}
+OldMiner::~OldMiner() {}
LocalMiner::LocalMiner(MinerHost* _host, unsigned _id)
{
diff --git a/libethereum/Miner.h b/libethereum/Miner.h
index 86d103db5..3abf93770 100644
--- a/libethereum/Miner.h
+++ b/libethereum/Miner.h
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include "State.h"
namespace dev
@@ -36,28 +37,6 @@ namespace dev
namespace eth
{
-struct WorkPackage
-{
- h256 boundary;
- h256 headerHash; ///< When h256() means "pause until notified a new work package is available".
- h256 seedHash;
-};
-
-static const WorkPackage NullWorkPackage;
-
-/**
- * @brief Describes the progress of a mining operation.
- */
-struct MineProgress
-{
- void combine(MineProgress 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.
- unsigned hashes = 0; ///< Total number of hashes computed.
- unsigned ms = 0; ///< Total number of milliseconds of mining thus far.
-};
-
/**
* @brief Class for hosting one or more Miners.
* @warning Must be implemented in a threadsafe manner since it will be called from multiple
@@ -66,10 +45,6 @@ struct MineProgress
class MinerHost
{
public:
- // ============================= NEW API =============================
- virtual WorkPackage const& getWork() const { return NullWorkPackage; }
-
- // ============================= OLD API =============================
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.
@@ -77,17 +52,17 @@ public:
virtual bool turbo() const = 0; ///< @returns true iff the Miner should use GPU if possible.
};
-class Miner
+class OldMiner
{
public:
- virtual ~Miner();
+ virtual ~OldMiner();
virtual void noteStateChange() = 0;
virtual bool isComplete() const = 0;
virtual bytes const& blockData() const = 0;
};
-class AsyncMiner: public Miner
+class AsyncMiner: public OldMiner
{
public:
/// Null constructor.
@@ -187,69 +162,5 @@ private:
std::list m_mineHistory; ///< What the history of our mining?
};
-/**
- * @brief A collective of Miners.
- * Miners ask for work, then submit proofs
- * @threadsafe
- */
-class Farm: public MinerHost
-{
-public:
- /**
- * @brief Sets the current mining mission.
- * @param _bi The block (header) we wish to be mining.
- */
- void setWork(BlockInfo const& _bi);
-
- /**
- * @brief (Re)start miners for CPU only.
- * @returns true if started properly.
- */
- bool startCPU();
-
- /**
- * @brief (Re)start miners for GPU only.
- * @returns true if started properly.
- */
- bool startGPU();
-
- /**
- * @brief Stop all mining activities.
- */
- void stop();
-
- /**
- * @brief Get information on the progress of mining this work package.
- * @return The progress with mining so far.
- */
- MineProgress const& mineProgress() const { ReadGuard l(x_progress); return m_progress; }
-
-protected:
- /**
- * @brief Called by a Miner to retrieve a work package. Reimplemented from MinerHost.
- * @return The work package to solve.
- */
- virtual WorkPackage const& getWork() const override { ReadGuard l(x_work); return m_work; }
-
- /**
- * @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.
- * @return true iff the solution was good (implying that mining should be .
- */
- virtual bool submitProof(ProofOfWork::Solution const& _p, WorkPackage const& _wp) = 0;
-
-private:
- mutable SharedMutex x_miners;
- std::vector> m_miners;
-
- mutable SharedMutex x_progress;
- MineProgress m_progress;
-
- mutable SharedMutex x_work;
- WorkPackage m_work;
-};
-
-
}
}
diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp
index 38f3b9429..7c72f53e8 100644
--- a/libethereum/TransactionQueue.cpp
+++ b/libethereum/TransactionQueue.cpp
@@ -28,7 +28,7 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
-ImportResult TransactionQueue::import(bytesConstRef _transactionRLP)
+ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallback const& _cb)
{
// Check if we already know this transaction.
h256 h = sha3(_transactionRLP);
@@ -50,7 +50,8 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP)
// If valid, append to blocks.
m_current[h] = t;
m_known.insert(h);
-
+ if (_cb)
+ m_callbacks[h] = _cb;
ctxq << "Queued vaguely legit-looking transaction" << h.abridged();
}
catch (Exception const& _e)
diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h
index 73ce24fbd..ad093b4e5 100644
--- a/libethereum/TransactionQueue.h
+++ b/libethereum/TransactionQueue.h
@@ -21,6 +21,7 @@
#pragma once
+#include
#include
#include
#include
@@ -45,8 +46,10 @@ struct TransactionQueueChannel: public LogChannel { static const char* name() {
class TransactionQueue
{
public:
- ImportResult import(bytes const& _tx) { return import(&_tx); }
- ImportResult import(bytesConstRef _tx);
+ using ImportCallback = std::function;
+
+ ImportResult import(bytes const& _tx, ImportCallback const& _cb = ImportCallback()) { return import(&_tx); }
+ ImportResult import(bytesConstRef _tx, ImportCallback const& _cb = ImportCallback());
void drop(h256 _txHash);
@@ -59,10 +62,11 @@ public:
void clear() { WriteGuard l(m_lock); m_known.clear(); m_current.clear(); m_unknown.clear(); }
private:
- mutable boost::shared_mutex m_lock; ///< General lock.
- std::set m_known; ///< Hashes of transactions in both sets.
- std::map m_current; ///< Map of SHA3(tx) to tx.
+ mutable boost::shared_mutex m_lock; ///< General lock.
+ std::set m_known; ///< Hashes of transactions in both sets.
+ std::map m_current; ///< Map of SHA3(tx) to tx.
std::multimap> m_unknown; ///< For transactions that have a future nonce; we map their sender address to the tx stuff, and insert once the sender has a valid TX.
+ std::map> m_callbacks; ///< Called once
};
}
diff --git a/libethereumx/Ethereum.h b/libethereumx/Ethereum.h
index 7ff685339..15f00f4ae 100644
--- a/libethereumx/Ethereum.h
+++ b/libethereumx/Ethereum.h
@@ -52,7 +52,7 @@ class Client;
*/
class Ethereum
{
- friend class Miner;
+ friend class OldMiner;
public:
/// Constructor. After this, everything should be set up to go.