13 #include "scale/encode_append.hpp" 26 std::shared_ptr<runtime::TrieStorageProvider> storage_provider,
27 std::shared_ptr<const runtime::MemoryProvider> memory_provider)
28 : storage_provider_(
std::move(storage_provider)),
29 memory_provider_(
std::move(memory_provider)),
31 "child_storage_extension")} {
37 const Buffer &child_storage_key) {
41 template <
typename R,
typename F,
typename... Args>
43 const Buffer &child_storage_key, F func, Args &&...args)
const {
44 OUTCOME_TRY(prefixed_child_key,
46 OUTCOME_TRY(child_batch,
49 auto result = func(child_batch, std::forward<Args>(args)...);
55 OUTCOME_TRY(new_child_root, child_batch->commit());
57 prefixed_child_key,
Buffer{scale::encode(new_child_root).value()}));
59 "Update child trie root: prefix is {}, new root is",
63 if constexpr (!std::is_void_v<R>) {
66 return outcome::success();
70 template <
typename Arg>
73 return memory.
loadN(span_ptr, span_size);
76 template <
typename... Args>
78 return std::make_tuple(
loadBuffer(memory, std::forward<Args>(spans))...);
86 auto [child_key_buffer, key_buffer, value_buffer] =
87 loadBuffer(memory, child_storage_key, key, value);
90 logger_, child_key_buffer, key_buffer, value_buffer);
92 auto result = executeOnChildStorage<void>(
94 [](
auto &child_batch,
auto &key,
auto &value) {
95 return child_batch->put(key, value);
102 "ext_default_child_storage_set_version_1 failed with reason: {}",
103 result.error().message());
111 auto child_key_buffer =
loadBuffer(memory, child_storage_key);
116 return executeOnChildStorage<runtime::WasmSpan>(
118 [&memory, &child_key_buffer, &key_buffer,
this](
119 auto &child_batch,
auto &key) {
120 constexpr
auto error_message =
121 "ext_default_child_storage_get_version_1( {}, {} ) => " 123 "obtained. Reason: {}";
125 auto result = child_batch->tryGet(key);
128 logger_, result.value(), child_key_buffer, key_buffer);
131 child_key_buffer.toHex(),
133 result.error().message());
136 return memory.storeBuffer(
137 scale::encode(result.value()).value());
146 auto [child_key_buffer, key_buffer] =
151 auto result = executeOnChildStorage<void>(
153 [](
auto &child_batch,
auto &key) {
return child_batch->remove(key); },
158 "ext_default_child_storage_clear_version_1 failed, due to fail in " 160 "db with reason: {}",
161 result.error().message());
170 auto [child_key_buffer, key_buffer] =
172 auto prefixed_child_key =
177 auto child_batch_outcome =
179 if (child_batch_outcome.has_error()) {
181 "ext_default_child_storage_next_key_version_1 resulted with error: " 183 child_batch_outcome.error().message());
187 auto child_batch = child_batch_outcome.value();
188 auto cursor = child_batch->trieCursor();
191 auto seek_result = cursor->seekUpperBound(key_buffer);
192 if (seek_result.has_error()) {
194 "ext_default_child_storage_next_key_version_1 resulted with error: " 196 seek_result.error().message());
199 auto next_key_opt = cursor->key();
200 if (
auto enc_res = scale::encode(next_key_opt); enc_res.has_value()) {
202 next_key_opt.has_value() ? next_key_opt.value()
206 return memory.storeBuffer(enc_res.value());
209 "ext_default_child_storage_next_key_version_1 result encoding " 210 "resulted with error: {}",
211 enc_res.error().message());
219 outcome::result<storage::trie::RootHash> res{{}};
221 auto child_key_buffer =
loadBuffer(memory, child_storage_key);
224 if (
auto child_batch =
226 child_batch.has_value() and child_batch.value() !=
nullptr) {
227 res = child_batch.value()->commit();
230 "ext_default_child_storage_root called in an ephemeral extension");
234 if (res.has_error()) {
236 "ext_default_child_storage_root resulted with an error: {}",
237 res.error().message());
239 const auto &root = res.value();
241 return memory.storeBuffer(root);
247 auto [child_key_buffer, prefix_buffer] =
248 loadBuffer(memory, child_storage_key, prefix);
252 auto result = executeOnChildStorage<std::tuple<bool, uint32_t>>(
254 [](
auto &child_batch,
auto &prefix) {
255 return child_batch->clearPrefix(prefix, std::nullopt);
261 "ext_default_child_storage_clear_prefix_version_1 failed with " 263 result.error().message());
274 auto [child_key_buffer, key_buffer] =
278 auto value = executeOnChildStorage<std::optional<common::Buffer>>(
280 [](
auto &child_batch,
auto &key) {
282 child_batch->tryGet(key),
286 std::optional<uint32_t> res{std::nullopt};
287 if (
auto data_opt_res = value; data_opt_res.has_value()) {
288 auto &data_opt = data_opt_res.value();
289 if (data_opt.has_value()) {
291 data = data.subspan(std::min<size_t>(offset, data.size()));
292 auto written = std::min<size_t>(data.size(), value_size);
293 memory.storeBuffer(value_ptr, data.subspan(0, written));
303 std::string_view{
"none"},
311 "Error in ext_storage_read_version_1: {}",
312 data_opt_res.error().message());
313 throw std::runtime_error{data_opt_res.error().message()};
316 return memory.storeBuffer(scale::encode(res).value());
322 auto [child_key_buffer, key_buffer] =
327 auto res = executeOnChildStorage<bool>(
329 [](
auto &child_batch,
auto &key) {
return child_batch->contains(key); },
334 "ext_default_child_storage_exists_version_1 failed with " 336 res.error().message());
339 return (res.has_value() and res.value()) ? 1 : 0;
345 auto child_key_buffer =
loadBuffer(memory, child_storage_key);
349 auto result = executeOnChildStorage<std::tuple<bool, uint32_t>>(
350 child_key_buffer, [](
auto &child_batch) {
351 return child_batch->clearPrefix({}, std::nullopt);
356 "ext_default_child_storage_storage_kill_version_1 failed with " 358 result.error().message());
runtime::WasmSpan ext_default_child_storage_get_version_1(runtime::WasmSpan child_storage_key, runtime::WasmSpan key) const
Class represents arbitrary (including empty) byte buffer.
runtime::WasmSpan ext_default_child_storage_next_key_version_1(runtime::WasmSpan child_storage_key, runtime::WasmSpan key) const
outcome::result< Buffer > make_prefixed_child_storage_key(const Buffer &child_storage_key)
runtime::WasmSpan ext_default_child_storage_read_version_1(runtime::WasmSpan child_storage_key, runtime::WasmSpan key, runtime::WasmSpan value_out, runtime::WasmOffset offset) const
#define SL_TRACE_FUNC_CALL(logger, ret,...)
uint32_t WasmOffset
Offset type is uint32_t because we are working in 32 bit address space.
virtual common::Buffer loadN(WasmPointer addr, WasmSize n) const =0
void ext_default_child_storage_storage_kill_version_1(runtime::WasmSpan child_storage_key)
auto loadBuffer(runtime::Memory &memory, Arg &&span)
const common::Buffer kChildStorageDefaultPrefix
SLBuffer< std::numeric_limits< size_t >::max()> Buffer
void ext_default_child_storage_set_version_1(runtime::WasmSpan child_storage_key, runtime::WasmSpan key, runtime::WasmSpan value)
SLBuffer & put(std::string_view view)
Put a string into byte buffer.
std::shared_ptr< const runtime::MemoryProvider > memory_provider_
runtime::WasmSpan ext_default_child_storage_root_version_1(runtime::WasmSpan child_storage_key) const
uint64_t WasmSpan
combination of pointer and size, where less significant part represents wasm pointer, and most significant represents size
ChildStorageExtension(std::shared_ptr< runtime::TrieStorageProvider > storage_provider, std::shared_ptr< const runtime::MemoryProvider > memory_provider)
uint32_t ext_default_child_storage_exists_version_1(runtime::WasmSpan child_storage_key, runtime::WasmSpan key) const
void ext_default_child_storage_clear_prefix_version_1(runtime::WasmSpan child_storage_key, runtime::WasmSpan prefix)
std::reference_wrapper< const Buffer > BufferConstRef
outcome::result< R > executeOnChildStorage(const common::Buffer &child_storage_key, F func, Args &&...args) const
TrieError
TrieDbError enum provides error codes for TrieDb methods.
Logger createLogger(const std::string &tag)
#define SL_TRACE_VOID_FUNC_CALL(logger,...)
void ext_default_child_storage_clear_version_1(runtime::WasmSpan child_storage_key, runtime::WasmSpan key)
std::shared_ptr< runtime::TrieStorageProvider > storage_provider_
outcome::result< std::optional< R > > map_result_optional(outcome::result< std::optional< T >> const &res_opt, F const &f)