Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 43 additions & 7 deletions barretenberg/cpp/src/barretenberg/vm2/common/avm_inputs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once

#include <cstdint>
#include <ostream>
#include <vector>

#include "barretenberg/common/utils.hpp"
Expand Down Expand Up @@ -36,6 +37,11 @@ struct AppendOnlyTreeSnapshot {

std::size_t hash() const noexcept { return utils::hash_as_tuple(root, nextAvailableLeafIndex); }
bool operator==(const AppendOnlyTreeSnapshot& other) const = default;
friend std::ostream& operator<<(std::ostream& os, const AppendOnlyTreeSnapshot& obj)
{
os << "root: " << obj.root << ", nextAvailableLeafIndex: " << obj.nextAvailableLeafIndex;
return os;
}

MSGPACK_FIELDS(root, nextAvailableLeafIndex);
};
Expand Down Expand Up @@ -187,6 +193,36 @@ template <typename Leaf> struct SequentialInsertHint {
MSGPACK_FIELDS(hintKey, treeId, leaf, lowLeavesWitnessData, insertionWitnessData, stateAfter);
};

struct CheckpointActionNoStateChangeHint {
// key
uint32_t actionCounter;
// current checkpoint evolution
uint32_t oldCheckpointId;
uint32_t newCheckpointId;

bool operator==(const CheckpointActionNoStateChangeHint& other) const = default;

MSGPACK_FIELDS(actionCounter, oldCheckpointId, newCheckpointId);
};

using CreateCheckpointHint = CheckpointActionNoStateChangeHint;
using CommitCheckpointHint = CheckpointActionNoStateChangeHint;

struct RevertCheckpointHint {
// key
uint32_t actionCounter;
// current checkpoint evolution
uint32_t oldCheckpointId;
uint32_t newCheckpointId;
// state evolution
TreeSnapshots stateBefore;
TreeSnapshots stateAfter;

bool operator==(const RevertCheckpointHint& other) const = default;

MSGPACK_FIELDS(actionCounter, oldCheckpointId, newCheckpointId, stateBefore, stateAfter);
};

////////////////////////////////////////////////////////////////////////////
// Hints (other)
////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -248,6 +284,9 @@ struct ExecutionHints {
std::vector<GetLeafValueHint> getLeafValueHints;
std::vector<SequentialInsertHint<crypto::merkle_tree::PublicDataLeafValue>> sequentialInsertHintsPublicDataTree;
std::vector<SequentialInsertHint<crypto::merkle_tree::NullifierLeafValue>> sequentialInsertHintsNullifierTree;
std::vector<CreateCheckpointHint> createCheckpointHints;
std::vector<CommitCheckpointHint> commitCheckpointHints;
Comment thread
dbanks12 marked this conversation as resolved.
std::vector<RevertCheckpointHint> revertCheckpointHints;

bool operator==(const ExecutionHints& other) const = default;

Expand All @@ -261,7 +300,10 @@ struct ExecutionHints {
getLeafPreimageHintsNullifierTree,
getLeafValueHints,
sequentialInsertHintsPublicDataTree,
sequentialInsertHintsNullifierTree);
sequentialInsertHintsNullifierTree,
createCheckpointHints,
commitCheckpointHints,
revertCheckpointHints);
};

////////////////////////////////////////////////////////////////////////////
Expand All @@ -278,9 +320,3 @@ struct AvmProvingInputs {
};

} // namespace bb::avm2

// Define hash function so that they can be used as keys in maps.
Comment thread
fcarreiro marked this conversation as resolved.
// See https://en.cppreference.com/w/cpp/utility/hash.
template <> struct std::hash<bb::avm2::AppendOnlyTreeSnapshot> {
std::size_t operator()(const bb::avm2::AppendOnlyTreeSnapshot& st) const noexcept { return st.hash(); }
};
Binary file not shown.
15 changes: 15 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm2/simulation/concrete_dbs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,19 @@ FF MerkleDB::storage_read(const FF& leaf_slot) const
return value;
}

void MerkleDB::create_checkpoint()
{
raw_merkle_db.create_checkpoint();
}

void MerkleDB::commit_checkpoint()
{
raw_merkle_db.commit_checkpoint();
}

void MerkleDB::revert_checkpoint()
{
raw_merkle_db.revert_checkpoint();
}

} // namespace bb::avm2::simulation
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class MerkleDB final : public HighLevelMerkleDBInterface {

// Unconstrained.
const TreeSnapshots& get_tree_roots() const override;
void create_checkpoint() override;
void commit_checkpoint() override;
void revert_checkpoint() override;

// Constrained.
// TODO: When actually using this, consider siloing inside (and taking a silo gadget in the constructor).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,14 @@ class LowLevelMerkleDBInterface {
virtual crypto::merkle_tree::IndexedLeaf<crypto::merkle_tree::NullifierLeafValue> get_leaf_preimage_nullifier_tree(
crypto::merkle_tree::index_t leaf_index) const = 0;

// Inserts a leaf into the public data tree sequentially, getting witnesses at every step.
// Note: This method doesn't support inserting empty leaves.
virtual world_state::SequentialInsertionResult<crypto::merkle_tree::PublicDataLeafValue>
insert_indexed_leaves_public_data_tree(const crypto::merkle_tree::PublicDataLeafValue& leaf_value) = 0;

// Inserts a leaf into the nullifier tree sequentially, getting witnesses at every step.
// Note: This method doesn't support inserting empty leaves.
virtual world_state::SequentialInsertionResult<crypto::merkle_tree::NullifierLeafValue>
insert_indexed_leaves_nullifier_tree(const crypto::merkle_tree::NullifierLeafValue& leaf_value) = 0;

virtual void create_checkpoint() = 0;
virtual void commit_checkpoint() = 0;
virtual void revert_checkpoint() = 0;
};

