Browse Source

Various fixes for mining.

cl-refactor
Gav Wood 10 years ago
parent
commit
2693659e56
  1. 1
      alethzero/DownloadView.h
  2. 10
      alethzero/MainWin.cpp
  3. 11
      alethzero/MiningView.cpp
  4. 4
      alethzero/MiningView.h
  5. 17
      eth/main.cpp
  6. 54
      exp/main.cpp
  7. 3
      libdevcore/Worker.h
  8. 52
      libethcore/Ethash.cpp
  9. 22
      libethcore/Ethash.h
  10. 35
      libethcore/Miner.h
  11. 43
      libethereum/Farm.h
  12. 23
      mix/MixClient.cpp
  13. 4
      mix/MixClient.h
  14. 10
      neth/main.cpp
  15. 31
      test/TestHelper.cpp
  16. 5
      test/TestHelper.h
  17. 115
      test/blockchain.cpp
  18. 12
      test/dagger.cpp
  19. 11
      test/stateOriginal.cpp
  20. 2
      third/MainWin.cpp

1
alethzero/DownloadView.h

@ -32,7 +32,6 @@
#endif
namespace dev { namespace eth {
struct MineInfo;
class DownloadMan;
}}

10
alethzero/MainWin.cpp

@ -45,7 +45,7 @@
#endif
#include <libdevcrypto/FileSystem.h>
#include <libethcore/CommonJS.h>
#include <libethcore/Ethasher.h>
#include <libethcore/EthashAux.h>
#include <liblll/Compiler.h>
#include <liblll/CodeFragment.h>
#include <libsolidity/Scanner.h>
@ -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 << "<div>Difficulty: <b>" << info.difficulty << "</b>" << "</div>";
if (info.number)
{
auto e = Ethasher::eval(info);
auto e = EthashAux::eval(info);
s << "<div>Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / info.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")" << "</div>";
s << "<div>Parent: <b>" << info.parentHash << "</b>" << "</div>";
}
@ -1510,7 +1510,7 @@ void Main::on_blocks_currentItemChanged()
s << line << "Nonce: <b>" << uncle.nonce << "</b>" << "</div>";
s << line << "Hash w/o nonce: <b>" << uncle.headerHash(WithoutNonce) << "</b>" << "</div>";
s << line << "Difficulty: <b>" << uncle.difficulty << "</b>" << "</div>";
auto e = Ethasher::eval(uncle);
auto e = EthashAux::eval(uncle);
s << line << "Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / uncle.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")" << "</div>";
}
if (info.parentHash)

11
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<MineInfo> const& _i, MineProgress const& _p)
void MiningView::appendStats(list<MineInfo> 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<MineInfo> 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));
*/
}

4
alethzero/MiningView.h

@ -42,14 +42,14 @@ class MiningView: public QWidget
public:
MiningView(QWidget* _p = nullptr);
void appendStats(std::list<dev::eth::MineInfo> const& _l, dev::eth::MineProgress const& _p);
void appendStats(std::list<dev::eth::MineInfo> 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<float> m_values;
std::vector<float> m_bests;

17
eth/main.cpp

@ -126,20 +126,22 @@ 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 <port> Listen on the given port for incoming connections (default: 30303)." << endl
<< " -l,--listen <ip> Listen on the given IP for incoming connections (default: 0.0.0.0)." << endl
<< " -u,--public-ip <ip> Force public ip to given (default: auto)." << endl
<< " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (Default: off)" << endl
<< " -n,--upnp <on/off> Use upnp for NAT (default: on)." << endl
<< " -n,-u,--upnp <on/off> Use upnp for NAT (default: on)." << endl
<< " -o,--mode <full/peer> Start a full node or a peer node (Default: full)." << endl
<< " -p,--port <port> Connect to remote port (default: 30303)." << endl
<< " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl
<< " -R,--rebuild First rebuild the blockchain from the existing database." << endl
<< " -r,--remote <host> Connect to remote host (default: none)." << endl
<< " -s,--secret <secretkeyhex> Set the secret key for use with send command (default: auto)." << endl
<< " -t,--miners <number> 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 <number> Attempt to connect to given number of peers (Default: 5)." << endl
<< " -V,--version Show the version and exit." << endl
@ -337,7 +339,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))
@ -489,15 +491,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")

54
exp/main.cpp

