8 #include <boost/algorithm/string/predicate.hpp> 9 #include <unordered_map> 19 std::shared_ptr<blockchain::BlockHeaderRepository> block_repo,
20 std::shared_ptr<const storage::trie::TrieStorage> trie_storage,
21 std::shared_ptr<blockchain::BlockTree> block_tree,
22 std::shared_ptr<runtime::Core> runtime_core,
23 std::shared_ptr<runtime::Metadata> metadata)
24 : header_repo_{std::move(block_repo)},
37 const std::shared_ptr<api::ApiService> &api_service) {
38 BOOST_ASSERT(api_service !=
nullptr);
44 const std::optional<common::Buffer> &prefix_opt,
45 const std::optional<primitives::BlockHash> &block_hash_opt)
const {
47 const auto &block_hash =
48 block_hash_opt.value_or(
block_tree_->getLastFinalized().hash);
50 OUTCOME_TRY(header,
header_repo_->getBlockHeader(block_hash));
51 OUTCOME_TRY(initial_trie_reader,
52 storage_->getEphemeralBatchAt(header.state_root));
53 OUTCOME_TRY(child_root, initial_trie_reader->get(child_storage_key));
54 OUTCOME_TRY(child_root_hash,
56 OUTCOME_TRY(child_storage_trie_reader,
57 storage_->getEphemeralBatchAt(child_root_hash));
58 auto cursor = child_storage_trie_reader->trieCursor();
60 OUTCOME_TRY(cursor->seekLowerBound(prefix));
62 std::vector<common::Buffer> result{};
63 while (cursor->isValid()) {
64 auto key = cursor->key();
65 BOOST_ASSERT(key.has_value());
68 if (!boost::starts_with(key.value(), prefix)) {
71 result.push_back(cursor->key().value());
72 OUTCOME_TRY(cursor->next());
80 const std::optional<common::Buffer> &prefix_opt,
82 const std::optional<common::Buffer> &prev_key_opt,
83 const std::optional<primitives::BlockHash> &block_hash_opt)
const {
85 const auto &prev_key = prev_key_opt.value_or(prefix);
86 const auto &block_hash =
87 block_hash_opt.value_or(
block_tree_->getLastFinalized().hash);
89 OUTCOME_TRY(header,
header_repo_->getBlockHeader(block_hash));
90 OUTCOME_TRY(initial_trie_reader,
91 storage_->getEphemeralBatchAt(header.state_root));
92 OUTCOME_TRY(child_root, initial_trie_reader->get(child_storage_key));
93 OUTCOME_TRY(child_root_hash,
95 OUTCOME_TRY(child_storage_trie_reader,
96 storage_->getEphemeralBatchAt(child_root_hash));
97 auto cursor = child_storage_trie_reader->trieCursor();
101 if (prev_key > prefix) {
102 OUTCOME_TRY(cursor->seekUpperBound(prev_key));
106 OUTCOME_TRY(cursor->seekLowerBound(prefix));
109 std::vector<common::Buffer> result{};
110 result.reserve(keys_amount);
111 for (uint32_t i = 0; i < keys_amount && cursor->isValid(); ++i) {
112 auto key = cursor->key();
113 BOOST_ASSERT(key.has_value());
116 if (!boost::starts_with(key.value(), prefix)) {
119 result.push_back(cursor->key().value());
120 OUTCOME_TRY(cursor->next());
129 const std::optional<primitives::BlockHash> &block_hash_opt)
const {
130 auto at = block_hash_opt ? block_hash_opt.value()
133 OUTCOME_TRY(trie_reader,
storage_->getEphemeralBatchAt(header.state_root));
134 OUTCOME_TRY(child_root, trie_reader->get(child_storage_key));
135 OUTCOME_TRY(child_root_hash,
137 OUTCOME_TRY(child_storage_trie_reader,
138 storage_->getEphemeralBatchAt(child_root_hash));
139 auto res = child_storage_trie_reader->tryGet(key);
141 [](
const auto &r) {
return r.get(); });
144 outcome::result<std::optional<primitives::BlockHash>>
148 const std::optional<primitives::BlockHash> &block_hash_opt)
const {
149 OUTCOME_TRY(value_opt,
getStorage(child_storage_key, key, block_hash_opt));
150 if (value_opt.has_value()) {
152 auto hash = codec.
hash256(value_opt.value());
161 const std::optional<primitives::BlockHash> &block_hash_opt)
const {
162 auto at = block_hash_opt ? block_hash_opt.value()
165 OUTCOME_TRY(trie_reader,
storage_->getEphemeralBatchAt(header.state_root));
166 OUTCOME_TRY(child_root, trie_reader->get(child_storage_key));
167 OUTCOME_TRY(child_root_hash,
169 OUTCOME_TRY(child_storage_trie_reader,
170 storage_->getEphemeralBatchAt(child_root_hash));
171 OUTCOME_TRY(value, child_storage_trie_reader->get(key));
172 return value.get().size();
Class represents arbitrary (including empty) byte buffer.
std::shared_ptr< blockchain::BlockTree > block_tree_
std::weak_ptr< api::ApiService > api_service_
outcome::result< std::optional< common::Buffer > > getStorage(const common::Buffer &child_storage_key, const common::Buffer &key, const std::optional< primitives::BlockHash > &block_hash_opt) const override
Returns a child storage entry.
std::shared_ptr< blockchain::BlockHeaderRepository > header_repo_
std::shared_ptr< runtime::Metadata > metadata_
ChildStateApiImpl(std::shared_ptr< blockchain::BlockHeaderRepository > block_repo, std::shared_ptr< const storage::trie::TrieStorage > trie_storage, std::shared_ptr< blockchain::BlockTree > block_tree, std::shared_ptr< runtime::Core > runtime_core, std::shared_ptr< runtime::Metadata > metadata)
std::shared_ptr< const storage::trie::TrieStorage > storage_
std::shared_ptr< runtime::Core > runtime_core_
outcome::result< std::vector< common::Buffer > > getKeysPaged(const common::Buffer &child_storage_key, const std::optional< common::Buffer > &prefix_opt, uint32_t keys_amount, const std::optional< common::Buffer > &prev_key_opt, const std::optional< primitives::BlockHash > &block_hash_opt) const override
Warning: This method is UNSAFE. Returns the keys from the specified child storage. Paginated version of getKeys. The keys can also be filtered based on a prefix.
outcome::result< std::vector< common::Buffer > > getKeys(const common::Buffer &child_storage_key, const std::optional< common::Buffer > &prefix_opt, const std::optional< primitives::BlockHash > &block_hash_opt) const override
Warning: This method is UNSAFE. Returns the keys from the specified child storage. The keys can also be filtered based on a prefix.
void setApiService(const std::shared_ptr< api::ApiService > &api_service) override
gsl::span< const uint8_t > make_span(const rocksdb::Slice &s)
static outcome::result< Blob< size_ > > fromSpan(const gsl::span< const uint8_t > &span)
common::Hash256 hash256(const BufferView &buf) const override
Get the hash of a node.
static const Buffer kEmptyBuffer
outcome::result< std::optional< primitives::BlockHash > > getStorageHash(const common::Buffer &child_storage_key, const common::Buffer &key, const std::optional< primitives::BlockHash > &block_hash_opt) const override
Returns the hash of a child storage entry.
outcome::result< std::optional< uint64_t > > getStorageSize(const common::Buffer &child_storage_key, const common::Buffer &key, const std::optional< primitives::BlockHash > &block_hash_opt) const override
Returns the size of a child storage entry.
outcome::result< std::optional< R > > map_result_optional(outcome::result< std::optional< T >> const &res_opt, F const &f)