25 #include <boost/filesystem.hpp> 26 #include <boost/timer.hpp> 47 namespace fs = boost::filesystem;
57 m_accountStartNonce(_accountStartNonce)
80 cnote <<
"Killing state database (WithExisting::Kill).";
81 boost::filesystem::remove_all(path +
"/state");
85 boost::filesystem::create_directories(path);
89 o.max_open_files = 256;
90 o.create_if_missing =
true;
92 ldb::Status status = ldb::DB::Open(o, path +
"/state", &db);
93 if (!status.ok() || !
db)
95 if (boost::filesystem::space(path +
"/state").available < 1024)
97 cwarn <<
"Not enough available space found on hard drive. Please free some up and then re-run. Bailing.";
98 BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace());
102 cwarn << status.ToString();
106 "already open. You appear to have another instance of ethereum running. Bailing.";
107 BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
111 ctrace <<
"Opened state DB.";
124 BOOST_THROW_EXCEPTION(InvalidAccountStartNonceInState());
133 BOOST_THROW_EXCEPTION(IncorrectAccountStartNonceInState());
139 if (i.second.isDirty() && i.second.isEmpty())
173 string stateBack =
m_state.at(_addr);
174 if (stateBack.empty())
182 RLP state(stateBack);
184 std::piecewise_construct,
185 std::forward_as_tuple(_addr),
186 std::forward_as_tuple(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>(), state[3].toHash<h256>(),
Account::Unchanged)
189 return &i.first->second;
204 auto cacheEntry =
m_cache.find(addr);
205 if (cacheEntry !=
m_cache.end() && !cacheEntry->second.isDirty())
223 unordered_map<Address, u256> ret;
225 if (i.second.isAlive())
226 ret[i.first] = i.second.balance();
228 if (m_cache.find(i.first) == m_cache.end())
253 return !
a->isEmpty();
296 if (!
a->isDirty() &&
a->isEmpty())
302 a->addBalance(_amount);
308 m_changeLog.emplace_back(Change::Balance, _id, _amount);
317 if (!a || a->
balance() < _value)
333 m_cache[_address] = std::move(_account);
335 m_changeLog.emplace_back(Change::Create, _address);
357 auto mit =
a->storageOverlay().find(_key);
358 if (mit !=
a->storageOverlay().end())
363 string payload = memdb.
at(_key);
365 a->setStorageCache(_key, ret);
375 m_cache[_contract].setStorage(_key, _value);
380 map<h256, pair<u256, u256>> ret;
389 for (
auto it = memdb.hashedBegin(); it != memdb.hashedEnd(); ++it)
391 h256 const hashedKey((*it).first);
394 ret[hashedKey] = make_pair(key, value);
399 for (
auto const& i :
a->storageOverlay())
401 h256 const key = i.first;
406 ret.erase(hashedKey);
429 if (a->
code().empty())
442 m_cache[_address].setNewCode(std::move(_code));
443 m_changeLog.emplace_back(Change::NewCode, _address);
449 return a->codeHash();
459 return a->code().size();
462 if (codeSizeCache.contains(codeHash))
463 return codeSizeCache.get(codeHash);
467 codeSizeCache.store(codeHash, size);
491 case Change::Storage:
494 case Change::Balance:
503 case Change::NewCode:
519 if (isChannelVisible<VMTraceChannel>())
549 _out <<
"--- " << _s.
rootHash() << std::endl;
551 std::set<Address> dtr;
554 d.
insert(i.first), dtr.insert(i.first);
562 string rlpString = dtr.count(i) ? trie.at(i) :
"";
566 if (cache && !cache->
isAlive())
567 _out <<
"XXX " << i << std::endl;
570 string lead = (cache ? r ?
" * " :
" + " :
" ");
574 stringstream contout;
578 std::map<u256, u256> mem;
580 std::set<u256> delta;
581 std::set<u256> cached;
585 for (
auto const& j: memdb)
586 mem[j.first] =
RLP(j.second).
toInt<
u256>(), back.insert(j.first);
591 if ((!mem.count(j.first) && j.second) || (mem.count(j.first) && mem.at(j.first) != j.second))
592 mem[j.first] = j.second, delta.insert(j.first);
594 cached.insert(j.first);
597 lead = (lead ==
" . ") ?
"*.* " :
"*** ";
609 for (
auto const& j: mem)
611 contout << std::endl << (delta.count(j.first) ? back.count(j.first) ?
" * " :
" + " : cached.count(j.first) ?
" . " :
" ") << std::hex << nouppercase << std::setw(64) << j.first <<
": " << std::setw(0) << j.second ;
613 contout << std::endl <<
"XXX " << std::hex << nouppercase << std::setw(64) << j.first <<
"";
616 contout <<
" [SIMPLE]";
617 _out << lead << i <<
": " << std::dec << (cache ? cache->
nonce() : r[0].
toInt<
u256>()) <<
" #:" << (cache ? cache->
balance() : r[1].
toInt<
u256>()) << contout.str() << std::endl;
bool addressInUse(Address const &_address) const
Check if the address is in use.
State(u256 const &_accountStartNonce)
Default constructor; creates with a blank database prepopulated with the genesis block.
u256 balance(Address const &_id) const
Get an account's balance.
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
void commit(CommitBehaviour _commitBehaviour)
Commit all changes waiting in the address cache to the DB.
ChainOperationParams const & chainParams() const
std::unordered_map< Address, Account > AccountMap
bool accountNonemptyAndExisting(Address const &_address) const
Check if the account exists in the state and is non empty (nonce > 0 || balance > 0 || code nonempty)...
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
void setNewCode(Address const &_address, bytes &&_code)
Sets the code of the account. Must only be called during / after contract creation.
static OverlayDB openDB(std::string const &_path, h256 const &_genesisHash, WithExisting _we=WithExisting::Trust)
Open a DB - useful for passing into the constructor & keeping for other states that are necessary...
Models the state of a single Ethereum account.
void noteAccountStartNonce(u256 const &_actual)
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
void rollback(size_t _savepoint)
Revert all recent changes up to the given _savepoint savepoint.
Account starts as though it has not been changed.
std::unordered_map< u256, u256 > const & storageOverlay() const
void noteCode(bytesConstRef _code)
Specify to the object what the actual code is for the account.
std::hash for asio::adress
assert(len-trim+(2 *lenIndices)<=WIDTH)
Different view on a GenericTrieDB that can use different key types.
void setNonce(u256 const &_nonce)
Set nonce to a new value.
u256 const & gasUsed() const
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
vector_ref< _T > cropped(size_t _begin, size_t _count) const
AddressHash m_touched
Tracks all addresses touched so far.
Description of the result of executing a transaction.
u256 const & number() const
h256 storageRoot(Address const &_contract) const
Get the root of the storage of an account.
Model of an Ethereum state, essentially a facade for the trie.
if(a.IndicesBefore(b, len, lenIndices))
OverlayDB const & db() const
bool go(OnOpFunc const &_onOp=OnOpFunc())
Executes (or continues execution of) the VM.
void populateFrom(AccountMap const &_map)
Populate the state from the given AccountMap. Just uses dev::eth::commit().
u256 const & requireAccountStartNonce() const
std::string lookup(h256 const &_h) const
void removeEmptyAccounts()
Turns all "touched" empty accounts into non-alive accounts.
void createAccount(Address const &_address, Account const &&_account)
_N toHash(int _flags=Strict) const
boost::random_device s_fixedHashEngine
virtual void kill(Address _a)
Delete an account (used for processing suicides).
std::pair< ExecutionResult, TransactionReceipt > execute(EnvInfo const &_envInfo, SealEngineFace const &_sealEngine, Transaction const &_t, Permanence _p=Permanence::Committed, OnOpFunc const &_onOp=OnOpFunc())
Execute a given transaction.
void store(h256 const &_hash, size_t size)
void createContract(Address const &_address)
Create a contract at the given address (with unset code and unchanged balance).
bytes const & code() const
void finalize()
Finalise a transaction previously set up with initialize().
void insert(KeyType _k, bytesConstRef _value)
std::vector< detail::Change > m_changeLog
std::vector< byte > bytes
u256 storage(Address const &_contract, u256 const &_memory) const
Get the value of a storage position of an account.
u256 getNonce(Address const &_addr) const
Get the account nonce – the number of transactions it has sent.
std::function< void(uint64_t, uint64_t, Instruction, bigint, bigint, bigint, VM *, ExtVMFace const *)> OnOpFunc
std::unordered_map< Address, u256 > addresses() const
bytes const & code(Address const &_addr) const
Get the code of an account.
Message-call/contract-creation executor; useful for executing transactions.
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
std::unordered_map< Address, Account > m_cache
Our address cache. This stores the states of each address that has (or at least might have) been chan...
LogEntries const & logs() const
Encodes a transaction, ready to be exported to or freshly imported from RLP.
u256 const & balance() const
void setRoot(h256 const &_root)
Resets any uncommitted changes to the cache.
h256 rootHash() const
The hash of the root of our state tree.
void initialize(bytesConstRef _transaction)
Initializes the executive for evaluating a transaction. You must call finalize() at some point follow...
SecureTrieDB< Address, OverlayDB > m_state
Our state tree, as an OverlayDB DB.
std::vector< Address > m_unchangedCacheEntries
Tracks entries in m_cache that can potentially be purged if it grows too large.
u256 u256Param(std::string const &_name) const
Convenience method to get an otherParam as a u256 int.
State & operator=(State const &_s)
Copy state object.
void setStorage(Address const &_contract, u256 const &_location, u256 const &_value)
Set the value of a storage position of an account.
void addBalance(u256 _value)
Increments the balance of this account by the given amount.
uint8_t const size_t const size
void setStorage(u256 _p, u256 _v)
Set a key/value pair in the account's storage.
bool execute()
Begins execution of a transaction.
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
virtual void addBalance(Address const &_id, u256 const &_amount)
Add some amount to balance.
OverlayDB m_db
Our overlay for the state tree.
static CodeSizeCache & instance()
std::string at(KeyType _k) const
const unsigned c_databaseVersion
Current database version.
void clearCacheIfTooLarge() const
Purges non-modified entries in m_cache if it grows too large.
AddressHash commit(AccountMap const &_cache, SecureTrieDB< Address, DB > &_state)
Account const * account(Address const &_addr) const
size_t codeSize(Address const &_contract) const
Get the byte-size of the code of an account.
static OnOpFunc simpleTrace()
Operation function for providing a simple trace of the VM execution.
size_t savepoint() const
Create a savepoint in the state changelog.
_T toInt(int _flags=Strict) const
Converts to int of type given; if isString(), decodes as big-endian bytestream.
std::set< Address > m_nonExistingAccountsCache
Tracks addresses that are known to not exist.
Class for interpreting Recursive Linear-Prefix Data.
void subBalance(Address const &_addr, u256 const &_value)
Subtract the _value amount from the balance of _addr account.
#define DEV_IGNORE_EXCEPTIONS(X)
bool addressHasCode(Address const &_address) const
Check if the address contains executable code.
void setResultRecipient(ExecutionResult &_res)
Collect execution results in the result storage provided.
void resetCode()
Reset the code set by previous CREATE message.
void incNonce(Address const &_id)
Increament the account nonce.
h256 codeHash(Address const &_contract) const
Get the code hash of an account.