Kagome
Polkadot Runtime Engine in C++17
trie_serializer_impl.cpp
Go to the documentation of this file.
1 
7 
8 #include "outcome/outcome.hpp"
9 #include "storage/trie/codec.hpp"
13 
14 namespace kagome::storage::trie {
16  std::shared_ptr<PolkadotTrieFactory> factory,
17  std::shared_ptr<Codec> codec,
18  std::shared_ptr<TrieStorageBackend> backend)
19  : trie_factory_{std::move(factory)},
20  codec_{std::move(codec)},
21  backend_{std::move(backend)} {
22  BOOST_ASSERT(trie_factory_ != nullptr);
23  BOOST_ASSERT(codec_ != nullptr);
24  BOOST_ASSERT(backend_ != nullptr);
25  }
26 
28  static const auto empty_hash = codec_->hash256(common::Buffer{0});
29  return empty_hash;
30  }
31 
32  outcome::result<RootHash> TrieSerializerImpl::storeTrie(PolkadotTrie &trie) {
33  if (trie.getRoot() == nullptr) {
34  return getEmptyRootHash();
35  }
36  return storeRootNode(*trie.getRoot());
37  }
38 
39  outcome::result<std::shared_ptr<PolkadotTrie>>
42  [this](const std::shared_ptr<OpaqueTrieNode> &parent)
43  -> outcome::result<PolkadotTrie::NodePtr> {
44  OUTCOME_TRY(node, retrieveNode(parent));
45  return std::move(node);
46  };
47  if (db_key == getEmptyRootHash()) {
48  return trie_factory_->createEmpty(std::move(f));
49  }
50  OUTCOME_TRY(root, retrieveNode(db_key));
51  return trie_factory_->createFromRoot(std::move(root), std::move(f));
52  }
53 
54  outcome::result<RootHash> TrieSerializerImpl::storeRootNode(TrieNode &node) {
55  auto batch = backend_->batch();
56 
57  OUTCOME_TRY(
58  enc,
59  codec_->encodeNodeAndStoreChildren(
60  node, [&](common::BufferView hash, common::Buffer &&encoded) {
61  return batch->put(hash, std::move(encoded));
62  }));
63  auto key = codec_->hash256(enc);
64  OUTCOME_TRY(batch->put(key, enc));
65  OUTCOME_TRY(batch->commit());
66 
67  return key;
68  }
69 
70  outcome::result<PolkadotTrie::NodePtr> TrieSerializerImpl::retrieveNode(
71  const std::shared_ptr<OpaqueTrieNode> &parent) const {
72  if (auto p = std::dynamic_pointer_cast<DummyNode>(parent); p != nullptr) {
73  OUTCOME_TRY(n, retrieveNode(p->db_key));
74  return std::move(n);
75  }
76  return std::dynamic_pointer_cast<TrieNode>(parent);
77  }
78 
79  outcome::result<PolkadotTrie::NodePtr> TrieSerializerImpl::retrieveNode(
80  const common::Buffer &db_key) const {
81  if (db_key.empty() or db_key == getEmptyRootHash()) {
82  return nullptr;
83  }
84  Buffer enc;
85  if (codec_->isMerkleHash(db_key)) {
86  OUTCOME_TRY(db, backend_->load(db_key));
87  enc = std::move(db);
88  } else {
89  // `isMerkleHash(db_key) == false` means `db_key` is value itself
90  enc = db_key;
91  }
92  OUTCOME_TRY(n, codec_->decodeNode(enc));
93  return std::dynamic_pointer_cast<TrieNode>(n);
94  }
95 
96 } // namespace kagome::storage::trie
Class represents arbitrary (including empty) byte buffer.
Definition: buffer.hpp:29
std::shared_ptr< PolkadotTrieFactory > trie_factory_
outcome::result< RootHash > storeTrie(PolkadotTrie &trie) override
TrieSerializerImpl(std::shared_ptr< PolkadotTrieFactory > factory, std::shared_ptr< Codec > codec, std::shared_ptr< TrieStorageBackend > backend)
outcome::result< std::shared_ptr< PolkadotTrie > > retrieveTrie(const common::Buffer &db_key) const override
std::shared_ptr< TrieStorageBackend > backend_
std::function< outcome::result< NodePtr >(std::shared_ptr< OpaqueTrieNode > const &)> NodeRetrieveFunctor
outcome::result< PolkadotTrie::NodePtr > retrieveNode(const common::Buffer &db_key) const
outcome::result< RootHash > storeRootNode(TrieNode &node)