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