Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
world_state.test.cpp
Go to the documentation of this file.
10#include <array>
11#include <cstdint>
12#include <filesystem>
13#include <gtest/gtest.h>
14#include <optional>
15#include <stdexcept>
16#include <sys/types.h>
17#include <unordered_map>
18
19using namespace bb::world_state;
20using namespace bb::crypto::merkle_tree;
21
22class WorldStateTest : public testing::Test {
23 protected:
24 void SetUp() override
25 {
27 std::filesystem::create_directories(data_dir);
28 }
29
30 void TearDown() override { std::filesystem::remove_all(data_dir); }
31
32 static std::string data_dir;
33 uint64_t map_size = 10240;
34 uint64_t thread_pool_size = 1;
35
36 // TODO(): https://github.com/AztecProtocol/aztec-packages/issues/8084
37 std::unordered_map<MerkleTreeId, uint32_t> tree_heights{
38 { MerkleTreeId::NULLIFIER_TREE, 40 }, { MerkleTreeId::NOTE_HASH_TREE, 40 },
39 { MerkleTreeId::PUBLIC_DATA_TREE, 40 }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 39 },
40 { MerkleTreeId::ARCHIVE, 29 },
41 };
42 std::unordered_map<MerkleTreeId, index_t> tree_prefill{
43 { MerkleTreeId::NULLIFIER_TREE, 128 },
44 { MerkleTreeId::PUBLIC_DATA_TREE, 128 },
45 };
47};
48
49std::string WorldStateTest::data_dir;
50
51template <typename Leaf>
53 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, index_t leaf_index, bool exists)
54{
55 std::optional<Leaf> leaf = ws.get_leaf<Leaf>(revision, tree_id, leaf_index);
56 EXPECT_EQ(leaf.has_value(), exists);
57}
58
59template <typename Leaf>
61 WorldStateRevision revision,
62 MerkleTreeId tree_id,
63 index_t leaf_index,
64 const Leaf& expected_value)
65{
66 std::optional<Leaf> leaf = ws.get_leaf<Leaf>(revision, tree_id, leaf_index);
67 EXPECT_EQ(leaf.has_value(), true);
68 EXPECT_EQ(leaf.value(), expected_value);
69}
70
71template <typename Leaf>
73 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, const Leaf& expected_value, bool exists)
74{
76 ws.find_leaf_indices<Leaf>(revision, tree_id, { expected_value }, indices);
77 EXPECT_EQ(indices.size(), 1);
78 EXPECT_EQ(indices[0].has_value(), exists);
79}
80
81template <typename Leaf>
83 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, const Leaf& value, index_t expected_index)
84{
86 ws.find_leaf_indices<Leaf>(revision, tree_id, { value }, indices);
87 EXPECT_EQ(indices.size(), 1);
88 EXPECT_TRUE(indices[0].has_value());
89 if (!indices[0].has_value()) {
90 return;
91 }
92 EXPECT_EQ(indices[0].value(), expected_index);
93}
94
95void assert_tree_size(const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, size_t expected_size)
96{
97 auto info = ws.get_tree_info(revision, tree_id);
98 EXPECT_EQ(info.meta.size, expected_size);
99}
100
102 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, fr root, fr leaf, index_t index)
103{
104 auto sibling_path = ws.get_sibling_path(revision, tree_id, index);
105 fr left;
106 fr right;
107 fr hash = leaf;
108 for (const auto& node : sibling_path) {
109 if (index % 2 == 0) {
110 left = hash;
111 right = node;
112 } else {
113 left = node;
114 right = hash;
115 }
116
117 hash = HashPolicy::hash_pair(left, right);
118 index >>= 1;
119 }
120
121 EXPECT_EQ(hash, root);
122}
123
125 Fork::Id forkId,
126 bool includeUncommitted,
127 const std::vector<MerkleTreeId>& trees = { MerkleTreeId::NULLIFIER_TREE,
128 MerkleTreeId::NOTE_HASH_TREE,
129 MerkleTreeId::PUBLIC_DATA_TREE,
130 MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
131 MerkleTreeId::ARCHIVE })
132{
133
134 for (auto tree_id : trees) {
135 auto canonical_tree_info =
136 ws.get_tree_info(WorldStateRevision{ .includeUncommitted = includeUncommitted }, tree_id);
137 auto fork_tree_info = ws.get_tree_info(
139 .forkId = forkId,
140 .includeUncommitted = includeUncommitted,
141 },
142 tree_id);
143
144 EXPECT_EQ(canonical_tree_info.meta, fork_tree_info.meta);
145 }
146}
147
148TEST_F(WorldStateTest, GetInitialTreeInfoForAllTrees)
149{
150 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
151
152 {
153 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE);
154 EXPECT_EQ(info.meta.size, 128);
155 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::NULLIFIER_TREE));
156 EXPECT_EQ(info.meta.root, bb::fr("0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073"));
157 }
158
159 {
160 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE);
161 EXPECT_EQ(info.meta.size, 0);
162 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::NOTE_HASH_TREE));
163 EXPECT_EQ(info.meta.root, bb::fr("0x1fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb"));
164 }
165
166 {
167 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE);
168 EXPECT_EQ(info.meta.size, 128);
169 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::PUBLIC_DATA_TREE));
170 EXPECT_EQ(info.meta.root, bb::fr("0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9"));
171 }
172
173 {
174 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
175 EXPECT_EQ(info.meta.size, 0);
176 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE));
177 EXPECT_EQ(info.meta.root, bb::fr("0x2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6"));
178 }
179
180 {
181 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
182 EXPECT_EQ(info.meta.size, 1);
183 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::ARCHIVE));
184 // this is the expected archive tree root at genesis
185 EXPECT_EQ(info.meta.root, bb::fr(GENESIS_ARCHIVE_ROOT));
186
187 // The leaf at index 0 is the genesis block hash.
189 ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 0, bb::fr(GENESIS_BLOCK_HEADER_HASH));
190 }
191}
192
193TEST_F(WorldStateTest, GetInitialTreeInfoWithPrefilledPublicData)
194{
195 std::string data_dir_prefilled = random_temp_directory();
196 std::filesystem::create_directories(data_dir_prefilled);
197
198 std::vector<PublicDataLeafValue> prefilled_values = { PublicDataLeafValue(1000, 2000),
199 PublicDataLeafValue(3000, 4000) };
200
201 WorldState ws_prefilled(thread_pool_size,
202 data_dir_prefilled,
203 map_size,
204 tree_heights,
205 tree_prefill,
206 prefilled_values,
207 initial_header_generator_point);
208
209 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
210
211 {
212 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE);
213 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE);
214 EXPECT_EQ(prefilled.meta.size, info.meta.size);
215 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
216 EXPECT_EQ(prefilled.meta.root, info.meta.root);
217 }
218
219 {
220 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE);
221 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE);
222 EXPECT_EQ(prefilled.meta.size, info.meta.size);
223 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
224 EXPECT_EQ(prefilled.meta.root, info.meta.root);
225 }
226
227 {
228 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE);
229 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE);
230 EXPECT_EQ(prefilled.meta.size, info.meta.size);
231 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
232 // Public data tree roots are different.
233 EXPECT_NE(prefilled.meta.root, info.meta.root);
234
235 // Prefilled values are appended at the end.
236 {
237 auto leaf = ws_prefilled.get_indexed_leaf<PublicDataLeafValue>(
238 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, prefilled.meta.size - 2);
239 EXPECT_EQ(leaf.value().leaf, prefilled_values[0]);
240 }
241 {
242 auto leaf = ws_prefilled.get_indexed_leaf<PublicDataLeafValue>(
243 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, prefilled.meta.size - 1);
244 EXPECT_EQ(leaf.value().leaf, prefilled_values[1]);
245 }
246 }
247
248 {
249 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
250 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
251 EXPECT_EQ(prefilled.meta.size, info.meta.size);
252 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
253 // Archive tree roots are different.
254 EXPECT_NE(prefilled.meta.root, info.meta.root);
255 }
256}
257
258TEST_F(WorldStateTest, GetStateReference)
259{
260 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
261
262 {
264 {
265 auto snapshot = state_ref.at(MerkleTreeId::NULLIFIER_TREE);
266 EXPECT_EQ(
267 snapshot,
268 std::make_pair(bb::fr("0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073"), 128UL));
269 }
270
271 {
272 auto snapshot = state_ref.at(MerkleTreeId::NOTE_HASH_TREE);
273 EXPECT_EQ(
274 snapshot,
275 std::make_pair(bb::fr("0x1fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb"), 0UL));
276 }
277
278 {
279 auto snapshot = state_ref.at(MerkleTreeId::PUBLIC_DATA_TREE);
280 EXPECT_EQ(
281 snapshot,
282 std::make_pair(bb::fr("0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9"), 128UL));
283 }
284
285 {
286 auto snapshot = state_ref.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
287 EXPECT_EQ(
288 snapshot,
289 std::make_pair(bb::fr("0x2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6"), 0UL));
290 }
291 }
292
293 {
294 ws.append_leaves<bb::fr>(MerkleTreeId::NOTE_HASH_TREE, { 1 });
295
297 {
298 auto snapshot = state_ref.at(MerkleTreeId::NULLIFIER_TREE);
299 EXPECT_EQ(
300 snapshot,
301 std::make_pair(bb::fr("0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073"), 128UL));
302 }
303
304 {
305 auto snapshot = state_ref.at(MerkleTreeId::NOTE_HASH_TREE);
306 EXPECT_EQ(
307 snapshot,
308 std::make_pair(bb::fr("0x0f031292dfc64353244dfc38871cbeac74ddbd03df4a0856c411bb1ddfb494f0"), 1UL));
309 }
310
311 {
312 auto snapshot = state_ref.at(MerkleTreeId::PUBLIC_DATA_TREE);
313 EXPECT_EQ(
314 snapshot,
315 std::make_pair(bb::fr("0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9"), 128UL));
316 }
317
318 {
319 auto snapshot = state_ref.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
320 EXPECT_EQ(
321 snapshot,
322 std::make_pair(bb::fr("0x2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6"), 0UL));
323 }
324 }
325}
326
327TEST_F(WorldStateTest, GetInitialStateReference)
328{
329 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
330
331 auto before_commit = ws.get_initial_state_reference();
332 ws.append_leaves<bb::fr>(MerkleTreeId::NOTE_HASH_TREE, { 1 });
334 ws.commit(status);
335
336 auto after_commit = ws.get_initial_state_reference();
337
338 EXPECT_EQ(before_commit, after_commit);
339}
340
341TEST_F(WorldStateTest, AppendOnlyTrees)
342{
343 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
344
345 // the trees that start out empty
346 std::vector tree_ids{ MerkleTreeId::NOTE_HASH_TREE, MerkleTreeId::L1_TO_L2_MESSAGE_TREE };
347
348 for (auto tree_id : tree_ids) {
349 auto initial = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
350 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 0, false);
351
352 ws.append_leaves<fr>(tree_id, { fr(42) });
354 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 0, false);
356
357 auto uncommitted = ws.get_tree_info(WorldStateRevision::uncommitted(), tree_id);
358 // uncommitted state diverges from committed state
359 EXPECT_EQ(uncommitted.meta.size, initial.meta.size + 1);
360 EXPECT_NE(uncommitted.meta.root, initial.meta.root);
361
362 assert_sibling_path(ws, WorldStateRevision::uncommitted(), tree_id, uncommitted.meta.root, fr(42), 0);
363
364 auto committed = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
365 EXPECT_EQ(committed.meta.size, initial.meta.size);
366 EXPECT_EQ(committed.meta.root, initial.meta.root);
367
369 ws.commit(status);
370 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 0, fr(42));
371 assert_leaf_index(ws, WorldStateRevision::committed(), tree_id, fr(42), 0);
372
373 auto after_commit = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
374 // commiting updates the committed state
375 EXPECT_EQ(after_commit.meta.size, uncommitted.meta.size);
376 EXPECT_EQ(after_commit.meta.root, uncommitted.meta.root);
377
378 assert_sibling_path(ws, WorldStateRevision::committed(), tree_id, after_commit.meta.root, fr(42), 0);
379
380 ws.append_leaves<fr>(tree_id, { fr(43) });
382 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 1, false);
384
385 auto before_rollback = ws.get_tree_info(WorldStateRevision::uncommitted(), tree_id);
386 EXPECT_EQ(before_rollback.meta.size, after_commit.meta.size + 1);
387 EXPECT_NE(before_rollback.meta.root, after_commit.meta.root);
388
389 ws.rollback();
390 assert_leaf_status<fr>(ws, WorldStateRevision::uncommitted(), tree_id, 1, false);
391 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 1, false);
392
393 auto after_rollback = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
394 // rollback restores the committed state
395 EXPECT_EQ(after_rollback.meta.size, after_commit.meta.size);
396 EXPECT_EQ(after_rollback.meta.root, after_commit.meta.root);
397 }
398}
399
400TEST_F(WorldStateTest, AppendOnlyAllowDuplicates)
401{
402 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
403
404 // the trees that start out empty
405 std::vector tree_ids{
406 MerkleTreeId::NOTE_HASH_TREE,
407 MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
408 };
409
410 for (auto tree_id : tree_ids) {
411 ws.append_leaves<fr>(tree_id, { fr(42), fr(42) });
412 ws.append_leaves<fr>(tree_id, { fr(42) });
413
417
419 ws.commit(status);
420
421 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 0, fr(42));
422 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 1, fr(42));
423 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 2, fr(42));
424 }
425}
426
428{
429 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
430 auto tree_id = MerkleTreeId::NULLIFIER_TREE;
431 NullifierLeafValue test_nullifier(142);
432
433 auto predecessor_of_142 =
434 ws.find_low_leaf_index(WorldStateRevision::committed(), tree_id, test_nullifier.get_key());
435 EXPECT_EQ(predecessor_of_142, GetLowIndexedLeafResponse(false, 127UL));
436
437 ws.append_leaves<NullifierLeafValue>(tree_id, { test_nullifier });
438 assert_leaf_value(ws, WorldStateRevision::uncommitted(), tree_id, 128, test_nullifier);
439
441 ws.commit(status);
442
443 auto test_leaf = ws.get_indexed_leaf<NullifierLeafValue>(WorldStateRevision::committed(), tree_id, 128);
444 // at this point 142 should be the biggest leaf so it wraps back to 0
445 EXPECT_TRUE(test_leaf.has_value());
446 EXPECT_EQ(test_leaf.value(), IndexedLeaf(test_nullifier, 0, 0));
447
448 auto predecessor_of_142_again =
449 ws.find_low_leaf_index(WorldStateRevision::committed(), tree_id, test_nullifier.get_key());
450 EXPECT_EQ(predecessor_of_142_again, GetLowIndexedLeafResponse(true, 128UL));
451
452 auto predecessor_of_143 = ws.find_low_leaf_index(WorldStateRevision::committed(), tree_id, 143);
453 EXPECT_EQ(predecessor_of_143,
454 GetLowIndexedLeafResponse(false, 128UL)); // predecessor is going to be nullifier 142 on slot 127
455
459 tree_id,
460 info.meta.root,
461 HashPolicy::hash(test_leaf.value().get_hash_inputs()),
462 128);
463}
464
465TEST_F(WorldStateTest, NullifierTreeDuplicates)
466{
467 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
468 auto tree_id = MerkleTreeId::NULLIFIER_TREE;
469 NullifierLeafValue test_nullifier(142);
470
471 ws.append_leaves<NullifierLeafValue>(tree_id, { test_nullifier });
473 ws.commit(status);
474
476 EXPECT_THROW(ws.append_leaves<NullifierLeafValue>(tree_id, { test_nullifier }), std::runtime_error);
478}
479
480TEST_F(WorldStateTest, NullifierBatchInsert)
481{
482 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
484 MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(150), NullifierLeafValue(142), NullifierLeafValue(180) }, 2);
485
486 std::vector<std::pair<NullifierLeafValue, size_t>> expected_sorted_leaves = { { NullifierLeafValue(180), 2 },
487 { NullifierLeafValue(150), 0 },
488 { NullifierLeafValue(142), 1 } };
489 EXPECT_EQ(response.sorted_leaves, expected_sorted_leaves);
490
491 {
492 // insertion happens in descending order, but keeping original indices
493 // first insert leaf 180, at index 130 (tree had size 127, 180 is the third item => 127 + 3)
494 // predecessor will be 127, currently linked to head of the list (0)
495 auto low_leaf = response.low_leaf_witness_data[0];
496 auto expected_low_leaf = IndexedLeaf(NullifierLeafValue(127), 0, fr(0));
497 EXPECT_EQ(low_leaf.index, 127);
498 EXPECT_EQ(low_leaf.leaf, expected_low_leaf);
499 }
500
501 {
502 // insert 150 on position 128 (127 + 1)
503 // predecessor will be 127 linked to 180
504 auto low_leaf = response.low_leaf_witness_data[1];
505 auto expected_low_leaf = IndexedLeaf(NullifierLeafValue(127), 130, fr(180));
506 EXPECT_EQ(low_leaf.index, 127);
507 EXPECT_EQ(low_leaf.leaf, expected_low_leaf);
508 }
509
510 {
511 // finally, insert 142 on position 129(127 + 2)
512 // prededecessor will be 127 linked to 150
513 auto low_leaf = response.low_leaf_witness_data[2];
514 auto expected_low_leaf = IndexedLeaf(NullifierLeafValue(127), 128, fr(150));
515 EXPECT_EQ(low_leaf.index, 127);
516 EXPECT_EQ(low_leaf.leaf, expected_low_leaf);
517 }
518}
519
521{
522 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
523
524 ws.append_leaves(MerkleTreeId::PUBLIC_DATA_TREE, std::vector{ PublicDataLeafValue(142, 0) });
525 assert_tree_size(ws, WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 129);
526
528 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 128);
529 EXPECT_EQ(leaf.value().leaf, PublicDataLeafValue(142, 0));
530
532 // updating insert a dummy leaf
533 assert_tree_size(ws, WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 130);
534
536 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 128);
537 EXPECT_EQ(leaf.value().leaf, PublicDataLeafValue(142, 1));
538}
539
540TEST_F(WorldStateTest, CommitsAndRollsBackAllTrees)
541{
542 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
543
544 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { fr(42) });
545 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { fr(42) });
546 ws.append_leaves<fr>(MerkleTreeId::ARCHIVE, { fr(42) });
547 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(142) });
548 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(142, 1) });
549
551 ws.commit(status);
552
553 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, 0, fr(42));
554 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 0, fr(42));
555 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 1, fr(42));
556 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, 128, NullifierLeafValue(142));
558 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, 128, PublicDataLeafValue(142, 1));
559
560 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { fr(43) });
561 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { fr(43) });
562 ws.append_leaves<fr>(MerkleTreeId::ARCHIVE, { fr(43) });
563 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(143) });
564 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(143, 1) });
565
566 ws.rollback();
567
568 assert_leaf_exists(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, fr(43), false);
569 assert_leaf_exists(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, fr(43), false);
570 assert_leaf_exists(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, fr(43), false);
572 ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, NullifierLeafValue(143), false);
574 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, PublicDataLeafValue(143, 1), false);
575}
576
577TEST_F(WorldStateTest, SyncExternalBlockFromEmpty)
578{
579 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
580 StateReference block_state_ref = {
581 { MerkleTreeId::NULLIFIER_TREE,
582 { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } },
583 { MerkleTreeId::NOTE_HASH_TREE,
584 { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } },
585 { MerkleTreeId::PUBLIC_DATA_TREE,
586 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
587 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
588 { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } },
589 };
590
592 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
593 WorldStateStatusSummary expected(1, 0, 1, true);
594 EXPECT_EQ(status.summary, expected);
595
596 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, 0, fr(42));
597 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 0, fr(43));
598 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, 128, NullifierLeafValue(144));
600 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, 128, PublicDataLeafValue(145, 1));
601 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 1, fr(1));
602
604 for (const auto& [tree_id, snapshot] : block_state_ref) {
605 EXPECT_EQ(state_ref.at(tree_id), snapshot);
606 }
607
610 WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, { 0 }, blockNumbers);
611 EXPECT_EQ(blockNumbers.size(), 1);
612 EXPECT_EQ(blockNumbers[0], 1);
613
615 WorldStateRevision{ .forkId = CANONICAL_FORK_ID, .blockNumber = 2, .includeUncommitted = false },
616 MerkleTreeId::NOTE_HASH_TREE,
617 { 0 },
618 blockNumbers),
619 std::runtime_error);
620}
621
622TEST_F(WorldStateTest, SyncBlockFromDirtyState)
623{
624 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
625 StateReference block_state_ref = {
626 { MerkleTreeId::NULLIFIER_TREE,
627 { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } },
628 { MerkleTreeId::NOTE_HASH_TREE,
629 { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } },
630 { MerkleTreeId::PUBLIC_DATA_TREE,
631 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
632 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
633 { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } },
634 };
635
636 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { fr(142) });
637 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { fr(143) });
638 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(142) });
639 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(142, 1) });
640
641 auto uncommitted_state_ref = ws.get_state_reference(WorldStateRevision::uncommitted());
642 for (const auto& [tree_id, snapshot] : block_state_ref) {
643 EXPECT_NE(uncommitted_state_ref.at(tree_id), snapshot);
644 }
645
647 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
648 WorldStateStatusSummary expected{ 1, 0, 1, true };
649 EXPECT_EQ(status.summary, expected);
650
651 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, 0, fr(42));
652 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 0, fr(43));
653 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, 128, NullifierLeafValue(144));
655 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, 128, PublicDataLeafValue(145, 1));
656 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 1, fr(1));
657
659 for (const auto& [tree_id, snapshot] : block_state_ref) {
660 EXPECT_EQ(state_ref.at(tree_id), snapshot);
661 }
662}
663
664TEST_F(WorldStateTest, SyncCurrentBlock)
665{
666 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
667 bb::fr block_hash(1);
668 StateReference block_state_ref = {
669 { MerkleTreeId::NULLIFIER_TREE,
670 { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } },
671 { MerkleTreeId::NOTE_HASH_TREE,
672 { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } },
673 { MerkleTreeId::PUBLIC_DATA_TREE,
674 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
675 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
676 { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } },
677 };
678
679 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { 42 });
680 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { 43 });
681 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(144) });
682 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(145, 1) });
683 ws.append_leaves<fr>(MerkleTreeId::ARCHIVE, { block_hash });
684
685 auto uncommitted_state_ref = ws.get_state_reference(WorldStateRevision::uncommitted());
686 for (const auto& [tree_id, snapshot] : block_state_ref) {
687 EXPECT_EQ(uncommitted_state_ref.at(tree_id), snapshot);
688 }
689
691 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
692 WorldStateStatusSummary expected{ 1, 0, 1, true };
693 EXPECT_EQ(status.summary, expected);
694
695 assert_leaf_value(ws, WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE, 1, fr(1));
696
698 for (const auto& [tree_id, snapshot] : block_state_ref) {
699 EXPECT_EQ(state_ref.at(tree_id), snapshot);
700 }
701}
702
703TEST_F(WorldStateTest, RejectSyncBlockWithBadPublicWriteBatches)
704{
705 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
706 StateReference block_state_ref = {
707 { MerkleTreeId::NULLIFIER_TREE,
708 { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } },
709 { MerkleTreeId::NOTE_HASH_TREE,
710 { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } },
711 { MerkleTreeId::PUBLIC_DATA_TREE,
712 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
713 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
714 { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } },
715 };
716
717 auto sync = [&]() {
718 return ws.sync_block(block_state_ref,
719 fr(1),
720 { 42 },
721 { 43 },
722 { NullifierLeafValue(144) },
723 // this should be rejected because we can't have duplicate slots in the same batch
724 { { PublicDataLeafValue(145, 1), PublicDataLeafValue(145, 2) } });
725 };
726
727 EXPECT_THROW(sync(), std::runtime_error);
728}
729
730TEST_F(WorldStateTest, RejectSyncBlockWithInvalidStateRef)
731{
732 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
733 StateReference block_state_ref = {
734 { MerkleTreeId::NULLIFIER_TREE,
735 { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } },
736 { MerkleTreeId::NOTE_HASH_TREE,
737 { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } },
738 { MerkleTreeId::PUBLIC_DATA_TREE,
739 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
740 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
741 { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } },
742 };
743
744 auto sync = [&]() {
745 return ws.sync_block(block_state_ref,
746 fr(1),
747 { 42 },
748 { 43 },
749 { NullifierLeafValue(144) },
750 // this should be rejected because public data tree root will not match the state ref above
751 // (state ref above is for slot[145]=1, not slot[145]=2)
752 { { PublicDataLeafValue(145, 2) } });
753 };
754
755 EXPECT_THROW(sync(), std::runtime_error);
756}
757
758TEST_F(WorldStateTest, SyncEmptyBlock)
759{
760 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
762 ws.sync_block(block_state_ref, fr(1), {}, {}, {}, {});
764 EXPECT_EQ(block_state_ref, after_sync);
765
767 ws.find_leaf_indices<fr>(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, { fr(1) }, indices);
769 EXPECT_EQ(indices, expected);
770}
771
772TEST_F(WorldStateTest, ForkingAtBlock0SameState)
773{
774 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
775 auto fork_id = ws.create_fork(0);
776
777 assert_fork_state_unchanged(ws, fork_id, false);
778 assert_fork_state_unchanged(ws, fork_id, true);
779}
780
781TEST_F(WorldStateTest, ForkingAtBlock0AndAdvancingFork)
782{
783 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
784 auto fork_id = ws.create_fork(0);
785
786 auto canonical_archive_state_before = ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
787 auto fork_archive_state_before = ws.get_tree_info(
789 .forkId = fork_id,
790 .includeUncommitted = true,
791 },
792 MerkleTreeId::ARCHIVE);
793
794 ws.append_leaves<bb::fr>(MerkleTreeId::ARCHIVE, { fr(1) }, fork_id);
795
796 auto canonical_archive_state_after = ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
797 auto fork_archive_state_after = ws.get_tree_info(
799 .forkId = fork_id,
800 .includeUncommitted = true,
801 },
802 MerkleTreeId::ARCHIVE);
803
804 EXPECT_EQ(canonical_archive_state_after.meta, canonical_archive_state_before.meta);
805 EXPECT_EQ(fork_archive_state_before.meta, canonical_archive_state_before.meta);
806 EXPECT_NE(fork_archive_state_after.meta, fork_archive_state_before.meta);
807}
808
809TEST_F(WorldStateTest, ForkingAtBlock0AndAdvancingCanonicalState)
810{
811 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
812 auto fork_id = ws.create_fork(0);
813
814 auto canonical_archive_state_before = ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
815 auto fork_archive_state_before_insert = ws.get_tree_info(
817 .forkId = fork_id,
818 .includeUncommitted = true,
819 },
820 MerkleTreeId::ARCHIVE);
821
822 // fork the state
823 ws.append_leaves<bb::fr>(MerkleTreeId::ARCHIVE, { fr(1) });
824 ws.append_leaves<bb::fr>(MerkleTreeId::ARCHIVE, { fr(2) }, fork_id);
825
826 auto canonical_archive_state_after_insert =
827 ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
828 auto fork_archive_state_after_insert = ws.get_tree_info(
830 .forkId = fork_id,
831 .includeUncommitted = true,
832 },
833 MerkleTreeId::ARCHIVE);
834
835 EXPECT_EQ(fork_archive_state_before_insert.meta, canonical_archive_state_before.meta);
836
837 EXPECT_NE(canonical_archive_state_after_insert.meta, canonical_archive_state_before.meta);
838 EXPECT_NE(fork_archive_state_after_insert.meta, fork_archive_state_before_insert.meta);
839 EXPECT_NE(fork_archive_state_after_insert.meta, canonical_archive_state_after_insert.meta);
840
842 ws.commit(status);
843 auto canonical_archive_state_after_commit =
844 ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
845 auto fork_archive_state_after_commit = ws.get_tree_info(
847 .forkId = fork_id,
848 .includeUncommitted = false,
849 },
850 MerkleTreeId::ARCHIVE);
851
852 // committed fork state should match the state before fork had been modified
853 EXPECT_EQ(fork_archive_state_after_commit.meta.size, fork_archive_state_before_insert.meta.size);
854 EXPECT_EQ(fork_archive_state_after_commit.meta.root, fork_archive_state_before_insert.meta.root);
855 // canonical state before commit should match state after commit
856 // EXPECT_EQ(canonical_archive_state_after_commit.meta, canonical_archive_state_after_insert.meta);
857 EXPECT_EQ(canonical_archive_state_after_commit.meta.root, canonical_archive_state_after_insert.meta.root);
858 EXPECT_EQ(canonical_archive_state_after_commit.meta.size, canonical_archive_state_after_insert.meta.size);
859
860 // canonical should have value 1 as the first leaf (committed state)
861 assert_leaf_value<bb::fr>(ws, WorldStateRevision{ .includeUncommitted = false }, MerkleTreeId::ARCHIVE, 1, 1);
862 // fork should still have value 2 as the first leaf (uncommitted)
863 assert_leaf_value<bb::fr>(
864 ws, WorldStateRevision{ .forkId = fork_id, .includeUncommitted = true }, MerkleTreeId::ARCHIVE, 1, 2);
865}
866
867TEST_F(WorldStateTest, BuildsABlockInAFork)
868{
869 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
870 auto fork_id = ws.create_fork(0);
871
872 ws.append_leaves<bb::fr>(MerkleTreeId::NOTE_HASH_TREE, { 42 }, fork_id);
873 ws.append_leaves<bb::fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { 43 }, fork_id);
874 ws.batch_insert_indexed_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { { 129 } }, 0, fork_id);
875 ws.batch_insert_indexed_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { { 129, 1 } }, 0, fork_id);
876
877 auto fork_state_ref = ws.get_state_reference(WorldStateRevision{ .forkId = fork_id, .includeUncommitted = true });
878
879 ws.update_archive(fork_state_ref, { 1 }, fork_id);
880 auto fork_archive =
881 ws.get_tree_info(WorldStateRevision{ .forkId = fork_id, .includeUncommitted = true }, MerkleTreeId::ARCHIVE);
882
883 ws.delete_fork(fork_id);
884
885 ws.sync_block(fork_state_ref, { 1 }, { 42 }, { 43 }, { { 129 } }, { { { 129, 1 } } });
886
887 EXPECT_EQ(fork_state_ref, ws.get_state_reference(WorldStateRevision::committed()));
888}
889
890TEST_F(WorldStateTest, GetBlockForIndex)
891{
892 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
893 // bb::fr block_hash(1);
894 StateReference block_state_ref = {
895 { MerkleTreeId::NULLIFIER_TREE,
896 { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } },
897 { MerkleTreeId::NOTE_HASH_TREE,
898 { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } },
899 { MerkleTreeId::PUBLIC_DATA_TREE,
900 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
901 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
902 { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } },
903 };
904
906 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
907 WorldStateStatusSummary expected{ 1, 0, 1, true };
908 EXPECT_EQ(status.summary, expected);
909
911
913 MerkleTreeId::NULLIFIER_TREE,
914 MerkleTreeId::NOTE_HASH_TREE,
915 MerkleTreeId::PUBLIC_DATA_TREE,
916 MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
917 };
918
919 for (const auto& id : tree_ids) {
922 WorldStateRevision::committed(), id, { state_ref[id].second - 1 }, blockNumbers);
923
924 EXPECT_EQ(blockNumbers.size(), 1);
925 EXPECT_TRUE(blockNumbers[0].has_value());
926 EXPECT_EQ(blockNumbers[0].value(), 1);
927 }
928}
#define GENESIS_ARCHIVE_ROOT
#define GENESIS_BLOCK_HEADER_HASH
void TearDown() override
void SetUp() override
static std::string data_dir
uint32_t initial_header_generator_point
std::unordered_map< MerkleTreeId, index_t > tree_prefill
std::unordered_map< MerkleTreeId, uint32_t > tree_heights
Implements a parallelized batch insertion indexed tree Accepts template argument of the type of store...
Holds the Merkle trees responsible for storing the state of the Aztec protocol.
BatchInsertionResult< T > batch_insert_indexed_leaves(MerkleTreeId tree_id, const std::vector< T > &leaves, uint32_t subtree_depth, Fork::Id fork_id=CANONICAL_FORK_ID)
Batch inserts a set of leaves into an indexed Merkle Tree.
void append_leaves(MerkleTreeId tree_id, const std::vector< T > &leaves, Fork::Id fork_id=CANONICAL_FORK_ID)
Appends a set of leaves to an existing Merkle Tree.
StateReference get_initial_state_reference() const
Gets the initial state reference for all the trees in the world state.
std::optional< crypto::merkle_tree::IndexedLeaf< T > > get_indexed_leaf(const WorldStateRevision &revision, MerkleTreeId tree_id, index_t leaf_index) const
Get the leaf preimage object.
crypto::merkle_tree::TreeMetaResponse get_tree_info(const WorldStateRevision &revision, MerkleTreeId tree_id) const
Get tree metadata for a particular tree.
std::pair< bool, std::string > commit(WorldStateStatusFull &status)
Commits the current state of the world state.
void get_block_numbers_for_leaf_indices(const WorldStateRevision &revision, MerkleTreeId tree_id, const std::vector< index_t > &leafIndices, std::vector< std::optional< block_number_t > > &blockNumbers) const
StateReference get_state_reference(const WorldStateRevision &revision) const
Gets the state reference for all the trees in the world state.
void update_public_data(const crypto::merkle_tree::PublicDataLeafValue &new_value, Fork::Id fork_id=CANONICAL_FORK_ID)
Updates a leaf in an existing Merkle Tree.
void rollback()
Rolls back any uncommitted changes made to the world state.
WorldStateStatusFull sync_block(const StateReference &block_state_ref, const bb::fr &block_header_hash, const std::vector< bb::fr > &notes, const std::vector< bb::fr > &l1_to_l2_messages, const std::vector< crypto::merkle_tree::NullifierLeafValue > &nullifiers, const std::vector< crypto::merkle_tree::PublicDataLeafValue > &public_writes)
void delete_fork(const uint64_t &forkId)
uint64_t create_fork(const std::optional< block_number_t > &blockNumber)
crypto::merkle_tree::fr_sibling_path get_sibling_path(const WorldStateRevision &revision, MerkleTreeId tree_id, index_t leaf_index) const
Get the sibling path object for a leaf in a tree.
void find_leaf_indices(const WorldStateRevision &revision, MerkleTreeId tree_id, const std::vector< T > &leaves, std::vector< std::optional< index_t > > &indices, index_t start_index=0) const
Finds the index of a leaf in a tree.
std::optional< T > get_leaf(const WorldStateRevision &revision, MerkleTreeId tree_id, index_t leaf_index) const
Gets the value of a leaf in a tree.
crypto::merkle_tree::GetLowIndexedLeafResponse find_low_leaf_index(const WorldStateRevision &revision, MerkleTreeId tree_id, const bb::fr &leaf_key) const
Finds the leaf that would have its nextIdx/nextValue fields modified if the target leaf were to be in...
void update_archive(const StateReference &block_state_ref, const bb::fr &block_header_hash, Fork::Id fork_id=CANONICAL_FORK_ID)
Updates the archive tree with a new block.
void info(Args... args)
Definition log.hpp:70
NullifierTreeLeafPreimage low_leaf
void hash(State &state) noexcept
std::string random_temp_directory()
Definition fixtures.hpp:42
std::unordered_map< MerkleTreeId, TreeStateReference > StateReference
Definition types.hpp:32
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:123
field< Bn254FrParams > fr
Definition fr.hpp:174
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static fr hash_pair(const fr &lhs, const fr &rhs)
Definition hash.hpp:35
static fr hash(const std::vector< fr > &inputs)
Definition hash.hpp:30
static WorldStateRevision committed()
Definition types.hpp:41
static WorldStateRevision uncommitted()
Definition types.hpp:42
WorldStateStatusSummary summary
Definition types.hpp:207
void assert_fork_state_unchanged(const WorldState &ws, Fork::Id forkId, bool includeUncommitted, const std::vector< MerkleTreeId > &trees={ MerkleTreeId::NULLIFIER_TREE, MerkleTreeId::NOTE_HASH_TREE, MerkleTreeId::PUBLIC_DATA_TREE, MerkleTreeId::L1_TO_L2_MESSAGE_TREE, MerkleTreeId::ARCHIVE })
void assert_leaf_value(const WorldState &ws, WorldStateRevision revision, MerkleTreeId tree_id, index_t leaf_index, const Leaf &expected_value)
void assert_leaf_index(const WorldState &ws, WorldStateRevision revision, MerkleTreeId tree_id, const Leaf &value, index_t expected_index)
void assert_tree_size(const WorldState &ws, WorldStateRevision revision, MerkleTreeId tree_id, size_t expected_size)
void assert_sibling_path(const WorldState &ws, WorldStateRevision revision, MerkleTreeId tree_id, fr root, fr leaf, index_t index)
void assert_leaf_exists(const WorldState &ws, WorldStateRevision revision, MerkleTreeId tree_id, const Leaf &expected_value, bool exists)
void assert_leaf_status(const WorldState &ws, WorldStateRevision revision, MerkleTreeId tree_id, index_t leaf_index, bool exists)