Browse Source

Modularise nonce, mix hash and seed hash.

cl-refactor
Gav Wood 10 years ago
parent
commit
bcc35d67a1
  1. 4
      alethzero/MainWin.cpp
  2. 10
      ethminer/MinerAux.h
  3. 2
      exp/main.cpp
  4. 45
      libethcore/BlockInfo.cpp
  5. 26
      libethcore/BlockInfo.h
  6. 5
      libethcore/Common.cpp
  7. 1
      libethcore/Common.h
  8. 52
      libethcore/Ethash.cpp
  9. 16
      libethcore/Ethash.h
  10. 7
      libethcore/EthashAux.cpp
  11. 2
      libethcore/EthashAux.h
  12. 1
      libethcore/ProofOfWork.h
  13. 8
      libethereum/BlockChain.cpp
  14. 12
      libethereum/BlockQueue.cpp
  15. 8
      libethereum/State.cpp
  16. 4
      libethereum/State.h
  17. 7
      libweb3jsonrpc/JsonHelper.cpp
  18. 1
      mix/MixClient.cpp
  19. 2
      test/TestHelper.cpp

4
alethzero/MainWin.cpp

@ -1718,7 +1718,7 @@ void Main::on_blocks_currentItemChanged()
s << "<div>Seed hash: <b>" << info.seedHash() << "</b>" << "</div>"; s << "<div>Seed hash: <b>" << info.seedHash() << "</b>" << "</div>";
s << "<div>Mix hash: <b>" << info.mixHash << "</b>" << "</div>"; s << "<div>Mix hash: <b>" << info.mixHash << "</b>" << "</div>";
s << "<div>Nonce: <b>" << info.nonce << "</b>" << "</div>"; s << "<div>Nonce: <b>" << info.nonce << "</b>" << "</div>";
s << "<div>Hash w/o nonce: <b>" << info.headerHash(WithoutNonce) << "</b>" << "</div>"; s << "<div>Hash w/o nonce: <b>" << info.headerHash(WithoutProof) << "</b>" << "</div>";
s << "<div>Difficulty: <b>" << info.difficulty << "</b>" << "</div>"; s << "<div>Difficulty: <b>" << info.difficulty << "</b>" << "</div>";
if (info.number) if (info.number)
{ {
@ -1749,7 +1749,7 @@ void Main::on_blocks_currentItemChanged()
s << line << "Seed hash: <b>" << uncle.seedHash() << "</b>" << "</div>"; s << line << "Seed hash: <b>" << uncle.seedHash() << "</b>" << "</div>";
s << line << "Mix hash: <b>" << uncle.mixHash << "</b>" << "</div>"; s << line << "Mix hash: <b>" << uncle.mixHash << "</b>" << "</div>";
s << line << "Nonce: <b>" << uncle.nonce << "</b>" << "</div>"; s << line << "Nonce: <b>" << uncle.nonce << "</b>" << "</div>";
s << line << "Hash w/o nonce: <b>" << uncle.headerHash(WithoutNonce) << "</b>" << "</div>"; s << line << "Hash w/o nonce: <b>" << uncle.headerHash(WithoutProof) << "</b>" << "</div>";
s << line << "Difficulty: <b>" << uncle.difficulty << "</b>" << "</div>"; s << line << "Difficulty: <b>" << uncle.difficulty << "</b>" << "</div>";
auto e = EthashAux::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>"; s << line << "Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / uncle.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")" << "</div>";

10
ethminer/MinerAux.h

@ -254,17 +254,17 @@ public:
bi.difficulty = u256(m); bi.difficulty = u256(m);
auto boundary = bi.boundary(); auto boundary = bi.boundary();
m = boost::to_lower_copy(string(argv[++i])); m = boost::to_lower_copy(string(argv[++i]));
bi.nonce = h64(m); bi.proof.nonce = h64(m);
auto r = EthashAux::eval(seedHash, powHash, bi.nonce); auto r = EthashAux::eval(seedHash, powHash, bi.proof.nonce);
bool valid = r.value < boundary; bool valid = r.value < boundary;
cout << (valid ? "VALID :-)" : "INVALID :-(") << endl; cout << (valid ? "VALID :-)" : "INVALID :-(") << endl;
cout << r.value << (valid ? " < " : " >= ") << boundary << endl; cout << r.value << (valid ? " < " : " >= ") << boundary << endl;
cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl; cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl;
cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.nonce << ")" << endl; cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.proof.nonce << ")" << endl;
cout << " with seed as " << seedHash << endl; cout << " with seed as " << seedHash << endl;
if (valid) if (valid)
cout << "(mixHash = " << r.mixHash << ")" << endl; cout << "(mixHash = " << r.mixHash << ")" << endl;
cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(bi.seedHash())->data()) << endl; cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(bi.proofCache())->data()) << endl;
exit(0); exit(0);
} }
catch (...) catch (...)
@ -382,7 +382,7 @@ private:
{ {
BlockInfo bi; BlockInfo bi;
bi.number = _n; bi.number = _n;
cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl; cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.proofCache().abridged() << "). This will take a while." << endl;
Ethash::prep(bi); Ethash::prep(bi);
exit(0); exit(0);
} }

