Browse Source

state cleanup

cl-refactor
arkpar 10 years ago
parent
commit
c82dd4842b
  1. 6
      libethereum/BlockChain.cpp
  2. 80
      libethereum/State.cpp
  3. 44
      libethereum/State.h

6
libethereum/BlockChain.cpp

@ -696,8 +696,10 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const&
exit(-1); exit(-1);
} }
try { try
State canary(_db, *this, _block.info.hash(), ImportRequirements::DontHave); {
State canary(_db, BaseState::Empty);
canary.populateFromChain(*this, _block.info.hash(), ImportRequirements::DontHave);
} }
catch (...) catch (...)
{ {

80
libethereum/State.cpp

@ -214,10 +214,6 @@ State& State::operator=(State const& _s)
return *this; return *this;
} }
State::~State()
{
}
StateDiff State::diff(State const& _c, bool _quick) const StateDiff State::diff(State const& _c, bool _quick) const
{ {
StateDiff ret; StateDiff ret;
@ -265,12 +261,12 @@ StateDiff State::diff(State const& _c, bool _quick) const
return ret; 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); ensureCached(m_cache, _a, _requireCode, _forceCreate);
} }
void State::ensureCached(std::unordered_map<Address, Account>& _cache, Address _a, bool _requireCode, bool _forceCreate) const void State::ensureCached(std::unordered_map<Address, Account>& _cache, const Address& _a, bool _requireCode, bool _forceCreate) const
{ {
auto it = _cache.find(_a); auto it = _cache.find(_a);
if (it == _cache.end()) 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 State::logBloom() const
{ {
LogBloom ret; LogBloom ret;
@ -991,7 +950,7 @@ void State::completeMine()
m_lastTx = m_db; m_lastTx = m_db;
} }
bool State::addressInUse(Address _id) const bool State::addressInUse(Address const& _id) const
{ {
ensureCached(_id, false, false); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1000,7 +959,7 @@ bool State::addressInUse(Address _id) const
return true; return true;
} }
bool State::addressHasCode(Address _id) const bool State::addressHasCode(Address const& _id) const
{ {
ensureCached(_id, false, false); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1009,7 +968,7 @@ bool State::addressHasCode(Address _id) const
return it->second.isFreshCode() || it->second.codeHash() != EmptySHA3; 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); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1018,7 +977,7 @@ u256 State::balance(Address _id) const
return it->second.balance(); return it->second.balance();
} }
void State::noteSending(Address _id) void State::noteSending(Address const& _id)
{ {
ensureCached(_id, false, false); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1032,7 +991,7 @@ void State::noteSending(Address _id)
it->second.incNonce(); it->second.incNonce();
} }
void State::addBalance(Address _id, u256 _amount) void State::addBalance(Address const& _id, u256 const& _amount)
{ {
ensureCached(_id, false, false); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1042,7 +1001,7 @@ void State::addBalance(Address _id, u256 _amount)
it->second.addBalance(_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); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1052,7 +1011,7 @@ void State::subBalance(Address _id, bigint _amount)
it->second.addBalance(-_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); auto h = sha3(_code);
m_db.insert(h, &_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); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1079,7 +1038,7 @@ u256 State::transactionsFrom(Address _id) const
return it->second.nonce(); 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); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
@ -1101,7 +1060,7 @@ u256 State::storage(Address _id, u256 _memory) const
return ret; return ret;
} }
unordered_map<u256, u256> State::storage(Address _id) const unordered_map<u256, u256> State::storage(Address const& _id) const
{ {
unordered_map<u256, u256> ret; unordered_map<u256, u256> ret;
@ -1127,18 +1086,7 @@ unordered_map<u256, u256> State::storage(Address _id) const
return ret; return ret;
} }
h256 State::storageRoot(Address _id) const bytes const& State::code(Address const& _contract) const
{
string s = m_state.at(_id);
if (s.size())
{
RLP r(s);
return r[2].toHash<h256>();
}
return EmptyTrie;
}
bytes const& State::code(Address _contract) const
{ {
if (!addressHasCode(_contract)) if (!addressHasCode(_contract))
return NullBytes; return NullBytes;
@ -1146,7 +1094,7 @@ bytes const& State::code(Address _contract) const
return m_cache[_contract].code(); return m_cache[_contract].code();
} }
h256 State::codeHash(Address _contract) const h256 State::codeHash(Address const& _contract) const
{ {
if (!addressHasCode(_contract)) if (!addressHasCode(_contract))
return EmptySHA3; return EmptySHA3;

44
libethereum/State.h

@ -122,8 +122,6 @@ public:
/// Copy state object. /// Copy state object.
State& operator=(State const& _s); State& operator=(State const& _s);
~State();
/// Construct state object from arbitrary point in blockchain. /// Construct state object from arbitrary point in blockchain.
PopulationStatistics populateFromChain(BlockChain const& _bc, h256 const& _hash, ImportRequirements::value _ir = ImportRequirements::Default); 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. /// Get the header information on the present block.
BlockInfo const& info() const { return m_currentBlock; } 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. /// Prepares the current state for mining.
/// Commits all transactions into the trie, compiles uncles and transactions list, applies all /// Commits all transactions into the trie, compiles uncles and transactions list, applies all
/// rewards and populates the current block header with the appropriate hashes. /// 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. /// This may be called multiple times and without issue.
void commitToMine(BlockChain const& _bc, bytes const& _extraData = {}); 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. /// Pass in a solution to the proof-of-work.
/// @returns true iff we were previously committed to mining. /// @returns true iff we were previously committed to mining.
template <class PoW> template <class PoW>
@ -196,24 +186,24 @@ public:
u256 gasLimitRemaining() const { return m_currentBlock.gasLimit - gasUsed(); } u256 gasLimitRemaining() const { return m_currentBlock.gasLimit - gasUsed(); }
/// Check if the address is in use. /// 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. /// Check if the address contains executable code.
bool addressHasCode(Address _address) const; bool addressHasCode(Address const& _address) const;
/// Get an account's balance. /// Get an account's balance.
/// @returns 0 if the address has never been used. /// @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. /// Add some amount to balance.
/// Will initialise the address if it has never been used. /// 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. /** Subtract some amount from balance.
* @throws NotEnoughCash if balance of @a _id is less than @a _value (or has never been used). * @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. * @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. * @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 _to Account to which @a _value will be added.
* @param _value Amount to be transferred. * @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. /// 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. /// Get the value of a storage position of an account.
/// @returns 0 if no account exists at that address. /// @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. /// 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. /// 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. /// Get the storage of an account.
/// @note This is expensive. Don't use it unless you need to. /// @note This is expensive. Don't use it unless you need to.
/// @returns std::unordered_map<u256, u256> if no account exists at that address. /// @returns std::unordered_map<u256, u256> if no account exists at that address.
std::unordered_map<u256, u256> storage(Address _contract) const; std::unordered_map<u256, u256> storage(Address const& _contract) const;
/// Get the code of an account. /// Get the code of an account.
/// @returns bytes() if no account exists at that address. /// @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. /// 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. /// @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. /// 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). /// Get the number of transactions a particular address has sent (used for the transaction nonce).
/// @returns 0 if the address has never been used. /// @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. /// The hash of the root of our state tree.
h256 rootHash() const { return m_state.root(); } 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 _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 /// If _forceCreate is true, then insert a default item into the cache, in the case it doesn't
/// exist in the DB. /// 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. /// Retrieve all information about a given address into a cache.
void ensureCached(std::unordered_map<Address, Account>& _cache, Address _a, bool _requireCode, bool _forceCreate) const; void ensureCached(std::unordered_map<Address, Account>& _cache, Address const& _a, bool _requireCode, bool _forceCreate) const;
/// Execute the given block, assuming it corresponds to m_currentBlock. /// Execute the given block, assuming it corresponds to m_currentBlock.
/// Throws on failure. /// Throws on failure.

Loading…
Cancel
Save