diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 0242fe1fa..a096d2c15 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1409,7 +1409,10 @@ void Main::on_blocks_currentItemChanged() s << "
Hash w/o nonce: " << info.headerHash(WithoutNonce) << ""; s << "
Difficulty: " << info.difficulty << ""; if (info.number) - s << "
Proof-of-Work: " << ProofOfWork::eval(info) << " <= " << (h256)u256((bigint(1) << 256) / info.difficulty) << ""; + { + auto e = ProofOfWork::eval(info); + s << "
Proof-of-Work: " << e.value << " <= " << (h256)u256((bigint(1) << 256) / info.difficulty) << " (mixhash: " << e.mixHash.abridged() << ")"; + } else s << "
Proof-of-Work: Phil has nothing to prove"; s << "
Parent: " << info.parentHash << ""; @@ -1431,7 +1434,7 @@ void Main::on_blocks_currentItemChanged() s << line << "Nonce: " << uncle.nonce << ""; s << line << "Hash w/o nonce: " << uncle.headerHash(WithoutNonce) << ""; s << line << "Difficulty: " << uncle.difficulty << ""; - auto e = Ethasher::eval(uncle); + auto e = ProofOfWork::eval(uncle); s << line << "Proof-of-Work: " << e.value << " <= " << (h256)u256((bigint(1) << 256) / uncle.difficulty) << " (mixhash: " << e.mixHash.abridged() << ")"; } if (info.parentHash) diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index d3843b3bb..107a189fb 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -58,7 +58,7 @@ void BlockInfo::setEmpty() timestamp = 0; extraData.clear(); seedHash = h256(); - mixBytes = h256(); + mixHash = h256(); nonce = Nonce(); hash = headerHash(WithNonce); } @@ -83,7 +83,7 @@ void BlockInfo::streamRLP(RLPStream& _s, IncludeNonce _n) const << parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot << receiptsRoot << logBloom << difficulty << number << gasLimit << gasUsed << timestamp << extraData << seedHash; if (_n == WithNonce) - _s << mixBytes << nonce; + _s << mixHash << nonce; } h256 BlockInfo::headerHash(bytesConstRef _block) @@ -112,7 +112,7 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce) timestamp = _header[field = 11].toInt(); extraData = _header[field = 12].toBytes(); seedHash = _header[field = 13].toHash(); - mixBytes = _header[field = 14].toHash(); + mixHash = _header[field = 14].toHash(); nonce = _header[field = 15].toHash(); } @@ -187,7 +187,12 @@ void BlockInfo::populateFromParent(BlockInfo const& _parent) gasLimit = calculateGasLimit(_parent); gasUsed = 0; difficulty = calculateDifficulty(_parent); - seedHash = number % 30 == 0 ? sha3(_parent.seedHash.asBytes() /*+ _parent.hash.asBytes()*/) : _parent.seedHash; + seedHash = calculateSeedHash(_parent); +} + +h256 BlockInfo::calculateSeedHash(BlockInfo const& _parent) const +{ + return number % 30 == 0 ? sha3(_parent.seedHash.asBytes()) : _parent.seedHash; } u256 BlockInfo::calculateGasLimit(BlockInfo const& _parent) const @@ -203,7 +208,7 @@ u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const if (!parentHash) return (u256)c_genesisDifficulty; else - return max(2048, timestamp >= _parent.timestamp + (c_protocolVersion == 49 ? 5 : 8) ? _parent.difficulty - (_parent.difficulty / 2048) : (_parent.difficulty + (_parent.difficulty / 2048))); + return max(2048, timestamp >= _parent.timestamp + 8 ? _parent.difficulty - (_parent.difficulty / 2048) : (_parent.difficulty + (_parent.difficulty / 2048))); } template inline N diff(N const& _a, N const& _b) { return max(_a, _b) - min(_a, _b); } @@ -221,6 +226,9 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const if (diff(gasLimit, _parent.gasLimit) <= _parent.gasLimit / 2048) BOOST_THROW_EXCEPTION(InvalidGasLimit(gasLimit, calculateGasLimit(_parent), diff(gasLimit, _parent.gasLimit), _parent.gasLimit / 2048)); + if (seedHash != calculateSeedHash(_parent)) + BOOST_THROW_EXCEPTION(InvalidSeedHash()); + // Check timestamp is after previous timestamp. if (parentHash) { diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h index 6ed985f75..95519b57d 100644 --- a/libethcore/BlockInfo.h +++ b/libethcore/BlockInfo.h @@ -74,7 +74,7 @@ public: u256 gasUsed; u256 timestamp; bytes extraData; - h256 mixBytes; + h256 mixHash; h256 seedHash; Nonce nonce; @@ -105,7 +105,7 @@ public: gasUsed == _cmp.gasUsed && timestamp == _cmp.timestamp && extraData == _cmp.extraData && - mixBytes == _cmp.mixBytes && + mixHash == _cmp.mixHash && seedHash == _cmp.seedHash && nonce == _cmp.nonce; } @@ -133,7 +133,7 @@ inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi) { _out << _bi.hash << " " << _bi.parentHash << " " << _bi.sha3Uncles << " " << _bi.coinbaseAddress << " " << _bi.stateRoot << " " << _bi.transactionsRoot << " " << _bi.receiptsRoot << " " << _bi.logBloom << " " << _bi.difficulty << " " << _bi.number << " " << _bi.gasLimit << " " << - _bi.gasUsed << " " << _bi.timestamp << " " << _bi.mixBytes << " " << _bi.seedHash << " " << _bi.nonce; + _bi.gasUsed << " " << _bi.timestamp << " " << _bi.mixHash << " " << _bi.seedHash << " " << _bi.nonce; return _out; } diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index bc9441c6b..45667f44a 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -57,6 +57,7 @@ struct InvalidGasUsed: virtual dev::Exception {}; class InvalidTransactionsHash: virtual public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real); h256 head; h256 real; }; struct InvalidTransaction: virtual dev::Exception {}; struct InvalidDifficulty: virtual dev::Exception {}; +struct InvalidSeedHash: virtual dev::Exception {}; class InvalidGasLimit: virtual public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0, u256 _gD = 0, u256 _mD = 0): provided(_provided), valid(_valid), givenDiff(_gD), maxDiff(_mD) {} u256 provided; u256 valid; u256 givenDiff; u256 maxDiff; virtual const char* what() const noexcept; }; class InvalidMinGasPrice: virtual public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual const char* what() const noexcept; }; struct InvalidTransactionGasUsed: virtual dev::Exception {}; diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp index 04e4249b6..c879df2ce 100644 --- a/libethcore/ProofOfWork.cpp +++ b/libethcore/ProofOfWork.cpp @@ -118,16 +118,16 @@ Ethasher* Ethasher::s_this = nullptr; bool Ethash::verify(BlockInfo const& _header) { bigint boundary = (bigint(1) << 256) / _header.difficulty; - u256 e(eval(_header, _header.nonce)); - return e <= boundary; + auto e = eval(_header, _header.nonce); + return (u256)e.value <= boundary && e.mixHash == _header.mixHash; } -h256 Ethash::eval(BlockInfo const& _header, Nonce const& _nonce) +Ethash::Result Ethash::eval(BlockInfo const& _header, Nonce const& _nonce) { auto p = Ethasher::params(_header); ethash_return_value r; ethash_compute_light(&r, Ethasher::get()->cache(_header).data(), &p, _header.headerHash(WithoutNonce).data(), (uint64_t)(u64)_nonce); - return h256(r.result, h256::ConstructFromPointer); + return Result{h256(r.result, h256::ConstructFromPointer), h256(r.mix_hash, h256::ConstructFromPointer)}; } std::pair Ethash::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) diff --git a/libethcore/ProofOfWork.h b/libethcore/ProofOfWork.h index 7b9787f61..fdf51f0d4 100644 --- a/libethcore/ProofOfWork.h +++ b/libethcore/ProofOfWork.h @@ -55,12 +55,17 @@ public: Nonce nonce; h256 mixHash; }; + struct Result + { + h256 value; + h256 mixHash; + }; - static h256 eval(BlockInfo const& _header) { return eval(_header, _header.nonce); } - static h256 eval(BlockInfo const& _header, Nonce const& _nonce); + static Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); } + static Result eval(BlockInfo const& _header, Nonce const& _nonce); static bool verify(BlockInfo const& _header); std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); - static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixBytes = _r.mixHash; } + static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } protected: Nonce m_last;