diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index 4b8828f1c..88ecd10f2 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -684,9 +684,9 @@ u256 State::execute(bytesConstRef _rlp)
Executive e(*this);
e.setup(_rlp);
-// cnote << "Executing " << e.t();
+ cnote << "Executing " << e.t();
// cnote << m_state.root() << "\n" << m_state;
-// cnote << *this;
+ cnote << *this;
u256 startGasUSed = gasUsed();
if (startGasUSed + e.t().gas > m_currentBlock.gasLimit)
@@ -695,11 +695,15 @@ u256 State::execute(bytesConstRef _rlp)
e.go();
e.finalize();
+ cnote << "Executed.";
+// cnote << m_state.root() << "\n" << m_state;
+ cnote << *this;
+
commit();
-// cnote << "Executed.";
+ cnote << "Committed.";
// cnote << m_state.root() << "\n" << m_state;
-// cnote << *this;
+ cnote << *this;
// Add to the user-originated transactions that we've executed.
m_transactions.push_back(TransactionReceipt(e.t(), m_state.root(), startGasUSed + e.gasUsed()));
@@ -835,3 +839,74 @@ void State::unapplyRewards(Addresses const& _uncleAddresses)
}
subBalance(m_currentBlock.coinbaseAddress, r);
}
+
+std::ostream& eth::operator<<(std::ostream& _out, State const& _s)
+{
+ _out << "--- " << _s.rootHash() << std::endl;
+ std::set
d;
+ std::set dtr;
+ auto trie = TrieDB(const_cast(&_s.m_db), _s.rootHash());
+ for (auto i: trie)
+ d.insert(i.first), dtr.insert(i.first);
+ for (auto i: _s.m_cache)
+ d.insert(i.first);
+
+ for (auto i: d)
+ {
+ auto it = _s.m_cache.find(i);
+ AddressState* cache = it != _s.m_cache.end() ? &it->second : nullptr;
+ auto rlpString = trie.at(i);
+ RLP r(dtr.count(i) ? rlpString : "");
+ assert(cache || r);
+
+ if (cache && !cache->isAlive())
+ _out << "XXX " << i << std::endl;
+ else
+ {
+ string lead = (cache ? r ? " * " : " + " : " ");
+ if (cache && r && (cache->balance() == r[0].toInt() && cache->nonce() == r[1].toInt()))
+ lead = " . ";
+
+ stringstream contout;
+
+ if ((!cache || cache->codeBearing()) && (!r || r[3].toHash() != EmptySHA3))
+ {
+ std::map mem;
+ std::set back;
+ std::set delta;
+ std::set cached;
+ if (r)
+ {
+ TrieDB memdb(const_cast(&_s.m_db), r[2].toHash()); // promise we won't alter the overlay! :)
+ for (auto const& j: memdb)
+ mem[j.first] = RLP(j.second).toInt(), back.insert(j.first);
+ }
+ if (cache)
+ for (auto const& j: cache->storage())
+ if ((!mem.count(j.first) && j.second) || (mem.count(j.first) && mem.at(j.first) != j.second))
+ mem[j.first] = j.second, delta.insert(j.first);
+ else if (j.second)
+ cached.insert(j.first);
+ if (delta.size())
+ lead = (lead == " . ") ? "*.* " : "*** ";
+
+ contout << " @:";
+ if (delta.size())
+ contout << "???";
+ else
+ contout << r[2].toHash();
+ contout << " $:" << (cache ? cache->isFreshCode() ? h256() : cache->codeHash() : r[3].toHash());
+
+ for (auto const& j: mem)
+ if (j.second)
+ contout << std::endl << (delta.count(j.first) ? back.count(j.first) ? " * " : " + " : cached.count(j.first) ? " . " : " ") << std::hex << std::setw(64) << j.first << ": " << std::setw(0) << j.second ;
+ else
+ contout << std::endl << "XXX " << std::hex << std::setw(64) << j.first << "";
+ }
+ else
+ contout << " [SIMPLE]";
+ _out << lead << i << ": " << std::dec << (cache ? cache->balance() : r[0].toInt()) << " #:" << (cache ? cache->nonce() : r[1].toInt()) << contout.str() << std::endl;
+ }
+ }
+ return _out;
+}
diff --git a/libethereum/State.h b/libethereum/State.h
index 5256a1d29..cfce5f543 100644
--- a/libethereum/State.h
+++ b/libethereum/State.h
@@ -273,58 +273,7 @@ private:
friend std::ostream& operator<<(std::ostream& _out, State const& _s);
};
-// TODO: Update for latest AddressState/StateTrie changes.
-// trie should always be used as base. AddressState just contains overlay.
-inline std::ostream& operator<<(std::ostream& _out, State const& _s)
-{
- _out << "--- " << _s.rootHash() << std::endl;
- std::set d;
- for (auto const& i: TrieDB(const_cast(&_s.m_db), _s.rootHash()))
- {
- auto it = _s.m_cache.find(i.first);
- if (it == _s.m_cache.end())
- {
- RLP r(i.second);
- _out << "[ ]" << i.first << ": " << std::dec << r[1].toInt() << "@" << r[0].toInt();
- if (r.itemCount() == 4)
- {
- _out << " *" << r[2].toHash();
- TrieDB memdb(const_cast(&_s.m_db), r[2].toHash()); // promise we won't alter the overlay! :)
- std::map mem;
- for (auto const& j: memdb)
- {
- _out << std::endl << " [" << j.first << ":" << toHex(j.second) << "]";
- mem[j.first] = RLP(j.second).toInt();
- }
- _out << std::endl << mem;
- }
- _out << std::endl;
- }
- else
- d.insert(i.first);
- }
- for (auto i: _s.m_cache)
- if (!i.second.isAlive())
- _out << "[XXX " << i.first << std::endl;
- else
- {
- _out << (d.count(i.first) ? "[ ! " : "[ * ") << "]" << i.first << ": " << std::dec << i.second.nonce() << "@" << i.second.balance();
- if (i.second.codeBearing())
- {
- _out << " *" << i.second.oldRoot();
- TrieDB memdb(const_cast(&_s.m_db), i.second.oldRoot()); // promise we won't alter the overlay! :)
- std::map mem;
- for (auto const& j: memdb)
- {
- _out << std::endl << " [" << j.first << ":" << toHex(j.second) << "]";
- mem[j.first] = RLP(j.second).toInt();
- }
- _out << std::endl << mem;
- }
- _out << std::endl;
- }
- return _out;
-}
+std::ostream& operator<<(std::ostream& _out, State const& _s);
template
void commit(std::map const& _cache, DB& _db, TrieDB& _state)