32 #include <boost/filesystem.hpp>
33 #include <boost/timer.hpp>
38 namespace fs = boost::filesystem;
43 m_accountStartNonce(_accountStartNonce)
54 m_unchangedCacheEntries(_s.m_unchangedCacheEntries),
55 m_nonExistingAccountsCache(_s.m_nonExistingAccountsCache),
56 m_touched(_s.m_touched),
57 m_accountStartNonce(_s.m_accountStartNonce)
67 fs::remove_all(path / fs::path(
"state"));
73 fs::create_directories(path);
83 catch (boost::exception
const& ex)
85 cwarn << boost::diagnostic_information(ex) <<
'\n';
88 else if (fs::space(path / fs::path(
"state")).available < 1024)
90 cwarn <<
"Not enough available space found on hard drive. Please free some up and then re-run. Bailing.";
91 BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace());
97 (path / fs::path(
"state")) <<
98 "already open. You appear to have another instance of ethereum running. Bailing.";
99 BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
113 BOOST_THROW_EXCEPTION(InvalidAccountStartNonceInState());
114 return m_accountStartNonce;
120 m_accountStartNonce = _actual;
121 else if (m_accountStartNonce != _actual)
122 BOOST_THROW_EXCEPTION(IncorrectAccountStartNonceInState());
125 void State::removeEmptyAccounts()
127 for (
auto& i: m_cache)
128 if (i.second.isDirty() && i.second.isEmpty())
139 m_cache = _s.m_cache;
140 m_unchangedCacheEntries = _s.m_unchangedCacheEntries;
141 m_nonExistingAccountsCache = _s.m_nonExistingAccountsCache;
142 m_touched = _s.m_touched;
143 m_accountStartNonce = _s.m_accountStartNonce;
149 return const_cast<State*
>(
this)->account(_a);
154 auto it = m_cache.find(_addr);
155 if (it != m_cache.end())
158 if (m_nonExistingAccountsCache.count(_addr))
162 string stateBack = m_state.at(_addr);
163 if (stateBack.empty())
165 m_nonExistingAccountsCache.insert(_addr);
169 clearCacheIfTooLarge();
171 RLP state(stateBack);
172 auto i = m_cache.emplace(
173 std::piecewise_construct,
174 std::forward_as_tuple(_addr),
175 std::forward_as_tuple(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>(), state[3].toHash<h256>(),
Account::Unchanged)
177 m_unchangedCacheEntries.push_back(_addr);
178 return &i.first->second;
181 void State::clearCacheIfTooLarge()
const
184 while (m_unchangedCacheEntries.size() > 1000)
188 size_t const randomIndex = std::uniform_int_distribution<size_t>(0, m_unchangedCacheEntries.size() - 1)(
dev::s_fixedHashEngine);
190 Address const addr = m_unchangedCacheEntries[randomIndex];
191 swap(m_unchangedCacheEntries[randomIndex], m_unchangedCacheEntries.back());
192 m_unchangedCacheEntries.pop_back();
194 auto cacheEntry = m_cache.find(addr);
195 if (cacheEntry != m_cache.end() && !cacheEntry->second.isDirty())
196 m_cache.erase(cacheEntry);
203 removeEmptyAccounts();
207 m_unchangedCacheEntries.clear();
213 unordered_map<Address, u256> ret;
214 for (
auto& i: m_cache)
215 if (i.second.isAlive())
216 ret[i.first] = i.second.balance();
217 for (
auto const& i: m_state)
218 if (m_cache.find(i.first) == m_cache.end())
222 BOOST_THROW_EXCEPTION(InterfaceNotSupported() <<
errinfo_interface(
"State::addresses()"));
227 h256 const& _beginHash,
size_t _maxResults)
const
233 for (
auto it = m_state.hashedLowerBound(_beginHash); it != m_state.hashedEnd(); ++it)
235 auto const address =
Address(it.key());
236 auto const itCachedAddress = m_cache.find(address);
239 if (itCachedAddress != m_cache.end() && itCachedAddress->second.isDirty() &&
240 !itCachedAddress->second.isAlive())
246 nextKey =
h256((*it).first);
250 h256 const hashedAddress((*it).first);
258 for (
auto const& addressAndAccount : m_cache)
260 auto const& address = addressAndAccount.first;
261 auto const addressHash =
sha3(address);
262 auto const& account = addressAndAccount.second;
263 if (account.
isDirty() && account.
isAlive() && addressHash >= _beginHash)
264 cacheAddresses.emplace(addressHash, address);
268 addresses.insert(cacheAddresses.begin(), cacheAddresses.end());
273 auto itEnd = std::next(
addresses.begin(), _maxResults);
274 nextKey = itEnd->first;
285 m_unchangedCacheEntries.clear();
286 m_nonExistingAccountsCache.clear();
293 return !!account(_id);
298 if (
Account const* a = account(_address))
299 return !a->isEmpty();
306 if (
auto a = account(_id))
314 if (
auto a = account(_id))
322 if (
Account* a = account(_addr))
324 auto oldNonce = a->nonce();
326 m_changeLog.emplace_back(_addr, oldNonce);
335 if (
Account* a = account(_addr))
337 auto oldNonce = a->nonce();
338 a->setNonce(_newNonce);
339 m_changeLog.emplace_back(_addr, oldNonce);
343 createAccount(_addr,
Account(_newNonce, 0));
356 if (!a->isDirty() && a->isEmpty())
362 a->addBalance(_amount);
377 if (!a || a->
balance() < _value)
399 void State::createAccount(
Address const& _address,
Account const&& _account)
401 assert(!
addressInUse(_address) &&
"Account already exists");
402 m_cache[_address] = std::move(_account);
403 m_nonExistingAccountsCache.erase(_address);
409 if (
auto a = account(_addr))
416 if (
auto a = account(_addr))
419 return m_accountStartNonce;
424 if (
Account const* a = account(_id))
425 return a->storageValue(_key, m_db);
432 m_changeLog.emplace_back(_contract, _key,
storage(_contract, _key));
433 m_cache[_contract].setStorage(_key, _value);
438 if (
Account const* a = account(_contract))
439 return a->originalStorageValue(_key, m_db);
446 h256 const& oldHash{m_cache[_contract].baseRoot()};
450 m_cache[_contract].clearStorage();
456 map<h256, pair<u256, u256>> ret;
458 if (
Account const* a = account(_id))
461 if (
h256 root = a->baseRoot())
465 for (
auto it = memdb.hashedBegin(); it != memdb.hashedEnd(); ++it)
467 h256 const hashedKey((*it).first);
470 ret[hashedKey] = make_pair(key, value);
475 for (
auto const& i : a->storageOverlay())
477 h256 const key = i.first;
482 ret.erase(hashedKey);
488 BOOST_THROW_EXCEPTION(InterfaceNotSupported() <<
errinfo_interface(
"State::storage(Address const& _id)"));
494 string s = m_state.at(_id);
505 Account const* a = account(_addr);
509 if (a->
code().empty())
522 m_changeLog.emplace_back(_address,
code(_address));
523 m_cache[_address].setCode(std::move(_code));
528 if (
Account const* a = account(_a))
529 return a->codeHash();
536 if (
Account const* a = account(_a))
539 return a->code().size();
542 if (codeSizeCache.contains(
codeHash))
546 size_t size =
code(_a).size();
547 codeSizeCache.store(
codeHash, size);
557 return m_changeLog.size();
562 while (_savepoint != m_changeLog.size())
564 auto& change = m_changeLog.back();
565 auto& account = m_cache[change.address];
584 m_cache.erase(change.address);
587 account.
setCode(std::move(change.oldCode));
591 m_unchangedCacheEntries.emplace_back(change.address);
594 m_changeLog.pop_back();
602 Executive e(*
this, _envInfo, _sealEngine);
612 bool const statusCode = executeTransaction(e, _t, onOp);
614 bool removeEmptyAccounts =
false;
631 return make_pair(res, receipt);
637 for (
unsigned i = 0; i < _txCount; ++i)
639 EnvInfo envInfo(_block.
info(), _lastHashes, gasUsed);
641 Executive e(*
this, envInfo, _sealEngine);
670 _out <<
"--- " << _s.
rootHash() << std::endl;
672 std::set<Address> dtr;
675 d.insert(i.first), dtr.insert(i.first);
676 for (
auto i: _s.m_cache)
681 auto it = _s.m_cache.find(i);
682 Account* cache = it != _s.m_cache.end() ? &it->second :
nullptr;
683 string rlpString = dtr.count(i) ? trie.at(i) :
"";
687 if (cache && !cache->
isAlive())
688 _out <<
"XXX " << i << std::endl;
691 string lead = (cache ? r ?
" * " :
" + " :
" ");
695 stringstream contout;
699 std::map<u256, u256> mem;
701 std::set<u256> delta;
702 std::set<u256> cached;
706 for (
auto const& j: memdb)
707 mem[j.first] =
RLP(j.second).
toInt<
u256>(), back.insert(j.first);
712 if ((!mem.count(j.first) && j.second) || (mem.count(j.first) && mem.at(j.first) != j.second))
713 mem[j.first] = j.second, delta.insert(j.first);
715 cached.insert(j.first);
718 lead = (lead ==
" . ") ?
"*.* " :
"*** ";
730 for (
auto const& j: mem)
732 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 ;
734 contout << std::endl <<
"XXX " << std::hex << nouppercase << std::setw(64) << j.first <<
"";
737 contout <<
" [SIMPLE]";
738 _out << lead << i <<
": " << std::dec << (cache ? cache->
nonce() : r[0].
toInt<
u256>()) <<
" #:" << (cache ? cache->
balance() : r[1].
toInt<
u256>()) << contout.str() << std::endl;
746 o_s = _block.
state();
762 for (
auto const& i: _cache)
763 if (i.second.isDirty())
765 if (!i.second.isAlive())
770 s << i.second.nonce() << i.second.balance();
772 if (i.second.storageOverlay().empty())
774 assert(i.second.baseRoot());
775 s.
append(i.second.baseRoot());
780 for (
auto const& j: i.second.storageOverlay())
782 storageDB.
insert(j.first,
rlp(j.second));
784 storageDB.
remove(j.first);
785 assert(storageDB.root());
786 s.
append(storageDB.root());
789 if (i.second.hasNewCode())
791 h256 ch = i.second.codeHash();
794 _state.db()->
insert(ch, &i.second.code());
798 s << i.second.codeHash();