diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index 96ef45e2d..75de6f76f 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -767,11 +767,18 @@ void Main::on_contracts_currentItemChanged()
auto h = h160((byte const*)hba.data(), h160::ConstructFromPointer);
stringstream s;
- auto storage = state().storage(h);
- for (auto const& i: storage)
- s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << "
";
- s << "
Body Code
" << disassemble(state().code(h));
- ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
+ try
+ {
+ auto storage = state().storage(h);
+ for (auto const& i: storage)
+ s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << "
";
+ s << "Body Code
" << disassemble(state().code(h));
+ ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
+ }
+ catch (eth::InvalidTrie)
+ {
+ ui->contractInfo->appendHtml("Corrupted trie.");
+ }
}
}
diff --git a/libethcore/FileSystem.cpp b/libethcore/FileSystem.cpp
index 559a58997..8c55937ed 100644
--- a/libethcore/FileSystem.cpp
+++ b/libethcore/FileSystem.cpp
@@ -23,6 +23,7 @@
#include "FileSystem.h"
#include "Common.h"
+#include "Log.h"
#ifdef _WIN32
#include
diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index ac605644f..13e9da421 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -848,13 +848,37 @@ bytes const& State::code(Address _contract) const
return m_cache[_contract].code();
}
+bool State::isTrieGood()
+{
+ for (auto const& i: m_state)
+ {
+ RLP r(i.second);
+ TrieDB storageDB(&m_db, r[2].toHash());
+ try
+ {
+ for (auto const& j: storageDB) {}
+ }
+ catch (InvalidTrie)
+ {
+ return false;
+ }
+ if (r[3].toHash() != EmptySHA3 && m_db.lookup(r[3].toHash()).empty())
+ return false;
+ }
+ return true;
+}
+
u256 State::execute(bytesConstRef _rlp)
{
#ifndef RELEASE
commit(); // get an updated hash
#endif
- // TODO: CHECK TRIE
+ if (!isTrieGood())
+ {
+ cwarn << "BAD TRIE before execution begins.";
+ throw InvalidTrie();
+ }
State old(*this);
auto h = rootHash();
@@ -880,7 +904,12 @@ u256 State::execute(bytesConstRef _rlp)
cnote << "Executed; now" << rootHash();
cnote << old.diff(*this);
- // TODO: CHECK TRIE
+ if (!isTrieGood())
+ {
+ cwarn << "BAD TRIE immediately after execution.";
+ throw InvalidTrie();
+ }
+
// TODO: CHECK TRIE after level DB flush to make sure exactly the same.
// Add to the user-originated transactions that we've executed.
diff --git a/libethereum/State.h b/libethereum/State.h
index 59e2c1a74..13cfb146e 100644
--- a/libethereum/State.h
+++ b/libethereum/State.h
@@ -299,6 +299,8 @@ private:
/// @returns gas used by transactions thus far executed.
u256 gasUsed() const { return m_transactions.size() ? m_transactions.back().gasUsed : 0; }
+ bool isTrieGood();
+
Overlay m_db; ///< Our overlay for the state tree.
TrieDB m_state; ///< Our state tree, as an Overlay DB.
std::vector m_transactions; ///< The current list of transactions that we've included in the state.