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, NULLIFIER_TREE_HEIGHT },
39 { MerkleTreeId::NOTE_HASH_TREE, NOTE_HASH_TREE_HEIGHT },
40 { MerkleTreeId::PUBLIC_DATA_TREE, PUBLIC_DATA_TREE_HEIGHT },
41 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_TREE_HEIGHT },
42 { MerkleTreeId::ARCHIVE, ARCHIVE_HEIGHT },
43 };
44 std::unordered_map<MerkleTreeId, index_t> tree_prefill{
45 { MerkleTreeId::NULLIFIER_TREE, 128 },
46 { MerkleTreeId::PUBLIC_DATA_TREE, 128 },
47 };
49};
50
51std::string WorldStateTest::data_dir;
52
53template <typename Leaf>
55 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, index_t leaf_index, bool exists)
56{
57 std::optional<Leaf> leaf = ws.get_leaf<Leaf>(revision, tree_id, leaf_index);
58 EXPECT_EQ(leaf.has_value(), exists);
59}
60
61template <typename Leaf>
63 WorldStateRevision revision,
64 MerkleTreeId tree_id,
65 index_t leaf_index,
66 const Leaf& expected_value)
67{
68 std::optional<Leaf> leaf = ws.get_leaf<Leaf>(revision, tree_id, leaf_index);
69 EXPECT_EQ(leaf.has_value(), true);
70 EXPECT_EQ(leaf.value(), expected_value);
71}
72
73template <typename Leaf>
75 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, const Leaf& expected_value, bool exists)
76{
78 ws.find_leaf_indices<Leaf>(revision, tree_id, { expected_value }, indices);
79 EXPECT_EQ(indices.size(), 1);
80 EXPECT_EQ(indices[0].has_value(), exists);
81}
82
83template <typename Leaf>
85 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, const Leaf& value, index_t expected_index)
86{
88 ws.find_leaf_indices<Leaf>(revision, tree_id, { value }, indices);
89 EXPECT_EQ(indices.size(), 1);
90 EXPECT_TRUE(indices[0].has_value());
91 if (!indices[0].has_value()) {
92 return;
93 }
94 EXPECT_EQ(indices[0].value(), expected_index);
95}
96
97void assert_tree_size(const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, size_t expected_size)
98{
99 auto info = ws.get_tree_info(revision, tree_id);
100 EXPECT_EQ(info.meta.size, expected_size);
101}
102
104 const WorldState& ws, WorldStateRevision revision, MerkleTreeId tree_id, fr root, fr leaf, index_t index)
105{
106 auto sibling_path = ws.get_sibling_path(revision, tree_id, index);
107 fr left;
108 fr right;
109 fr hash = leaf;
110 for (const auto& node : sibling_path) {
111 if (index % 2 == 0) {
112 left = hash;
113 right = node;
114 } else {
115 left = node;
116 right = hash;
117 }
118
119 hash = HashPolicy::hash_pair(left, right);
120 index >>= 1;
121 }
122
123 EXPECT_EQ(hash, root);
124}
125
127 Fork::Id forkId,
128 bool includeUncommitted,
129 const std::vector<MerkleTreeId>& trees = { MerkleTreeId::NULLIFIER_TREE,
130 MerkleTreeId::NOTE_HASH_TREE,
131 MerkleTreeId::PUBLIC_DATA_TREE,
132 MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
133 MerkleTreeId::ARCHIVE })
134{
135
136 for (auto tree_id : trees) {
137 auto canonical_tree_info =
138 ws.get_tree_info(WorldStateRevision{ .includeUncommitted = includeUncommitted }, tree_id);
139 auto fork_tree_info = ws.get_tree_info(
141 .forkId = forkId,
142 .includeUncommitted = includeUncommitted,
143 },
144 tree_id);
145
146 EXPECT_EQ(canonical_tree_info.meta, fork_tree_info.meta);
147 }
148}
149
150TEST_F(WorldStateTest, GetInitialTreeInfoForAllTrees)
151{
152 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
153
154 {
155 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE);
156 EXPECT_EQ(info.meta.size, 128);
157 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::NULLIFIER_TREE));
158 EXPECT_EQ(info.meta.root, bb::fr("0x1ec3788cd1c32e54d889d67fe29e481114f9d4afe9b44b229aa29d8ad528dd31"));
159 }
160
161 {
162 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE);
163 EXPECT_EQ(info.meta.size, 0);
164 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::NOTE_HASH_TREE));
165 EXPECT_EQ(info.meta.root, bb::fr("0x2ac5dda169f6bb3b9ca09bbac34e14c94d1654597db740153a1288d859a8a30a"));
166 }
167
168 {
169 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE);
170 EXPECT_EQ(info.meta.size, 128);
171 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::PUBLIC_DATA_TREE));
172 EXPECT_EQ(info.meta.root, bb::fr("0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9"));
173 }
174
175 {
176 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
177 EXPECT_EQ(info.meta.size, 0);
178 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE));
179 EXPECT_EQ(info.meta.root, bb::fr("0x0d582c10ff8115413aa5b70564fdd2f3cefe1f33a1e43a47bc495081e91e73e5"));
180 }
181
182 {
183 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
184 EXPECT_EQ(info.meta.size, 1);
185 EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::ARCHIVE));
186 // this is the expected archive tree root at genesis
187 EXPECT_EQ(info.meta.root, bb::fr(GENESIS_ARCHIVE_ROOT));
188
189 // The leaf at index 0 is the genesis block hash.
191 ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 0, bb::fr(GENESIS_BLOCK_HEADER_HASH));
192 }
193}
194
195TEST_F(WorldStateTest, GetInitialTreeInfoWithPrefilledPublicData)
196{
197 std::string data_dir_prefilled = random_temp_directory();
198 std::filesystem::create_directories(data_dir_prefilled);
199
200 std::vector<PublicDataLeafValue> prefilled_values = { PublicDataLeafValue(1000, 2000),
201 PublicDataLeafValue(3000, 4000) };
202
203 WorldState ws_prefilled(thread_pool_size,
204 data_dir_prefilled,
205 map_size,
206 tree_heights,
207 tree_prefill,
208 prefilled_values,
209 initial_header_generator_point);
210
211 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
212
213 {
214 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE);
215 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE);
216 EXPECT_EQ(prefilled.meta.size, info.meta.size);
217 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
218 EXPECT_EQ(prefilled.meta.root, info.meta.root);
219 }
220
221 {
222 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE);
223 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE);
224 EXPECT_EQ(prefilled.meta.size, info.meta.size);
225 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
226 EXPECT_EQ(prefilled.meta.root, info.meta.root);
227 }
228
229 {
230 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE);
231 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE);
232 EXPECT_EQ(prefilled.meta.size, info.meta.size);
233 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
234 // Public data tree roots are different.
235 EXPECT_NE(prefilled.meta.root, info.meta.root);
236
237 // Prefilled values are appended at the end.
238 {
239 auto leaf = ws_prefilled.get_indexed_leaf<PublicDataLeafValue>(
240 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, prefilled.meta.size - 2);
241 EXPECT_EQ(leaf.value().leaf, prefilled_values[0]);
242 }
243 {
244 auto leaf = ws_prefilled.get_indexed_leaf<PublicDataLeafValue>(
245 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, prefilled.meta.size - 1);
246 EXPECT_EQ(leaf.value().leaf, prefilled_values[1]);
247 }
248 }
249
250 {
251 auto prefilled = ws_prefilled.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
252 auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
253 EXPECT_EQ(prefilled.meta.size, info.meta.size);
254 EXPECT_EQ(prefilled.meta.depth, info.meta.depth);
255 // Archive tree roots are different.
256 EXPECT_NE(prefilled.meta.root, info.meta.root);
257 }
258}
259
260TEST_F(WorldStateTest, GetStateReference)
261{
262 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
263
264 {
266 {
267 auto snapshot = state_ref.at(MerkleTreeId::NULLIFIER_TREE);
268 EXPECT_EQ(
269 snapshot,
270 std::make_pair(bb::fr("0x1ec3788cd1c32e54d889d67fe29e481114f9d4afe9b44b229aa29d8ad528dd31"), 128UL));
271 }
272
273 {
274 auto snapshot = state_ref.at(MerkleTreeId::NOTE_HASH_TREE);
275 EXPECT_EQ(
276 snapshot,
277 std::make_pair(bb::fr("0x2ac5dda169f6bb3b9ca09bbac34e14c94d1654597db740153a1288d859a8a30a"), 0UL));
278 }
279
280 {
281 auto snapshot = state_ref.at(MerkleTreeId::PUBLIC_DATA_TREE);
282 EXPECT_EQ(
283 snapshot,
284 std::make_pair(bb::fr("0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9"), 128UL));
285 }
286
287 {
288 auto snapshot = state_ref.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
289 EXPECT_EQ(
290 snapshot,
291 std::make_pair(bb::fr("0x0d582c10ff8115413aa5b70564fdd2f3cefe1f33a1e43a47bc495081e91e73e5"), 0UL));
292 }
293 }
294
295 {
296 ws.append_leaves<bb::fr>(MerkleTreeId::NOTE_HASH_TREE, { 1 });
297
299 {
300 auto snapshot = state_ref.at(MerkleTreeId::NULLIFIER_TREE);
301 EXPECT_EQ(
302 snapshot,
303 std::make_pair(bb::fr("0x1ec3788cd1c32e54d889d67fe29e481114f9d4afe9b44b229aa29d8ad528dd31"), 128UL));
304 }
305
306 {
307 auto snapshot = state_ref.at(MerkleTreeId::NOTE_HASH_TREE);
308 EXPECT_EQ(
309 snapshot,
310 std::make_pair(bb::fr("0x19581629b6133a7e6fb7b472992ed85cf2b33ee6a74109fd5323ffd2f12e4550"), 1UL));
311 }
312
313 {
314 auto snapshot = state_ref.at(MerkleTreeId::PUBLIC_DATA_TREE);
315 EXPECT_EQ(
316 snapshot,
317 std::make_pair(bb::fr("0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9"), 128UL));
318 }
319
320 {
321 auto snapshot = state_ref.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE);
322 EXPECT_EQ(
323 snapshot,
324 std::make_pair(bb::fr("0x0d582c10ff8115413aa5b70564fdd2f3cefe1f33a1e43a47bc495081e91e73e5"), 0UL));
325 }
326 }
327}
328
329TEST_F(WorldStateTest, GetInitialStateReference)
330{
331 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
332
333 auto before_commit = ws.get_initial_state_reference();
334 ws.append_leaves<bb::fr>(MerkleTreeId::NOTE_HASH_TREE, { 1 });
336 ws.commit(status);
337
338 auto after_commit = ws.get_initial_state_reference();
339
340 EXPECT_EQ(before_commit, after_commit);
341}
342
343TEST_F(WorldStateTest, AppendOnlyTrees)
344{
345 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
346
347 // the trees that start out empty
348 std::vector tree_ids{ MerkleTreeId::NOTE_HASH_TREE, MerkleTreeId::L1_TO_L2_MESSAGE_TREE };
349
350 for (auto tree_id : tree_ids) {
351 auto initial = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
352 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 0, false);
353
354 ws.append_leaves<fr>(tree_id, { fr(42) });
356 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 0, false);
358
359 auto uncommitted = ws.get_tree_info(WorldStateRevision::uncommitted(), tree_id);
360 // uncommitted state diverges from committed state
361 EXPECT_EQ(uncommitted.meta.size, initial.meta.size + 1);
362 EXPECT_NE(uncommitted.meta.root, initial.meta.root);
363
364 assert_sibling_path(ws, WorldStateRevision::uncommitted(), tree_id, uncommitted.meta.root, fr(42), 0);
365
366 auto committed = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
367 EXPECT_EQ(committed.meta.size, initial.meta.size);
368 EXPECT_EQ(committed.meta.root, initial.meta.root);
369
371 ws.commit(status);
372 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 0, fr(42));
373 assert_leaf_index(ws, WorldStateRevision::committed(), tree_id, fr(42), 0);
374
375 auto after_commit = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
376 // commiting updates the committed state
377 EXPECT_EQ(after_commit.meta.size, uncommitted.meta.size);
378 EXPECT_EQ(after_commit.meta.root, uncommitted.meta.root);
379
380 assert_sibling_path(ws, WorldStateRevision::committed(), tree_id, after_commit.meta.root, fr(42), 0);
381
382 ws.append_leaves<fr>(tree_id, { fr(43) });
384 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 1, false);
386
387 auto before_rollback = ws.get_tree_info(WorldStateRevision::uncommitted(), tree_id);
388 EXPECT_EQ(before_rollback.meta.size, after_commit.meta.size + 1);
389 EXPECT_NE(before_rollback.meta.root, after_commit.meta.root);
390
391 ws.rollback();
392 assert_leaf_status<fr>(ws, WorldStateRevision::uncommitted(), tree_id, 1, false);
393 assert_leaf_status<fr>(ws, WorldStateRevision::committed(), tree_id, 1, false);
394
395 auto after_rollback = ws.get_tree_info(WorldStateRevision::committed(), tree_id);
396 // rollback restores the committed state
397 EXPECT_EQ(after_rollback.meta.size, after_commit.meta.size);
398 EXPECT_EQ(after_rollback.meta.root, after_commit.meta.root);
399 }
400}
401
402TEST_F(WorldStateTest, AppendOnlyAllowDuplicates)
403{
404 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
405
406 // the trees that start out empty
407 std::vector tree_ids{
408 MerkleTreeId::NOTE_HASH_TREE,
409 MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
410 };
411
412 for (auto tree_id : tree_ids) {
413 ws.append_leaves<fr>(tree_id, { fr(42), fr(42) });
414 ws.append_leaves<fr>(tree_id, { fr(42) });
415
419
421 ws.commit(status);
422
423 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 0, fr(42));
424 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 1, fr(42));
425 assert_leaf_value(ws, WorldStateRevision::committed(), tree_id, 2, fr(42));
426 }
427}
428
430{
431 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
432 auto tree_id = MerkleTreeId::NULLIFIER_TREE;
433 NullifierLeafValue test_nullifier(142);
434
435 auto predecessor_of_142 =
436 ws.find_low_leaf_index(WorldStateRevision::committed(), tree_id, test_nullifier.get_key());
437 EXPECT_EQ(predecessor_of_142, GetLowIndexedLeafResponse(false, 127UL));
438
439 ws.append_leaves<NullifierLeafValue>(tree_id, { test_nullifier });
440 assert_leaf_value(ws, WorldStateRevision::uncommitted(), tree_id, 128, test_nullifier);
441
443 ws.commit(status);
444
445 auto test_leaf = ws.get_indexed_leaf<NullifierLeafValue>(WorldStateRevision::committed(), tree_id, 128);
446 // at this point 142 should be the biggest leaf so it wraps back to 0
447 EXPECT_TRUE(test_leaf.has_value());
448 EXPECT_EQ(test_leaf.value(), IndexedLeaf(test_nullifier, 0, 0));
449
450 auto predecessor_of_142_again =
451 ws.find_low_leaf_index(WorldStateRevision::committed(), tree_id, test_nullifier.get_key());
452 EXPECT_EQ(predecessor_of_142_again, GetLowIndexedLeafResponse(true, 128UL));
453
454 auto predecessor_of_143 = ws.find_low_leaf_index(WorldStateRevision::committed(), tree_id, 143);
455 EXPECT_EQ(predecessor_of_143,
456 GetLowIndexedLeafResponse(false, 128UL)); // predecessor is going to be nullifier 142 on slot 127
457
461 tree_id,
462 info.meta.root,
463 HashPolicy::hash(test_leaf.value().get_hash_inputs()),
464 128);
465}
466
467TEST_F(WorldStateTest, NullifierTreeDuplicates)
468{
469 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
470 auto tree_id = MerkleTreeId::NULLIFIER_TREE;
471 NullifierLeafValue test_nullifier(142);
472
473 ws.append_leaves<NullifierLeafValue>(tree_id, { test_nullifier });
475 ws.commit(status);
476
478 EXPECT_THROW(ws.append_leaves<NullifierLeafValue>(tree_id, { test_nullifier }), std::runtime_error);
480}
481
482TEST_F(WorldStateTest, NullifierBatchInsert)
483{
484 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
486 MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(150), NullifierLeafValue(142), NullifierLeafValue(180) }, 2);
487
488 std::vector<std::pair<NullifierLeafValue, size_t>> expected_sorted_leaves = { { NullifierLeafValue(180), 2 },
489 { NullifierLeafValue(150), 0 },
490 { NullifierLeafValue(142), 1 } };
491 EXPECT_EQ(response.sorted_leaves, expected_sorted_leaves);
492
493 {
494 // insertion happens in descending order, but keeping original indices
495 // first insert leaf 180, at index 130 (tree had size 127, 180 is the third item => 127 + 3)
496 // predecessor will be 127, currently linked to head of the list (0)
497 auto low_leaf = response.low_leaf_witness_data[0];
498 auto expected_low_leaf = IndexedLeaf(NullifierLeafValue(127), 0, fr(0));
499 EXPECT_EQ(low_leaf.index, 127);
500 EXPECT_EQ(low_leaf.leaf, expected_low_leaf);
501 }
502
503 {
504 // insert 150 on position 128 (127 + 1)
505 // predecessor will be 127 linked to 180
506 auto low_leaf = response.low_leaf_witness_data[1];
507 auto expected_low_leaf = IndexedLeaf(NullifierLeafValue(127), 130, fr(180));
508 EXPECT_EQ(low_leaf.index, 127);
509 EXPECT_EQ(low_leaf.leaf, expected_low_leaf);
510 }
511
512 {
513 // finally, insert 142 on position 129(127 + 2)
514 // prededecessor will be 127 linked to 150
515 auto low_leaf = response.low_leaf_witness_data[2];
516 auto expected_low_leaf = IndexedLeaf(NullifierLeafValue(127), 128, fr(150));
517 EXPECT_EQ(low_leaf.index, 127);
518 EXPECT_EQ(low_leaf.leaf, expected_low_leaf);
519 }
520}
521
523{
524 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
525
526 ws.append_leaves(MerkleTreeId::PUBLIC_DATA_TREE, std::vector{ PublicDataLeafValue(142, 0) });
527 assert_tree_size(ws, WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 129);
528
530 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 128);
531 EXPECT_EQ(leaf.value().leaf, PublicDataLeafValue(142, 0));
532
534 // updating insert a dummy leaf
535 assert_tree_size(ws, WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 130);
536
538 WorldStateRevision::uncommitted(), MerkleTreeId::PUBLIC_DATA_TREE, 128);
539 EXPECT_EQ(leaf.value().leaf, PublicDataLeafValue(142, 1));
540}
541
542TEST_F(WorldStateTest, CommitsAndRollsBackAllTrees)
543{
544 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
545
546 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { fr(42) });
547 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { fr(42) });
548 ws.append_leaves<fr>(MerkleTreeId::ARCHIVE, { fr(42) });
549 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(142) });
550 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(142, 1) });
551
553 ws.commit(status);
554
555 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, 0, fr(42));
556 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 0, fr(42));
557 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 1, fr(42));
558 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, 128, NullifierLeafValue(142));
560 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, 128, PublicDataLeafValue(142, 1));
561
562 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { fr(43) });
563 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { fr(43) });
564 ws.append_leaves<fr>(MerkleTreeId::ARCHIVE, { fr(43) });
565 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(143) });
566 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(143, 1) });
567
568 ws.rollback();
569
570 assert_leaf_exists(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, fr(43), false);
571 assert_leaf_exists(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, fr(43), false);
572 assert_leaf_exists(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, fr(43), false);
574 ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, NullifierLeafValue(143), false);
576 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, PublicDataLeafValue(143, 1), false);
577}
578
579TEST_F(WorldStateTest, SyncExternalBlockFromEmpty)
580{
581 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
582 StateReference block_state_ref = {
583 { MerkleTreeId::NULLIFIER_TREE,
584 { fr("0x1a8a3172ecd372de7d144459831cfabf0496159a5defd0f2ecb8f5124f1717af"), 129 } },
585 { MerkleTreeId::NOTE_HASH_TREE,
586 { fr("0x2496ae3983b59733967ef32aecb041134d5f17bd2b040def30e699432dcc8967"), 1 } },
587 { MerkleTreeId::PUBLIC_DATA_TREE,
588 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
589 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
590 { fr("0x149be5d1559bbefa0006c5e55ed982c43a1db53848e2f59385523d0c40d74a94"), 1 } },
591 };
592
594 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
595 WorldStateStatusSummary expected(1, 0, 1, true);
596 EXPECT_EQ(status.summary, expected);
597
598 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, 0, fr(42));
599 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 0, fr(43));
600 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, 128, NullifierLeafValue(144));
602 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, 128, PublicDataLeafValue(145, 1));
603 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 1, fr(1));
604
606 for (const auto& [tree_id, snapshot] : block_state_ref) {
607 EXPECT_EQ(state_ref.at(tree_id), snapshot);
608 }
609
612 WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, { 0 }, blockNumbers);
613 EXPECT_EQ(blockNumbers.size(), 1);
614 EXPECT_EQ(blockNumbers[0], 1);
615
617 WorldStateRevision{ .forkId = CANONICAL_FORK_ID, .blockNumber = 2, .includeUncommitted = false },
618 MerkleTreeId::NOTE_HASH_TREE,
619 { 0 },
620 blockNumbers),
621 std::runtime_error);
622}
623
624TEST_F(WorldStateTest, SyncBlockFromDirtyState)
625{
626 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
627 StateReference block_state_ref = {
628 { MerkleTreeId::NULLIFIER_TREE,
629 { fr("0x1a8a3172ecd372de7d144459831cfabf0496159a5defd0f2ecb8f5124f1717af"), 129 } },
630 { MerkleTreeId::NOTE_HASH_TREE,
631 { fr("0x2496ae3983b59733967ef32aecb041134d5f17bd2b040def30e699432dcc8967"), 1 } },
632 { MerkleTreeId::PUBLIC_DATA_TREE,
633 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
634 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
635 { fr("0x149be5d1559bbefa0006c5e55ed982c43a1db53848e2f59385523d0c40d74a94"), 1 } },
636 };
637
638 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { fr(142) });
639 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { fr(143) });
640 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(142) });
641 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(142, 1) });
642
643 auto uncommitted_state_ref = ws.get_state_reference(WorldStateRevision::uncommitted());
644 for (const auto& [tree_id, snapshot] : block_state_ref) {
645 EXPECT_NE(uncommitted_state_ref.at(tree_id), snapshot);
646 }
647
649 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
650 WorldStateStatusSummary expected{ 1, 0, 1, true };
651 EXPECT_EQ(status.summary, expected);
652
653 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE, 0, fr(42));
654 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 0, fr(43));
655 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE, 128, NullifierLeafValue(144));
657 ws, WorldStateRevision::committed(), MerkleTreeId::PUBLIC_DATA_TREE, 128, PublicDataLeafValue(145, 1));
658 assert_leaf_value(ws, WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, 1, fr(1));
659
661 for (const auto& [tree_id, snapshot] : block_state_ref) {
662 EXPECT_EQ(state_ref.at(tree_id), snapshot);
663 }
664}
665
666TEST_F(WorldStateTest, SyncCurrentBlock)
667{
668 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
669 bb::fr block_hash(1);
670 StateReference block_state_ref = {
671 { MerkleTreeId::NULLIFIER_TREE,
672 { fr("0x1a8a3172ecd372de7d144459831cfabf0496159a5defd0f2ecb8f5124f1717af"), 129 } },
673 { MerkleTreeId::NOTE_HASH_TREE,
674 { fr("0x2496ae3983b59733967ef32aecb041134d5f17bd2b040def30e699432dcc8967"), 1 } },
675 { MerkleTreeId::PUBLIC_DATA_TREE,
676 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
677 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
678 { fr("0x149be5d1559bbefa0006c5e55ed982c43a1db53848e2f59385523d0c40d74a94"), 1 } },
679 };
680
681 ws.append_leaves<fr>(MerkleTreeId::NOTE_HASH_TREE, { 42 });
682 ws.append_leaves<fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { 43 });
683 ws.append_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { NullifierLeafValue(144) });
684 ws.append_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { PublicDataLeafValue(145, 1) });
685 ws.append_leaves<fr>(MerkleTreeId::ARCHIVE, { block_hash });
686
687 auto uncommitted_state_ref = ws.get_state_reference(WorldStateRevision::uncommitted());
688 for (const auto& [tree_id, snapshot] : block_state_ref) {
689 EXPECT_EQ(uncommitted_state_ref.at(tree_id), snapshot);
690 }
691
693 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
694 WorldStateStatusSummary expected{ 1, 0, 1, true };
695 EXPECT_EQ(status.summary, expected);
696
697 assert_leaf_value(ws, WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE, 1, fr(1));
698
700 for (const auto& [tree_id, snapshot] : block_state_ref) {
701 EXPECT_EQ(state_ref.at(tree_id), snapshot);
702 }
703}
704
705TEST_F(WorldStateTest, RejectSyncBlockWithBadPublicWriteBatches)
706{
707 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
708 StateReference block_state_ref = {
709 { MerkleTreeId::NULLIFIER_TREE,
710 { fr("0x1a8a3172ecd372de7d144459831cfabf0496159a5defd0f2ecb8f5124f1717af"), 129 } },
711 { MerkleTreeId::NOTE_HASH_TREE,
712 { fr("0x2496ae3983b59733967ef32aecb041134d5f17bd2b040def30e699432dcc8967"), 1 } },
713 { MerkleTreeId::PUBLIC_DATA_TREE,
714 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
715 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
716 { fr("0x149be5d1559bbefa0006c5e55ed982c43a1db53848e2f59385523d0c40d74a94"), 1 } },
717 };
718
719 auto sync = [&]() {
720 return ws.sync_block(block_state_ref,
721 fr(1),
722 { 42 },
723 { 43 },
724 { NullifierLeafValue(144) },
725 // this should be rejected because we can't have duplicate slots in the same batch
726 { { PublicDataLeafValue(145, 1), PublicDataLeafValue(145, 2) } });
727 };
728
729 EXPECT_THROW(sync(), std::runtime_error);
730}
731
732TEST_F(WorldStateTest, RejectSyncBlockWithInvalidStateRef)
733{
734 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
735 StateReference block_state_ref = {
736 { MerkleTreeId::NULLIFIER_TREE,
737 { fr("0x1a8a3172ecd372de7d144459831cfabf0496159a5defd0f2ecb8f5124f1717af"), 129 } },
738 { MerkleTreeId::NOTE_HASH_TREE,
739 { fr("0x2496ae3983b59733967ef32aecb041134d5f17bd2b040def30e699432dcc8967"), 1 } },
740 { MerkleTreeId::PUBLIC_DATA_TREE,
741 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
742 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
743 { fr("0x149be5d1559bbefa0006c5e55ed982c43a1db53848e2f59385523d0c40d74a94"), 1 } },
744 };
745
746 auto sync = [&]() {
747 return ws.sync_block(block_state_ref,
748 fr(1),
749 { 42 },
750 { 43 },
751 { NullifierLeafValue(144) },
752 // this should be rejected because public data tree root will not match the state ref above
753 // (state ref above is for slot[145]=1, not slot[145]=2)
754 { { PublicDataLeafValue(145, 2) } });
755 };
756
757 EXPECT_THROW(sync(), std::runtime_error);
758}
759
760TEST_F(WorldStateTest, SyncEmptyBlock)
761{
762 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
764 ws.sync_block(block_state_ref, fr(1), {}, {}, {}, {});
766 EXPECT_EQ(block_state_ref, after_sync);
767
769 ws.find_leaf_indices<fr>(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE, { fr(1) }, indices);
771 EXPECT_EQ(indices, expected);
772}
773
774TEST_F(WorldStateTest, ForkingAtBlock0SameState)
775{
776 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
777 auto fork_id = ws.create_fork(0);
778
779 assert_fork_state_unchanged(ws, fork_id, false);
780 assert_fork_state_unchanged(ws, fork_id, true);
781}
782
783TEST_F(WorldStateTest, ForkingAtBlock0AndAdvancingFork)
784{
785 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
786 auto fork_id = ws.create_fork(0);
787
788 auto canonical_archive_state_before = ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
789 auto fork_archive_state_before = ws.get_tree_info(
791 .forkId = fork_id,
792 .includeUncommitted = true,
793 },
794 MerkleTreeId::ARCHIVE);
795
796 ws.append_leaves<bb::fr>(MerkleTreeId::ARCHIVE, { fr(1) }, fork_id);
797
798 auto canonical_archive_state_after = ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
799 auto fork_archive_state_after = ws.get_tree_info(
801 .forkId = fork_id,
802 .includeUncommitted = true,
803 },
804 MerkleTreeId::ARCHIVE);
805
806 EXPECT_EQ(canonical_archive_state_after.meta, canonical_archive_state_before.meta);
807 EXPECT_EQ(fork_archive_state_before.meta, canonical_archive_state_before.meta);
808 EXPECT_NE(fork_archive_state_after.meta, fork_archive_state_before.meta);
809}
810
811TEST_F(WorldStateTest, ForkingAtBlock0AndAdvancingCanonicalState)
812{
813 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
814 auto fork_id = ws.create_fork(0);
815
816 auto canonical_archive_state_before = ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
817 auto fork_archive_state_before_insert = ws.get_tree_info(
819 .forkId = fork_id,
820 .includeUncommitted = true,
821 },
822 MerkleTreeId::ARCHIVE);
823
824 // fork the state
825 ws.append_leaves<bb::fr>(MerkleTreeId::ARCHIVE, { fr(1) });
826 ws.append_leaves<bb::fr>(MerkleTreeId::ARCHIVE, { fr(2) }, fork_id);
827
828 auto canonical_archive_state_after_insert =
829 ws.get_tree_info(WorldStateRevision::uncommitted(), MerkleTreeId::ARCHIVE);
830 auto fork_archive_state_after_insert = ws.get_tree_info(
832 .forkId = fork_id,
833 .includeUncommitted = true,
834 },
835 MerkleTreeId::ARCHIVE);
836
837 EXPECT_EQ(fork_archive_state_before_insert.meta, canonical_archive_state_before.meta);
838
839 EXPECT_NE(canonical_archive_state_after_insert.meta, canonical_archive_state_before.meta);
840 EXPECT_NE(fork_archive_state_after_insert.meta, fork_archive_state_before_insert.meta);
841 EXPECT_NE(fork_archive_state_after_insert.meta, canonical_archive_state_after_insert.meta);
842
844 ws.commit(status);
845 auto canonical_archive_state_after_commit =
846 ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::ARCHIVE);
847 auto fork_archive_state_after_commit = ws.get_tree_info(
849 .forkId = fork_id,
850 .includeUncommitted = false,
851 },
852 MerkleTreeId::ARCHIVE);
853
854 // committed fork state should match the state before fork had been modified
855 EXPECT_EQ(fork_archive_state_after_commit.meta.size, fork_archive_state_before_insert.meta.size);
856 EXPECT_EQ(fork_archive_state_after_commit.meta.root, fork_archive_state_before_insert.meta.root);
857 // canonical state before commit should match state after commit
858 // EXPECT_EQ(canonical_archive_state_after_commit.meta, canonical_archive_state_after_insert.meta);
859 EXPECT_EQ(canonical_archive_state_after_commit.meta.root, canonical_archive_state_after_insert.meta.root);
860 EXPECT_EQ(canonical_archive_state_after_commit.meta.size, canonical_archive_state_after_insert.meta.size);
861
862 // canonical should have value 1 as the first leaf (committed state)
863 assert_leaf_value<bb::fr>(ws, WorldStateRevision{ .includeUncommitted = false }, MerkleTreeId::ARCHIVE, 1, 1);
864 // fork should still have value 2 as the first leaf (uncommitted)
865 assert_leaf_value<bb::fr>(
866 ws, WorldStateRevision{ .forkId = fork_id, .includeUncommitted = true }, MerkleTreeId::ARCHIVE, 1, 2);
867}
868
869TEST_F(WorldStateTest, BuildsABlockInAFork)
870{
871 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
872 auto fork_id = ws.create_fork(0);
873
874 ws.append_leaves<bb::fr>(MerkleTreeId::NOTE_HASH_TREE, { 42 }, fork_id);
875 ws.append_leaves<bb::fr>(MerkleTreeId::L1_TO_L2_MESSAGE_TREE, { 43 }, fork_id);
876 ws.batch_insert_indexed_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { { 129 } }, 0, fork_id);
877 ws.batch_insert_indexed_leaves<PublicDataLeafValue>(MerkleTreeId::PUBLIC_DATA_TREE, { { 129, 1 } }, 0, fork_id);
878
879 auto fork_state_ref = ws.get_state_reference(WorldStateRevision{ .forkId = fork_id, .includeUncommitted = true });
880
881 ws.update_archive(fork_state_ref, { 1 }, fork_id);
882 auto fork_archive =
883 ws.get_tree_info(WorldStateRevision{ .forkId = fork_id, .includeUncommitted = true }, MerkleTreeId::ARCHIVE);
884
885 ws.delete_fork(fork_id);
886
887 ws.sync_block(fork_state_ref, { 1 }, { 42 }, { 43 }, { { 129 } }, { { { 129, 1 } } });
888
889 EXPECT_EQ(fork_state_ref, ws.get_state_reference(WorldStateRevision::committed()));
890}
891
892TEST_F(WorldStateTest, GetBlockForIndex)
893{
894 WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point);
895 // bb::fr block_hash(1);
896 StateReference block_state_ref = {
897 { MerkleTreeId::NULLIFIER_TREE,
898 { fr("0x1a8a3172ecd372de7d144459831cfabf0496159a5defd0f2ecb8f5124f1717af"), 129 } },
899 { MerkleTreeId::NOTE_HASH_TREE,
900 { fr("0x2496ae3983b59733967ef32aecb041134d5f17bd2b040def30e699432dcc8967"), 1 } },
901 { MerkleTreeId::PUBLIC_DATA_TREE,
902 { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } },
903 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
904 { fr("0x149be5d1559bbefa0006c5e55ed982c43a1db53848e2f59385523d0c40d74a94"), 1 } },
905 };
906
908 block_state_ref, fr(1), { 42 }, { 43 }, { NullifierLeafValue(144) }, { { PublicDataLeafValue(145, 1) } });
909 WorldStateStatusSummary expected{ 1, 0, 1, true };
910 EXPECT_EQ(status.summary, expected);
911
913
915 MerkleTreeId::NULLIFIER_TREE,
916 MerkleTreeId::NOTE_HASH_TREE,
917 MerkleTreeId::PUBLIC_DATA_TREE,
918 MerkleTreeId::L1_TO_L2_MESSAGE_TREE,
919 };
920
921 for (const auto& id : tree_ids) {
924 WorldStateRevision::committed(), id, { state_ref[id].second - 1 }, blockNumbers);
925
926 EXPECT_EQ(blockNumbers.size(), 1);
927 EXPECT_TRUE(blockNumbers[0].has_value());
928 EXPECT_EQ(blockNumbers[0].value(), 1);
929 }
930}
#define ARCHIVE_HEIGHT
#define L1_TO_L2_MSG_TREE_HEIGHT
#define GENESIS_ARCHIVE_ROOT
#define NULLIFIER_TREE_HEIGHT
#define GENESIS_BLOCK_HEADER_HASH
#define NOTE_HASH_TREE_HEIGHT
#define PUBLIC_DATA_TREE_HEIGHT
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:74
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:188
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:33
static fr hash(const std::vector< fr > &inputs)
Definition hash.hpp:28
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)