diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index eec988d76..dceb1d70a 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -65,10 +65,10 @@ public: FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); } /// Explicitly construct, copying from a byte array. - explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } } + explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else if (_t != FailIfDifferent) { m_data.fill(0); auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } /// Explicitly construct, copying from a byte array. - explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } } + explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else if (_t != FailIfDifferent) { m_data.fill(0); auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } /// Explicitly construct, copying from a bytes in memory with given pointer. explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); } diff --git a/libdevcrypto/MemoryDB.h b/libdevcrypto/MemoryDB.h index 7d39ba73b..2f4233f01 100644 --- a/libdevcrypto/MemoryDB.h +++ b/libdevcrypto/MemoryDB.h @@ -51,9 +51,8 @@ public: bool kill(h256 _h); void purge(); - bytes lookupAux(h256 _h) const { auto h = aux(_h); return m_aux.count(h) ? m_aux.at(h) : bytes(); } - void removeAux(h256 _h) { m_auxActive.erase(aux(_h)); } - void insertAux(h256 _h, bytesConstRef _v) { auto h = aux(_h); m_auxActive.insert(h); m_aux[h] = _v.toBytes(); } + bytes lookupAux(h256 _h) const { return asBytes(lookup(h256(sha3(_h).ref().cropped(16), h256::AlignRight))); } + void insertAux(h256 _h, bytesConstRef _v) { return insert(h256(sha3(_h).ref().cropped(16), h256::AlignRight), _v); } std::set keys() const; diff --git a/libdevcrypto/TrieDB.h b/libdevcrypto/TrieDB.h index 79852304c..91a39b3cc 100644 --- a/libdevcrypto/TrieDB.h +++ b/libdevcrypto/TrieDB.h @@ -68,7 +68,7 @@ class GenericTrieDB public: using DB = _DB; - GenericTrieDB(DB* _db = nullptr): m_db(_db) {} + GenericTrieDB(DB* _db): m_db(_db) {} GenericTrieDB(DB* _db, h256 _root) { open(_db, _root); } ~GenericTrieDB() {} @@ -294,7 +294,7 @@ public: using DB = typename Generic::DB; using KeyType = _KeyType; - SpecificTrieDB(DB* _db = nullptr): Generic(_db) {} + SpecificTrieDB(DB* _db): Generic(_db) {} SpecificTrieDB(DB* _db, h256 _root): Generic(_db, _root) {} std::string operator[](KeyType _k) const { return at(_k); } @@ -334,19 +334,20 @@ std::ostream& operator<<(std::ostream& _out, SpecificTrieDB co return _out; } -template -class SecureGenericTrieDB: private TrieDB +template +class HashedGenericTrieDB: private SpecificTrieDB, h256> { - using Super = TrieDB; + using Super = SpecificTrieDB, h256>; public: - SecureGenericTrieDB(DB* _db): Super(_db) {} - SecureGenericTrieDB(DB* _db, h256 _root): Super(_db, _root) {} + using DB = _DB; + + HashedGenericTrieDB(DB* _db): Super(_db) {} + HashedGenericTrieDB(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; @@ -359,29 +360,63 @@ 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)); } - bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); } + + // empty from the PoV of the iterator interface. + using iterator = void*; + iterator begin() const { return nullptr; } + iterator end() const { return nullptr; } + iterator lower_bound(bytesConstRef) const { return end(); } }; -template -class SecureTrieDB: public SecureGenericTrieDB +// Hashed & Basic +template +class FatGenericTrieDB: public GenericTrieDB { - using Super = SecureGenericTrieDB; + using Super = GenericTrieDB; public: - SecureTrieDB(DB* _db): Super(_db) {} - SecureTrieDB(DB* _db, h256 _root): Super(_db, _root) {} + FatGenericTrieDB(DB* _db): Super(_db), m_secure(_db) {} + FatGenericTrieDB(DB* _db, h256 _root) { open(_db, _root); } - std::string operator[](KeyType _k) const { return at(_k); } + void open(DB* _db, h256 _root) { Super::open(_db); m_secure.open(_db); setRoot(_root); } - 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))); } + void init() { Super::init(); m_secure.init(); syncRoot(); } + + void setRoot(h256 _root) + { + m_secure.setRoot(_root); + Super::setRoot(h256(Super::db()->lookupAux(m_secure.root()))); + } + + 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()); + } + + HashedGenericTrieDB m_secure; }; +template using TrieDB = SpecificTrieDB, KeyType>; + +#if ETH_FAT_DB +template using SecureTrieDB = SpecificTrieDB, KeyType>; +#else +template using SecureTrieDB = SpecificTrieDB, KeyType>; +#endif + } // Template implementations...