Kagome
Polkadot Runtime Engine in C++17
trie_storage_provider_impl.cpp
Go to the documentation of this file.
1 
7 
11 
14  e) {
16  switch (e) {
17  case E::NO_BATCH:
18  return "Batch was not created or already was destructed.";
19  }
20  return "Unknown error";
21 }
22 
23 namespace kagome::runtime {
24  using storage::trie::TopperTrieBatch;
25  using storage::trie::TopperTrieBatchImpl;
26  using storage::trie::TrieSerializer;
27  using storage::trie::TrieStorage;
28 
30  std::shared_ptr<TrieStorage> trie_storage,
31  std::shared_ptr<TrieSerializer> trie_serializer)
32  : trie_storage_{std::move(trie_storage)},
33  trie_serializer_{std::move(trie_serializer)},
34  logger_{log::createLogger("TrieStorageProvider", "runtime_api")} {
35  BOOST_ASSERT(trie_storage_ != nullptr);
36  }
37 
39  const common::Hash256 &state_root) {
40  SL_DEBUG(logger_,
41  "Setting storage provider to ephemeral batch with root {}",
42  state_root.toHex());
43  OUTCOME_TRY(batch, trie_storage_->getEphemeralBatchAt(state_root));
44  current_batch_ = std::move(batch);
45  return outcome::success();
46  }
47 
49  const common::Hash256 &state_root) {
50  SL_DEBUG(logger_,
51  "Setting storage provider to new persistent batch with root {}",
52  state_root.toHex());
53  OUTCOME_TRY(batch, trie_storage_->getPersistentBatchAt(state_root));
54  persistent_batch_ = std::move(batch);
56  return outcome::success();
57  }
58 
59  std::shared_ptr<TrieStorageProviderImpl::Batch>
61  return current_batch_;
62  }
63 
64  std::optional<std::shared_ptr<TrieStorageProviderImpl::PersistentBatch>>
66  return isCurrentlyPersistent() ? std::make_optional(persistent_batch_)
67  : std::nullopt;
68  }
69 
71  return std::dynamic_pointer_cast<PersistentBatch>(current_batch_)
72  != nullptr;
73  }
74 
75  outcome::result<std::shared_ptr<TrieStorageProvider::PersistentBatch>>
77  if (!child_batches_.count(root_path)) {
78  SL_DEBUG(logger_,
79  "Creating new persistent batch for child storage {}",
80  root_path.toHex());
81  OUTCOME_TRY(child_root_value, getCurrentBatch()->tryGet(root_path));
82  auto child_root_hash =
83  child_root_value ? common::Hash256::fromSpan(
84  gsl::make_span(child_root_value.value().get()))
85  .value()
86  : trie_serializer_->getEmptyRootHash();
87  OUTCOME_TRY(child_batch,
88  trie_storage_->getPersistentBatchAt(child_root_hash));
89  child_batches_.emplace(root_path, std::move(child_batch));
90  }
91  SL_DEBUG(logger_,
92  "Fetching persistent batch for child storage {}",
93  root_path.toHex());
94  return child_batches_.at(root_path);
95  }
96 
98  child_batches_.clear();
99  }
100 
101  outcome::result<storage::trie::RootHash>
103  if (persistent_batch_) {
104  return persistent_batch_->commit();
105  }
106  if (auto ephemeral =
107  std::dynamic_pointer_cast<storage::trie::EphemeralTrieBatch>(
108  current_batch_)) {
109  // won't actually write any data to the storage but will calculate the
110  // root hash for the state represented by the batch
111  OUTCOME_TRY(root, ephemeral->hash());
112  SL_TRACE(logger_, "Force commit ephemeral batch, root: {}", root);
113  return std::move(root);
114  }
115  return Error::NO_BATCH;
116  }
117 
120  SL_TRACE(logger_,
121  "Start storage transaction, depth {}",
122  stack_of_batches_.size());
124  std::make_shared<TopperTrieBatchImpl>(std::move(current_batch_));
125  return outcome::success();
126  }
127 
129  if (stack_of_batches_.empty()) {
131  }
132 
133  current_batch_ = std::move(stack_of_batches_.top());
134  SL_TRACE(logger_,
135  "Rollback storage transaction, depth {}",
136  stack_of_batches_.size());
137  stack_of_batches_.pop();
138  return outcome::success();
139  }
140 
142  if (stack_of_batches_.empty()) {
144  }
145 
146  auto commitee_batch =
147  std::dynamic_pointer_cast<TopperTrieBatch>(current_batch_);
148  BOOST_ASSERT(commitee_batch != nullptr);
149  OUTCOME_TRY(commitee_batch->writeBack());
150 
151  current_batch_ = std::move(stack_of_batches_.top());
152  SL_TRACE(logger_,
153  "Commit storage transaction, depth {}",
154  stack_of_batches_.size());
155  stack_of_batches_.pop();
156  return outcome::success();
157  }
158 
159 } // namespace kagome::runtime
Class represents arbitrary (including empty) byte buffer.
Definition: buffer.hpp:29
outcome::result< void > commitTransaction() override
Commit and finish last started transaction.
std::shared_ptr< PersistentBatch > persistent_batch_
outcome::result< void > startTransaction() override
Start nested transaction.
outcome::result< std::shared_ptr< PersistentBatch > > getChildBatchAt(const common::Buffer &root_path) override
Get (or create new) Child Batch with given root hash.
outcome::result< void > setToPersistentAt(const common::Hash256 &state_root) override
outcome::result< void > setToEphemeralAt(const common::Hash256 &state_root) override
std::shared_ptr< storage::trie::TrieSerializer > trie_serializer_
gsl::span< const uint8_t > make_span(const rocksdb::Slice &s)
std::string toHex() const
encode bytearray as hex
Definition: buffer.hpp:167
static outcome::result< Blob< size_ > > fromSpan(const gsl::span< const uint8_t > &span)
Definition: blob.hpp:208
std::shared_ptr< storage::trie::TrieStorage > trie_storage_
std::string toHex() const noexcept
Definition: blob.hpp:160
std::unordered_map< common::Buffer, std::shared_ptr< PersistentBatch > > child_batches_
std::stack< std::shared_ptr< Batch > > stack_of_batches_
std::shared_ptr< Batch > getCurrentBatch() const override
outcome::result< void > rollbackTransaction() override
Rollback and finish last started transaction.
std::optional< std::shared_ptr< PersistentBatch > > tryGetPersistentBatch() const override
OUTCOME_CPP_DEFINE_CATEGORY(kagome::runtime, TrieStorageProviderImpl::Error, e)
Logger createLogger(const std::string &tag)
Definition: logger.cpp:112
TrieStorageProviderImpl(std::shared_ptr< storage::trie::TrieStorage > trie_storage, std::shared_ptr< storage::trie::TrieSerializer > trie_serializer)
outcome::result< storage::trie::RootHash > forceCommit() override
storage::trie::PersistentTrieBatch PersistentBatch