diff --git a/libethcore/TrieDB.cpp b/libethcore/TrieDB.cpp index 5418ff04f..a00c64bfd 100644 --- a/libethcore/TrieDB.cpp +++ b/libethcore/TrieDB.cpp @@ -44,6 +44,14 @@ std::string BasicMap::lookup(h256 _h) const return std::string(); } +bool BasicMap::exists(h256 _h) const +{ + auto it = m_over.find(_h); + if (it != m_over.end() && (!m_enforceRefs || (m_refCount.count(it->first) && m_refCount.at(it->first)))) + return true; + return false; +} + void BasicMap::insert(h256 _h, bytesConstRef _v) { m_over[_h] = _v.toString(); @@ -58,7 +66,7 @@ void BasicMap::kill(h256 _h) if (m_refCount[_h] > 0) --m_refCount[_h]; else - cwarn << "Decreasing DB node ref count below zero. Probably have a corrupt Trie."; + cwarn << "Decreasing DB node ref count below zero. Probably have a corrupt Trie." << _h.abridged(); } tdebug << "KILL" << _h.abridged() << "=>" << m_refCount[_h]; } @@ -113,4 +121,14 @@ std::string Overlay::lookup(h256 _h) const return ret; } +bool Overlay::exists(h256 _h) const +{ + if (BasicMap::exists(_h)) + return true; + std::string ret; + if (m_db) + m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); + return !ret.empty(); +} + } diff --git a/libethcore/TrieDB.h b/libethcore/TrieDB.h index d36991d05..3c59463cc 100644 --- a/libethcore/TrieDB.h +++ b/libethcore/TrieDB.h @@ -44,6 +44,7 @@ public: std::map const& get() const { return m_over; } std::string lookup(h256 _h) const; + bool exists(h256 _h) const; void insert(h256 _h, bytesConstRef _v); void kill(h256 _h); void purge(); @@ -83,6 +84,7 @@ public: void rollback(); std::string lookup(h256 _h) const; + bool exists(h256 _h) const; private: using BasicMap::clear; @@ -132,7 +134,16 @@ public: void open(DB* _db, h256 _root) { m_db = _db; setRoot(_root); } void init(); - void setRoot(h256 _root) { m_root = _root == h256() ? c_shaNull : _root; /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/ if (!node(m_root).size()) throw RootNotFound(); } + void setRoot(h256 _root) + { + m_root = _root == h256() ? c_shaNull : _root; + if (m_root == c_shaNull && !m_db->exists(m_root)) + init(); + + /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/ + if (!node(m_root).size()) + throw RootNotFound(); + } bool haveRoot(h256 _root, bool _enforceRefs = true) { return _root == h256() ? true : m_db->lookup(_root, _enforceRefs).size(); } /// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node).