Kagome
Polkadot Runtime Engine in C++17
storage_util.cpp
Go to the documentation of this file.
1 
7 
10 
16 
19  switch (e) {
20  case E::INVALID_KEY:
21  return "Invalid storage key";
22  }
23  return "Unknown error";
24 }
25 
26 namespace kagome::blockchain {
27 
28  outcome::result<void> putNumberToIndexKey(
29  storage::BufferStorage &map, const primitives::BlockInfo &block) {
30  auto num_to_idx_key =
32  auto block_lookup_key = numberAndHashToLookupKey(block.number, block.hash);
33  return map.put(num_to_idx_key, block_lookup_key);
34  }
35 
36  outcome::result<void> putWithPrefix(storage::BufferStorage &map,
37  prefix::Prefix prefix,
38  BlockNumber num,
39  Hash256 block_hash,
40  const common::Buffer &value) {
41  auto block_lookup_key = numberAndHashToLookupKey(num, block_hash);
42 
43  auto hash_to_idx_key = prependPrefix(block_hash, Prefix::ID_TO_LOOKUP_KEY);
44  OUTCOME_TRY(map.put(hash_to_idx_key, block_lookup_key));
45 
46  auto value_lookup_key = prependPrefix(block_lookup_key, prefix);
47 
48  return map.put(value_lookup_key, value);
49  }
50 
51  outcome::result<bool> hasWithPrefix(const storage::BufferStorage &map,
52  prefix::Prefix prefix,
53  const primitives::BlockId &block_id) {
54  OUTCOME_TRY(key, idToLookupKey(map, block_id));
55  if (!key.has_value()) return false;
56  return map.contains(prependPrefix(key.value(), prefix));
57  }
58 
59  outcome::result<std::optional<common::Buffer>> getWithPrefix(
60  const storage::BufferStorage &map,
61  prefix::Prefix prefix,
62  const primitives::BlockId &block_id) {
63  OUTCOME_TRY(key, idToLookupKey(map, block_id));
64  if (!key.has_value()) return std::nullopt;
65  return map.tryLoad(prependPrefix(key.value(), prefix));
66  }
67 
69  // TODO(Harrm) Figure out why exactly it is this way in substrate
70  BOOST_ASSERT((n & 0xffffffff00000000) == 0);
71 
72  return {uint8_t(n >> 24u),
73  uint8_t((n >> 16u) & 0xffu),
74  uint8_t((n >> 8u) & 0xffu),
75  uint8_t(n & 0xffu)};
76  }
77 
79  const common::Hash256 &hash) {
80  auto lookup_key = numberToIndexKey(number);
81  lookup_key.put(hash);
82  return lookup_key;
83  }
84 
85  outcome::result<primitives::BlockNumber> lookupKeyToNumber(
86  const common::BufferView &key) {
87  if (key.size() < 4) {
88  return outcome::failure(KeyValueRepositoryError::INVALID_KEY);
89  }
90  return (uint64_t(key[0]) << 24u) | (uint64_t(key[1]) << 16u)
91  | (uint64_t(key[2]) << 8u) | uint64_t(key[3]);
92  }
93 
95  prefix::Prefix key_column) {
96  return common::Buffer{}
97  .reserve(key.size() + 1)
98  .putUint8(key_column)
99  .put(key);
100  }
101 
102 } // namespace kagome::blockchain
Class represents arbitrary (including empty) byte buffer.
Definition: buffer.hpp:29
outcome::result< primitives::BlockNumber > lookupKeyToNumber(const common::BufferView &key)
Blob< 32 > Hash256
Definition: blob.hpp:230
common::Buffer numberAndHashToLookupKey(primitives::BlockNumber number, const common::Hash256 &hash)
outcome::result< std::optional< common::Buffer > > idToLookupKey(const ReadableBufferStorage &map, const primitives::BlockId &id)
Definition: common.cpp:15
common::Buffer numberToIndexKey(primitives::BlockNumber n)
outcome::result< void > putWithPrefix(storage::BufferStorage &map, prefix::Prefix prefix, BlockNumber num, Hash256 block_hash, const common::Buffer &value)
outcome::result< void > putNumberToIndexKey(storage::BufferStorage &map, const primitives::BlockInfo &block)
uint32_t BlockNumber
Definition: common.hpp:18
SLBuffer< std::numeric_limits< size_t >::max()> Buffer
Definition: buffer.hpp:244
SLBuffer & put(std::string_view view)
Put a string into byte buffer.
Definition: buffer.hpp:117
primitives::BlockNumber BlockNumber
Definition: common.hpp:24
SLBuffer & reserve(size_t size)
Definition: buffer.hpp:61
outcome::result< std::optional< common::Buffer > > getWithPrefix(const storage::BufferStorage &map, prefix::Prefix prefix, const primitives::BlockId &block_id)
virtual outcome::result< void > put(const K &key, const V &value)=0
Store value by key.
virtual outcome::result< bool > contains(const Key &key) const =0
Checks if given key-value binding exists in the storage.
boost::variant< BlockHash, BlockNumber > BlockId
Block id is the variant over BlockHash and BlockNumber.
Definition: block_id.hpp:18
outcome::result< bool > hasWithPrefix(const storage::BufferStorage &map, prefix::Prefix prefix, const primitives::BlockId &block_id)
OUTCOME_CPP_DEFINE_CATEGORY(kagome::blockchain, KeyValueRepositoryError, e)
common::Buffer prependPrefix(common::BufferView key, prefix::Prefix key_column)
virtual outcome::result< std::optional< V > > tryLoad(const Key &key) const =0
Load value by key.