2
exp/main.cpp

@ -197,7 +197,7 @@ int main()
bool completed = false; bool completed = false;
f.onSolutionFound([&](ProofOfWork::Solution sol) f.onSolutionFound([&](ProofOfWork::Solution sol)
{ {
ProofOfWork::assignResult(sol, bi); bi.proof = sol;
return completed = true; return completed = true;
}); });
f.setWork(bi); f.setWork(bi);

45
libethcore/BlockInfo.cpp

@ -26,7 +26,6 @@
#include <libethcore/Common.h> #include <libethcore/Common.h>
#include <libethcore/Params.h> #include <libethcore/Params.h>
#include "EthashAux.h" #include "EthashAux.h"
#include "ProofOfWork.h"
#include "Exceptions.h" #include "Exceptions.h"
#include "BlockInfo.h" #include "BlockInfo.h"
using namespace std; using namespace std;
@ -57,22 +56,21 @@ void BlockInfo::clear()
gasUsed = 0; gasUsed = 0;
timestamp = 0; timestamp = 0;
extraData.clear(); extraData.clear();
mixHash = h256(); proof = ProofOfWork::Solution();
nonce = Nonce(); m_proofCache = ProofOfWork::HeaderCache();
m_hash = m_seedHash = h256(); m_hash = h256();
} }
h256 const& BlockInfo::seedHash() const ProofOfWork::HeaderCache const& BlockInfo::proofCache() const
{ {
if (!m_seedHash) ProofOfWork::ensureHeaderCacheValid(m_proofCache, *this);
m_seedHash = EthashAux::seedHash((unsigned)number); return m_proofCache;
return m_seedHash;
} }
h256 const& BlockInfo::hash() const h256 const& BlockInfo::hash() const
{ {
if (!m_hash) if (!m_hash)
m_hash = headerHash(WithNonce); m_hash = headerHash(WithProof);
return m_hash; return m_hash;
} }
@ -90,20 +88,20 @@ BlockInfo BlockInfo::fromHeader(bytesConstRef _header, Strictness _s, h256 const
return ret; return ret;
} }
h256 BlockInfo::headerHash(IncludeNonce _n) const h256 BlockInfo::headerHash(IncludeProof _n) const
{ {
RLPStream s; RLPStream s;
streamRLP(s, _n); streamRLP(s, _n);
return sha3(s.out()); return sha3(s.out());
} }
void BlockInfo::streamRLP(RLPStream& _s, IncludeNonce _n) const void BlockInfo::streamRLP(RLPStream& _s, IncludeProof _n) const
{ {
_s.appendList(_n == WithNonce ? 15 : 13) _s.appendList(_n == WithProof ? 13 + ProofOfWork::Solution::Fields : 13)
<< parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot << receiptsRoot << logBloom << parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot << receiptsRoot << logBloom
<< difficulty << number << gasLimit << gasUsed << timestamp << extraData; << difficulty << number << gasLimit << gasUsed << timestamp << extraData;
if (_n == WithNonce) if (_n == WithProof)
_s << mixHash << nonce; proof.streamRLP(_s);
} }
h256 BlockInfo::headerHash(bytesConstRef _block) h256 BlockInfo::headerHash(bytesConstRef _block)
@ -116,12 +114,12 @@ void BlockInfo::populateFromHeader(RLP const& _header, Strictness _s, h256 const
m_hash = _h; m_hash = _h;
if (_h) if (_h)
assert(_h == dev::sha3(_header.data())); assert(_h == dev::sha3(_header.data()));
m_seedHash = h256(); m_proofCache = ProofOfWork::HeaderCache();
int field = 0; int field = 0;
try try
{ {
if (_header.itemCount() != 15) if (_header.itemCount() != 13 + ProofOfWork::Solution::Fields)
BOOST_THROW_EXCEPTION(InvalidBlockHeaderItemCount()); BOOST_THROW_EXCEPTION(InvalidBlockHeaderItemCount());
parentHash = _header[field = 0].toHash<h256>(RLP::VeryStrict); parentHash = _header[field = 0].toHash<h256>(RLP::VeryStrict);
sha3Uncles = _header[field = 1].toHash<h256>(RLP::VeryStrict); sha3Uncles = _header[field = 1].toHash<h256>(RLP::VeryStrict);
@ -136,8 +134,7 @@ void BlockInfo::populateFromHeader(RLP const& _header, Strictness _s, h256 const
gasUsed = _header[field = 10].toInt<u256>(); gasUsed = _header[field = 10].toInt<u256>();
timestamp = _header[field = 11].toInt<u256>(); timestamp = _header[field = 11].toInt<u256>();
extraData = _header[field = 12].toBytes(); extraData = _header[field = 12].toBytes();
mixHash = _header[field = 13].toHash<h256>(RLP::VeryStrict); proof.populateFromRLP(_header, field = 13);
nonce = _header[field = 14].toHash<Nonce>(RLP::VeryStrict);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
@ -152,22 +149,18 @@ void BlockInfo::populateFromHeader(RLP const& _header, Strictness _s, h256 const
if (_s == CheckEverything && parentHash && !ProofOfWork::verify(*this)) if (_s == CheckEverything && parentHash && !ProofOfWork::verify(*this))
{ {
InvalidBlockNonce ex; InvalidBlockNonce ex;
ex << errinfo_hash256(headerHash(WithoutNonce)); ProofOfWork::composeException(ex, *this);
ex << errinfo_nonce(nonce); ex << errinfo_hash256(headerHash(WithoutProof));
ex << errinfo_difficulty(difficulty); ex << errinfo_difficulty(difficulty);
ex << errinfo_seedHash(seedHash());
ex << errinfo_target(boundary()); ex << errinfo_target(boundary());
ex << errinfo_mixHash(mixHash);
Ethash::Result er = EthashAux::eval(seedHash(), headerHash(WithoutNonce), nonce);
ex << errinfo_ethashResult(make_tuple(er.value, er.mixHash));
BOOST_THROW_EXCEPTION(ex); BOOST_THROW_EXCEPTION(ex);
} }
else if (_s == QuickNonce && parentHash && !ProofOfWork::preVerify(*this)) else if (_s == QuickNonce && parentHash && !ProofOfWork::preVerify(*this))
{ {
InvalidBlockNonce ex; InvalidBlockNonce ex;
ex << errinfo_hash256(headerHash(WithoutNonce)); ex << errinfo_hash256(headerHash(WithoutProof));
ex << errinfo_nonce(nonce);
ex << errinfo_difficulty(difficulty); ex << errinfo_difficulty(difficulty);
ProofOfWork::composeExceptionPre(ex, *this);
BOOST_THROW_EXCEPTION(ex); BOOST_THROW_EXCEPTION(ex);
} }

26
libethcore/BlockInfo.h

@ -24,16 +24,17 @@
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include "Common.h" #include "Common.h"
#include "ProofOfWork.h"
namespace dev namespace dev
{ {
namespace eth namespace eth
{ {
enum IncludeNonce enum IncludeProof
{ {
WithoutNonce = 0, WithoutProof = 0,
WithNonce = 1 WithProof = 1
}; };
enum Strictness enum Strictness
@ -82,8 +83,7 @@ public:
u256 gasUsed; u256 gasUsed;
u256 timestamp = Invalid256; u256 timestamp = Invalid256;
bytes extraData; bytes extraData;
h256 mixHash; typename ProofOfWork::Solution proof;
Nonce nonce;
BlockInfo(); BlockInfo();
explicit BlockInfo(bytes const& _block, Strictness _s = IgnoreNonce, h256 const& _h = h256()): BlockInfo(&_block, _s, _h) {} explicit BlockInfo(bytes const& _block, Strictness _s = IgnoreNonce, h256 const& _h = h256()): BlockInfo(&_block, _s, _h) {}
@ -112,14 +112,13 @@ public:
gasUsed == _cmp.gasUsed && gasUsed == _cmp.gasUsed &&
timestamp == _cmp.timestamp && timestamp == _cmp.timestamp &&
extraData == _cmp.extraData && extraData == _cmp.extraData &&
mixHash == _cmp.mixHash && proof == _cmp.proof;
nonce == _cmp.nonce;
} }
bool operator!=(BlockInfo const& _cmp) const { return !operator==(_cmp); } bool operator!=(BlockInfo const& _cmp) const { return !operator==(_cmp); }
void clear(); void clear();
void noteDirty() const { m_hash = m_seedHash = m_boundary = h256(); } void noteDirty() const { m_hash = m_boundary = h256(); m_proofCache = ProofOfWork::HeaderCache(); }
void populateFromHeader(RLP const& _header, Strictness _s = IgnoreNonce, h256 const& _h = h256()); void populateFromHeader(RLP const& _header, Strictness _s = IgnoreNonce, h256 const& _h = h256());
void populate(bytesConstRef _block, Strictness _s = IgnoreNonce, h256 const& _h = h256()); void populate(bytesConstRef _block, Strictness _s = IgnoreNonce, h256 const& _h = h256());
@ -130,16 +129,17 @@ public:
u256 calculateDifficulty(BlockInfo const& _parent) const; u256 calculateDifficulty(BlockInfo const& _parent) const;
u256 selectGasLimit(BlockInfo const& _parent) const; u256 selectGasLimit(BlockInfo const& _parent) const;
h256 const& seedHash() const; ProofOfWork::HeaderCache const& proofCache() const;
h256 const& hash() const; h256 const& hash() const;
h256 const& boundary() const; h256 const& boundary() const;
/// sha3 of the header only. /// sha3 of the header only.
h256 headerHash(IncludeNonce _n) const; h256 headerHash(IncludeProof _n) const;
void streamRLP(RLPStream& _s, IncludeNonce _n) const; void streamRLP(RLPStream& _s, IncludeProof _n) const;
private: private:
mutable h256 m_seedHash;
mutable ProofOfWork::HeaderCache m_proofCache;
mutable h256 m_hash; ///< SHA3 hash of the block header! Not serialised. mutable h256 m_hash; ///< SHA3 hash of the block header! Not serialised.
mutable h256 m_boundary; ///< 2^256 / difficulty mutable h256 m_boundary; ///< 2^256 / difficulty
}; };
@ -148,7 +148,7 @@ inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi)
{ {
_out << _bi.hash() << " " << _bi.parentHash << " " << _bi.sha3Uncles << " " << _bi.coinbaseAddress << " " << _bi.stateRoot << " " << _bi.transactionsRoot << " " << _out << _bi.hash() << " " << _bi.parentHash << " " << _bi.sha3Uncles << " " << _bi.coinbaseAddress << " " << _bi.stateRoot << " " << _bi.transactionsRoot << " " <<
_bi.receiptsRoot << " " << _bi.logBloom << " " << _bi.difficulty << " " << _bi.number << " " << _bi.gasLimit << " " << _bi.receiptsRoot << " " << _bi.logBloom << " " << _bi.difficulty << " " << _bi.number << " " << _bi.gasLimit << " " <<
_bi.gasUsed << " " << _bi.timestamp << " " << _bi.mixHash << " " << _bi.nonce << " (" << _bi.seedHash() << ")"; _bi.gasUsed << " " << _bi.timestamp;
return _out; return _out;
} }

5
libethcore/Common.cpp

@ -26,6 +26,7 @@
#include <libdevcore/SHA3.h> #include <libdevcore/SHA3.h>
#include "Exceptions.h" #include "Exceptions.h"
#include "ProofOfWork.h" #include "ProofOfWork.h"
#include "BlockInfo.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
@ -112,9 +113,9 @@ std::string formatBalance(bigint const& _b)
static void badBlockInfo(BlockInfo const& _bi, string const& _err) static void badBlockInfo(BlockInfo const& _bi, string const& _err)
{ {
string const c_line = EthReset EthOnMaroon + string(80, ' '); string const c_line = EthReset EthOnMaroon + string(80, ' ') + EthReset;
string const c_border = EthReset EthOnMaroon + string(2, ' ') + EthReset EthMaroonBold; string const c_border = EthReset EthOnMaroon + string(2, ' ') + EthReset EthMaroonBold;
string const c_space = c_border + string(76, ' ') + c_border; string const c_space = c_border + string(76, ' ') + c_border + EthReset;
stringstream ss; stringstream ss;
ss << c_line << endl; ss << c_line << endl;
ss << c_space << endl; ss << c_space << endl;

1
libethcore/Common.h

@ -189,6 +189,7 @@ struct TransactionSkeleton
Address to; Address to;
u256 value; u256 value;
bytes data; bytes data;
u256 nonce = UndefinedU256;
u256 gas = UndefinedU256; u256 gas = UndefinedU256;
u256 gasPrice = UndefinedU256; u256 gasPrice = UndefinedU256;
u256 nonce = UndefinedU256; u256 nonce = UndefinedU256;

52
libethcore/Ethash.cpp

@ -46,6 +46,7 @@
#endif #endif
#include "BlockInfo.h" #include "BlockInfo.h"
#include "EthashAux.h" #include "EthashAux.h"
#include "Exceptions.h"
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
@ -56,6 +57,26 @@ namespace eth
const Ethash::WorkPackage Ethash::NullWorkPackage = Ethash::WorkPackage(); const Ethash::WorkPackage Ethash::NullWorkPackage = Ethash::WorkPackage();
void Ethash::ensureHeaderCacheValid(HeaderCache& io_out, BlockInfo const& _h)
{
if (!io_out)
io_out = EthashAux::seedHash((unsigned)_h.number);
}
void Ethash::composeException(Exception& _ex, BlockInfo& _bi)
{
_ex << errinfo_nonce(_bi.proof.nonce);
_ex << errinfo_mixHash(_bi.proof.mixHash);
_ex << errinfo_seedHash(_bi.proofCache());
Ethash::Result er = EthashAux::eval(_bi.proofCache(), _bi.headerHash(WithoutProof), _bi.proof.nonce);
_ex << errinfo_ethashResult(make_tuple(er.value, er.mixHash));
}
void Ethash::composeExceptionPre(Exception& _ex, BlockInfo& _bi)
{
_ex << errinfo_nonce(_bi.proof.nonce);
}
std::string Ethash::name() std::string Ethash::name()
{ {
return "Ethash"; return "Ethash";
@ -66,12 +87,23 @@ unsigned Ethash::revision()
return ETHASH_REVISION; return ETHASH_REVISION;
} }
void Ethash::Solution::populateFromRLP(RLP const& _header, int& _field)
{
mixHash = _header[_field].toHash<h256>(RLP::VeryStrict);
nonce = _header[++_field].toHash<Nonce>(RLP::VeryStrict);
}
void Ethash::Solution::streamRLP(RLPStream& io_rlp) const
{
io_rlp << mixHash << nonce;
}
Ethash::WorkPackage Ethash::package(BlockInfo const& _bi) Ethash::WorkPackage Ethash::package(BlockInfo const& _bi)
{ {
WorkPackage ret; WorkPackage ret;
ret.boundary = _bi.boundary(); ret.boundary = _bi.boundary();
ret.headerHash = _bi.headerHash(WithoutNonce); ret.headerHash = _bi.headerHash(WithoutProof);
ret.seedHash = _bi.seedHash(); ret.seedHash = _bi.proofCache();
return ret; return ret;
} }
@ -84,7 +116,7 @@ void Ethash::ensurePrecomputed(unsigned _number)
void Ethash::prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f) void Ethash::prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f)
{ {
EthashAux::full(_header.seedHash(), true, _f); EthashAux::full(_header.proofCache(), true, _f);
} }
bool Ethash::preVerify(BlockInfo const& _header) bool Ethash::preVerify(BlockInfo const& _header)
@ -95,9 +127,9 @@ bool Ethash::preVerify(BlockInfo const& _header)
h256 boundary = u256((bigint(1) << 256) / _header.difficulty); h256 boundary = u256((bigint(1) << 256) / _header.difficulty);
bool ret = !!ethash_quick_check_difficulty( bool ret = !!ethash_quick_check_difficulty(
(ethash_h256_t const*)_header.headerHash(WithoutNonce).data(), (ethash_h256_t const*)_header.headerHash(WithoutProof).data(),
(uint64_t)(u64)_header.nonce, (uint64_t)(u64)_header.proof.nonce,
(ethash_h256_t const*)_header.mixHash.data(), (ethash_h256_t const*)_header.proof.mixHash.data(),
(ethash_h256_t const*)boundary.data()); (ethash_h256_t const*)boundary.data());
return ret; return ret;
@ -115,7 +147,7 @@ bool Ethash::verify(BlockInfo const& _header)
#endif #endif
auto result = EthashAux::eval(_header); auto result = EthashAux::eval(_header);
bool slow = result.value <= _header.boundary() && result.mixHash == _header.mixHash; bool slow = result.value <= _header.boundary() && result.mixHash == _header.proof.mixHash;
// cdebug << (slow ? "VERIFY" : "VERYBAD"); // cdebug << (slow ? "VERIFY" : "VERYBAD");
// cdebug << result.value.hex() << _header.boundary().hex(); // cdebug << result.value.hex() << _header.boundary().hex();
@ -125,9 +157,9 @@ bool Ethash::verify(BlockInfo const& _header)
if (!pre && slow) if (!pre && slow)
{ {
cwarn << "WARNING: evaluated result gives true whereas ethash_quick_check_difficulty gives false."; cwarn << "WARNING: evaluated result gives true whereas ethash_quick_check_difficulty gives false.";
cwarn << "headerHash:" << _header.headerHash(WithoutNonce); cwarn << "headerHash:" << _header.headerHash(WithoutProof);
cwarn << "nonce:" << _header.nonce; cwarn << "nonce:" << _header.proof.nonce;
cwarn << "mixHash:" << _header.mixHash; cwarn << "mixHash:" << _header.proof.mixHash;
cwarn << "difficulty:" << _header.difficulty; cwarn << "difficulty:" << _header.difficulty;
cwarn << "boundary:" << _header.boundary(); cwarn << "boundary:" << _header.boundary();
cwarn << "result.value:" << result.value; cwarn << "result.value:" << result.value;

16
libethcore/Ethash.h

@ -28,16 +28,20 @@
#include <cstdint> #include <cstdint>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include "Common.h" #include "Common.h"
#include "BlockInfo.h"
#include "Miner.h" #include "Miner.h"
class ethash_cl_miner; class ethash_cl_miner;
namespace dev namespace dev
{ {
class RLP;
class RLPStream;
namespace eth namespace eth
{ {
class BlockInfo;
class EthashCLHook; class EthashCLHook;
class Ethash class Ethash
@ -45,8 +49,17 @@ class Ethash
public: public:
using Miner = GenericMiner<Ethash>; using Miner = GenericMiner<Ethash>;
using HeaderCache = h256;
static void ensureHeaderCacheValid(HeaderCache& io_out, BlockInfo const& _h);
static void composeException(Exception& _ex, BlockInfo& _bi);
static void composeExceptionPre(Exception& _ex, BlockInfo& _bi);
struct Solution struct Solution
{ {
bool operator==(Solution const& _v) const { return nonce == _v.nonce && mixHash == _v.mixHash; }
void populateFromRLP(RLP const& io_rlp, int& io_field);
void streamRLP(RLPStream& io_rlp) const;
static const unsigned Fields = 2;
Nonce nonce; Nonce nonce;
h256 mixHash; h256 mixHash;
}; };
@ -78,7 +91,6 @@ public:
static bool verify(BlockInfo const& _header); static bool verify(BlockInfo const& _header);
static bool preVerify(BlockInfo const& _header); static bool preVerify(BlockInfo const& _header);
static WorkPackage package(BlockInfo const& _header); static WorkPackage package(BlockInfo const& _header);
static void assignResult(Solution const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
class CPUMiner: public Miner, Worker class CPUMiner: public Miner, Worker
{ {

7
libethcore/EthashAux.cpp

@ -200,6 +200,11 @@ EthashAux::FullType EthashAux::full(h256 const& _seedHash, bool _createIfMissing
return ret; return ret;
} }
Ethash::Result EthashAux::eval(BlockInfo const& _header)
{
return eval(_header, _header.proof.nonce);
}
#define DEV_IF_THROWS(X) try { X; } catch (...) #define DEV_IF_THROWS(X) try { X; } catch (...)
unsigned EthashAux::computeFull(h256 const& _seedHash, bool _createIfMissing) unsigned EthashAux::computeFull(h256 const& _seedHash, bool _createIfMissing)
@ -252,7 +257,7 @@ Ethash::Result EthashAux::LightAllocation::compute(h256 const& _headerHash, Nonc
Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce) Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce)
{ {
return eval(_header.seedHash(), _header.headerHash(WithoutNonce), _nonce); return eval(_header.proofCache(), _header.headerHash(WithoutProof), _nonce);
} }
Ethash::Result EthashAux::eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) Ethash::Result EthashAux::eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce)

2
libethcore/EthashAux.h

@ -78,7 +78,7 @@ public:
/// Kicks off generation of DAG for @a _blocknumber and blocks until ready; @returns result or empty pointer if not existing and _createIfMissing is false. /// Kicks off generation of DAG for @a _blocknumber and blocks until ready; @returns result or empty pointer if not existing and _createIfMissing is false.
static FullType full(h256 const& _seedHash, bool _createIfMissing = false, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>()); static FullType full(h256 const& _seedHash, bool _createIfMissing = false, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>());
static Ethash::Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); } static Ethash::Result eval(BlockInfo const& _header);
static Ethash::Result eval(BlockInfo const& _header, Nonce const& _nonce); static Ethash::Result eval(BlockInfo const& _header, Nonce const& _nonce);
static Ethash::Result eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce); static Ethash::Result eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce);

1
libethcore/ProofOfWork.h

@ -38,7 +38,6 @@ namespace eth
* typename Solution * typename Solution
* typename CPUMiner * typename CPUMiner
* typename GPUMiner * typename GPUMiner
* void assignResult(BlockInfo&, Result)
* and a few others. TODO * and a few others. TODO
*/ */
using ProofOfWork = Ethash; using ProofOfWork = Ethash;

8
libethereum/BlockChain.cpp

@ -575,8 +575,8 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const&
#endif #endif
StructuredLogger::chainReceivedNewBlock( StructuredLogger::chainReceivedNewBlock(
_block.info.headerHash(WithoutNonce).abridged(), _block.info.headerHash(WithoutProof).abridged(),
_block.info.nonce.abridged(), _block.info.proof.nonce.abridged(),
currentHash().abridged(), currentHash().abridged(),
"", // TODO: remote id ?? "", // TODO: remote id ??
_block.info.parentHash.abridged() _block.info.parentHash.abridged()
@ -666,8 +666,8 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const&
clog(BlockChainNote) << " Imported and best" << td << " (#" << _block.info.number << "). Has" << (details(_block.info.parentHash).children.size() - 1) << "siblings. Route:" << route; clog(BlockChainNote) << " Imported and best" << td << " (#" << _block.info.number << "). Has" << (details(_block.info.parentHash).children.size() - 1) << "siblings. Route:" << route;
StructuredLogger::chainNewHead( StructuredLogger::chainNewHead(
_block.info.headerHash(WithoutNonce).abridged(), _block.info.headerHash(WithoutProof).abridged(),
_block.info.nonce.abridged(), _block.info.proof.nonce.abridged(),
currentHash().abridged(), currentHash().abridged(),
_block.info.parentHash.abridged() _block.info.parentHash.abridged()
); );

12
libethereum/BlockQueue.cpp

@ -101,7 +101,7 @@ void BlockQueue::verifierBody()
swap(work, m_unverified.front()); swap(work, m_unverified.front());
m_unverified.pop_front(); m_unverified.pop_front();
BlockInfo bi; BlockInfo bi;
bi.mixHash = work.hash; bi.proof.mixHash = work.hash;
bi.parentHash = work.parentHash; bi.parentHash = work.parentHash;
m_verifying.emplace_back(move(bi)); m_verifying.emplace_back(move(bi));
} }
@ -121,7 +121,7 @@ void BlockQueue::verifierBody()
m_readySet.erase(work.hash); m_readySet.erase(work.hash);
m_knownBad.insert(work.hash); m_knownBad.insert(work.hash);
for (auto it = m_verifying.begin(); it != m_verifying.end(); ++it) for (auto it = m_verifying.begin(); it != m_verifying.end(); ++it)
if (it->verified.info.mixHash == work.hash) if (it->verified.info.proof.mixHash == work.hash)
{ {
m_verifying.erase(it); m_verifying.erase(it);
goto OK1; goto OK1;
@ -136,7 +136,7 @@ void BlockQueue::verifierBody()
{ {
WriteGuard l2(m_lock); WriteGuard l2(m_lock);
unique_lock<Mutex> l(m_verification); unique_lock<Mutex> l(m_verification);
if (!m_verifying.empty() && m_verifying.front().verified.info.mixHash == work.hash) if (!m_verifying.empty() && m_verifying.front().verified.info.proof.mixHash == work.hash)
{ {
// we're next! // we're next!
m_verifying.pop_front(); m_verifying.pop_front();
@ -154,7 +154,7 @@ void BlockQueue::verifierBody()
else else
{ {
for (auto& i: m_verifying) for (auto& i: m_verifying)
if (i.verified.info.mixHash == work.hash) if (i.verified.info.proof.mixHash == work.hash)
{ {
i = move(res); i = move(res);
goto OK; goto OK;
@ -323,9 +323,9 @@ void BlockQueue::updateBad_WITH_LOCK(h256 const& _bad)
std::deque<VerifiedBlock> oldVerifying; std::deque<VerifiedBlock> oldVerifying;
swap(m_verifying, oldVerifying); swap(m_verifying, oldVerifying);
for (auto& b: oldVerifying) for (auto& b: oldVerifying)
if (m_knownBad.count(b.verified.info.parentHash) || m_knownBad.count(b.verified.info.mixHash)) if (m_knownBad.count(b.verified.info.parentHash) || m_knownBad.count(b.verified.info.proof.mixHash))
{ {
h256 const& h = b.blockData.size() != 0 ? b.verified.info.hash() : b.verified.info.mixHash; h256 const& h = b.blockData.size() != 0 ? b.verified.info.hash() : b.verified.info.proof.mixHash;
m_knownBad.insert(h); m_knownBad.insert(h);
m_readySet.erase(h); m_readySet.erase(h);
collectUnknownBad_WITH_BOTH_LOCKS(h); collectUnknownBad_WITH_BOTH_LOCKS(h);

8
libethereum/State.cpp

@ -837,7 +837,7 @@ bool State::amIJustParanoid(BlockChain const& _bc)
// Compile block: // Compile block:
RLPStream block; RLPStream block;
block.appendList(3); block.appendList(3);
m_currentBlock.streamRLP(block, WithNonce); m_currentBlock.streamRLP(block, WithProof);
block.appendRaw(m_currentTxs); block.appendRaw(m_currentTxs);
block.appendRaw(m_currentUncles); block.appendRaw(m_currentUncles);
@ -902,7 +902,7 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
if (!excluded.count(u)) // ignore any uncles/mainline blocks that we know about. if (!excluded.count(u)) // ignore any uncles/mainline blocks that we know about.
{ {
BlockInfo ubi(_bc.block(u)); BlockInfo ubi(_bc.block(u));
ubi.streamRLP(unclesData, WithNonce); ubi.streamRLP(unclesData, WithProof);
++unclesCount; ++unclesCount;
uncleBlockHeaders.push_back(ubi); uncleBlockHeaders.push_back(ubi);
if (unclesCount == 2) if (unclesCount == 2)
@ -970,7 +970,7 @@ void State::completeMine()
// Compile block: // Compile block:
RLPStream ret; RLPStream ret;
ret.appendList(3); ret.appendList(3);
m_currentBlock.streamRLP(ret, WithNonce); m_currentBlock.streamRLP(ret, WithProof);
ret.appendRaw(m_currentTxs); ret.appendRaw(m_currentTxs);
ret.appendRaw(m_currentUncles); ret.appendRaw(m_currentUncles);
ret.swapOut(m_currentBytes); ret.swapOut(m_currentBytes);
@ -978,7 +978,7 @@ void State::completeMine()
cnote << "Mined " << m_currentBlock.hash() << "(parent: " << m_currentBlock.parentHash << ")"; cnote << "Mined " << m_currentBlock.hash() << "(parent: " << m_currentBlock.parentHash << ")";
StructuredLogger::minedNewBlock( StructuredLogger::minedNewBlock(
m_currentBlock.hash().abridged(), m_currentBlock.hash().abridged(),
m_currentBlock.nonce.abridged(), m_currentBlock.proof.nonce.abridged(),
"", //TODO: chain head hash here ?? "", //TODO: chain head hash here ??
m_currentBlock.parentHash.abridged() m_currentBlock.parentHash.abridged()
); );

4
libethereum/State.h

@ -169,11 +169,11 @@ public:
if (!m_committedToMine) if (!m_committedToMine)
return false; return false;
PoW::assignResult(_result, m_currentBlock); m_currentBlock.proof = _result;
if (!PoW::verify(m_currentBlock)) if (!PoW::verify(m_currentBlock))
return false; return false;
cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce) << m_currentBlock.nonce << m_currentBlock.difficulty << PoW::verify(m_currentBlock); cnote << "Completed" << m_currentBlock.headerHash(WithoutProof) << m_currentBlock.proof.nonce << m_currentBlock.difficulty << PoW::verify(m_currentBlock);
completeMine(); completeMine();

7
libweb3jsonrpc/JsonHelper.cpp

@ -99,11 +99,12 @@ Json::Value toJson(dev::eth::BlockInfo const& _bi)
res["gasLimit"] = toJS(_bi.gasLimit); res["gasLimit"] = toJS(_bi.gasLimit);
res["timestamp"] = toJS(_bi.timestamp); res["timestamp"] = toJS(_bi.timestamp);
res["extraData"] = toJS(_bi.extraData); res["extraData"] = toJS(_bi.extraData);
res["nonce"] = toJS(_bi.nonce);
res["logsBloom"] = toJS(_bi.logBloom); res["logsBloom"] = toJS(_bi.logBloom);
res["seedHash"] = toJS(_bi.seedHash());
res["target"] = toJS(_bi.boundary()); res["target"] = toJS(_bi.boundary());
// TODO: move into ProofOfWork.
res["nonce"] = toJS(_bi.proof.nonce);
res["seedHash"] = toJS(_bi.proofCache());
} }
return res; return res;
} }

1
mix/MixClient.cpp

@ -49,7 +49,6 @@ namespace
struct MixPow //dummy POW struct MixPow //dummy POW
{ {
typedef int Solution; typedef int Solution;
static void assignResult(int, BlockInfo const&) {}
static bool verify(BlockInfo const&) { return true; } static bool verify(BlockInfo const&) { return true; }
}; };

2
test/TestHelper.cpp

@ -81,7 +81,7 @@ void mine(BlockInfo& _bi)
bool completed = false; bool completed = false;
f.onSolutionFound([&](ProofOfWork::Solution sol) f.onSolutionFound([&](ProofOfWork::Solution sol)
{ {
ProofOfWork::assignResult(sol, _bi); _bi.proof = sol;
return completed = true; return completed = true;
}); });
f.setWork(_bi); f.setWork(_bi);

Loading…
Cancel
Save