// High level access to a merkle db. In general these will be constrained.
Expand All @@ -58,6 +57,11 @@ class HighLevelMerkleDBInterface {

virtual const TreeSnapshots& get_tree_roots() const = 0;
virtual FF storage_read(const FF& key) const = 0;

virtual void create_checkpoint() = 0;
virtual void commit_checkpoint() = 0;
virtual void revert_checkpoint() = 0;

virtual LowLevelMerkleDBInterface& as_unconstrained() const = 0;
};

Expand Down
191 changes: 165 additions & 26 deletions barretenberg/cpp/src/barretenberg/vm2/simulation/lib/raw_data_dbs.cpp
Comment thread
dbanks12 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,30 @@
#include <cassert>
#include <optional>
#include <stdexcept>
#include <string>

#include "barretenberg/common/log.hpp"
#include "barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp"
#include "barretenberg/vm2/simulation/lib/contract_crypto.hpp"

namespace bb::avm2::simulation {

namespace {

std::string to_string(const TreeSnapshots& snapshots)
{
return format("PUBLIC_DATA_TREE: ",
snapshots.publicDataTree,
"\nNULLIFIER_TREE: ",
snapshots.nullifierTree,
"\nNOTE_HASH_TREE: ",
snapshots.noteHashTree,
"\nL1_TO_L2_MESSAGE_TREE: ",
snapshots.l1ToL2MessageTree);
}

} // namespace

// HintedRawContractDB starts.
HintedRawContractDB::HintedRawContractDB(const ExecutionHints& hints)
{
Expand Down Expand Up @@ -98,41 +115,27 @@ HintedRawMerkleDB::HintedRawMerkleDB(const ExecutionHints& hints, const TreeSnap
: tree_roots(tree_roots)
{
vinfo("Initializing HintedRawMerkleDB with...",
"\n * get_sibling_path hints: ",
"\n * get_sibling_path_hints: ",
hints.getSiblingPathHints.size(),
"\n * get_previous_value_index hints: ",
"\n * get_previous_value_index_hints: ",
hints.getPreviousValueIndexHints.size(),
"\n * get_leaf_preimage hints_public_data_tree: ",
"\n * get_leaf_preimage_hints_public_data_tree: ",
hints.getLeafPreimageHintsPublicDataTree.size(),
"\n * get_leaf_preimage hints_nullifier_tree: ",
"\n * get_leaf_preimage_hints_nullifier_tree: ",
hints.getLeafPreimageHintsNullifierTree.size(),
"\n * get_leaf_value_hints: ",
hints.getLeafValueHints.size(),
"\n * sequential_insert_hints_public_data_tree: ",
hints.sequentialInsertHintsPublicDataTree.size(),
"\n * sequential_insert_hints_nullifier_tree: ",
hints.sequentialInsertHintsNullifierTree.size());
debug("Initializing HintedRawMerkleDB with snapshots...",
"\n * nullifierTree: ",
tree_roots.nullifierTree.root,
" (size: ",
tree_roots.nullifierTree.nextAvailableLeafIndex,
")",
"\n * publicDataTree: ",
tree_roots.publicDataTree.root,
" (size: ",
tree_roots.publicDataTree.nextAvailableLeafIndex,
")",
"\n * noteHashTree: ",
tree_roots.noteHashTree.root,
" (size: ",
tree_roots.noteHashTree.nextAvailableLeafIndex,
")",
"\n * l1ToL2MessageTree: ",
tree_roots.l1ToL2MessageTree.root,
" (size: ",
tree_roots.l1ToL2MessageTree.nextAvailableLeafIndex,
")");
hints.sequentialInsertHintsNullifierTree.size(),
"\n * create_checkpoint_hints: ",
hints.createCheckpointHints.size(),
"\n * commit_checkpoint_hints: ",
hints.commitCheckpointHints.size(),
"\n * revert_checkpoint_hints: ",
hints.revertCheckpointHints.size());
debug("Initializing HintedRawMerkleDB with snapshots...\n", to_string(tree_roots));

for (const auto& get_sibling_path_hint : hints.getSiblingPathHints) {
GetSiblingPathKey key = { get_sibling_path_hint.hintKey,
Expand Down Expand Up @@ -179,6 +182,18 @@ HintedRawMerkleDB::HintedRawMerkleDB(const ExecutionHints& hints, const TreeSnap
sequential_insert_hint.leaf };
sequential_insert_hints_nullifier_tree[key] = sequential_insert_hint;
}

for (const auto& create_checkpoint_hint : hints.createCheckpointHints) {
create_checkpoint_hints[create_checkpoint_hint.actionCounter] = create_checkpoint_hint;
}

for (const auto& commit_checkpoint_hint : hints.commitCheckpointHints) {
commit_checkpoint_hints[commit_checkpoint_hint.actionCounter] = commit_checkpoint_hint;
}

for (const auto& revert_checkpoint_hint : hints.revertCheckpointHints) {
revert_checkpoint_hints[revert_checkpoint_hint.actionCounter] = revert_checkpoint_hint;
}
Comment thread
dbanks12 marked this conversation as resolved.
}

const AppendOnlyTreeSnapshot& HintedRawMerkleDB::get_tree_info(world_state::MerkleTreeId tree_id) const
Expand Down Expand Up @@ -361,4 +376,128 @@ world_state::SequentialInsertionResult<crypto::merkle_tree::NullifierLeafValue>
return result;
}

void HintedRawMerkleDB::create_checkpoint()
{
auto it = create_checkpoint_hints.find(checkpoint_action_counter);
if (it == create_checkpoint_hints.end()) {
throw std::runtime_error(
format("[create_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
}
const auto& hint = it->second;

// Sanity check.
if (hint.oldCheckpointId != checkpoint_stack.top()) {
throw std::runtime_error(format("[create_checkpoint@",
checkpoint_action_counter,
"] Old checkpoint id does not match the current checkpoint id: ",
hint.oldCheckpointId,
" != ",
checkpoint_stack.top()));
}

debug("[create_checkpoint@",
checkpoint_action_counter,
"] Checkpoint evolved ",
hint.oldCheckpointId,
" -> ",
hint.newCheckpointId);

checkpoint_stack.push(hint.newCheckpointId);
checkpoint_action_counter++;
}
Comment thread
fcarreiro marked this conversation as resolved.

void HintedRawMerkleDB::commit_checkpoint()
{
auto it = commit_checkpoint_hints.find(checkpoint_action_counter);
if (it == commit_checkpoint_hints.end()) {
throw std::runtime_error(
format("[commit_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
}
const auto& hint = it->second;

// Sanity check.
if (hint.oldCheckpointId != checkpoint_stack.top()) {
throw std::runtime_error(format("[commit_checkpoint@",
checkpoint_action_counter,
"] Old checkpoint id does not match the current checkpoint id: ",
hint.oldCheckpointId,
" != ",
checkpoint_stack.top()));
}

checkpoint_stack.pop();

// Sanity check.
if (hint.newCheckpointId != checkpoint_stack.top()) {
throw std::runtime_error(format("[commit_checkpoint@",
checkpoint_action_counter,
"] New checkpoint id does not match the current checkpoint id: ",
hint.newCheckpointId,
" != ",
checkpoint_stack.top()));
}

debug("[commit_checkpoint@",
checkpoint_action_counter,
"] Checkpoint evolved ",
hint.oldCheckpointId,
" -> ",
hint.newCheckpointId);

checkpoint_action_counter++;
}

void HintedRawMerkleDB::revert_checkpoint()
{
auto it = revert_checkpoint_hints.find(checkpoint_action_counter);
if (it == revert_checkpoint_hints.end()) {
throw std::runtime_error(
format("[revert_checkpoint@", checkpoint_action_counter, "] Hint not found for action counter!"));
}
const auto& hint = it->second;

// Sanity check of checkpoint stack.
if (hint.oldCheckpointId != checkpoint_stack.top()) {
throw std::runtime_error(format("[revert_checkpoint@",
checkpoint_action_counter,
"] Old checkpoint id does not match the current checkpoint id: ",
hint.oldCheckpointId,
" != ",
checkpoint_stack.top()));
}

// Sanity check of tree snapshots.
if (hint.stateBefore != tree_roots) {
vinfo("Hint tree snapshots: ", to_string(hint.stateBefore));
vinfo("Current tree roots: ", to_string(tree_roots));
throw std::runtime_error(format("[revert_checkpoint@",
checkpoint_action_counter,
"] Hint tree snapshots do not match the current tree roots."));
}

checkpoint_stack.pop();

// Sanity check.
if (hint.newCheckpointId != checkpoint_stack.top()) {
throw std::runtime_error(format("[revert_checkpoint@",
checkpoint_action_counter,
"] New checkpoint id does not match the current checkpoint id: ",
hint.newCheckpointId,
" != ",
checkpoint_stack.top()));
}

// Evolve trees.
tree_roots = hint.stateAfter;

debug("[revert_checkpoint@",
checkpoint_action_counter,
"] Checkpoint evolved ",
hint.oldCheckpointId,
" -> ",
hint.newCheckpointId);

checkpoint_action_counter++;
}

} // namespace bb::avm2::simulation
Loading