70 const std::vector<fr>& initial_values = {},
71 bool commit_genesis_state =
true);
110 bool includeUncommitted)
const;
121 bool includeUncommitted)
const;
132 uint32_t subtree_depth,
134 bool includeUncommitted)
const;
150 bool includeUncommitted,
170 bool includeUncommitted,
177 bool includeUncommitted,
185 bool includeUncommitted,
192 bool includeUncommitted,
200 bool includeUncommitted,
208 bool includeUncommitted,
217 bool includeUncommitted,
281 uint32_t subtree_depth,
288 bool updateNodesByIndexCache =
false)
const;
302template <
typename Store,
typename HashingPolicy>
304 std::unique_ptr<Store> store,
306 const std::vector<fr>& initial_values,
307 bool commit_genesis_state)
308 : store_(
std::move(store))
318 auto current = HashingPolicy::zero_hash();
319 for (
size_t i =
depth_; i > 0; --i) {
322 current = HashingPolicy::hash_pair(current, current);
333 if (initial_values.empty()) {
346 throw std::runtime_error(
format(
"Failed to initialize tree: ", result.
message));
356 if (commit_genesis_state) {
357 store_->commit_genesis_state();
361template <
typename Store,
typename HashingPolicy>
365 auto job = [=,
this]() {
366 execute_and_report<TreeMetaResponse>(
369 store_->get_meta(response.
inner.meta, *tx, includeUncommitted);
373 workers_->enqueue(job);
376template <
typename Store,
typename HashingPolicy>
378 bool includeUncommitted,
381 auto job = [=,
this]() {
382 execute_and_report<TreeMetaResponse>(
385 store_->get_meta(response.
inner.meta, *tx, includeUncommitted);
388 if (!store_->get_block_data(blockNumber, blockData, *tx)) {
389 throw std::runtime_error(
390 format(
"Unable to get meta data for block ", blockNumber,
", failed to get block data."));
393 response.
inner.meta.size = blockData.
size;
394 response.
inner.meta.committedSize = blockData.
size;
395 response.
inner.meta.root = blockData.
root;
399 workers_->enqueue(job);
402template <
typename Store,
typename HashingPolicy>
405 bool includeUncommitted)
const
407 get_subtree_sibling_path(
index, 0, on_completion, includeUncommitted);
410template <
typename Store,
typename HashingPolicy>
414 bool includeUncommitted)
const
416 auto job = [=,
this]() {
417 execute_and_report<GetSiblingPathResponse>(
421 if (!store_->get_block_data(blockNumber, blockData, *tx)) {
422 throw std::runtime_error(format(
"Unable to get sibling path for index ",
426 ", failed to get block data."));
430 requestContext.blockNumber = blockNumber;
431 requestContext.includeUncommitted = includeUncommitted;
432 requestContext.root = blockData.
root;
434 response.
inner.path = optional_sibling_path_to_full_sibling_path(optional_path);
438 workers_->enqueue(job);
441template <
typename Store,
typename HashingPolicy>
445 auto job = [=,
this]() {
446 execute_and_report<BlockForIndexResponse>(
448 response.
inner.blockNumbers.reserve(indices.size());
452 response.
inner.blockNumbers.emplace_back(block);
457 workers_->enqueue(job);
460template <
typename Store,
typename HashingPolicy>
462 const std::vector<index_t>& indices,
466 auto job = [=,
this]() {
467 execute_and_report<BlockForIndexResponse>(
469 response.
inner.blockNumbers.reserve(indices.size());
472 if (!store_->get_block_data(blockNumber, blockPayload, *tx)) {
473 throw std::runtime_error(
format(
"Unable to find block numbers for indices for block ",
475 ", failed to get block data."));
479 bool outOfRange =
index >= maxIndex;
482 response.
inner.blockNumbers.emplace_back(block);
487 workers_->enqueue(job);
490template <
typename Store,
typename HashingPolicy>
492 uint32_t subtree_depth,
const HashPathCallback& on_completion,
bool includeUncommitted)
const
494 auto job = [=,
this]() {
495 execute_and_report<GetSiblingPathResponse>(
499 store_->get_meta(meta, *tx, includeUncommitted);
502 requestContext.
root = store_->get_current_root(*tx, includeUncommitted);
504 get_subtree_sibling_path_internal(meta.
size, subtree_depth, requestContext, *tx);
505 response.
inner.path = optional_sibling_path_to_full_sibling_path(optional_path);
509 workers_->enqueue(job);
512template <
typename Store,
typename HashingPolicy>
515 uint32_t subtree_depth,
517 bool includeUncommitted)
const
519 auto job = [=,
this]() {
520 execute_and_report<GetSiblingPathResponse>(
525 requestContext.
root = store_->get_current_root(*tx, includeUncommitted);
528 get_subtree_sibling_path_internal(leaf_index, subtree_depth, requestContext, *tx);
529 response.
inner.path = optional_sibling_path_to_full_sibling_path(optional_path);
533 workers_->enqueue(job);
536template <
typename Store,
typename HashingPolicy>
540 if (optionalPath.empty()) {
544 size_t pathIndex = optionalPath.size() - 1;
545 for (
index_t level = 1; level <= optionalPath.size(); level++) {
547 path[pathIndex] = op.has_value() ? op.value() : zero_hashes_[level];
553template <
typename Store,
typename HashingPolicy>
558 bool updateNodesByIndexCache)
const
562 if (leaf_index >= max_size_) {
563 throw std::runtime_error(
format(
"Leaf index ", leaf_index,
" out of range for tree of depth ", depth_));
566 fr hash = requestContext.
root;
569 index_t child_index_at_level = 0;
570 for (uint32_t i = 0; i < depth_; ++i) {
574 bool success = store_->get_node_by_hash(hash, nodePayload, tx, requestContext.
includeUncommitted);
582 bool is_right =
static_cast<bool>(leaf_index & mask);
590 if (!child.has_value()) {
594 if (updateNodesByIndexCache) {
595 child_index_at_level = is_right ? (child_index_at_level * 2) + 1 : (child_index_at_level * 2);
597 index_t sibling_index_at_level = is_right ? child_index_at_level - 1 : child_index_at_level + 1;
598 if (sibling.has_value()) {
599 store_->put_cached_node_by_index(i + 1, sibling_index_at_level, sibling.value(),
false);
606 hash = child.value();
608 if (!updateNodesByIndexCache) {
612 child_index_at_level = is_right ? (child_index_at_level * 2) + 1 : (child_index_at_level * 2);
615 store_->put_cached_node_by_index(i + 1, child_index_at_level, hash,
false);
617 index_t sibling_index_at_level = is_right ? child_index_at_level - 1 : child_index_at_level + 1;
618 if (sibling.has_value()) {
622 store_->put_cached_node_by_index(i + 1, sibling_index_at_level, sibling.value(),
false);
630template <
typename Store,
typename HashingPolicy>
633 HashingPolicy>::get_subtree_sibling_path_internal(
const index_t& leaf_index,
634 uint32_t subtree_depth,
640 if (subtree_depth >= depth_) {
643 path.resize(depth_ - subtree_depth);
644 size_t path_index = path.size() - 1;
649 fr hash = requestContext.
root;
652 for (uint32_t level = 0; level < depth_ - subtree_depth; ++level) {
655 bool is_right =
static_cast<bool>(leaf_index & mask);
668 hash = child.has_value() ? child.value() : zero_hashes_[level + 1];
671 path[path_index--] = sibling;
680template <
typename Store,
typename HashingPolicy>
682 bool includeUncommitted,
685 auto job = [=,
this]() {
686 execute_and_report<GetLeafResponse>(
689 if (max_size_ <= leaf_index) {
693 format(
"Unable to get leaf at index ", leaf_index,
", leaf index out of tree range.");
699 requestContext.
root = store_->get_current_root(*tx, includeUncommitted);
700 std::optional<fr> leaf_hash = find_leaf_hash(leaf_index, requestContext, *tx,
false);
701 response.
success = leaf_hash.has_value();
703 response.
inner.leaf = leaf_hash.value();
708 response.
message =
format(
"Failed to find leaf hash at index ", leaf_index);
713 workers_->enqueue(job);
720template <
typename Store,
typename HashingPolicy>
723 bool includeUncommitted,
726 auto job = [=,
this]() {
727 execute_and_report<GetLeafResponse>(
731 if (!store_->get_block_data(blockNumber, blockData, *tx)) {
732 throw std::runtime_error(format(
"Unable to get leaf at index ",
736 ", failed to get block data."));
738 if (max_size_ <= leaf_index) {
744 ", leaf index out of tree range.");
748 if (blockData.
size <= leaf_index) {
756 ", leaf index out of block range.");
763 requestContext.
root = blockData.
root;
764 std::optional<fr> leaf_hash = find_leaf_hash(leaf_index, requestContext, *tx,
false);
765 response.
success = leaf_hash.has_value();
767 response.
inner.leaf = leaf_hash.value();
773 format(
"Failed to find leaf hash at index ", leaf_index,
" for block number ", blockNumber);
778 workers_->enqueue(job);
781template <
typename Store,
typename HashingPolicy>
784 bool includeUncommitted,
787 find_leaf_indices_from(leaves, 0, includeUncommitted, on_completion);
790template <
typename Store,
typename HashingPolicy>
794 bool includeUncommitted,
797 find_leaf_indices_from(leaves, 0, blockNumber, includeUncommitted, on_completion);
800template <
typename Store,
typename HashingPolicy>
804 bool includeUncommitted,
807 auto job = [=,
this]() ->
void {
808 execute_and_report<FindLeafIndexResponse>(
810 response.
inner.leaf_indices.reserve(leaves.size());
816 for (
const auto& leaf : leaves) {
818 store_->find_leaf_index_from(leaf, start_index, requestContext, *tx);
819 response.
inner.leaf_indices.emplace_back(leaf_index);
824 workers_->enqueue(job);
827template <
typename Store,
typename HashingPolicy>
832 bool includeUncommitted,
835 auto job = [=,
this]() ->
void {
836 execute_and_report<FindLeafIndexResponse>(
838 response.
inner.leaf_indices.reserve(leaves.size());
841 if (!store_->get_block_data(blockNumber, blockData, *tx)) {
842 throw std::runtime_error(
format(
"Unable to find leaf from index ",
846 ", failed to get block data."));
854 for (
const auto& leaf : leaves) {
856 store_->find_leaf_index_from(leaf, start_index, requestContext, *tx);
857 response.
inner.leaf_indices.emplace_back(leaf_index);
862 workers_->enqueue(job);
865template <
typename Store,
typename HashingPolicy>
868 bool includeUncommitted,
871 auto job = [=,
this]() ->
void {
872 execute_and_report<FindLeafPathResponse>(
874 response.
inner.leaf_paths.reserve(leaves.size());
879 requestContext.
root = store_->get_current_root(*tx, includeUncommitted);
881 for (
const auto& leaf : leaves) {
883 if (!leaf_index.has_value()) {
888 get_subtree_sibling_path_internal(leaf_index.value(), 0, requestContext, *tx);
890 sibling_path_and_index.
path = optional_sibling_path_to_full_sibling_path(optional_path);
891 sibling_path_and_index.
index = leaf_index.value();
892 response.
inner.leaf_paths.emplace_back(sibling_path_and_index);
897 workers_->enqueue(job);
900template <
typename Store,
typename HashingPolicy>
904 bool includeUncommitted,
907 auto job = [=,
this]() ->
void {
908 execute_and_report<FindLeafPathResponse>(
910 response.
inner.leaf_paths.reserve(leaves.size());
913 if (!store_->get_block_data(blockNumber, blockData, *tx)) {
914 throw std::runtime_error(
915 format(
"Unable to find sibling path for block ", blockNumber,
", failed to get block data."));
922 requestContext.
root = blockData.
root;
924 for (
const auto& leaf : leaves) {
926 if (!leaf_index.has_value()) {
931 get_subtree_sibling_path_internal(leaf_index.value(), 0, requestContext, *tx);
933 sibling_path_and_index.
path = optional_sibling_path_to_full_sibling_path(optional_path);
934 sibling_path_and_index.
index = leaf_index.value();
935 response.
inner.leaf_paths.emplace_back(sibling_path_and_index);
940 workers_->enqueue(job);
943template <
typename Store,
typename HashingPolicy>
950template <
typename Store,
typename HashingPolicy>
954 add_values_internal(values, on_completion,
true);
957template <
typename Store,
typename HashingPolicy>
962 auto append_op = [=,
this]() ->
void {
963 execute_and_report<AddDataResponse>(
965 add_values_internal(hashes, response.
inner.root, response.
inner.size, update_index);
969 workers_->enqueue(append_op);
972template <
typename Store,
typename HashingPolicy>
975 auto job = [=,
this]() {
976 execute_and_report<CommitResponse>(
978 store_->commit_block(response.
inner.meta, response.
inner.stats);
982 workers_->enqueue(job);
985template <
typename Store,
typename HashingPolicy>
988 auto job = [=,
this]() {
execute_and_report([=,
this]() { store_->rollback(); }, on_completion); };
989 workers_->enqueue(job);
992template <
typename Store,
typename HashingPolicy>
995 auto job = [=,
this]() {
996 execute_and_report<CheckpointResponse>(
1000 workers_->enqueue(job);
1003template <
typename Store,
typename HashingPolicy>
1007 auto job = [=,
this]() {
execute_and_report([=,
this]() { store_->commit_checkpoint(); }, on_completion); };
1008 workers_->enqueue(job);
1011template <
typename Store,
typename HashingPolicy>
1015 auto job = [=,
this]() {
execute_and_report([=,
this]() { store_->revert_checkpoint(); }, on_completion); };
1016 workers_->enqueue(job);
1019template <
typename Store,
typename HashingPolicy>
1023 auto job = [=,
this]() {
execute_and_report([=,
this]() { store_->commit_all_checkpoints_to(); }, on_completion); };
1024 workers_->enqueue(job);
1027template <
typename Store,
typename HashingPolicy>
1031 auto job = [=,
this]() {
execute_and_report([=,
this]() { store_->revert_all_checkpoints_to(); }, on_completion); };
1032 workers_->enqueue(job);
1035template <
typename Store,
typename HashingPolicy>
1039 auto job = [=,
this]() {
1040 execute_and_report([=,
this]() { store_->commit_to_depth(target_depth); }, on_completion);
1042 workers_->enqueue(job);
1045template <
typename Store,
typename HashingPolicy>
1049 auto job = [=,
this]() {
1050 execute_and_report([=,
this]() { store_->revert_to_depth(target_depth); }, on_completion);
1052 workers_->enqueue(job);
1055template <
typename Store,
typename HashingPolicy>
1058 return store_->checkpoint_depth();
1060template <
typename Store,
typename HashingPolicy>
1064 auto job = [=,
this]() {
1065 execute_and_report<RemoveHistoricResponse>(
1067 if (blockNumber == 0) {
1068 throw std::runtime_error(
"Unable to remove historic block 0");
1070 store_->remove_historical_block(blockNumber, response.
inner.meta, response.
inner.stats);
1074 workers_->enqueue(job);
1077template <
typename Store,
typename HashingPolicy>
1081 auto job = [=,
this]() {
1082 execute_and_report<UnwindResponse>(
1084 if (blockNumber == 0) {
1085 throw std::runtime_error(
"Unable to unwind block 0");
1087 store_->unwind_block(blockNumber, response.
inner.meta, response.
inner.stats);
1091 workers_->enqueue(job);
1094template <
typename Store,
typename HashingPolicy>
1098 auto job = [=,
this]() {
1101 if (blockNumber == 0) {
1102 throw std::runtime_error(
"Unable to finalize block 0");
1104 store_->advance_finalized_block(blockNumber);
1108 workers_->enqueue(job);
1111template <
typename Store,
typename HashingPolicy>
1116 if (treeSize != 0U) {
1117 while (!(minPower2 & treeSize)) {
1120 if (minPower2 <= remainingAppendSize) {
1125 while (maxPower2 <= remainingAppendSize) {
1128 return maxPower2 >> 1;
1131template <
typename Store,
typename HashingPolicy>
1139 store_->get_meta(meta);
1141 new_size = meta.
size;
1143 while (sizeToAppend != 0U) {
1144 index_t batchSize = get_batch_insertion_size(new_size, sizeToAppend);
1145 sizeToAppend -= batchSize;
1146 int64_t start =
static_cast<int64_t
>(batchIndex);
1147 int64_t end =
static_cast<int64_t
>(batchIndex + batchSize);
1148 std::vector<fr> batch = std::vector<fr>(values->begin() + start, values->begin() + end);
1149 batchIndex += batchSize;
1150 add_batch_internal(batch, new_root, new_size, update_index, *tx);
1154template <
typename Store,
typename HashingPolicy>
1158 uint32_t start_level = depth_;
1159 uint32_t level = start_level;
1160 std::vector<fr>& hashes_local = values;
1161 auto number_to_insert =
static_cast<uint32_t
>(hashes_local.size());
1164 store_->get_meta(meta);
1166 new_size = meta.
size + number_to_insert;
1169 if (values.empty()) {
1173 if (new_size > max_size_) {
1174 throw std::runtime_error(
1175 format(
"Unable to append leaves to tree ", meta.
name,
" new size: ", new_size,
" max size: ", max_size_));
1179 for (uint32_t i = 0; i < number_to_insert; ++i) {
1183 store_->put_cached_node_by_index(level, i +
index, hashes_local[i]);
1188 for (uint32_t i = 0; i < number_to_insert; ++i) {
1190 if (hashes_local[i] ==
fr::zero()) {
1194 store_->update_index(
index + i, hashes_local[i]);
1199 while (number_to_insert > 1) {
1200 number_to_insert >>= 1;
1204 for (uint32_t i = 0; i < number_to_insert; ++i) {
1205 fr left = hashes_local[i * 2];
1206 fr right = hashes_local[i * 2 + 1];
1207 hashes_local[i] = HashingPolicy::hash_pair(left, right);
1209 store_->put_node_by_hash(hashes_local[i], { .left = left, .right = right, .ref = 1 });
1210 store_->put_cached_node_by_index(level,
index + i, hashes_local[i]);
1216 fr new_hash = hashes_local[0];
1221 requestContext.
root = store_->get_current_root(tx,
true);
1223 get_subtree_sibling_path_internal(meta.
size, depth_ - level, requestContext, tx);
1224 fr_sibling_path sibling_path_to_root = optional_sibling_path_to_full_sibling_path(optional_sibling_path_to_root);
1225 size_t sibling_path_index = 0;
1231 bool is_right =
static_cast<bool>(
index & 0x01);
1235 fr left_hash = is_right ? sibling_path_to_root[sibling_path_index] : new_hash;
1236 fr right_hash = is_right ? new_hash : sibling_path_to_root[sibling_path_index];
1238 std::optional<fr> left_op = is_right ? optional_sibling_path_to_root[sibling_path_index] : new_hash;
1239 std::optional<fr> right_op = is_right ? new_hash : optional_sibling_path_to_root[sibling_path_index];
1241 new_hash = HashingPolicy::hash_pair(left_hash, right_hash);
1246 ++sibling_path_index;
1247 store_->put_cached_node_by_index(level,
index, new_hash);
1248 store_->put_node_by_hash(new_hash, { .left = left_op, .right = right_op, .ref = 1 });
1252 new_root = new_hash;
1253 meta.
root = new_hash;
1254 meta.
size = new_size;
1256 store_->put_meta(meta);
std::shared_ptr< Napi::ThreadSafeFunction > revert_checkpoint
std::shared_ptr< Napi::ThreadSafeFunction > commit_checkpoint
Implements a simple append-only merkle tree All methods are asynchronous unless specified as otherwis...
typename Store::ReadTransaction ReadTransaction
void get_leaf(const index_t &index, bool includeUncommitted, const GetLeafCallback &completion) const
Returns the leaf value at the provided index.
void remove_historic_block(const block_number_t &blockNumber, const RemoveHistoricBlockCallback &on_completion)
std::function< void(TypedResponse< FindLeafPathResponse > &)> FindSiblingPathCallback
void revert_all_checkpoints_to(const CheckpointRevertCallback &on_completion)
OptionalSiblingPath get_subtree_sibling_path_internal(const index_t &leaf_index, uint32_t subtree_depth, const RequestContext &requestContext, ReadTransaction &tx) const
void get_sibling_path(const index_t &index, const HashPathCallback &on_completion, bool includeUncommitted) const
Returns the sibling path from the leaf at the given index to the root.
void commit(const CommitCallback &on_completion)
Commit the tree to the backing store.
void add_values_internal(std::shared_ptr< std::vector< fr > > values, fr &new_root, index_t &new_size, bool update_index)
void commit_to_depth(uint32_t target_depth, const CheckpointCommitCallback &on_completion)
void add_batch_internal(std::vector< fr > &values, fr &new_root, index_t &new_size, bool update_index, ReadTransaction &tx)
std::function< void(Response &)> EmptyResponseCallback
std::shared_ptr< ThreadPool > workers_
void commit_checkpoint(const CheckpointCommitCallback &on_completion)
std::vector< fr > zero_hashes_
uint32_t depth() const
Synchronous method to retrieve the depth of the tree.
EmptyResponseCallback RollbackCallback
void commit_all_checkpoints_to(const CheckpointCommitCallback &on_completion)
std::vector< std::optional< fr > > OptionalSiblingPath
virtual ~ContentAddressedAppendOnlyTree()=default
std::function< void(TypedResponse< GetLeafResponse > &)> GetLeafCallback
virtual void add_values(const std::vector< fr > &values, const AppendCompletionCallback &on_completion)
Adds the given set of values to the end of the tree.
ContentAddressedAppendOnlyTree & operator=(ContentAddressedAppendOnlyTree const &other)=delete
void get_meta_data(bool includeUncommitted, const MetaDataCallback &on_completion) const
Returns the tree meta data.
fr_sibling_path optional_sibling_path_to_full_sibling_path(const OptionalSiblingPath &optionalPath) const
std::unique_ptr< Store > store_
EmptyResponseCallback FinalizeBlockCallback
ContentAddressedAppendOnlyTree & operator=(ContentAddressedAppendOnlyTree const &&other)=delete
void find_block_numbers(const std::vector< index_t > &indices, const GetBlockForIndexCallback &on_completion) const
Returns the block numbers that correspond to the given indices values.
void unwind_block(const block_number_t &blockNumber, const UnwindBlockCallback &on_completion)
std::function< void(TypedResponse< FindLeafIndexResponse > &)> FindLeafCallback
std::function< void(TypedResponse< GetSiblingPathResponse > &)> HashPathCallback
std::function< void(TypedResponse< TreeMetaResponse > &)> MetaDataCallback
void revert_checkpoint(const CheckpointRevertCallback &on_completion)
std::function< void(TypedResponse< UnwindResponse > &)> UnwindBlockCallback
std::function< void(TypedResponse< AddDataResponse > &)> AppendCompletionCallback
virtual void add_value(const fr &value, const AppendCompletionCallback &on_completion)
Adds a single value to the end of the tree.
std::function< void(TypedResponse< CheckpointResponse > &)> CheckpointCallback
std::optional< fr > find_leaf_hash(const index_t &leaf_index, const RequestContext &requestContext, ReadTransaction &tx, bool updateNodesByIndexCache=false) const
EmptyResponseCallback CheckpointRevertCallback
void revert_to_depth(uint32_t target_depth, const CheckpointRevertCallback &on_completion)
void rollback(const RollbackCallback &on_completion)
Rollback the uncommitted changes.
typename Store::ReadTransactionPtr ReadTransactionPtr
void find_leaf_indices(const std::vector< typename Store::LeafType > &leaves, bool includeUncommitted, const FindLeafCallback &on_completion) const
Returns the index of the provided leaf in the tree.
void get_subtree_sibling_path(uint32_t subtree_depth, const HashPathCallback &on_completion, bool includeUncommitted) const
Get the subtree sibling path object.
std::function< void(TypedResponse< CommitResponse > &)> CommitCallback
index_t get_batch_insertion_size(const index_t &treeSize, const index_t &remainingAppendSize)
ContentAddressedAppendOnlyTree(ContentAddressedAppendOnlyTree &&other)=delete
uint32_t checkpoint_depth() const
void finalize_block(const block_number_t &blockNumber, const FinalizeBlockCallback &on_completion)
void checkpoint(const CheckpointCallback &on_completion)
void find_leaf_indices_from(const std::vector< typename Store::LeafType > &leaves, const index_t &start_index, bool includeUncommitted, const FindLeafCallback &on_completion) const
Returns the index of the provided leaf in the tree only if it exists after the index value provided.
std::function< void(TypedResponse< BlockForIndexResponse > &)> GetBlockForIndexCallback
ContentAddressedAppendOnlyTree(std::unique_ptr< Store > store, std::shared_ptr< ThreadPool > workers, const std::vector< fr > &initial_values={}, bool commit_genesis_state=true)
std::function< void(TypedResponse< RemoveHistoricResponse > &)> RemoveHistoricBlockCallback
ContentAddressedAppendOnlyTree(ContentAddressedAppendOnlyTree const &other)=delete
EmptyResponseCallback CheckpointCommitCallback
void find_leaf_sibling_paths(const std::vector< typename Store::LeafType > &leaves, bool includeUncommitted, const FindSiblingPathCallback &on_completion) const
Returns the sibling paths for the provided leaves in the tree.
Used in parallel insertions in the the IndexedTree. Workers signal to other following workes as they ...
void signal_level(uint32_t level=0)
Signals that the given level has been passed.
void wait_for_level(uint32_t level=0)
Causes the thread to wait until the required level has been signalled.
std::string format(Args... args)
ContentAddressedCachedTreeStore< bb::fr > Store
void add_values(TreeType &tree, const std::vector< NullifierLeafValue > &values)
void execute_and_report(const std::function< void(TypedResponse< ResponseType > &)> &f, const std::function< void(TypedResponse< ResponseType > &)> &on_completion)
std::vector< fr > fr_sibling_path
constexpr uint64_t pow64(const uint64_t input, const uint64_t exponent)
Entry point for Barretenberg command-line interface.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::optional< fr > right
std::optional< index_t > maxIndex
std::optional< block_number_t > blockNumber
static constexpr field zero()