Browse Source

New SecureTrie.

cl-refactor
Gav Wood 10 years ago
parent
commit
5ac16c53f3
  1. 92
      libdevcrypto/TrieDB.h
  2. 11
      libethcore/Common.cpp
  3. 28
      libethereum/State.cpp
  4. 38
      libethereum/State.h

92
libdevcrypto/TrieDB.h

@ -334,20 +334,19 @@ std::ostream& operator<<(std::ostream& _out, SpecificTrieDB<Generic, KeyType> co
return _out; return _out;
} }
template <class _DB> template <class DB>
class HashedGenericTrieDB: private SpecificTrieDB<GenericTrieDB<_DB>, h256> class SecureGenericTrieDB: private TrieDB<h256, DB>
{ {
using Super = SpecificTrieDB<GenericTrieDB<_DB>, h256>; using Super = TrieDB<h256, DB>;
public: public:
using DB = _DB; SecureGenericTrieDB(DB* _db): Super(_db) {}
SecureGenericTrieDB(DB* _db, h256 _root): Super(_db, _root) {}
HashedGenericTrieDB(DB* _db = nullptr): Super(_db) {}
HashedGenericTrieDB(DB* _db, h256 _root): Super(_db, _root) {}
using Super::open; using Super::open;
using Super::init; using Super::init;
using Super::setRoot; using Super::setRoot;
using Super::haveRoot;
/// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node). /// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node).
using Super::isNull; using Super::isNull;
@ -360,84 +359,29 @@ public:
using Super::check; using Super::check;
std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); } 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 insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(sha3(_key), _value); }
void remove(bytesConstRef _key) { Super::remove(sha3(_key)); } void remove(bytesConstRef _key) { Super::remove(sha3(_key)); }
bool contains(bytesConstRef _key) { return Super::contains(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<bytesConstRef, bytesConstRef>;
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(); }
}; };
// Hashed & Basic template <class KeyType, class DB>
template <class DB> class SecureTrieDB: public SecureGenericTrieDB<DB>
class FatGenericTrieDB: public GenericTrieDB<DB>
{ {
using Super = GenericTrieDB<DB>; using Super = SecureGenericTrieDB<DB>;
public: public:
FatGenericTrieDB(DB* _db): Super(_db), m_secure(_db) {} SecureTrieDB(DB* _db): Super(_db) {}
FatGenericTrieDB(DB* _db, h256 _root) { open(_db, _root); } SecureTrieDB(DB* _db, h256 _root): Super(_db, _root) {}
void open(DB* _db, h256 _root) { Super::open(_db); m_secure.open(_db); setRoot(_root); } std::string operator[](KeyType _k) const { return at(_k); }
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<h256> 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());
}
HashedGenericTrieDB<DB> 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 <class KeyType, class DB> using TrieDB = SpecificTrieDB<GenericTrieDB<DB>, KeyType>;
#if ETH_FATDB
template <class KeyType, class DB> using SecureTrieDB = SpecificTrieDB<FatGenericTrieDB<DB>, KeyType>;
#else
template <class KeyType, class DB> using SecureTrieDB = SpecificTrieDB<HashedGenericTrieDB<DB>, KeyType>;
#endif
} }
// Template implementations... // Template implementations...

11
libethcore/Common.cpp

