diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index 1f845ad20..4c71353d6 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -166,7 +166,7 @@ u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const if (!parentHash) return c_genesisDifficulty; else - return timestamp >= _parent.timestamp + 42 ? _parent.difficulty - (_parent.difficulty >> 10) : (_parent.difficulty + (_parent.difficulty >> 10)); + return timestamp >= _parent.timestamp + 9 ? _parent.difficulty - (_parent.difficulty >> 10) : (_parent.difficulty + (_parent.difficulty >> 10)); } void BlockInfo::verifyParent(BlockInfo const& _parent) const diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index 475ab1f05..9fb80d8c6 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -20,7 +20,8 @@ class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; class InvalidUnclesHash: public Exception {}; class InvalidUncle: public Exception {}; -class UncleNotAnUncle: public Exception {}; +class UncleTooOld: public Exception {}; +class UncleInChain: public Exception {}; class DuplicateUncleNonce: public Exception {}; class InvalidStateRoot: public Exception {}; class InvalidTransactionsHash: public Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } }; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 842343480..06117c01b 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -386,6 +386,20 @@ void BlockChain::checkConsistency() delete it; } +h256Set BlockChain::allUnclesFrom(h256 _parent) const +{ + // Get all uncles cited given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5). + h256Set ret; + h256 p = _parent; + for (unsigned i = 0; i < 6 && p != m_genesisHash; ++i, p = details(p).parent) + { + ret.insert(sha3(RLP(block(p))[0].data())); + for (auto i: RLP(block(p))[2]) + ret.insert(sha3(i.data())); + } + return ret; +} + bytes BlockChain::block(h256 _hash) const { if (_hash == m_genesisHash) diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index d13ef7614..8fcf09691 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -107,6 +107,11 @@ public: /// Get the hash of a block of a given number. Slow; try not to use it too much. h256 numberHash(unsigned _n) const; + /// Get all blocks not allowed as uncles given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5). + /// @returns set including the header-hash of every parent (including @a _parent) up to and including generation +5 + /// togther with all their quoted uncles. + h256Set allUnclesFrom(h256 _parent) const; + /// @returns the genesis block header. static BlockInfo const& genesis() { UpgradableGuard l(x_genesis); if (!s_genesis) { auto gb = createGenesisBlock(); UpgradeGuard ul(l); (s_genesis = new BlockInfo)->populate(&gb); } return *s_genesis; } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 105c725f6..7b46228b4 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -390,7 +390,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const sync(_bc, _bi.parentHash); resetCurrent(); m_previousBlock = biParent; - return enact(_block, biGrandParent); + return enact(_block, &_bc); } map
State::addresses() const @@ -499,7 +499,7 @@ h256s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged) return ret; } -u256 State::enact(bytesConstRef _block, BlockInfo const& _grandParent, bool _checkNonce) +u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce) { // m_currentBlock is assumed to be prepopulated and reset. @@ -558,16 +558,21 @@ u256 State::enact(bytesConstRef _block, BlockInfo const& _grandParent, bool _che // Check uncles & apply their rewards to state. set