diff --git a/libethcore/Common.h b/libethcore/Common.h index ec826d2d1..303adc739 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -96,5 +96,16 @@ enum class ImportResult BadChain }; +struct ImportRequirements +{ + using value = unsigned; + enum + { + ValidNonce = 1, + DontHave = 2, + Default = ValidNonce + }; +}; + } } diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 4df91e3d1..186448d41 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -347,7 +347,7 @@ pair BlockChain::attemptImport(bytes const& _block, OverlayDB const } } -pair BlockChain::import(bytes const& _block, OverlayDB const& _db, Aversion _force, bool _checkNonce) +pair BlockChain::import(bytes const& _block, OverlayDB const& _db, Aversion _force, ImportRequirements::value _ir) { //@tidy This is a behemoth of a method - could do to be split into a few smaller ones. @@ -432,7 +432,7 @@ pair BlockChain::import(bytes const& _block, OverlayDB const& _db, // Check transactions are valid and that they result in a state equivalent to our state_root. // Get total difficulty increase and update state, checking it. State s(_db); //, bi.coinbaseAddress - auto tdIncrease = s.enactOn(&_block, bi, *this, _checkNonce); + auto tdIncrease = s.enactOn(&_block, bi, *this, _ir); BlockLogBlooms blb; BlockReceipts br; diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 635399494..00f41ab0a 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -112,7 +112,7 @@ public: /// Import block into disk-backed DB /// @returns the block hashes of any blocks that came into/went out of the canonical block chain. - std::pair import(bytes const& _block, OverlayDB const& _stateDB, Aversion _force = Aversion::AvoidOldBlocks, bool _checkNonce = true); + std::pair import(bytes const& _block, OverlayDB const& _stateDB, Aversion _force = Aversion::AvoidOldBlocks, ImportRequirements::value _ir = ImportRequirements::Default); /// Returns true if the given block is known (though not necessarily a part of the canon chain). bool isKnown(h256 const& _hash) const; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 1a645ab67..6ffd0bdad 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -274,7 +274,7 @@ bool State::sync(BlockChain const& _bc) return sync(_bc, _bc.currentHash()); } -bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, bool _checkNonce) +bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, ImportRequirements::value _ir) { bool ret = false; // BLOCK @@ -337,7 +337,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, bool for (auto it = chain.rbegin(); it != chain.rend(); ++it) { auto b = _bc.block(*it); - enact(&b, _bc, _checkNonce); + enact(&b, _bc, _ir); cleanup(true); } } @@ -355,7 +355,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, bool return ret; } -u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc, bool _checkNonce) +u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc, ImportRequirements::value _ir) { #if ETH_TIMED_ENACTMENTS boost::timer t; @@ -383,7 +383,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const t.restart(); #endif - sync(_bc, _bi.parentHash, BlockInfo(), _checkNonce); + sync(_bc, _bi.parentHash, BlockInfo(), _ir); resetCurrent(); #if ETH_TIMED_ENACTMENTS @@ -392,7 +392,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const #endif m_previousBlock = biParent; - auto ret = enact(_block, _bc, _checkNonce); + auto ret = enact(_block, _bc, _ir); #if ETH_TIMED_ENACTMENTS enactment = t.elapsed(); @@ -538,11 +538,11 @@ TransactionReceipts State::sync(BlockChain const& _bc, TransactionQueue& _tq, Ga return ret; } -u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce) +u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirements::value _ir) { // m_currentBlock is assumed to be prepopulated and reset. - BlockInfo bi(_block, _checkNonce ? CheckEverything : IgnoreNonce); + BlockInfo bi(_block, ((_ir & (ImportRequirements::ValidNonce | ImportRequirements::DontHave)) == ImportRequirements::ValidNonce) ? CheckEverything : IgnoreNonce); #if !ETH_RELEASE assert(m_previousBlock.hash() == bi.parentHash); diff --git a/libethereum/State.h b/libethereum/State.h index e1699c256..d23347bcd 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -306,11 +306,11 @@ public: bool sync(BlockChain const& _bc); /// Sync with the block chain, but rather than synching to the latest block, instead sync to the given block. - bool sync(BlockChain const& _bc, h256 _blockHash, BlockInfo const& _bi = BlockInfo(), bool _checkNonce = true); + bool sync(BlockChain const& _bc, h256 _blockHash, BlockInfo const& _bi = BlockInfo(), ImportRequirements::value _ir = ImportRequirements::Default); /// Execute all transactions within a given block. /// @returns the additional total difficulty. - u256 enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc, bool _checkNonce); + u256 enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc, ImportRequirements::value _ir = ImportRequirements::Default); /// Returns back to a pristine state after having done a playback. /// @arg _fullCommit if true flush everything out to disk. If false, this effectively only validates @@ -338,7 +338,7 @@ private: /// Execute the given block, assuming it corresponds to m_currentBlock. /// Throws on failure. - u256 enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce = true); + u256 enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirements::value _ir = ImportRequirements::Default); /// Finalise the block, applying the earned rewards. void applyRewards(std::vector const& _uncleBlockHeaders); diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index a68bfdf83..63fbbbf43 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -251,7 +251,7 @@ void MixClient::mine() WriteGuard l(x_state); m_state.commitToMine(bc()); m_state.completeMine(); - bc().import(m_state.blockData(), m_stateDB, Aversion::AvoidOldBlocks, false); + bc().import(m_state.blockData(), m_stateDB, Aversion::AvoidOldBlocks, ImportRequirements::ValidNonce | ImportRequirements::DontHave); m_state.sync(bc()); m_startState = m_state; h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter };