Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
wsdb_execute.cpp
Go to the documentation of this file.
5#include <optional>
6#include <stdexcept>
7
8namespace bb::wsdb {
9
10using namespace bb::world_state;
11using namespace bb::crypto::merkle_tree;
12
13// ---------------------------------------------------------------------------
14// Helper: serialize a value to msgpack bytes
15// ---------------------------------------------------------------------------
16
17template <typename T> static std::vector<uint8_t> serialize_to_msgpack(const T& value)
18{
19 msgpack::sbuffer buf;
20 msgpack::pack(buf, value);
21 return std::vector<uint8_t>(buf.data(), buf.data() + buf.size());
22}
23
24// ---------------------------------------------------------------------------
25// Helper: deserialize leaves from raw bytes based on tree type
26// ---------------------------------------------------------------------------
27
28template <typename LeafType>
29static std::vector<LeafType> deserialize_leaves(const std::vector<std::vector<uint8_t>>& raw_leaves)
30{
32 leaves.reserve(raw_leaves.size());
33 for (const auto& raw : raw_leaves) {
34 auto unpacked = msgpack::unpack(reinterpret_cast<const char*>(raw.data()), raw.size());
35 LeafType leaf;
36 unpacked.get().convert(leaf);
37 leaves.push_back(std::move(leaf));
38 }
39 return leaves;
40}
41
42// ---------------------------------------------------------------------------
43// Top-level dispatch
44// ---------------------------------------------------------------------------
45
47{
48 return execute(request, std::move(command));
49}
50
51// ---------------------------------------------------------------------------
52// Tree info / state queries
53// ---------------------------------------------------------------------------
54
56{
57 auto info = request.world_state.get_tree_info(revision, treeId);
58 return Response{ .treeId = treeId, .root = info.meta.root, .size = info.meta.size, .depth = info.meta.depth };
59}
60
62{
63 auto state = request.world_state.get_state_reference(revision);
64 return Response{ .state = state };
65}
66
68{
69 auto state = request.world_state.get_initial_state_reference();
70 return Response{ .state = state };
71}
72
73// ---------------------------------------------------------------------------
74// Leaf queries
75// ---------------------------------------------------------------------------
76
78{
79 switch (treeId) {
80 case MerkleTreeId::NOTE_HASH_TREE:
81 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
82 case MerkleTreeId::ARCHIVE: {
83 auto leaf = request.world_state.get_leaf<bb::fr>(revision, treeId, leafIndex);
84 if (!leaf.has_value()) {
85 return Response{ .value = std::nullopt };
86 }
87 return Response{ .value = serialize_to_msgpack(leaf.value()) };
88 }
89 case MerkleTreeId::PUBLIC_DATA_TREE: {
90 auto leaf = request.world_state.get_leaf<PublicDataLeafValue>(revision, treeId, leafIndex);
91 if (!leaf.has_value()) {
92 return Response{ .value = std::nullopt };
93 }
94 return Response{ .value = serialize_to_msgpack(leaf.value()) };
95 }
96 case MerkleTreeId::NULLIFIER_TREE: {
97 auto leaf = request.world_state.get_leaf<NullifierLeafValue>(revision, treeId, leafIndex);
98 if (!leaf.has_value()) {
99 return Response{ .value = std::nullopt };
100 }
101 return Response{ .value = serialize_to_msgpack(leaf.value()) };
102 }
103 default:
104 throw std::runtime_error("Unsupported tree type for get_leaf_value");
105 }
106}
107
109{
110 switch (treeId) {
111 case MerkleTreeId::NULLIFIER_TREE: {
112 auto leaf = request.world_state.get_indexed_leaf<NullifierLeafValue>(revision, treeId, leafIndex);
113 if (!leaf.has_value()) {
114 return Response{ .preimage = std::nullopt };
115 }
116 return Response{ .preimage = serialize_to_msgpack(leaf.value()) };
117 }
118 case MerkleTreeId::PUBLIC_DATA_TREE: {
119 auto leaf = request.world_state.get_indexed_leaf<PublicDataLeafValue>(revision, treeId, leafIndex);
120 if (!leaf.has_value()) {
121 return Response{ .preimage = std::nullopt };
122 }
123 return Response{ .preimage = serialize_to_msgpack(leaf.value()) };
124 }
125 default:
126 throw std::runtime_error("Unsupported tree type for get_leaf_preimage");
127 }
128}
129
131{
132 fr_sibling_path path = request.world_state.get_sibling_path(revision, treeId, leafIndex);
133 return Response{ .path = path };
134}
135
137{
138 Response response;
139 request.world_state.get_block_numbers_for_leaf_indices(revision, treeId, leafIndices, response.blockNumbers);
140 return response;
141}
142
143// ---------------------------------------------------------------------------
144// Leaf search operations
145// ---------------------------------------------------------------------------
146
148{
149 Response response;
150 switch (treeId) {
151 case MerkleTreeId::NOTE_HASH_TREE:
152 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
153 case MerkleTreeId::ARCHIVE: {
154 auto typed_leaves = deserialize_leaves<bb::fr>(leaves);
155 request.world_state.find_leaf_indices<bb::fr>(revision, treeId, typed_leaves, response.indices, startIndex);
156 break;
157 }
158 case MerkleTreeId::PUBLIC_DATA_TREE: {
159 auto typed_leaves = deserialize_leaves<PublicDataLeafValue>(leaves);
160 request.world_state.find_leaf_indices<PublicDataLeafValue>(
161 revision, treeId, typed_leaves, response.indices, startIndex);
162 break;
163 }
164 case MerkleTreeId::NULLIFIER_TREE: {
165 auto typed_leaves = deserialize_leaves<NullifierLeafValue>(leaves);
166 request.world_state.find_leaf_indices<NullifierLeafValue>(
167 revision, treeId, typed_leaves, response.indices, startIndex);
168 break;
169 }
170 default:
171 throw std::runtime_error("Unsupported tree type for find_leaf_indices");
172 }
173 return response;
174}
175
177{
178 auto low_leaf_info = request.world_state.find_low_leaf_index(revision, treeId, key);
179 return Response{ .alreadyPresent = low_leaf_info.is_already_present, .index = low_leaf_info.index };
180}
181
183{
184 Response response;
185 switch (treeId) {
186 case MerkleTreeId::NOTE_HASH_TREE:
187 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
188 case MerkleTreeId::ARCHIVE: {
189 auto typed_leaves = deserialize_leaves<bb::fr>(leaves);
190 request.world_state.find_sibling_paths<bb::fr>(revision, treeId, typed_leaves, response.paths);
191 break;
192 }
193 case MerkleTreeId::PUBLIC_DATA_TREE: {
194 auto typed_leaves = deserialize_leaves<PublicDataLeafValue>(leaves);
195 request.world_state.find_sibling_paths<PublicDataLeafValue>(revision, treeId, typed_leaves, response.paths);
196 break;
197 }
198 case MerkleTreeId::NULLIFIER_TREE: {
199 auto typed_leaves = deserialize_leaves<NullifierLeafValue>(leaves);
200 request.world_state.find_sibling_paths<NullifierLeafValue>(revision, treeId, typed_leaves, response.paths);
201 break;
202 }
203 default:
204 throw std::runtime_error("Unsupported tree type for find_sibling_paths");
205 }
206 return response;
207}
208
209// ---------------------------------------------------------------------------
210// Tree mutation operations
211// ---------------------------------------------------------------------------
212
214{
215 switch (treeId) {
216 case MerkleTreeId::NOTE_HASH_TREE:
217 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
218 case MerkleTreeId::ARCHIVE: {
219 auto typed_leaves = deserialize_leaves<bb::fr>(leaves);
220 request.world_state.append_leaves<bb::fr>(treeId, typed_leaves, forkId);
221 break;
222 }
223 case MerkleTreeId::PUBLIC_DATA_TREE: {
224 auto typed_leaves = deserialize_leaves<PublicDataLeafValue>(leaves);
225 request.world_state.append_leaves<PublicDataLeafValue>(treeId, typed_leaves, forkId);
226 break;
227 }
228 case MerkleTreeId::NULLIFIER_TREE: {
229 auto typed_leaves = deserialize_leaves<NullifierLeafValue>(leaves);
230 request.world_state.append_leaves<NullifierLeafValue>(treeId, typed_leaves, forkId);
231 break;
232 }
233 default:
234 throw std::runtime_error("Unsupported tree type for append_leaves");
235 }
236 return Response{};
237}
238
240{
241 switch (treeId) {
242 case MerkleTreeId::PUBLIC_DATA_TREE: {
243 auto typed_leaves = deserialize_leaves<PublicDataLeafValue>(leaves);
244 auto result = request.world_state.batch_insert_indexed_leaves<PublicDataLeafValue>(
245 treeId, typed_leaves, subtreeDepth, forkId);
246 return Response{ .result = serialize_to_msgpack(result) };
247 }
248 case MerkleTreeId::NULLIFIER_TREE: {
249 auto typed_leaves = deserialize_leaves<NullifierLeafValue>(leaves);
250 auto result = request.world_state.batch_insert_indexed_leaves<NullifierLeafValue>(
251 treeId, typed_leaves, subtreeDepth, forkId);
252 return Response{ .result = serialize_to_msgpack(result) };
253 }
254 default:
255 throw std::runtime_error("Unsupported tree type for batch_insert");
256 }
257}
258
260{
261 switch (treeId) {
262 case MerkleTreeId::PUBLIC_DATA_TREE: {
263 auto typed_leaves = deserialize_leaves<PublicDataLeafValue>(leaves);
264 auto result = request.world_state.insert_indexed_leaves<PublicDataLeafValue>(treeId, typed_leaves, forkId);
265 return Response{ .result = serialize_to_msgpack(result) };
266 }
267 case MerkleTreeId::NULLIFIER_TREE: {
268 auto typed_leaves = deserialize_leaves<NullifierLeafValue>(leaves);
269 auto result = request.world_state.insert_indexed_leaves<NullifierLeafValue>(treeId, typed_leaves, forkId);
270 return Response{ .result = serialize_to_msgpack(result) };
271 }
272 default:
273 throw std::runtime_error("Unsupported tree type for sequential_insert");
274 }
275}
276
278{
279 request.world_state.update_archive(blockStateRef, blockHeaderHash, forkId);
280 return Response{};
281}
282
283// ---------------------------------------------------------------------------
284// Transaction operations
285// ---------------------------------------------------------------------------
286
288{
290 request.world_state.commit(status);
291 return Response{ .status = status };
292}
293
295{
296 request.world_state.rollback();
297 return Response{};
298}
299
300// ---------------------------------------------------------------------------
301// Block synchronization
302// ---------------------------------------------------------------------------
303
305{
306 WorldStateStatusFull status = request.world_state.sync_block(
307 blockStateRef, blockHeaderHash, paddedNoteHashes, paddedL1ToL2Messages, paddedNullifiers, publicDataWrites);
308 return Response{ .status = status };
309}
310
311// ---------------------------------------------------------------------------
312// Fork management
313// ---------------------------------------------------------------------------
314
316{
318 uint64_t id = request.world_state.create_fork(block);
319 return Response{ .forkId = id };
320}
321
323{
324 request.world_state.delete_fork(forkId);
325 return Response{};
326}
327
328// ---------------------------------------------------------------------------
329// Block management
330// ---------------------------------------------------------------------------
331
333{
334 WorldStateStatusSummary status = request.world_state.set_finalized_blocks(toBlockNumber);
335 return Response{ .status = status };
336}
337
339{
340 WorldStateStatusFull status = request.world_state.unwind_blocks(toBlockNumber);
341 return Response{ .status = status };
342}
343
345{
346 WorldStateStatusFull status = request.world_state.remove_historical_blocks(toBlockNumber);
347 return Response{ .status = status };
348}
349
350// ---------------------------------------------------------------------------
351// Status
352// ---------------------------------------------------------------------------
353
355{
357 request.world_state.get_status_summary(status);
358 return Response{ .status = status };
359}
360
361// ---------------------------------------------------------------------------
362// Checkpoint operations
363// ---------------------------------------------------------------------------
364
366{
367 request.world_state.checkpoint(forkId);
368 return Response{};
369}
370
372{
373 request.world_state.commit_checkpoint(forkId);
374 return Response{};
375}
376
378{
379 request.world_state.revert_checkpoint(forkId);
380 return Response{};
381}
382
384{
385 request.world_state.commit_all_checkpoints_to(forkId, 0);
386 return Response{};
387}
388
390{
391 request.world_state.revert_all_checkpoints_to(forkId, 0);
392 return Response{};
393}
394
395// ---------------------------------------------------------------------------
396// Database operations
397// ---------------------------------------------------------------------------
398
400{
401 request.world_state.copy_stores(dstPath, compact.value_or(false));
402 return Response{};
403}
404
405// ---------------------------------------------------------------------------
406// Lifecycle
407// ---------------------------------------------------------------------------
408
410{
411 return Response{};
412}
413
414} // namespace bb::wsdb
A wrapper around std::variant that provides msgpack serialization based on type names.
#define info(...)
Definition log.hpp:93
std::vector< fr > fr_sibling_path
Definition hash_path.hpp:14
std::vector< uint8_t > serialize_to_msgpack(const T &data)
Serializes data to msgpack format.
WsdbCommandResponse wsdb(WsdbRequest &request, WsdbCommand &&command)
Top-level wsdb API entry point. Takes a WsdbRequest and dispatches the command.
WsdbCommandResponse execute(WsdbRequest &request, WsdbCommand &&command)
Execute a wsdb command using the visitor pattern.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
std::vector< std::optional< index_t > > indices
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
std::vector< std::optional< SiblingPathAndIndex > > paths
Response execute(WsdbRequest &request) &&
std::vector< std::optional< block_number_t > > blockNumbers
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
std::optional< std::vector< uint8_t > > preimage
Response execute(WsdbRequest &request) &&
std::optional< std::vector< uint8_t > > value
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Context passed to each command's execute() method, providing access to the WorldState.
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
Response execute(WsdbRequest &request) &&
WsdbCommand NamedUnion, WsdbRequest context, and dispatch function.