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
314Napi::Value WorldStateWrapper::getHandle(const Napi::CallbackInfo& info)
315{
316 Napi::Env env = info.Env();
317
318 if (!_ws) {
319 throw Napi::Error::New(env, "World state has been closed");
320 }
321
322 // Return a NAPI External that wraps the raw WorldState pointer
323 // This allows other NAPI functions to access the WorldState instance
324 return Napi::External<WorldState>::New(env, _ws.get());
325}
326
327bool WorldStateWrapper::get_tree_info(msgpack::object& obj, msgpack::sbuffer& buffer) const
328{
330 obj.convert(request);
331 auto info = _ws->get_tree_info(request.value.revision, request.value.treeId);
332
333 MsgHeader header(request.header.messageId);
336 header,
337 { request.value.treeId, info.meta.root, info.meta.size, info.meta.depth });
338
339 msgpack::pack(buffer, resp_msg);
340
341 return true;
342}
343
344bool WorldStateWrapper::get_state_reference(msgpack::object& obj, msgpack::sbuffer& buffer) const
345{
347 obj.convert(request);
348 auto state = _ws->get_state_reference(request.value.revision);
349
350 MsgHeader header(request.header.messageId);
353
354 msgpack::pack(buffer, resp_msg);
355
356 return true;
357}
358
359bool WorldStateWrapper::get_initial_state_reference(msgpack::object& obj, msgpack::sbuffer& buffer) const
360{
361 HeaderOnlyMessage request;
362 obj.convert(request);
363 auto state = _ws->get_initial_state_reference();
364
365 MsgHeader header(request.header.messageId);
368
369 msgpack::pack(buffer, resp_msg);
370
371 return true;
372}
373
374bool WorldStateWrapper::get_leaf_value(msgpack::object& obj, msgpack::sbuffer& buffer) const
375{
377 obj.convert(request);
378
379 switch (request.value.treeId) {
380 case MerkleTreeId::NOTE_HASH_TREE:
381 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
382 case MerkleTreeId::ARCHIVE: {
383 auto leaf = _ws->get_leaf<bb::fr>(request.value.revision, request.value.treeId, request.value.leafIndex);
384
385 MsgHeader header(request.header.messageId);
387 msgpack::pack(buffer, resp_msg);
388 break;
389 }
390
391 case MerkleTreeId::PUBLIC_DATA_TREE: {
392 auto leaf = _ws->get_leaf<crypto::merkle_tree::PublicDataLeafValue>(
393 request.value.revision, request.value.treeId, request.value.leafIndex);
394 MsgHeader header(request.header.messageId);
397 msgpack::pack(buffer, resp_msg);
398 break;
399 }
400
401 case MerkleTreeId::NULLIFIER_TREE: {
402 auto leaf = _ws->get_leaf<crypto::merkle_tree::NullifierLeafValue>(
403 request.value.revision, request.value.treeId, request.value.leafIndex);
404 MsgHeader header(request.header.messageId);
407 msgpack::pack(buffer, resp_msg);
408 break;
409 }
410
411 default:
412 throw std::runtime_error("Unsupported tree type");
413 }
414
415 return true;
416}
417
418bool WorldStateWrapper::get_leaf_preimage(msgpack::object& obj, msgpack::sbuffer& buffer) const
419{
421 obj.convert(request);
422
423 MsgHeader header(request.header.messageId);
424
425 switch (request.value.treeId) {
426 case MerkleTreeId::NULLIFIER_TREE: {
427 auto leaf = _ws->get_indexed_leaf<NullifierLeafValue>(
428 request.value.revision, request.value.treeId, request.value.leafIndex);
431 msgpack::pack(buffer, resp_msg);
432 break;
433 }
434
435 case MerkleTreeId::PUBLIC_DATA_TREE: {
436 auto leaf = _ws->get_indexed_leaf<PublicDataLeafValue>(
437 request.value.revision, request.value.treeId, request.value.leafIndex);
438
441 msgpack::pack(buffer, resp_msg);
442 break;
443 }
444
445 default:
446 throw std::runtime_error("Unsupported tree type");
447 }
448
449 return true;
450}
451
452bool WorldStateWrapper::get_sibling_path(msgpack::object& obj, msgpack::sbuffer& buffer) const
453{
455 obj.convert(request);
456
457 fr_sibling_path path = _ws->get_sibling_path(request.value.revision, request.value.treeId, request.value.leafIndex);
458
459 MsgHeader header(request.header.messageId);
461
462 msgpack::pack(buffer, resp_msg);
463
464 return true;
465}
466
467bool WorldStateWrapper::get_block_numbers_for_leaf_indices(msgpack::object& obj, msgpack::sbuffer& buffer) const
468{
470 obj.convert(request);
471
473 _ws->get_block_numbers_for_leaf_indices(
474 request.value.revision, request.value.treeId, request.value.leafIndices, response.blockNumbers);
475
476 MsgHeader header(request.header.messageId);
479
480 msgpack::pack(buffer, resp_msg);
481
482 return true;
483}
484
485bool WorldStateWrapper::find_leaf_indices(msgpack::object& obj, msgpack::sbuffer& buffer) const
486{
488 obj.convert(request);
489
491
492 switch (request.value.treeId) {
493 case MerkleTreeId::NOTE_HASH_TREE:
494 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
495 case MerkleTreeId::ARCHIVE: {
497 obj.convert(r1);
498 _ws->find_leaf_indices<bb::fr>(
499 request.value.revision, request.value.treeId, r1.value.leaves, response.indices, r1.value.startIndex);
500 break;
501 }
502
503 case MerkleTreeId::PUBLIC_DATA_TREE: {
505 obj.convert(r2);
506 _ws->find_leaf_indices<PublicDataLeafValue>(
507 request.value.revision, request.value.treeId, r2.value.leaves, response.indices, r2.value.startIndex);
508 break;
509 }
510 case MerkleTreeId::NULLIFIER_TREE: {
512 obj.convert(r3);
513 _ws->find_leaf_indices<NullifierLeafValue>(
514 request.value.revision, request.value.treeId, r3.value.leaves, response.indices, r3.value.startIndex);
515 break;
516 }
517 }
518
519 MsgHeader header(request.header.messageId);
522 msgpack::pack(buffer, resp_msg);
523
524 return true;
525}
526
527bool WorldStateWrapper::find_sibling_paths(msgpack::object& obj, msgpack::sbuffer& buffer) const
528{
530 obj.convert(request);
531
532 FindLeafPathsResponse response;
533
534 switch (request.value.treeId) {
535 case MerkleTreeId::NOTE_HASH_TREE:
536 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
537 case MerkleTreeId::ARCHIVE: {
539 obj.convert(r1);
540 _ws->find_sibling_paths<bb::fr>(request.value.revision, request.value.treeId, r1.value.leaves, response.paths);
541 break;
542 }
543
544 case MerkleTreeId::PUBLIC_DATA_TREE: {
546 obj.convert(r2);
547 _ws->find_sibling_paths<PublicDataLeafValue>(
548 request.value.revision, request.value.treeId, r2.value.leaves, response.paths);
549 break;
550 }
551 case MerkleTreeId::NULLIFIER_TREE: {
553 obj.convert(r3);
554 _ws->find_sibling_paths<NullifierLeafValue>(
555 request.value.revision, request.value.treeId, r3.value.leaves, response.paths);
556 break;
557 }
558 }
559
560 MsgHeader header(request.header.messageId);
563 msgpack::pack(buffer, resp_msg);
564
565 return true;
566}
567
568bool WorldStateWrapper::find_low_leaf(msgpack::object& obj, msgpack::sbuffer& buffer) const
569{
571 obj.convert(request);
572
573 GetLowIndexedLeafResponse low_leaf_info =
574 _ws->find_low_leaf_index(request.value.revision, request.value.treeId, request.value.key);
575
576 MsgHeader header(request.header.messageId);
578 WorldStateMessageType::FIND_LOW_LEAF, header, { low_leaf_info.is_already_present, low_leaf_info.index });
579 msgpack::pack(buffer, response);
580
581 return true;
582}
583
584bool WorldStateWrapper::append_leaves(msgpack::object& obj, msgpack::sbuffer& buf)
585{
587 obj.convert(request);
588
589 switch (request.value.treeId) {
590 case MerkleTreeId::NOTE_HASH_TREE:
591 case MerkleTreeId::L1_TO_L2_MESSAGE_TREE:
592 case MerkleTreeId::ARCHIVE: {
594 obj.convert(r1);
595 _ws->append_leaves<bb::fr>(r1.value.treeId, r1.value.leaves, r1.value.forkId);
596 break;
597 }
598 case MerkleTreeId::PUBLIC_DATA_TREE: {
600 obj.convert(r2);
601 _ws->append_leaves<crypto::merkle_tree::PublicDataLeafValue>(r2.value.treeId, r2.value.leaves, r2.value.forkId);
602 break;
603 }
604 case MerkleTreeId::NULLIFIER_TREE: {
606 obj.convert(r3);
607 _ws->append_leaves<crypto::merkle_tree::NullifierLeafValue>(r3.value.treeId, r3.value.leaves, r3.value.forkId);
608 break;
609 }
610 }
611
612 MsgHeader header(request.header.messageId);
614 msgpack::pack(buf, resp_msg);
615
616 return true;
617}
618
619bool WorldStateWrapper::batch_insert(msgpack::object& obj, msgpack::sbuffer& buffer)
620{
622 obj.convert(request);
623
624 switch (request.value.treeId) {
625 case MerkleTreeId::PUBLIC_DATA_TREE: {
627 obj.convert(r1);
628 auto result = _ws->batch_insert_indexed_leaves<crypto::merkle_tree::PublicDataLeafValue>(
629 request.value.treeId, r1.value.leaves, r1.value.subtreeDepth, r1.value.forkId);
630 MsgHeader header(request.header.messageId);
633 msgpack::pack(buffer, resp_msg);
634
635 break;
636 }
637 case MerkleTreeId::NULLIFIER_TREE: {
639 obj.convert(r2);
640 auto result = _ws->batch_insert_indexed_leaves<crypto::merkle_tree::NullifierLeafValue>(
641 request.value.treeId, r2.value.leaves, r2.value.subtreeDepth, r2.value.forkId);
642 MsgHeader header(request.header.messageId);
645 msgpack::pack(buffer, resp_msg);
646 break;
647 }
648 default:
649 throw std::runtime_error("Unsupported tree type");
650 }
651
652 return true;
653}
654
655bool WorldStateWrapper::sequential_insert(msgpack::object& obj, msgpack::sbuffer& buffer)
656{
658 obj.convert(request);
659
660 switch (request.value.treeId) {
661 case MerkleTreeId::PUBLIC_DATA_TREE: {
663 obj.convert(r1);
664 auto result = _ws->insert_indexed_leaves<crypto::merkle_tree::PublicDataLeafValue>(
665 request.value.treeId, r1.value.leaves, r1.value.forkId);
666 MsgHeader header(request.header.messageId);
669 msgpack::pack(buffer, resp_msg);
670
671 break;
672 }
673 case MerkleTreeId::NULLIFIER_TREE: {
675 obj.convert(r2);
676 auto result = _ws->insert_indexed_leaves<crypto::merkle_tree::NullifierLeafValue>(
677 request.value.treeId, r2.value.leaves, r2.value.forkId);
678 MsgHeader header(request.header.messageId);
681 msgpack::pack(buffer, resp_msg);
682 break;
683 }
684 default:
685 throw std::runtime_error("Unsupported tree type");
686 }
687
688 return true;
689}
690
691bool WorldStateWrapper::update_archive(msgpack::object& obj, msgpack::sbuffer& buf)
692{
694 obj.convert(request);
695
696 _ws->update_archive(request.value.blockStateRef, request.value.blockHeaderHash, request.value.forkId);
697
698 MsgHeader header(request.header.messageId);
700 msgpack::pack(buf, resp_msg);
701
702 return true;
703}
704
705bool WorldStateWrapper::commit(msgpack::object& obj, msgpack::sbuffer& buf)
706{
707 HeaderOnlyMessage request;
708 obj.convert(request);
709
711 _ws->commit(status);
712
713 MsgHeader header(request.header.messageId);
715 msgpack::pack(buf, resp_msg);
716
717 return true;
718}
719
720bool WorldStateWrapper::rollback(msgpack::object& obj, msgpack::sbuffer& buf)
721{
722 HeaderOnlyMessage request;
723 obj.convert(request);
724
725 _ws->rollback();
726
727 MsgHeader header(request.header.messageId);
729 msgpack::pack(buf, resp_msg);
730
731 return true;
732}
733
734bool WorldStateWrapper::sync_block(msgpack::object& obj, msgpack::sbuffer& buf)
735{
737 obj.convert(request);
738
739 WorldStateStatusFull status = _ws->sync_block(request.value.blockStateRef,
740 request.value.blockHeaderHash,
741 request.value.paddedNoteHashes,
742 request.value.paddedL1ToL2Messages,
743 request.value.paddedNullifiers,
744 request.value.publicDataWrites);
745
746 MsgHeader header(request.header.messageId);
748 msgpack::pack(buf, resp_msg);
749
750 return true;
751}
752
753bool WorldStateWrapper::create_fork(msgpack::object& obj, msgpack::sbuffer& buf)
754{
756 obj.convert(request);
757
759 request.value.latest ? std::nullopt : std::optional<block_number_t>(request.value.blockNumber);
760
761 uint64_t forkId = _ws->create_fork(blockNumber);
762
763 MsgHeader header(request.header.messageId);
765 msgpack::pack(buf, resp_msg);
766
767 return true;
768}
769
770bool WorldStateWrapper::delete_fork(msgpack::object& obj, msgpack::sbuffer& buf)
771{
773 obj.convert(request);
774
775 _ws->delete_fork(request.value.forkId);
776
777 MsgHeader header(request.header.messageId);
779 msgpack::pack(buf, resp_msg);
780
781 return true;
782}
783
784bool WorldStateWrapper::close(msgpack::object& obj, msgpack::sbuffer& buf)
785{
786 HeaderOnlyMessage request;
787 obj.convert(request);
788
789 // The only reason this API exists is for testing purposes in TS (e.g. close db, open new db instance to test
790 // persistence)
791 _ws.reset(nullptr);
792
793 MsgHeader header(request.header.messageId);
795 msgpack::pack(buf, resp_msg);
796
797 return true;
798}
799
800bool WorldStateWrapper::set_finalized(msgpack::object& obj, msgpack::sbuffer& buf) const
801{
803 obj.convert(request);
804 WorldStateStatusSummary status = _ws->set_finalized_blocks(request.value.toBlockNumber);
805 MsgHeader header(request.header.messageId);
807 WorldStateMessageType::FINALIZE_BLOCKS, header, { status });
808 msgpack::pack(buf, resp_msg);
809
810 return true;
811}
812
813bool WorldStateWrapper::unwind(msgpack::object& obj, msgpack::sbuffer& buf) const
814{
816 obj.convert(request);
817
818 WorldStateStatusFull status = _ws->unwind_blocks(request.value.toBlockNumber);
819
820 MsgHeader header(request.header.messageId);
822 msgpack::pack(buf, resp_msg);
823
824 return true;
825}
826
827bool WorldStateWrapper::remove_historical(msgpack::object& obj, msgpack::sbuffer& buf) const
828{
830 obj.convert(request);
831 WorldStateStatusFull status = _ws->remove_historical_blocks(request.value.toBlockNumber);
832
833 MsgHeader header(request.header.messageId);
836 msgpack::pack(buf, resp_msg);
837
838 return true;
839}
840
841bool WorldStateWrapper::checkpoint(msgpack::object& obj, msgpack::sbuffer& buffer)
842{
844 obj.convert(request);
845
846 _ws->checkpoint(request.value.forkId);
847
848 MsgHeader header(request.header.messageId);
850 msgpack::pack(buffer, resp_msg);
851
852 return true;
853}
854
855bool WorldStateWrapper::commit_checkpoint(msgpack::object& obj, msgpack::sbuffer& buffer)
856{
858 obj.convert(request);
859
860 _ws->commit_checkpoint(request.value.forkId);
861
862 MsgHeader header(request.header.messageId);
864 msgpack::pack(buffer, resp_msg);
865
866 return true;
867}
868
869bool WorldStateWrapper::revert_checkpoint(msgpack::object& obj, msgpack::sbuffer& buffer)
870{
872 obj.convert(request);
873
874 _ws->revert_checkpoint(request.value.forkId);
875
876 MsgHeader header(request.header.messageId);
878 msgpack::pack(buffer, resp_msg);
879
880 return true;
881}
882
883bool WorldStateWrapper::commit_all_checkpoints(msgpack::object& obj, msgpack::sbuffer& buffer)
884{
886 obj.convert(request);
887
888 _ws->commit_all_checkpoints(request.value.forkId);
889
890 MsgHeader header(request.header.messageId);
892 msgpack::pack(buffer, resp_msg);
893
894 return true;
895}
896
897bool WorldStateWrapper::revert_all_checkpoints(msgpack::object& obj, msgpack::sbuffer& buffer)
898{
900 obj.convert(request);
901
902 _ws->revert_all_checkpoints(request.value.forkId);
903
904 MsgHeader header(request.header.messageId);
906 msgpack::pack(buffer, resp_msg);
907
908 return true;
909}
910
911bool WorldStateWrapper::get_status(msgpack::object& obj, msgpack::sbuffer& buf) const
912{
913 HeaderOnlyMessage request;
914 obj.convert(request);
915
917 _ws->get_status_summary(status);
918
919 MsgHeader header(request.header.messageId);
921 msgpack::pack(buf, resp_msg);
922
923 return true;
924}
925
926bool WorldStateWrapper::copy_stores(msgpack::object& obj, msgpack::sbuffer& buffer)
927{
929 obj.convert(request);
930
931 _ws->copy_stores(request.value.dstPath, request.value.compact.value_or(false));
932
933 MsgHeader header(request.header.messageId);
935 msgpack::pack(buffer, resp_msg);
936
937 return true;
938}
939
940Napi::Function WorldStateWrapper::get_class(Napi::Env env)
941{
942 return DefineClass(env,
943 "WorldState",
944 {
945 WorldStateWrapper::InstanceMethod("call", &WorldStateWrapper::call),
946 WorldStateWrapper::InstanceMethod("getHandle", &WorldStateWrapper::getHandle),
947 });
948}
std::shared_ptr< Napi::ThreadSafeFunction > revert_checkpoint
std::shared_ptr< Napi::ThreadSafeFunction > commit_checkpoint
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)
Napi::Value getHandle(const Napi::CallbackInfo &)
Get a NAPI External handle to the underlying WorldState pointer. This allows other NAPI functions to ...
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:75
const std::vector< MemoryValue > 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