Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
world_state.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <any>
5#include <array>
6#include <cstdint>
7#include <iostream>
8#include <memory>
9#include <optional>
10#include <sstream>
11#include <stdexcept>
12#include <sys/types.h>
13#include <unordered_map>
14
27#include "napi.h"
28
29using namespace bb::nodejs;
30using namespace bb::world_state;
31using namespace bb::crypto::merkle_tree;
32using namespace bb::messaging;
33
34const uint64_t DEFAULT_MAP_SIZE = 1024UL * 1024;
35
37 : ObjectWrap(info)
38{
39 uint64_t thread_pool_size = 16;
40 std::string data_dir;
42 { MerkleTreeId::ARCHIVE, DEFAULT_MAP_SIZE },
43 { MerkleTreeId::NULLIFIER_TREE, DEFAULT_MAP_SIZE },
44 { MerkleTreeId::NOTE_HASH_TREE, DEFAULT_MAP_SIZE },
45 { MerkleTreeId::PUBLIC_DATA_TREE, DEFAULT_MAP_SIZE },
46 { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, DEFAULT_MAP_SIZE },
47 };
48 std::unordered_map<MerkleTreeId, uint32_t> tree_height;
49 std::unordered_map<MerkleTreeId, index_t> tree_prefill;
50 std::vector<PublicDataLeafValue> prefilled_public_data;
52 MerkleTreeId::NULLIFIER_TREE, MerkleTreeId::NOTE_HASH_TREE, MerkleTreeId::PUBLIC_DATA_TREE,
53 MerkleTreeId::L1_TO_L2_MESSAGE_TREE, MerkleTreeId::ARCHIVE,
54 };
55 uint32_t initial_header_generator_point = 0;
56
57 Napi::Env env = info.Env();
58
59 size_t data_dir_index = 0;
60 if (info.Length() > data_dir_index && info[data_dir_index].IsString()) {
61 data_dir = info[data_dir_index].As<Napi::String>();
62 } else {
63 throw Napi::TypeError::New(env, "Directory needs to be a string");
64 }
65
66 size_t tree_height_index = 1;
67 if (info.Length() > tree_height_index && info[tree_height_index].IsObject()) {
68 Napi::Object obj = info[tree_height_index].As<Napi::Object>();
69
70 for (auto tree_id : tree_ids) {
71 if (obj.Has(tree_id)) {
72 tree_height[tree_id] = obj.Get(tree_id).As<Napi::Number>().Uint32Value();
73 }
74 }
75 } else {
76 throw Napi::TypeError::New(env, "Tree heights must be a map");
77 }
78
79 size_t tree_prefill_index = 2;
80 if (info.Length() > tree_prefill_index && info[tree_prefill_index].IsObject()) {
81 Napi::Object obj = info[tree_prefill_index].As<Napi::Object>();
82
83 for (auto tree_id : tree_ids) {
84 if (obj.Has(tree_id)) {
85 tree_prefill[tree_id] = obj.Get(tree_id).As<Napi::Number>().Uint32Value();
86 }
87 }
88 } else {
89 throw Napi::TypeError::New(env, "Tree prefill must be a map");
90 }
91
92 size_t prefilled_public_data_index = 3;
93 if (info.Length() > prefilled_public_data_index && info[prefilled_public_data_index].IsArray()) {
94 Napi::Array arr = info[prefilled_public_data_index].As<Napi::Array>();
95 for (uint32_t i = 0; i < arr.Length(); ++i) {
96 Napi::Array deserialized = arr.Get(i).As<Napi::Array>();
97 if (deserialized.Length() != 2 || !deserialized.Get(uint32_t(0)).IsBuffer() ||
98 !deserialized.Get(uint32_t(1)).IsBuffer()) {
99 throw Napi::TypeError::New(env, "Prefilled public data value must be a buffer array of size 2");
100 }
101 Napi::Buffer<uint8_t> slot_buf = deserialized.Get(uint32_t(0)).As<Napi::Buffer<uint8_t>>();
102 Napi::Buffer<uint8_t> value_buf = deserialized.Get(uint32_t(1)).As<Napi::Buffer<uint8_t>>();
103 uint256_t slot = 0;
104 uint256_t value = 0;
105 for (size_t j = 0; j < 32; ++j) {
106 slot = (slot << 8) | slot_buf[j];
107 value = (value << 8) | value_buf[j];
108 }
109 prefilled_public_data.push_back(PublicDataLeafValue(slot, value));
110 }
111 } else {
112 throw Napi::TypeError::New(env, "Prefilled public data must be an array");
113 }
114
115 size_t initial_header_generator_point_index = 4;
116 if (info.Length() > initial_header_generator_point_index && info[initial_header_generator_point_index].IsNumber()) {
117 initial_header_generator_point = info[initial_header_generator_point_index].As<Napi::Number>().Uint32Value();
118 } else {
119 throw Napi::TypeError::New(env, "Header generator point needs to be a number");
120 }
121
122 // optional parameters
123 size_t map_size_index = 5;
124 if (info.Length() > map_size_index) {
125 if (info[map_size_index].IsObject()) {
126 Napi::Object obj = info[map_size_index].As<Napi::Object>();
127
128 for (auto tree_id : tree_ids) {
129 if (obj.Has(tree_id)) {
130 map_size[tree_id] = obj.Get(tree_id).As<Napi::Number>().Uint32Value();
131 }
132 }
133 } else if (info[map_size_index].IsNumber()) {
134 uint64_t size = info[map_size_index].As<Napi::Number>().Uint32Value();
135 for (auto tree_id : tree_ids) {
136 map_size[tree_id] = size;
137 }
138 } else {
139 throw Napi::TypeError::New(env, "Map size must be a number or an object");
140 }
141 }
142
143 size_t thread_pool_size_index = 6;
144 if (info.Length() > thread_pool_size_index) {
145 if (!info[thread_pool_size_index].IsNumber()) {
146 throw Napi::TypeError::New(env, "Thread pool size must be a number");
147 }
148
149 thread_pool_size = info[thread_pool_size_index].As<Napi::Number>().Uint32Value();
150 }
151
152 _ws = std::make_unique<WorldState>(thread_pool_size,
153 data_dir,
154 map_size,
155 tree_height,
156 tree_prefill,
157 prefilled_public_data,
158 initial_header_generator_point);
159
162 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return get_tree_info(obj, buffer); });
163
166 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return get_state_reference(obj, buffer); });
167
170 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return get_initial_state_reference(obj, buffer); });
171
174 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return get_leaf_value(obj, buffer); });
175
178 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return get_leaf_preimage(obj, buffer); });
179
182 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return get_sibling_path(obj, buffer); });
183
185 [this](msgpack::object& obj, msgpack::sbuffer& buffer) {
187 });
188
191 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return find_leaf_indices(obj, buffer); });
192
195 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return find_sibling_paths(obj, buffer); });
196
199 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return find_low_leaf(obj, buffer); });
200
203 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return append_leaves(obj, buffer); });
204
207 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return batch_insert(obj, buffer); });
208
211 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return sequential_insert(obj, buffer); });
212
215 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return update_archive(obj, buffer); });
216
218 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return commit(obj, buffer); });
219
222 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return rollback(obj, buffer); });
223
226 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return sync_block(obj, buffer); });
227
230 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return create_fork(obj, buffer); });
231
234 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return delete_fork(obj, buffer); });
235
238 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return set_finalized(obj, buffer); });
239
241 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return unwind(obj, buffer); });
242
245 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return remove_historical(obj, buffer); });
246
249 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return get_status(obj, buffer); });
250
252 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return close(obj, buffer); });
253
256 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return checkpoint(obj, buffer); });
257
260 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return commit_checkpoint(obj, buffer); });
261
264 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return revert_checkpoint(obj, buffer); });
265
268 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return commit_all_checkpoints(obj, buffer); });
269
272 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return revert_all_checkpoints(obj, buffer); });
273
276 [this](msgpack::object& obj, msgpack::sbuffer& buffer) { return copy_stores(obj, buffer); });
277}
278
279Napi::Value WorldStateWrapper::call(const Napi::CallbackInfo& info)
280{
281 Napi::Env env = info.Env();
282 // keep this in a shared pointer so that AsyncOperation can resolve/reject the promise once the execution is
283 // complete on an separate thread
285
286 if (info.Length() < 1) {
287 deferred->Reject(Napi::TypeError::New(env, "Wrong number of arguments").Value());
288 } else if (!info[0].IsBuffer()) {
289 deferred->Reject(Napi::TypeError::New(env, "Argument must be a buffer").Value());
290 } else if (!_ws) {
291 deferred->Reject(Napi::TypeError::New(env, "World state has been closed").Value());
292 } else {
293 auto buffer = info[0].As<Napi::Buffer<char>>();
294 size_t length = buffer.Length();
295 // we mustn't access the Napi::Env outside of this top-level function
296 // so copy the data to a variable we own
297 // and make it a shared pointer so that it doesn't get destroyed as soon as we exit this code block
299 std::copy_n(buffer.Data(), length, data->data());
300
301 auto* op = new AsyncOperation(env, deferred, [=, this](msgpack::sbuffer& buf) {
302 msgpack::object_handle obj_handle = msgpack::unpack(data->data(), length);
303 msgpack::object obj = obj_handle.get();
305 });
306
307 // Napi is now responsible for destroying this object
308 op->Queue();
309 }
310
311 return deferred->Promise();
312}
313
314bool WorldStateWrapper::get_tree_info(msgpack::object& obj, msgpack::sbuffer& buffer) const
315{
317 obj.convert(request);
318 auto info = _ws->get_tree_info(request.value.revision, request.value.treeId);
319
320 MsgHeader header(request.header.messageId);
323 header,
324 { request.value.treeId, info.meta.root, info.meta.size, info.meta.depth });
325
326 msgpack::pack(buffer, resp_msg);
327
328 return true;
329}
330
331bool WorldStateWrapper::get_state_reference(msgpack::object& obj, msgpack::sbuffer& buffer) const
332{
334 obj.convert(request);
335 auto state = _ws->get_state_reference(request.value.revision);
336
337 MsgHeader header(request.header.messageId);
340
341 msgpack::pack(buffer, resp_msg);
342
343 return true;
344}
345
346bool WorldStateWrapper::get_initial_state_reference(msgpack::object& obj, msgpack::sbuffer& buffer) const
347{
348 HeaderOnlyMessage request;
349 obj.convert(request);
350 auto state = _ws->get_initial_state_reference();
351
352 MsgHeader header(request.header.messageId);
355
356 msgpack::pack(buffer, resp_msg);
357
358 return true;
359}
360
361bool WorldStateWrapper::get_leaf_value(msgpack::object& obj, msgpack::sbuffer& buffer) const
362{
364 obj.convert(request);
365
366 switch (request.value.treeId) {
367 case MerkleTreeId::NOTE_HASH_TREE:
368 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
369 case MerkleTreeId::ARCHIVE: {
370 auto leaf = _ws->get_leaf<bb::fr>(request.value.revision, request.value.treeId, request.value.leafIndex);
371
372 MsgHeader header(request.header.messageId);
374 msgpack::pack(buffer, resp_msg);
375 break;
376 }
377
378 case MerkleTreeId::PUBLIC_DATA_TREE: {
379 auto leaf = _ws->get_leaf<crypto::merkle_tree::PublicDataLeafValue>(
380 request.value.revision, request.value.treeId, request.value.leafIndex);
381 MsgHeader header(request.header.messageId);
384 msgpack::pack(buffer, resp_msg);
385 break;
386 }
387
388 case MerkleTreeId::NULLIFIER_TREE: {
389 auto leaf = _ws->get_leaf<crypto::merkle_tree::NullifierLeafValue>(
390 request.value.revision, request.value.treeId, request.value.leafIndex);
391 MsgHeader header(request.header.messageId);
394 msgpack::pack(buffer, resp_msg);
395 break;
396 }
397
398 default:
399 throw std::runtime_error("Unsupported tree type");
400 }
401
402 return true;
403}
404
405bool WorldStateWrapper::get_leaf_preimage(msgpack::object& obj, msgpack::sbuffer& buffer) const
406{
408 obj.convert(request);
409
410 MsgHeader header(request.header.messageId);
411
412 switch (request.value.treeId) {
413 case MerkleTreeId::NULLIFIER_TREE: {
414 auto leaf = _ws->get_indexed_leaf<NullifierLeafValue>(
415 request.value.revision, request.value.treeId, request.value.leafIndex);
418 msgpack::pack(buffer, resp_msg);
419 break;
420 }
421
422 case MerkleTreeId::PUBLIC_DATA_TREE: {
423 auto leaf = _ws->get_indexed_leaf<PublicDataLeafValue>(
424 request.value.revision, request.value.treeId, request.value.leafIndex);
425
428 msgpack::pack(buffer, resp_msg);
429 break;
430 }
431
432 default:
433 throw std::runtime_error("Unsupported tree type");
434 }
435
436 return true;
437}
438
439bool WorldStateWrapper::get_sibling_path(msgpack::object& obj, msgpack::sbuffer& buffer) const
440{
442 obj.convert(request);
443
444 fr_sibling_path path = _ws->get_sibling_path(request.value.revision, request.value.treeId, request.value.leafIndex);
445
446 MsgHeader header(request.header.messageId);
448
449 msgpack::pack(buffer, resp_msg);
450
451 return true;
452}
453
454bool WorldStateWrapper::get_block_numbers_for_leaf_indices(msgpack::object& obj, msgpack::sbuffer& buffer) const
455{
457 obj.convert(request);
458
460 _ws->get_block_numbers_for_leaf_indices(
461 request.value.revision, request.value.treeId, request.value.leafIndices, response.blockNumbers);
462
463 MsgHeader header(request.header.messageId);
466
467 msgpack::pack(buffer, resp_msg);
468
469 return true;
470}
471
472bool WorldStateWrapper::find_leaf_indices(msgpack::object& obj, msgpack::sbuffer& buffer) const
473{
475 obj.convert(request);
476
478
479 switch (request.value.treeId) {
480 case MerkleTreeId::NOTE_HASH_TREE:
481 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
482 case MerkleTreeId::ARCHIVE: {
484 obj.convert(r1);
485 _ws->find_leaf_indices<bb::fr>(
486 request.value.revision, request.value.treeId, r1.value.leaves, response.indices, r1.value.startIndex);
487 break;
488 }
489
490 case MerkleTreeId::PUBLIC_DATA_TREE: {
492 obj.convert(r2);
493 _ws->find_leaf_indices<PublicDataLeafValue>(
494 request.value.revision, request.value.treeId, r2.value.leaves, response.indices, r2.value.startIndex);
495 break;
496 }
497 case MerkleTreeId::NULLIFIER_TREE: {
499 obj.convert(r3);
500 _ws->find_leaf_indices<NullifierLeafValue>(
501 request.value.revision, request.value.treeId, r3.value.leaves, response.indices, r3.value.startIndex);
502 break;
503 }
504 }
505
506 MsgHeader header(request.header.messageId);
509 msgpack::pack(buffer, resp_msg);
510
511 return true;
512}
513
514bool WorldStateWrapper::find_sibling_paths(msgpack::object& obj, msgpack::sbuffer& buffer) const
515{
517 obj.convert(request);
518
519 FindLeafPathsResponse response;
520
521 switch (request.value.treeId) {
522 case MerkleTreeId::NOTE_HASH_TREE:
523 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
524 case MerkleTreeId::ARCHIVE: {
526 obj.convert(r1);
527 _ws->find_sibling_paths<bb::fr>(request.value.revision, request.value.treeId, r1.value.leaves, response.paths);
528 break;
529 }
530
531 case MerkleTreeId::PUBLIC_DATA_TREE: {
533 obj.convert(r2);
534 _ws->find_sibling_paths<PublicDataLeafValue>(
535 request.value.revision, request.value.treeId, r2.value.leaves, response.paths);
536 break;
537 }
538 case MerkleTreeId::NULLIFIER_TREE: {
540 obj.convert(r3);
541 _ws->find_sibling_paths<NullifierLeafValue>(
542 request.value.revision, request.value.treeId, r3.value.leaves, response.paths);
543 break;
544 }
545 }
546
547 MsgHeader header(request.header.messageId);
550 msgpack::pack(buffer, resp_msg);
551
552 return true;
553}
554
555bool WorldStateWrapper::find_low_leaf(msgpack::object& obj, msgpack::sbuffer& buffer) const
556{
558 obj.convert(request);
559
560 GetLowIndexedLeafResponse low_leaf_info =
561 _ws->find_low_leaf_index(request.value.revision, request.value.treeId, request.value.key);
562
563 MsgHeader header(request.header.messageId);
565 WorldStateMessageType::FIND_LOW_LEAF, header, { low_leaf_info.is_already_present, low_leaf_info.index });
566 msgpack::pack(buffer, response);
567
568 return true;
569}
570
571bool WorldStateWrapper::append_leaves(msgpack::object& obj, msgpack::sbuffer& buf)
572{
574 obj.convert(request);
575
576 switch (request.value.treeId) {
577 case MerkleTreeId::NOTE_HASH_TREE:
578 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
579 case MerkleTreeId::ARCHIVE: {
581 obj.convert(r1);
582 _ws->append_leaves<bb::fr>(r1.value.treeId, r1.value.leaves, r1.value.forkId);
583 break;
584 }
585 case MerkleTreeId::PUBLIC_DATA_TREE: {
587 obj.convert(r2);
588 _ws->append_leaves<crypto::merkle_tree::PublicDataLeafValue>(r2.value.treeId, r2.value.leaves, r2.value.forkId);
589 break;
590 }
591 case MerkleTreeId::NULLIFIER_TREE: {
593 obj.convert(r3);
594 _ws->append_leaves<crypto::merkle_tree::NullifierLeafValue>(r3.value.treeId, r3.value.leaves, r3.value.forkId);
595 break;
596 }
597 }
598
599 MsgHeader header(request.header.messageId);
601 msgpack::pack(buf, resp_msg);
602
603 return true;
604}
605
606bool WorldStateWrapper::batch_insert(msgpack::object& obj, msgpack::sbuffer& buffer)
607{
609 obj.convert(request);
610
611 switch (request.value.treeId) {
612 case MerkleTreeId::PUBLIC_DATA_TREE: {
614 obj.convert(r1);
615 auto result = _ws->batch_insert_indexed_leaves<crypto::merkle_tree::PublicDataLeafValue>(
616 request.value.treeId, r1.value.leaves, r1.value.subtreeDepth, r1.value.forkId);
617 MsgHeader header(request.header.messageId);
620 msgpack::pack(buffer, resp_msg);
621
622 break;
623 }
624 case MerkleTreeId::NULLIFIER_TREE: {
626 obj.convert(r2);
627 auto result = _ws->batch_insert_indexed_leaves<crypto::merkle_tree::NullifierLeafValue>(
628 request.value.treeId, r2.value.leaves, r2.value.subtreeDepth, r2.value.forkId);
629 MsgHeader header(request.header.messageId);
632 msgpack::pack(buffer, resp_msg);
633 break;
634 }
635 default:
636 throw std::runtime_error("Unsupported tree type");
637 }
638
639 return true;
640}
641
642bool WorldStateWrapper::sequential_insert(msgpack::object& obj, msgpack::sbuffer& buffer)
643{
645 obj.convert(request);
646
647 switch (request.value.treeId) {
648 case MerkleTreeId::PUBLIC_DATA_TREE: {
650 obj.convert(r1);
651 auto result = _ws->insert_indexed_leaves<crypto::merkle_tree::PublicDataLeafValue>(
652 request.value.treeId, r1.value.leaves, r1.value.forkId);
653 MsgHeader header(request.header.messageId);
656 msgpack::pack(buffer, resp_msg);
657
658 break;
659 }
660 case MerkleTreeId::NULLIFIER_TREE: {
662 obj.convert(r2);
663 auto result = _ws->insert_indexed_leaves<crypto::merkle_tree::NullifierLeafValue>(
664 request.value.treeId, r2.value.leaves, r2.value.forkId);
665 MsgHeader header(request.header.messageId);
668 msgpack::pack(buffer, resp_msg);
669 break;
670 }
671 default:
672 throw std::runtime_error("Unsupported tree type");
673 }
674
675 return true;
676}
677
678bool WorldStateWrapper::update_archive(msgpack::object& obj, msgpack::sbuffer& buf)
679{
681 obj.convert(request);
682
683 _ws->update_archive(request.value.blockStateRef, request.value.blockHeaderHash, request.value.forkId);
684
685 MsgHeader header(request.header.messageId);
687 msgpack::pack(buf, resp_msg);
688
689 return true;
690}
691
692bool WorldStateWrapper::commit(msgpack::object& obj, msgpack::sbuffer& buf)
693{
694 HeaderOnlyMessage request;
695 obj.convert(request);
696
698 _ws->commit(status);
699
700 MsgHeader header(request.header.messageId);
702 msgpack::pack(buf, resp_msg);
703
704 return true;
705}
706
707bool WorldStateWrapper::rollback(msgpack::object& obj, msgpack::sbuffer& buf)
708{
709 HeaderOnlyMessage request;
710 obj.convert(request);
711
712 _ws->rollback();
713
714 MsgHeader header(request.header.messageId);
716 msgpack::pack(buf, resp_msg);
717
718 return true;
719}
720
721bool WorldStateWrapper::sync_block(msgpack::object& obj, msgpack::sbuffer& buf)
722{
724 obj.convert(request);
725
726 WorldStateStatusFull status = _ws->sync_block(request.value.blockStateRef,
727 request.value.blockHeaderHash,
728 request.value.paddedNoteHashes,
729 request.value.paddedL1ToL2Messages,
730 request.value.paddedNullifiers,
731 request.value.publicDataWrites);
732
733 MsgHeader header(request.header.messageId);
735 msgpack::pack(buf, resp_msg);
736
737 return true;
738}
739
740bool WorldStateWrapper::create_fork(msgpack::object& obj, msgpack::sbuffer& buf)
741{
743 obj.convert(request);
744
746 request.value.latest ? std::nullopt : std::optional<block_number_t>(request.value.blockNumber);
747
748 uint64_t forkId = _ws->create_fork(blockNumber);
749
750 MsgHeader header(request.header.messageId);
752 msgpack::pack(buf, resp_msg);
753
754 return true;
755}
756
757bool WorldStateWrapper::delete_fork(msgpack::object& obj, msgpack::sbuffer& buf)
758{
760 obj.convert(request);
761
762 _ws->delete_fork(request.value.forkId);
763
764 MsgHeader header(request.header.messageId);
766 msgpack::pack(buf, resp_msg);
767
768 return true;
769}
770
771bool WorldStateWrapper::close(msgpack::object& obj, msgpack::sbuffer& buf)
772{
773 HeaderOnlyMessage request;
774 obj.convert(request);
775
776 // The only reason this API exists is for testing purposes in TS (e.g. close db, open new db instance to test
777 // persistence)
778 _ws.reset(nullptr);
779
780 MsgHeader header(request.header.messageId);
782 msgpack::pack(buf, resp_msg);
783
784 return true;
785}
786
787bool WorldStateWrapper::set_finalized(msgpack::object& obj, msgpack::sbuffer& buf) const
788{
790 obj.convert(request);
791 WorldStateStatusSummary status = _ws->set_finalized_blocks(request.value.toBlockNumber);
792 MsgHeader header(request.header.messageId);
794 WorldStateMessageType::FINALIZE_BLOCKS, header, { status });
795 msgpack::pack(buf, resp_msg);
796
797 return true;
798}
799
800bool WorldStateWrapper::unwind(msgpack::object& obj, msgpack::sbuffer& buf) const
801{
803 obj.convert(request);
804
805 WorldStateStatusFull status = _ws->unwind_blocks(request.value.toBlockNumber);
806
807 MsgHeader header(request.header.messageId);
809 msgpack::pack(buf, resp_msg);
810
811 return true;
812}
813
814bool WorldStateWrapper::remove_historical(msgpack::object& obj, msgpack::sbuffer& buf) const
815{
817 obj.convert(request);
818 WorldStateStatusFull status = _ws->remove_historical_blocks(request.value.toBlockNumber);
819
820 MsgHeader header(request.header.messageId);
823 msgpack::pack(buf, resp_msg);
824
825 return true;
826}
827
828bool WorldStateWrapper::checkpoint(msgpack::object& obj, msgpack::sbuffer& buffer)
829{
831 obj.convert(request);
832
833 _ws->checkpoint(request.value.forkId);
834
835 MsgHeader header(request.header.messageId);
837 msgpack::pack(buffer, resp_msg);
838
839 return true;
840}
841
842bool WorldStateWrapper::commit_checkpoint(msgpack::object& obj, msgpack::sbuffer& buffer)
843{
845 obj.convert(request);
846
847 _ws->commit_checkpoint(request.value.forkId);
848
849 MsgHeader header(request.header.messageId);
851 msgpack::pack(buffer, resp_msg);
852
853 return true;
854}
855
856bool WorldStateWrapper::revert_checkpoint(msgpack::object& obj, msgpack::sbuffer& buffer)
857{
859 obj.convert(request);
860
861 _ws->revert_checkpoint(request.value.forkId);
862
863 MsgHeader header(request.header.messageId);
865 msgpack::pack(buffer, resp_msg);
866
867 return true;
868}
869
870bool WorldStateWrapper::commit_all_checkpoints(msgpack::object& obj, msgpack::sbuffer& buffer)
871{
873 obj.convert(request);
874
875 _ws->commit_all_checkpoints(request.value.forkId);
876
877 MsgHeader header(request.header.messageId);
879 msgpack::pack(buffer, resp_msg);
880
881 return true;
882}
883
884bool WorldStateWrapper::revert_all_checkpoints(msgpack::object& obj, msgpack::sbuffer& buffer)
885{
887 obj.convert(request);
888
889 _ws->revert_all_checkpoints(request.value.forkId);
890
891 MsgHeader header(request.header.messageId);
893 msgpack::pack(buffer, resp_msg);
894
895 return true;
896}
897
898bool WorldStateWrapper::get_status(msgpack::object& obj, msgpack::sbuffer& buf) const
899{
900 HeaderOnlyMessage request;
901 obj.convert(request);
902
904 _ws->get_status_summary(status);
905
906 MsgHeader header(request.header.messageId);
908 msgpack::pack(buf, resp_msg);
909
910 return true;
911}
912
913bool WorldStateWrapper::copy_stores(msgpack::object& obj, msgpack::sbuffer& buffer)
914{
916 obj.convert(request);
917
918 _ws->copy_stores(request.value.dstPath, request.value.compact.value_or(false));
919
920 MsgHeader header(request.header.messageId);
922 msgpack::pack(buffer, resp_msg);
923
924 return true;
925}
926
927Napi::Function WorldStateWrapper::get_class(Napi::Env env)
928{
929 return DefineClass(env,
930 "WorldState",
931 {
932 WorldStateWrapper::InstanceMethod("call", &WorldStateWrapper::call),
933 });
934}
bool on_new_data(msgpack::object &obj, msgpack::sbuffer &buffer) const
void register_target(uint32_t msgType, const message_handler &handler, bool unique=false)
Encapsulatest some work that can be done off the JavaScript main thread.
Definition async_op.hpp:27
bool get_tree_info(msgpack::object &obj, msgpack::sbuffer &buffer) const
WorldStateWrapper(const Napi::CallbackInfo &)
bool get_initial_state_reference(msgpack::object &obj, msgpack::sbuffer &buffer) const
std::unique_ptr< bb::world_state::WorldState > _ws
bool find_low_leaf(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool get_leaf_value(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool update_archive(msgpack::object &obj, msgpack::sbuffer &buffer)
bool rollback(msgpack::object &obj, msgpack::sbuffer &buffer)
bool set_finalized(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool get_state_reference(msgpack::object &obj, msgpack::sbuffer &buffer) const
bb::messaging::MessageDispatcher _dispatcher
bool remove_historical(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool get_leaf_preimage(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool sequential_insert(msgpack::object &obj, msgpack::sbuffer &buffer)
bool get_block_numbers_for_leaf_indices(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool delete_fork(msgpack::object &obj, msgpack::sbuffer &buffer)
bool revert_checkpoint(msgpack::object &obj, msgpack::sbuffer &buffer)
bool find_sibling_paths(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool sync_block(msgpack::object &obj, msgpack::sbuffer &buffer)
bool close(msgpack::object &obj, msgpack::sbuffer &buffer)
bool create_fork(msgpack::object &obj, msgpack::sbuffer &buffer)
static Napi::Function get_class(Napi::Env)
Register the WorldStateAddon class with the JavaScript runtime.
bool append_leaves(msgpack::object &obj, msgpack::sbuffer &buffer)
bool commit_all_checkpoints(msgpack::object &obj, msgpack::sbuffer &buffer)
bool copy_stores(msgpack::object &obj, msgpack::sbuffer &buffer)
bool revert_all_checkpoints(msgpack::object &obj, msgpack::sbuffer &buffer)
bool find_leaf_indices(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool get_status(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool unwind(msgpack::object &obj, msgpack::sbuffer &buffer) const
bool commit_checkpoint(msgpack::object &obj, msgpack::sbuffer &buffer)
bool checkpoint(msgpack::object &obj, msgpack::sbuffer &buffer)
bool batch_insert(msgpack::object &obj, msgpack::sbuffer &buffer)
bool get_sibling_path(msgpack::object &obj, msgpack::sbuffer &buffer) const
Napi::Value call(const Napi::CallbackInfo &)
The only instance method exposed to JavaScript. Takes a msgpack Message and returns a Promise.
bool commit(msgpack::object &obj, msgpack::sbuffer &buffer)
void info(Args... args)
Definition log.hpp:70
const std::vector< FF > data
uint8_t const size_t length
Definition data_store.hpp:9
uint8_t const * buf
Definition data_store.hpp:9
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
const uint64_t DEFAULT_MAP_SIZE
std::vector< fr > fr_sibling_path
Definition hash_path.hpp:16
std::vector< uint8_t > Value
Definition types.hpp:12
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
const uint64_t DEFAULT_MAP_SIZE
std::vector< std::optional< index_t > > indices
std::vector< std::optional< SiblingPathAndIndex > > paths
std::vector< std::optional< block_number_t > > blockNumbers