diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index 5e1752cab..42dffe92f 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -206,9 +206,11 @@ u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const if (!parentHash) return (u256)c_genesisDifficulty; else - return max(c_minimumDifficulty, timestamp >= _parent.timestamp + c_durationLimit ? _parent.difficulty - (_parent.difficulty / c_difficultyBoundDivisor) : (_parent.difficulty + (_parent.difficulty / c_difficultyBoundDivisor))); + return max(2048, timestamp >= _parent.timestamp + (c_protocolVersion == 49 ? 5 : 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); } + void BlockInfo::verifyParent(BlockInfo const& _parent) const { // Check difficulty is correct given the two timestamps. @@ -219,8 +221,9 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const gasLimit > _parent.gasLimit * (c_gasLimitBoundDivisor + 1) / c_gasLimitBoundDivisor) BOOST_THROW_EXCEPTION(InvalidGasLimit(gasLimit, _parent.gasLimit * (c_gasLimitBoundDivisor - 1) / c_gasLimitBoundDivisor, _parent.gasLimit * (c_gasLimitBoundDivisor + 1) / c_gasLimitBoundDivisor)); - if (seedHash != calculateSeedHash(_parent)) - BOOST_THROW_EXCEPTION(InvalidSeedHash()); + if (diff(gasLimit, _parent.gasLimit) <= _parent.gasLimit / 1024) + BOOST_THROW_EXCEPTION(InvalidGasLimit(gasLimit, calculateGasLimit(_parent), diff(gasLimit, _parent.gasLimit), _parent.gasLimit / 1024)); + // Check timestamp is after previous timestamp. if (parentHash) diff --git a/libethcore/Exceptions.cpp b/libethcore/Exceptions.cpp index c489c8f4a..c4628f4aa 100644 --- a/libethcore/Exceptions.cpp +++ b/libethcore/Exceptions.cpp @@ -39,7 +39,7 @@ static boost::thread_specific_ptr g_exceptionMessage; const char* InvalidBlockFormat::what() const noexcept { ETH_RETURN_STRING("Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"); } const char* UncleInChain::what() const noexcept { ETH_RETURN_STRING("Uncle in block already mentioned: Uncles " + toString(m_uncles) + " (" + m_block.abridged() + ")"); } const char* InvalidTransactionsHash::what() const noexcept { ETH_RETURN_STRING("Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref())); } -const char* InvalidGasLimit::what() const noexcept { ETH_RETURN_STRING("Invalid gas limit (provided: " + toString(provided) + " minimum:" + toString(minimum) + " max:" + toString(maximum) + ")"); } +const char* InvalidGasLimit::what() const noexcept { ETH_RETURN_STRING("Invalid gas limit (provided: " + toString(provided) + " default:" + toString(valid) + " givenDiff:" + toString(givenDiff) + " maxDiff:" + toString(maxDiff) + ")"); } const char* InvalidMinGasPrice::what() const noexcept { ETH_RETURN_STRING("Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")"); } const char* InvalidNonce::what() const noexcept { ETH_RETURN_STRING("Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")"); } const char* InvalidBlockNonce::what() const noexcept { ETH_RETURN_STRING("Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"); } diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index edf3d6b03..e1561ef0e 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -57,8 +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 _n = 0, u256 _x = 0): provided(_provided), minimum(_n), maximum(_x) {} u256 provided; u256 minimum; u256 maximum; virtual const char* what() const noexcept; }; +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 {}; struct InvalidTransactionsStateRoot: virtual dev::Exception {}; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 568629084..ec6643684 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -547,7 +547,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce) if (rlp[2].itemCount() > 2) BOOST_THROW_EXCEPTION(TooManyUncles()); - set nonces = { m_currentBlock.nonce }; + set nonces = { m_currentBlock.nonce }; Addresses rewarded; set knownUncles = _bc.allUnclesFrom(m_currentBlock.parentHash);