Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
lmdb_tree_store.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
21#include "lmdb.h"
22#include <cstdint>
23#include <optional>
24#include <ostream>
25#include <stdexcept>
26#include <string>
27#include <typeinfo>
28#include <unordered_map>
29#include <utility>
30
32
33using namespace bb::lmdblib;
34
36
40
42
43 bool operator==(const BlockPayload& other) const
44 {
45 return size == other.size && blockNumber == other.blockNumber && root == other.root;
46 }
47};
48
49inline std::ostream& operator<<(std::ostream& os, const BlockPayload& block)
50{
51 os << "BlockPayload{size: " << std::dec << block.size << ", blockNumber: " << std::dec << block.blockNumber
52 << ", root: " << block.root << "}";
53 return os;
54}
55
59 uint64_t ref;
60
62
63 bool operator==(const NodePayload& other) const
64 {
65 return left == other.left && right == other.right && ref == other.ref;
66 }
67};
68
70 std::vector<block_number_t> blockNumbers;
71
73
74 bool operator==(const BlockIndexPayload& other) const { return blockNumbers == other.blockNumbers; }
75
76 bool is_empty() const { return blockNumbers.empty(); }
77
79
80 void delete_block(const block_number_t& blockNumber)
81 {
82 // Shouldn't be possible, but no need to do anything here
83 if (blockNumbers.empty()) {
84 return;
85 }
86
87 // If the size is 1, the blocknumber must match that in index 0, if it does remove it
88 if (blockNumbers.size() == 1) {
89 if (blockNumbers[0] == blockNumber) {
90 blockNumbers.pop_back();
91 }
92 return;
93 }
94
95 // we have 2 entries, we must verify that the block number is equal to the item in index 1
96 if (blockNumbers[1] != blockNumber) {
97 throw std::runtime_error(format("Unable to delete block number ",
98 blockNumber,
99 " for retrieval by index, current max block number at that index: ",
100 blockNumbers[1]));
101 }
102 // It is equal, decrement it, we know that the new block number must have been added previously
103 --blockNumbers[1];
104
105 // We have modified the high block. If it is now equal to the low block then pop it
106 if (blockNumbers[0] == blockNumbers[1]) {
107 blockNumbers.pop_back();
108 }
109 }
110
111 void add_block(const block_number_t& blockNumber)
112 {
113 // If empty, just add the block number
114 if (blockNumbers.empty()) {
115 blockNumbers.emplace_back(blockNumber);
116 return;
117 }
118
119 // If the size is 1, then we must be adding the block 1 larger than that in index 0
120 if (blockNumbers.size() == 1) {
121 if (blockNumber != blockNumbers[0] + 1) {
122 // We can't accept a block number for this index that does not immediately follow the block before
123 throw std::runtime_error(format("Unable to store block number ",
124 blockNumber,
125 " for retrieval by index, current max block number at that index: ",
126 blockNumbers[0]));
127 }
128 blockNumbers.emplace_back(blockNumber);
129 return;
130 }
131
132 // Size must be 2 here, if larger, this is an error
133 if (blockNumbers.size() != 2) {
134 throw std::runtime_error(format("Unable to store block number ",
135 blockNumber,
136 " for retrieval by index, block numbers is of invalid size: ",
137 blockNumbers.size()));
138 }
139
140 // If the size is 2, then we must be adding the block 1 larger than that in index 1
141 if (blockNumber != blockNumbers[1] + 1) {
142 // We can't accept a block number for this index that does not immediately follow the block before
143 throw std::runtime_error(format("Unable to store block number ",
144 blockNumber,
145 " for retrieval by index, current max block number at that index: ",
146 blockNumbers[1]));
147 }
148 blockNumbers[1] = blockNumber;
149 }
150};
157 public:
162 LMDBTreeStore(std::string directory, std::string name, uint64_t mapSizeKb, uint64_t maxNumReaders);
163 LMDBTreeStore(const LMDBTreeStore& other) = delete;
164 LMDBTreeStore(LMDBTreeStore&& other) = delete;
165 LMDBTreeStore& operator=(const LMDBTreeStore& other) = delete;
167 ~LMDBTreeStore() override = default;
168
169 const std::string& get_name() const;
170
171 void get_stats(TreeDBStats& stats, ReadTransaction& tx);
172
173 void write_block_data(const block_number_t& blockNumber, const BlockPayload& blockData, WriteTransaction& tx);
174
175 bool read_block_data(const block_number_t& blockNumber, BlockPayload& blockData, ReadTransaction& tx);
176
177 void delete_block_data(const block_number_t& blockNumber, WriteTransaction& tx);
178
179 void write_block_index_data(const block_number_t& blockNumber, const index_t& sizeAtBlock, WriteTransaction& tx);
180
181 // index here is 0 based
182 bool find_block_for_index(const index_t& index, block_number_t& blockNumber, ReadTransaction& tx);
183
184 void delete_block_index(const index_t& sizeAtBlock, const block_number_t& blockNumber, WriteTransaction& tx);
185
186 void write_meta_data(const TreeMeta& metaData, WriteTransaction& tx);
187
188 bool read_meta_data(TreeMeta& metaData, ReadTransaction& tx);
189
190 template <typename TxType> bool read_leaf_index(const fr& leafValue, index_t& leafIndex, TxType& tx);
191
192 fr find_low_leaf(const fr& leafValue, index_t& index, const std::optional<index_t>& sizeLimit, ReadTransaction& tx);
193
194 void write_leaf_index(const fr& leafValue, const index_t& leafIndex, WriteTransaction& tx);
195
196 void delete_leaf_index(const fr& leafValue, WriteTransaction& tx);
197
198 bool read_node(const fr& nodeHash, NodePayload& nodeData, ReadTransaction& tx);
199
200 void write_node(const fr& nodeHash, const NodePayload& nodeData, WriteTransaction& tx);
201
202 void increment_node_reference_count(const fr& nodeHash, WriteTransaction& tx);
203
204 void set_or_increment_node_reference_count(const fr& nodeHash, NodePayload& nodeData, WriteTransaction& tx);
205
206 void decrement_node_reference_count(const fr& nodeHash, NodePayload& nodeData, WriteTransaction& tx);
207
208 template <typename LeafType, typename TxType>
209 bool read_leaf_by_hash(const fr& leafHash, LeafType& leafData, TxType& tx);
210
211 template <typename LeafType>
212 void write_leaf_by_hash(const fr& leafHash, const LeafType& leafData, WriteTransaction& tx);
213
214 void delete_leaf_by_hash(const fr& leafHash, WriteTransaction& tx);
215
216 private:
217 std::string _name;
223
224 template <typename TxType> bool get_node_data(const fr& nodeHash, NodePayload& nodeData, TxType& tx);
225};
226
227template <typename TxType> bool LMDBTreeStore::read_leaf_index(const fr& leafValue, index_t& leafIndex, TxType& tx)
228{
229 FrKeyType key(leafValue);
230 return tx.template get_value<FrKeyType>(key, leafIndex, *_leafKeyToIndexDatabase);
231}
232
233template <typename LeafType, typename TxType>
234bool LMDBTreeStore::read_leaf_by_hash(const fr& leafHash, LeafType& leafData, TxType& tx)
235{
236 FrKeyType key(leafHash);
237 std::vector<uint8_t> data;
238 bool success = tx.template get_value<FrKeyType>(key, data, *_leafHashToPreImageDatabase);
239 if (success) {
240 msgpack::unpack((const char*)data.data(), data.size()).get().convert(leafData);
241 }
242 return success;
243}
244
245template <typename LeafType>
246void LMDBTreeStore::write_leaf_by_hash(const fr& leafHash, const LeafType& leafData, WriteTransaction& tx)
247{
248 msgpack::sbuffer buffer;
249 msgpack::pack(buffer, leafData);
250 std::vector<uint8_t> encoded(buffer.data(), buffer.data() + buffer.size());
251 FrKeyType key(leafHash);
253}
254
255template <typename TxType> bool LMDBTreeStore::get_node_data(const fr& nodeHash, NodePayload& nodeData, TxType& tx)
256{
257 FrKeyType key(nodeHash);
258 std::vector<uint8_t> data;
259 bool success = tx.template get_value<FrKeyType>(key, data, *_nodeDatabase);
260 if (success) {
261 msgpack::unpack((const char*)data.data(), data.size()).get().convert(nodeData);
262 }
263 return success;
264}
265} // namespace bb::crypto::merkle_tree
void write_leaf_by_hash(const fr &leafHash, const LeafType &leafData, WriteTransaction &tx)
void set_or_increment_node_reference_count(const fr &nodeHash, NodePayload &nodeData, WriteTransaction &tx)
LMDBTreeStore(const LMDBTreeStore &other)=delete
std::shared_ptr< LMDBTreeStore > SharedPtr
bool get_node_data(const fr &nodeHash, NodePayload &nodeData, TxType &tx)
std::unique_ptr< LMDBTreeStore > Ptr
void delete_block_data(const block_number_t &blockNumber, WriteTransaction &tx)
bool find_block_for_index(const index_t &index, block_number_t &blockNumber, ReadTransaction &tx)
void write_node(const fr &nodeHash, const NodePayload &nodeData, WriteTransaction &tx)
void write_block_data(const block_number_t &blockNumber, const BlockPayload &blockData, WriteTransaction &tx)
void write_leaf_index(const fr &leafValue, const index_t &leafIndex, WriteTransaction &tx)
void delete_block_index(const index_t &sizeAtBlock, const block_number_t &blockNumber, WriteTransaction &tx)
bool read_node(const fr &nodeHash, NodePayload &nodeData, ReadTransaction &tx)
const std::string & get_name() const
void delete_leaf_by_hash(const fr &leafHash, WriteTransaction &tx)
void decrement_node_reference_count(const fr &nodeHash, NodePayload &nodeData, WriteTransaction &tx)
LMDBTreeStore & operator=(LMDBTreeStore &&other)=delete
void write_meta_data(const TreeMeta &metaData, WriteTransaction &tx)
bool read_block_data(const block_number_t &blockNumber, BlockPayload &blockData, ReadTransaction &tx)
void get_stats(TreeDBStats &stats, ReadTransaction &tx)
LMDBTreeStore(LMDBTreeStore &&other)=delete
LMDBTreeStore & operator=(const LMDBTreeStore &other)=delete
bool read_leaf_by_hash(const fr &leafHash, LeafType &leafData, TxType &tx)
void write_block_index_data(const block_number_t &blockNumber, const index_t &sizeAtBlock, WriteTransaction &tx)
void delete_leaf_index(const fr &leafValue, WriteTransaction &tx)
void increment_node_reference_count(const fr &nodeHash, WriteTransaction &tx)
fr find_low_leaf(const fr &leafValue, index_t &index, const std::optional< index_t > &sizeLimit, ReadTransaction &tx)
bool read_meta_data(TreeMeta &metaData, ReadTransaction &tx)
bool read_leaf_index(const fr &leafValue, index_t &leafIndex, TxType &tx)
std::unique_ptr< LMDBDatabase > Ptr
void put_value(T &key, Value &data, const LMDBDatabase &db)
std::string format(Args... args)
Definition log.hpp:23
const std::vector< MemoryValue > data
std::unique_ptr< uint8_t[]> buffer
Definition engine.cpp:50
#define MSGPACK_FIELDS(...)
Definition msgpack.hpp:121
uint32_t block_number_t
Definition types.hpp:19
std::ostream & operator<<(std::ostream &os, const BlockPayload &block)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
void add_block(const block_number_t &blockNumber)
void delete_block(const block_number_t &blockNumber)
std::vector< block_number_t > blockNumbers