@ -32,15 +32,8 @@ namespace dev
namespace eth namespace eth
{ {
const unsigned c_protocolVersion = 56; const unsigned c_protocolVersion = 55;
const unsigned c_databaseBaseVersion = 7; const unsigned c_databaseVersion = 5;
#if ETH_FATDB
const unsigned c_databaseVersionModifier = 1000;
#else
const unsigned c_databaseVersionModifier = 0;
#endif
const unsigned c_databaseVersion = c_databaseBaseVersion + c_databaseVersionModifier;
vector<pair<u256, string>> const& units() vector<pair<u256, string>> const& units()
{ {

28
libethereum/State.cpp

@ -180,10 +180,11 @@ StateDiff State::diff(State const& _c) const
auto trie = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&m_db), rootHash()); auto trie = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&m_db), rootHash());
auto trieD = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&_c.m_db), _c.rootHash()); auto trieD = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&_c.m_db), _c.rootHash());
for (auto i: trie) // TODO: fix
ads.insert(i.first), trieAds.insert(i.first); // for (auto i: trie)
for (auto i: trieD) // ads.insert(i.first), trieAds.insert(i.first);
ads.insert(i.first), trieAdsD.insert(i.first); // for (auto i: trieD)
// ads.insert(i.first), trieAdsD.insert(i.first);
for (auto i: m_cache) for (auto i: m_cache)
ads.insert(i.first); ads.insert(i.first);
for (auto i: _c.m_cache) for (auto i: _c.m_cache)
@ -345,9 +346,10 @@ map<Address, u256> State::addresses() const
for (auto i: m_cache) for (auto i: m_cache)
if (i.second.isAlive()) if (i.second.isAlive())
ret[i.first] = i.second.balance(); ret[i.first] = i.second.balance();
for (auto const& i: m_state) // TODO: fix.
if (m_cache.find(i.first) == m_cache.end()) // for (auto const& i: m_state)
ret[i.first] = RLP(i.second)[1].toInt<u256>(); // if (m_cache.find(i.first) == m_cache.end())
// ret[i.first] = RLP(i.second)[1].toInt<u256>();
return ret; return ret;
} }
@ -952,9 +954,10 @@ map<u256, u256> State::storage(Address _id) const
// Pull out all values from trie storage. // Pull out all values from trie storage.
if (it->second.baseRoot()) if (it->second.baseRoot())
{ {
SecureTrieDB<h256, OverlayDB> memdb(const_cast<OverlayDB*>(&m_db), it->second.baseRoot()); // promise we won't alter the overlay! :) // TODO: fix
for (auto const& i: memdb) // SecureTrieDB<h256, OverlayDB> memdb(const_cast<OverlayDB*>(&m_db), it->second.baseRoot()); // promise we won't alter the overlay! :)
ret[i.first] = RLP(i.second).toInt<u256>(); // for (auto const& i: memdb)
// ret[i.first] = RLP(i.second).toInt<u256>();
} }
// Then merge cached storage over the top. // Then merge cached storage over the top.
@ -1190,8 +1193,9 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, State const& _s)
if (r) if (r)
{ {
SecureTrieDB<h256, OverlayDB> memdb(const_cast<OverlayDB*>(&_s.m_db), r[2].toHash<h256>()); // promise we won't alter the overlay! :) SecureTrieDB<h256, OverlayDB> memdb(const_cast<OverlayDB*>(&_s.m_db), r[2].toHash<h256>()); // promise we won't alter the overlay! :)
for (auto const& j: memdb) // TODO: fix
mem[j.first] = RLP(j.second).toInt<u256>(), back.insert(j.first); // for (auto const& j: memdb)
// mem[j.first] = RLP(j.second).toInt<u256>(), back.insert(j.first);
} }
if (cache) if (cache)
for (auto const& j: cache->storageOverlay()) for (auto const& j: cache->storageOverlay())

38
libethereum/State.h

@ -334,36 +334,14 @@ void commit(std::map<Address, Account> const& _cache, DB& _db, SecureTrieDB<Addr
_state.remove(i.first); _state.remove(i.first);
else else
{ {
RLPStream s(4); SecureTrieDB<h256, DB> storageDB(&_db, i.second.baseRoot());
s << i.second.nonce() << i.second.balance(); for (auto const& j: i.second.storageOverlay())
if (j.second)
if (i.second.storageOverlay().empty()) storageDB.insert(j.first, rlp(j.second));
{ else
assert(i.second.baseRoot()); storageDB.remove(j.first);
s.append(i.second.baseRoot()); assert(storageDB.root());
} s.append(storageDB.root());
else
{
SecureTrieDB<h256, DB> 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());
} }
} }
} }

Loading…
Cancel
Save