@ -34,9 +34,9 @@
#include <libdevcore/CommonIO.h>
#include <libdevcrypto/TrieDB.h>
#include <libp2p/All.h>
#include <libethcore/Ethasher.h>
#include <libethcore/ProofOfWork.h>
#include <libethereum/All.h>
#include <libethereum/Farm.h>
#include <libethereum/AccountDiff.h>
#include <libethereum/DownloadMan.h>
#include <liblll/All.h>
@ -109,18 +109,50 @@ int main()
#else
int main()
{
#if ETH_ETHASHCL
EthashCL ecl;
GenericFarm<Ethash> f;
BlockInfo genesis = CanonBlockChain::genesis();
genesis.difficulty = 1 << 18;
cdebug << (h256)u256((bigint(1) << 256) / genesis.difficulty);
std::pair<MineInfo, Ethash::Solution> 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<Ethash>& 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

3
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;

52
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(&ethashReturn, 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()
{
if (m_miner)
m_hook->abort();
// 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)
{
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

22
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;

35
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 PoW> 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;
};
}

43
libethereum/Farm.h

@ -55,17 +55,17 @@ public:
* @param _bi The block (header) we wish to be mining.
*/
void setWork(BlockInfo const& _bi)
{
WorkPackage w;
{
WriteGuard l(x_work);
m_header = _bi;
w = m_work = PoW::package(m_header);
}
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::milliseconds>(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<bool(Solution const&)>;
@ -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 <class MinerType>
bool start()
{
WriteGuard l(x_miners);
ReadGuard l(x_work);
WriteGuard l2(x_miners);
if (!m_miners.empty() && !!std::dynamic_pointer_cast<MinerType>(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<Miner>(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<std::shared_ptr<Miner>> 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;

23
mix/MixClient.cpp

@ -20,6 +20,7 @@
* Ethereum IDE client.
*/
#include "MixClient.h"
#include <vector>
#include <libdevcore/Exceptions.h>
#include <libethereum/CanonBlockChain.h>
@ -28,10 +29,8 @@
#include <libethereum/ExtVM.h>
#include <libethereum/BlockChain.h>
#include <libevm/VM.h>
#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<ProofOfWork> f;
bool completed = false;
f.onSolutionFound([&](ProofOfWork::Solution sol)
{
return completed = m_state.completeMine<ProofOfWork>(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();
}
}

4
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<h256, u256> getWork() override { return std::pair<h256, u256>(); }
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 {}

10
neth/main.cpp

@ -40,7 +40,6 @@
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#endif
#include <libethcore/Ethasher.h>
#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<string>{"eth", "shh"} : set<string>(),
netPrefs,
&nodesState,
miners
);
&nodesState);
web3.setIdealPeerCount(peers);
std::shared_ptr<eth::BasicGasPricer> gasPricer = make_shared<eth::BasicGasPricer>(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());
}

31
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<ProofOfWork> f;
bool completed = false;
f.onSolutionFound([&](ProofOfWork::Solution sol)
{
return completed = s.completeMine<ProofOfWork>(sol);
});
f.setWork(s.info());
f.startCPU();
while (!completed)
this_thread::sleep_for(chrono::milliseconds(20));
}
void mine(BlockInfo& _bi)
{
GenericFarm<ProofOfWork> 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

5
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:
};
};
}
}

115
test/blockchain.cpp

@ -190,11 +190,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)
{
@ -519,76 +515,55 @@ bytes createBlockRLPFromFields(mObject& _tObj)
return rlpStream.out();
}
void overwriteBlockHeader(BlockInfo& _currentBlockHeader, mObject& _blObj)
{
if (_blObj["blockHeader"].get_obj().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());
void overwriteBlockHeader(BlockInfo& _header, mObject& _blObj)
{
auto ho = _blObj["blockHeader"].get_obj();
if (ho.size() != 14)
{
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)
{
_currentBlockHeader = tmp;
ProofOfWork pow;
std::pair<MineInfo, Ethash::Solution> ret;
while (!ProofOfWork::verify(_currentBlockHeader))
if (tmp != _header)
{
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);
}
}
@ -620,13 +595,7 @@ BlockInfo constructBlock(mObject& _o)
void updatePoW(BlockInfo& _bi)
{
ProofOfWork pow;
std::pair<MineInfo, Ethash::Solution> ret;
while (!ProofOfWork::verify(_bi))
{
ret = pow.mine(_bi, 10000, true);
Ethash::assignResult(ret.second, _bi);
}
mine(_bi);
_bi.noteDirty();
}

12
test/dagger.cpp

@ -25,7 +25,7 @@
#include "JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/Ethasher.h>
#include <libethcore/EthashAux.h>
#include <boost/test/unit_test.hpp>
#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);
}

11
test/stateOriginal.cpp

@ -25,7 +25,9 @@
#include <secp256k1/secp256k1.h>
#include <libethereum/CanonBlockChain.h>
#include <libethereum/State.h>
#include <libethereum/Farm.h>
#include <libethereum/Defaults.h>
#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;

2
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");
}

Loading…
Cancel
Save