Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
wsdb_ipc_merkle_db.cpp
Go to the documentation of this file.
5
6#include <cstring>
7
8namespace bb::avm2::simulation {
9
10// Wire <-> domain conversion helpers are shared with the server handlers
11// (see wsdb_handlers.cpp) so both sides use the same encoding boundary.
12using bb::wsdb::Fr;
24
25// ---------------------------------------------------------------------------
26// Constructor
27// ---------------------------------------------------------------------------
28
30 : client_(client)
31 , revision_(revision)
32{}
33
34// ---------------------------------------------------------------------------
35// Tree roots
36// ---------------------------------------------------------------------------
37
39{
40 if (cached_tree_roots_.has_value()) {
41 return cached_tree_roots_.value();
42 }
43
44 auto wire_rev = revision_to_wire(revision_);
45
46 auto l1_info = client_.get_tree_info(
47 wsdb::WsdbGetTreeInfo{ .treeId = tree_id_to_wire(MerkleTreeId::L1_TO_L2_MESSAGE_TREE), .revision = wire_rev });
48 auto nh_info = client_.get_tree_info(
49 wsdb::WsdbGetTreeInfo{ .treeId = tree_id_to_wire(MerkleTreeId::NOTE_HASH_TREE), .revision = wire_rev });
50 auto null_info = client_.get_tree_info(
51 wsdb::WsdbGetTreeInfo{ .treeId = tree_id_to_wire(MerkleTreeId::NULLIFIER_TREE), .revision = wire_rev });
52 auto pd_info = client_.get_tree_info(
53 wsdb::WsdbGetTreeInfo{ .treeId = tree_id_to_wire(MerkleTreeId::PUBLIC_DATA_TREE), .revision = wire_rev });
54
55 avm2::TreeSnapshots snapshots{
56 .l1_to_l2_message_tree = avm2::AppendOnlyTreeSnapshot{ .root = fr_from_wire(l1_info.root),
57 .next_available_leaf_index = l1_info.size },
58 .note_hash_tree = avm2::AppendOnlyTreeSnapshot{ .root = fr_from_wire(nh_info.root),
59 .next_available_leaf_index = nh_info.size },
60 .nullifier_tree = avm2::AppendOnlyTreeSnapshot{ .root = fr_from_wire(null_info.root),
61 .next_available_leaf_index = null_info.size },
62 .public_data_tree = avm2::AppendOnlyTreeSnapshot{ .root = fr_from_wire(pd_info.root),
63 .next_available_leaf_index = pd_info.size },
64 };
65 cached_tree_roots_ = snapshots;
66 return snapshots;
67}
68
73
74// ---------------------------------------------------------------------------
75// Query methods
76// ---------------------------------------------------------------------------
77
79{
80 auto resp = client_.get_sibling_path(wsdb::WsdbGetSiblingPath{
81 .treeId = tree_id_to_wire(tree_id), .revision = revision_to_wire(revision_), .leafIndex = leaf_index });
82 return fr_vec_from_wire(resp.path);
83}
84
86 const avm2::FF& value) const
87{
88 auto resp = client_.find_low_leaf(wsdb::WsdbFindLowLeaf{
89 .treeId = tree_id_to_wire(tree_id), .revision = revision_to_wire(revision_), .key = fr_to_wire(value) });
90 return GetLowIndexedLeafResponse(resp.alreadyPresent, resp.index);
91}
92
94{
95 auto resp = client_.get_leaf_value(wsdb::WsdbGetLeafValue{
96 .treeId = tree_id_to_wire(tree_id), .revision = revision_to_wire(revision_), .leafIndex = leaf_index });
97 if (!resp.value.has_value()) {
98 throw std::runtime_error("Invalid get_leaf_value request for tree " +
99 std::to_string(static_cast<uint64_t>(tree_id)) + " index " +
100 std::to_string(leaf_index));
101 }
102 return fr_from_wire(resp.value.value());
103}
104
106{
107 auto resp = client_.get_public_data_leaf_preimage(
108 wsdb::WsdbGetPublicDataLeafPreimage{ .revision = revision_to_wire(revision_), .leafIndex = leaf_index });
109 if (!resp.preimage.has_value()) {
110 throw std::runtime_error("Invalid get_leaf_preimage_public_data_tree request for index " +
111 std::to_string(leaf_index));
112 }
113 return indexed_public_data_leaf_from_wire(resp.preimage.value());
114}
115
117{
118 auto resp = client_.get_nullifier_leaf_preimage(
119 wsdb::WsdbGetNullifierLeafPreimage{ .revision = revision_to_wire(revision_), .leafIndex = leaf_index });
120 if (!resp.preimage.has_value()) {
121 throw std::runtime_error("Invalid get_leaf_preimage_nullifier_tree request for index " +
122 std::to_string(leaf_index));
123 }
124 return indexed_nullifier_leaf_from_wire(resp.preimage.value());
125}
126
127// ---------------------------------------------------------------------------
128// State modification methods
129// ---------------------------------------------------------------------------
130
132 const PublicDataLeafValue& leaf_value)
133{
134 auto resp = client_.sequential_insert_public_data(wsdb::WsdbSequentialInsertPublicData{
135 .leaves = { public_data_leaf_to_wire(leaf_value) }, .forkId = revision_.forkId });
137 return sequential_public_data_from_wire(resp.result);
138}
139
141 const NullifierLeafValue& leaf_value)
142{
143 auto resp = client_.sequential_insert_nullifier(wsdb::WsdbSequentialInsertNullifier{
144 .leaves = { nullifier_leaf_to_wire(leaf_value) }, .forkId = revision_.forkId });
146 return sequential_nullifier_from_wire(resp.result);
147}
148
150{
151 std::vector<Fr> wire_leaves;
152 wire_leaves.reserve(leaves.size());
153 for (const auto& leaf : leaves) {
154 wire_leaves.push_back(fr_to_wire(leaf));
155 }
156 client_.append_leaves(wsdb::WsdbAppendLeaves{
157 .treeId = tree_id_to_wire(tree_id), .leaves = std::move(wire_leaves), .forkId = revision_.forkId });
159}
160
161void WsdbIpcMerkleDB::pad_tree(MerkleTreeId tree_id, size_t num_leaves)
162{
163 switch (tree_id) {
164 case MerkleTreeId::NULLIFIER_TREE: {
166 padding_leaves.reserve(num_leaves);
167 auto empty_leaf = NullifierLeafValue::empty();
168 for (size_t i = 0; i < num_leaves; i++) {
169 padding_leaves.push_back(nullifier_leaf_to_wire(empty_leaf));
170 }
171 client_.batch_insert_nullifier(wsdb::WsdbBatchInsertNullifier{ .leaves = std::move(padding_leaves),
172 .subtreeDepth = NULLIFIER_SUBTREE_HEIGHT,
173 .forkId = revision_.forkId });
174 break;
175 }
176 case MerkleTreeId::NOTE_HASH_TREE: {
177 std::vector<Fr> padding_leaves;
178 padding_leaves.reserve(num_leaves);
179 auto zero = avm2::FF(0);
180 for (size_t i = 0; i < num_leaves; i++) {
181 padding_leaves.push_back(fr_to_wire(zero));
182 }
183 client_.append_leaves(wsdb::WsdbAppendLeaves{ .treeId = tree_id_to_wire(MerkleTreeId::NOTE_HASH_TREE),
184 .leaves = std::move(padding_leaves),
185 .forkId = revision_.forkId });
186 break;
187 }
188 default:
189 throw std::runtime_error("Padding not supported for tree " + std::to_string(static_cast<uint64_t>(tree_id)));
190 }
192}
193
194// ---------------------------------------------------------------------------
195// Checkpoint methods
196// ---------------------------------------------------------------------------
197
199{
200 client_.create_checkpoint(wsdb::WsdbCreateCheckpoint{ .forkId = revision_.forkId });
201 uint32_t current_id = checkpoint_stack_.top();
202 checkpoint_stack_.push(current_id + 1);
203}
204
206{
207 client_.commit_checkpoint(wsdb::WsdbCommitCheckpoint{ .forkId = revision_.forkId });
209 checkpoint_stack_.pop();
210}
211
213{
214 client_.revert_checkpoint(wsdb::WsdbRevertCheckpoint{ .forkId = revision_.forkId });
216 checkpoint_stack_.pop();
217}
218
220{
221 return checkpoint_stack_.top();
222}
223
224} // namespace bb::avm2::simulation
#define NULLIFIER_SUBTREE_HEIGHT
avm2::simulation::IndexedLeaf< avm2::simulation::PublicDataLeafValue > get_leaf_preimage_public_data_tree(avm2::simulation::index_t leaf_index) const override
world_state::WorldStateRevision revision_
avm2::FF get_leaf_value(avm2::simulation::MerkleTreeId tree_id, avm2::simulation::index_t leaf_index) const override
crypto::merkle_tree::GetLowIndexedLeafResponse get_low_indexed_leaf(avm2::simulation::MerkleTreeId tree_id, const avm2::FF &value) const override
void pad_tree(avm2::simulation::MerkleTreeId tree_id, size_t num_leaves) override
WsdbIpcMerkleDB(wsdb::WsdbIpcClient &client, world_state::WorldStateRevision revision)
Construct from a connected WSDB IPC client and world state revision.
avm2::simulation::SequentialInsertionResult< avm2::simulation::NullifierLeafValue > insert_indexed_leaves_nullifier_tree(const avm2::simulation::NullifierLeafValue &leaf_value) override
avm2::TreeSnapshots get_tree_roots() const override
avm2::simulation::IndexedLeaf< avm2::simulation::NullifierLeafValue > get_leaf_preimage_nullifier_tree(avm2::simulation::index_t leaf_index) const override
void append_leaves(avm2::simulation::MerkleTreeId tree_id, std::span< const avm2::FF > leaves) override
avm2::simulation::SequentialInsertionResult< avm2::simulation::PublicDataLeafValue > insert_indexed_leaves_public_data_tree(const avm2::simulation::PublicDataLeafValue &leaf_value) override
std::optional< avm2::TreeSnapshots > cached_tree_roots_
avm2::simulation::SiblingPath get_sibling_path(avm2::simulation::MerkleTreeId tree_id, avm2::simulation::index_t leaf_index) const override
AVM range check gadget for witness generation.
::bb::crypto::merkle_tree::fr_sibling_path SiblingPath
Definition db.hpp:36
::bb::crypto::merkle_tree::index_t index_t
Definition db.hpp:37
AvmFlavorSettings::FF FF
Definition field.hpp:10
std::vector< bb::fr > fr_vec_from_wire(const std::vector< Fr > &w)
world_state::SequentialInsertionResult< crypto::merkle_tree::NullifierLeafValue > sequential_nullifier_from_wire(const wire::SequentialInsertionResultNullifier &w)
wire::NullifierLeafValue nullifier_leaf_to_wire(const crypto::merkle_tree::NullifierLeafValue &d)
wire::WorldStateRevision revision_to_wire(const world_state::WorldStateRevision &d)
crypto::merkle_tree::IndexedLeaf< crypto::merkle_tree::PublicDataLeafValue > indexed_public_data_leaf_from_wire(const wire::IndexedPublicDataLeafValue &w)
Fr fr_to_wire(const bb::fr &d)
world_state::SequentialInsertionResult< crypto::merkle_tree::PublicDataLeafValue > sequential_public_data_from_wire(const wire::SequentialInsertionResultPublicData &w)
MerkleTreeId tree_id_to_wire(world_state::MerkleTreeId d)
wire::PublicDataLeafValue public_data_leaf_to_wire(const crypto::merkle_tree::PublicDataLeafValue &d)
bb::fr fr_from_wire(const Fr &w)
crypto::merkle_tree::IndexedLeaf< crypto::merkle_tree::NullifierLeafValue > indexed_nullifier_leaf_from_wire(const wire::IndexedNullifierLeafValue &w)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
AppendOnlyTreeSnapshot l1_to_l2_message_tree
LowLevelMerkleDBInterface implementation backed by WSDB IPC.
Wire <-> domain conversion helpers for the aztec-wsdb service.