From 5ac16c53f3181c29145cd1de801b07aa81f21bf2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 1 Mar 2015 00:52:51 +0100 Subject: [PATCH] New SecureTrie. --- libdevcrypto/TrieDB.h | 92 +++++++++---------------------------------- libethcore/Common.cpp | 11 +----- libethereum/State.cpp | 28 +++++++------ libethereum/State.h | 38 ++++-------------- 4 files changed, 44 insertions(+), 125 deletions(-) diff --git a/libdevcrypto/TrieDB.h b/libdevcrypto/TrieDB.h index 1abf2d8c0..79852304c 100644 --- a/libdevcrypto/TrieDB.h +++ b/libdevcrypto/TrieDB.h @@ -334,20 +334,19 @@ std::ostream& operator<<(std::ostream& _out, SpecificTrieDB co return _out; } -template -class HashedGenericTrieDB: private SpecificTrieDB, h256> +template +class SecureGenericTrieDB: private TrieDB { - using Super = SpecificTrieDB, h256>; + using Super = TrieDB; public: - using DB = _DB; - - HashedGenericTrieDB(DB* _db = nullptr): Super(_db) {} - HashedGenericTrieDB(DB* _db, h256 _root): Super(_db, _root) {} + SecureGenericTrieDB(DB* _db): Super(_db) {} + SecureGenericTrieDB(DB* _db, h256 _root): Super(_db, _root) {} using Super::open; using Super::init; using Super::setRoot; + using Super::haveRoot; /// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node). using Super::isNull; @@ -360,84 +359,29 @@ public: using Super::check; std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); } - bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); } void insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(sha3(_key), _value); } void remove(bytesConstRef _key) { Super::remove(sha3(_key)); } - - // empty from the PoV of the iterator interface; still need a basic iterator impl though. - class iterator - { - public: - using value_type = std::pair; - - iterator() {} - iterator(HashedGenericTrieDB const*) {} - iterator(HashedGenericTrieDB const*, bytesConstRef) {} - - iterator& operator++() { return *this; } - value_type operator*() const { return value_type(); } - value_type operator->() const { return value_type(); } - - bool operator==(iterator const&) const { return true; } - bool operator!=(iterator const&) const { return false; } - - value_type at() const { return value_type(); } - }; - iterator begin() const { return iterator(); } - iterator end() const { return iterator(); } - iterator lower_bound(bytesConstRef) const { return iterator(); } + bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); } }; -// Hashed & Basic -template -class FatGenericTrieDB: public GenericTrieDB +template +class SecureTrieDB: public SecureGenericTrieDB { - using Super = GenericTrieDB; + using Super = SecureGenericTrieDB; public: - FatGenericTrieDB(DB* _db): Super(_db), m_secure(_db) {} - FatGenericTrieDB(DB* _db, h256 _root) { open(_db, _root); } + SecureTrieDB(DB* _db): Super(_db) {} + SecureTrieDB(DB* _db, h256 _root): Super(_db, _root) {} - void open(DB* _db, h256 _root) { Super::open(_db); m_secure.open(_db); setRoot(_root); } - - void init() { Super::init(); m_secure.init(); syncRoot(); } - - void setRoot(h256 _root) - { - if (!m_secure.isNull()) - Super::db()->removeAux(m_secure.root()); - m_secure.setRoot(_root); - auto rb = Super::db()->lookupAux(m_secure.root()); - auto r = h256(rb); - Super::setRoot(r); - } - - h256 root() const { return m_secure.root(); } - - void insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(_key, _value); m_secure.insert(_key, _value); syncRoot(); } - void remove(bytesConstRef _key) { Super::remove(_key); m_secure.remove(_key); syncRoot(); } - - std::set leftOvers(std::ostream* = nullptr) const { return {}; } - bool check(bool) const { return m_secure.check(false) && Super::check(false); } - -private: - void syncRoot() - { - // Root changed. Need to record the mapping so we can determine on setRoot. - Super::db()->insertAux(m_secure.root(), Super::root().ref()); - } + std::string operator[](KeyType _k) const { return at(_k); } - HashedGenericTrieDB m_secure; + bool contains(KeyType _k) const { return Super::contains(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } + std::string at(KeyType _k) const { return Super::at(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } + void insert(KeyType _k, bytesConstRef _value) { Super::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); } + void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); } + void remove(KeyType _k) { Super::remove(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } }; -template using TrieDB = SpecificTrieDB, KeyType>; - -#if ETH_FATDB -template using SecureTrieDB = SpecificTrieDB, KeyType>; -#else -template using SecureTrieDB = SpecificTrieDB, KeyType>; -#endif - } // Template implementations... diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index 9eb622fe3..331ee837e 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -32,15 +32,8 @@ namespace dev namespace eth { -const unsigned c_protocolVersion = 56; -const unsigned c_databaseBaseVersion = 7; -#if ETH_FATDB -const unsigned c_databaseVersionModifier = 1000; -#else -const unsigned c_databaseVersionModifier = 0; -#endif - -const unsigned c_databaseVersion = c_databaseBaseVersion + c_databaseVersionModifier; +const unsigned c_protocolVersion = 55; +const unsigned c_databaseVersion = 5; vector> const& units() { diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 568629084..faa212cc7 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -180,10 +180,11 @@ StateDiff State::diff(State const& _c) const auto trie = SecureTrieDB(const_cast(&m_db), rootHash()); auto trieD = SecureTrieDB(const_cast(&_c.m_db), _c.rootHash()); - for (auto i: trie) - ads.insert(i.first), trieAds.insert(i.first); - for (auto i: trieD) - ads.insert(i.first), trieAdsD.insert(i.first); + // TODO: fix +// for (auto i: trie) +// ads.insert(i.first), trieAds.insert(i.first); +// for (auto i: trieD) +// ads.insert(i.first), trieAdsD.insert(i.first); for (auto i: m_cache) ads.insert(i.first); for (auto i: _c.m_cache) @@ -345,9 +346,10 @@ map State::addresses() const for (auto i: m_cache) if (i.second.isAlive()) ret[i.first] = i.second.balance(); - for (auto const& i: m_state) - if (m_cache.find(i.first) == m_cache.end()) - ret[i.first] = RLP(i.second)[1].toInt(); + // TODO: fix. +// for (auto const& i: m_state) +// if (m_cache.find(i.first) == m_cache.end()) +// ret[i.first] = RLP(i.second)[1].toInt(); return ret; } @@ -952,9 +954,10 @@ map State::storage(Address _id) const // Pull out all values from trie storage. if (it->second.baseRoot()) { - SecureTrieDB memdb(const_cast(&m_db), it->second.baseRoot()); // promise we won't alter the overlay! :) - for (auto const& i: memdb) - ret[i.first] = RLP(i.second).toInt(); + // TODO: fix +// SecureTrieDB memdb(const_cast(&m_db), it->second.baseRoot()); // promise we won't alter the overlay! :) +// for (auto const& i: memdb) +// ret[i.first] = RLP(i.second).toInt(); } // Then merge cached storage over the top. @@ -1190,8 +1193,9 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, State const& _s) if (r) { SecureTrieDB 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); + // TODO: fix +// for (auto const& j: memdb) +// mem[j.first] = RLP(j.second).toInt(), back.insert(j.first); } if (cache) for (auto const& j: cache->storageOverlay()) diff --git a/libethereum/State.h b/libethereum/State.h index 00a735291..eedf324fb 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -334,36 +334,14 @@ void commit(std::map const& _cache, DB& _db, SecureTrieDB storageDB(&_db, i.second.baseRoot()); - for (auto const& j: i.second.storageOverlay()) - if (j.second) - storageDB.insert(j.first, rlp(j.second)); - else - storageDB.remove(j.first); - assert(storageDB.root()); - s.append(storageDB.root()); - } - - if (i.second.isFreshCode()) - { - h256 ch = sha3(i.second.code()); - _db.insert(ch, &i.second.code()); - s << ch; - } - else - s << i.second.codeHash(); - - _state.insert(i.first, &s.out()); + SecureTrieDB storageDB(&_db, i.second.baseRoot()); + for (auto const& j: i.second.storageOverlay()) + if (j.second) + storageDB.insert(j.first, rlp(j.second)); + else + storageDB.remove(j.first); + assert(storageDB.root()); + s.append(storageDB.root()); } } }