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.
std::unique_ptr< ReadTransaction > ReadTransactionPtr
typename PersistedStoreType::ReadTransaction ReadTransaction
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()