diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 43b115c49..03ebcb56e 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -696,8 +696,10 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& exit(-1); } - try { - State canary(_db, *this, _block.info.hash(), ImportRequirements::DontHave); + try + { + State canary(_db, BaseState::Empty); + canary.populateFromChain(*this, _block.info.hash(), ImportRequirements::DontHave); } catch (...) { diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 10d637509..fac587557 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -214,10 +214,6 @@ State& State::operator=(State const& _s) return *this; } -State::~State() -{ -} - StateDiff State::diff(State const& _c, bool _quick) const { StateDiff ret; @@ -265,12 +261,12 @@ StateDiff State::diff(State const& _c, bool _quick) const return ret; } -void State::ensureCached(Address _a, bool _requireCode, bool _forceCreate) const +void State::ensureCached(Address const& _a, bool _requireCode, bool _forceCreate) const { ensureCached(m_cache, _a, _requireCode, _forceCreate); } -void State::ensureCached(std::unordered_map& _cache, Address _a, bool _requireCode, bool _forceCreate) const +void State::ensureCached(std::unordered_map& _cache, const Address& _a, bool _requireCode, bool _forceCreate) const { auto it = _cache.find(_a); if (it == _cache.end()) @@ -827,43 +823,6 @@ void State::uncommitToMine() } } -bool State::amIJustParanoid(BlockChain const& _bc) -{ - commitToMine(_bc); - - // Update difficulty according to timestamp. - m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock); - - // Compile block: - RLPStream block; - block.appendList(3); - m_currentBlock.streamRLP(block, WithNonce); - block.appendRaw(m_currentTxs); - block.appendRaw(m_currentUncles); - - State s(*this); - s.resetCurrent(); - try - { - cnote << "PARANOIA root:" << s.rootHash(); -// s.m_currentBlock.populate(&block.out(), false); -// s.m_currentBlock.verifyInternals(&block.out()); - s.enact(BlockChain::verifyBlock(block.out()), _bc, false); // don't check nonce for this since we haven't mined it yet. - s.cleanup(false); - return true; - } - catch (Exception const& _e) - { - cwarn << "Bad block: " << diagnostic_information(_e); - } - catch (std::exception const& _e) - { - cwarn << "Bad block: " << _e.what(); - } - - return false; -} - LogBloom State::logBloom() const { LogBloom ret; @@ -991,7 +950,7 @@ void State::completeMine() m_lastTx = m_db; } -bool State::addressInUse(Address _id) const +bool State::addressInUse(Address const& _id) const { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1000,7 +959,7 @@ bool State::addressInUse(Address _id) const return true; } -bool State::addressHasCode(Address _id) const +bool State::addressHasCode(Address const& _id) const { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1009,7 +968,7 @@ bool State::addressHasCode(Address _id) const return it->second.isFreshCode() || it->second.codeHash() != EmptySHA3; } -u256 State::balance(Address _id) const +u256 State::balance(Address const& _id) const { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1018,7 +977,7 @@ u256 State::balance(Address _id) const return it->second.balance(); } -void State::noteSending(Address _id) +void State::noteSending(Address const& _id) { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1032,7 +991,7 @@ void State::noteSending(Address _id) it->second.incNonce(); } -void State::addBalance(Address _id, u256 _amount) +void State::addBalance(Address const& _id, u256 const& _amount) { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1042,7 +1001,7 @@ void State::addBalance(Address _id, u256 _amount) it->second.addBalance(_amount); } -void State::subBalance(Address _id, bigint _amount) +void State::subBalance(Address const& _id, bigint const& _amount) { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1052,7 +1011,7 @@ void State::subBalance(Address _id, bigint _amount) it->second.addBalance(-_amount); } -Address State::newContract(u256 _balance, bytes const& _code) +Address State::newContract(u256 const& _balance, bytes const& _code) { auto h = sha3(_code); m_db.insert(h, &_code); @@ -1069,7 +1028,7 @@ Address State::newContract(u256 _balance, bytes const& _code) } } -u256 State::transactionsFrom(Address _id) const +u256 State::transactionsFrom(Address const& _id) const { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1079,7 +1038,7 @@ u256 State::transactionsFrom(Address _id) const return it->second.nonce(); } -u256 State::storage(Address _id, u256 _memory) const +u256 State::storage(Address const& _id, u256 const& _memory) const { ensureCached(_id, false, false); auto it = m_cache.find(_id); @@ -1101,7 +1060,7 @@ u256 State::storage(Address _id, u256 _memory) const return ret; } -unordered_map State::storage(Address _id) const +unordered_map State::storage(Address const& _id) const { unordered_map ret; @@ -1127,18 +1086,7 @@ unordered_map State::storage(Address _id) const return ret; } -h256 State::storageRoot(Address _id) const -{ - string s = m_state.at(_id); - if (s.size()) - { - RLP r(s); - return r[2].toHash(); - } - return EmptyTrie; -} - -bytes const& State::code(Address _contract) const +bytes const& State::code(Address const& _contract) const { if (!addressHasCode(_contract)) return NullBytes; @@ -1146,7 +1094,7 @@ bytes const& State::code(Address _contract) const return m_cache[_contract].code(); } -h256 State::codeHash(Address _contract) const +h256 State::codeHash(Address const& _contract) const { if (!addressHasCode(_contract)) return EmptySHA3; diff --git a/libethereum/State.h b/libethereum/State.h index ef8a3251a..594212162 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -122,8 +122,6 @@ public: /// Copy state object. State& operator=(State const& _s); - ~State(); - /// Construct state object from arbitrary point in blockchain. PopulationStatistics populateFromChain(BlockChain const& _bc, h256 const& _hash, ImportRequirements::value _ir = ImportRequirements::Default); @@ -145,11 +143,6 @@ public: /// Get the header information on the present block. BlockInfo const& info() const { return m_currentBlock; } - /// @brief Checks that mining the current object will result in a valid block. - /// Effectively attempts to import the serialised block. - /// @returns true if all is ok. If it's false, worry. - bool amIJustParanoid(BlockChain const& _bc); - /// Prepares the current state for mining. /// Commits all transactions into the trie, compiles uncles and transactions list, applies all /// rewards and populates the current block header with the appropriate hashes. @@ -158,9 +151,6 @@ public: /// This may be called multiple times and without issue. void commitToMine(BlockChain const& _bc, bytes const& _extraData = {}); - /// @returns true iff commitToMine() has been called without any subsequest transactions added &c. - bool isCommittedToMine() const { return m_committedToMine; } - /// Pass in a solution to the proof-of-work. /// @returns true iff we were previously committed to mining. template @@ -196,24 +186,24 @@ public: u256 gasLimitRemaining() const { return m_currentBlock.gasLimit - gasUsed(); } /// Check if the address is in use. - bool addressInUse(Address _address) const; + bool addressInUse(Address const& _address) const; /// Check if the address contains executable code. - bool addressHasCode(Address _address) const; + bool addressHasCode(Address const& _address) const; /// Get an account's balance. /// @returns 0 if the address has never been used. - u256 balance(Address _id) const; + u256 balance(Address const& _id) const; /// Add some amount to balance. /// Will initialise the address if it has never been used. - void addBalance(Address _id, u256 _amount); + void addBalance(Address const& _id, u256 const& _amount); /** Subtract some amount from balance. * @throws NotEnoughCash if balance of @a _id is less than @a _value (or has never been used). * @note We use bigint here as we don't want any accidental problems with negative numbers. */ - void subBalance(Address _id, bigint _value); + void subBalance(Address const& _id, bigint const& _value); /** * @brief Transfers "the balance @a _value between two accounts. @@ -221,40 +211,40 @@ public: * @param _to Account to which @a _value will be added. * @param _value Amount to be transferred. */ - void transferBalance(Address _from, Address _to, u256 _value) { subBalance(_from, _value); addBalance(_to, _value); } + void transferBalance(Address const& _from, Address const& _to, u256 const& _value) { subBalance(_from, _value); addBalance(_to, _value); } /// Get the root of the storage of an account. - h256 storageRoot(Address _contract) const; + h256 storageRoot(Address const& _contract) const; /// Get the value of a storage position of an account. /// @returns 0 if no account exists at that address. - u256 storage(Address _contract, u256 _memory) const; + u256 storage(Address const& _contract, u256 const& _memory) const; /// Set the value of a storage position of an account. - void setStorage(Address _contract, u256 _location, u256 _value) { m_cache[_contract].setStorage(_location, _value); } + void setStorage(Address const& _contract, u256 const& _location, u256 const& _value) { m_cache[_contract].setStorage(_location, _value); } /// Create a new contract. - Address newContract(u256 _balance, bytes const& _code); + Address newContract(u256 const& _balance, bytes const& _code); /// Get the storage of an account. /// @note This is expensive. Don't use it unless you need to. /// @returns std::unordered_map if no account exists at that address. - std::unordered_map storage(Address _contract) const; + std::unordered_map storage(Address const& _contract) const; /// Get the code of an account. /// @returns bytes() if no account exists at that address. - bytes const& code(Address _contract) const; + bytes const& code(Address const& _contract) const; /// Get the code hash of an account. /// @returns EmptySHA3 if no account exists at that address or if there is no code associated with the address. - h256 codeHash(Address _contract) const; + h256 codeHash(Address const& _contract) const; /// Note that the given address is sending a transaction and thus increment the associated ticker. - void noteSending(Address _id); + void noteSending(Address const& _id); /// Get the number of transactions a particular address has sent (used for the transaction nonce). /// @returns 0 if the address has never been used. - u256 transactionsFrom(Address _address) const; + u256 transactionsFrom(Address const& _address) const; /// The hash of the root of our state tree. h256 rootHash() const { return m_state.root(); } @@ -333,10 +323,10 @@ private: /// If _requireMemory is true, grab the full memory should it be a contract item. /// If _forceCreate is true, then insert a default item into the cache, in the case it doesn't /// exist in the DB. - void ensureCached(Address _a, bool _requireCode, bool _forceCreate) const; + void ensureCached(Address const& _a, bool _requireCode, bool _forceCreate) const; /// Retrieve all information about a given address into a cache. - void ensureCached(std::unordered_map& _cache, Address _a, bool _requireCode, bool _forceCreate) const; + void ensureCached(std::unordered_map& _cache, Address const& _a, bool _requireCode, bool _forceCreate) const; /// Execute the given block, assuming it corresponds to m_currentBlock. /// Throws on failure.