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.
7
8namespace bb::wsdb_client {
9
10// Use avm2::simulation for interface types, but NOT world_state (it transitively
11// imports crypto::merkle_tree which conflicts with avm2::simulation aliases).
12using namespace avm2::simulation;
13
14// ---------------------------------------------------------------------------
15// Helpers
16// ---------------------------------------------------------------------------
17
18template <typename T> std::vector<uint8_t> WsdbIpcMerkleDB::serialize_to_msgpack(const T& value)
19{
20 msgpack::sbuffer buf;
21 msgpack::pack(buf, value);
22 return std::vector<uint8_t>(buf.data(), buf.data() + buf.size());
23}
24
25template <typename T> T WsdbIpcMerkleDB::deserialize_from_msgpack(const std::vector<uint8_t>& bytes)
26{
27 auto unpacked = msgpack::unpack(reinterpret_cast<const char*>(bytes.data()), bytes.size());
28 T value;
29 unpacked.get().convert(value);
30 return value;
31}
32
33// ---------------------------------------------------------------------------
34// Constructor
35// ---------------------------------------------------------------------------
36
38 : client_(client)
39 , revision_(revision)
40{}
41
42// ---------------------------------------------------------------------------
43// Tree roots
44// ---------------------------------------------------------------------------
45
47{
48 if (cached_tree_roots_.has_value()) {
49 return cached_tree_roots_.value();
50 }
51
52 auto l1_info = client_.get_tree_info(
53 wsdb::WsdbGetTreeInfo{ .treeId = MerkleTreeId::L1_TO_L2_MESSAGE_TREE, .revision = revision_ });
54 auto nh_info =
55 client_.get_tree_info(wsdb::WsdbGetTreeInfo{ .treeId = MerkleTreeId::NOTE_HASH_TREE, .revision = revision_ });
56 auto null_info =
57 client_.get_tree_info(wsdb::WsdbGetTreeInfo{ .treeId = MerkleTreeId::NULLIFIER_TREE, .revision = revision_ });
58 auto pd_info =
59 client_.get_tree_info(wsdb::WsdbGetTreeInfo{ .treeId = MerkleTreeId::PUBLIC_DATA_TREE, .revision = revision_ });
60
61 avm2::TreeSnapshots snapshots{
63 avm2::AppendOnlyTreeSnapshot{ .root = l1_info.root, .next_available_leaf_index = l1_info.size },
64 .note_hash_tree =
65 avm2::AppendOnlyTreeSnapshot{ .root = nh_info.root, .next_available_leaf_index = nh_info.size },
66 .nullifier_tree =
67 avm2::AppendOnlyTreeSnapshot{ .root = null_info.root, .next_available_leaf_index = null_info.size },
68 .public_data_tree =
69 avm2::AppendOnlyTreeSnapshot{ .root = pd_info.root, .next_available_leaf_index = pd_info.size },
70 };
71 cached_tree_roots_ = snapshots;
72 return snapshots;
73}
74
79
80// ---------------------------------------------------------------------------
81// Query methods
82// ---------------------------------------------------------------------------
83
85{
86 auto resp = client_.get_sibling_path(
87 wsdb::WsdbGetSiblingPath{ .treeId = tree_id, .revision = revision_, .leafIndex = leaf_index });
88 return resp.path;
89}
90
92 const avm2::FF& value) const
93{
94 auto resp = client_.find_low_leaf(wsdb::WsdbFindLowLeaf{ .treeId = tree_id, .revision = revision_, .key = value });
95 return GetLowIndexedLeafResponse(resp.alreadyPresent, resp.index);
96}
97
99{
100 auto resp = client_.get_leaf_value(
101 wsdb::WsdbGetLeafValue{ .treeId = tree_id, .revision = revision_, .leafIndex = leaf_index });
102 if (!resp.value.has_value()) {
103 throw std::runtime_error("Invalid get_leaf_value request for tree " +
104 std::to_string(static_cast<uint64_t>(tree_id)) + " index " +
105 std::to_string(leaf_index));
106 }
107 return deserialize_from_msgpack<avm2::FF>(resp.value.value());
108}
109
111{
113 .treeId = MerkleTreeId::PUBLIC_DATA_TREE, .revision = revision_, .leafIndex = leaf_index });
114 if (!resp.preimage.has_value()) {
115 throw std::runtime_error("Invalid get_leaf_preimage_public_data_tree request for index " +
116 std::to_string(leaf_index));
117 }
118 return deserialize_from_msgpack<IndexedLeaf<PublicDataLeafValue>>(resp.preimage.value());
119}
120
122{
124 .treeId = MerkleTreeId::NULLIFIER_TREE, .revision = revision_, .leafIndex = leaf_index });
125 if (!resp.preimage.has_value()) {
126 throw std::runtime_error("Invalid get_leaf_preimage_nullifier_tree request for index " +
127 std::to_string(leaf_index));
128 }
129 return deserialize_from_msgpack<IndexedLeaf<NullifierLeafValue>>(resp.preimage.value());
130}
131
132// ---------------------------------------------------------------------------
133// State modification methods
134// ---------------------------------------------------------------------------
135
137 const PublicDataLeafValue& leaf_value)
138{
139 std::vector<std::vector<uint8_t>> serialized_leaves = { serialize_to_msgpack(leaf_value) };
141 .treeId = MerkleTreeId::PUBLIC_DATA_TREE, .leaves = std::move(serialized_leaves), .forkId = revision_.forkId });
143 return deserialize_from_msgpack<SequentialInsertionResult<PublicDataLeafValue>>(resp.result);
144}
145
147 const NullifierLeafValue& leaf_value)
148{
149 std::vector<std::vector<uint8_t>> serialized_leaves = { serialize_to_msgpack(leaf_value) };
151 .treeId = MerkleTreeId::NULLIFIER_TREE, .leaves = std::move(serialized_leaves), .forkId = revision_.forkId });
153 return deserialize_from_msgpack<SequentialInsertionResult<NullifierLeafValue>>(resp.result);
154}
155
157{
158 std::vector<std::vector<uint8_t>> serialized_leaves;
159 serialized_leaves.reserve(leaves.size());
160 for (const auto& leaf : leaves) {
161 serialized_leaves.push_back(serialize_to_msgpack(leaf));
162 }
164 .treeId = tree_id, .leaves = std::move(serialized_leaves), .forkId = revision_.forkId });
166}
167
168void WsdbIpcMerkleDB::pad_tree(MerkleTreeId tree_id, size_t num_leaves)
169{
170 switch (tree_id) {
171 case MerkleTreeId::NULLIFIER_TREE: {
172 std::vector<std::vector<uint8_t>> padding_leaves;
173 padding_leaves.reserve(num_leaves);
174 auto empty_leaf = NullifierLeafValue::empty();
175 for (size_t i = 0; i < num_leaves; i++) {
176 padding_leaves.push_back(serialize_to_msgpack(empty_leaf));
177 }
178 client_.batch_insert(wsdb::WsdbBatchInsert{ .treeId = MerkleTreeId::NULLIFIER_TREE,
179 .leaves = std::move(padding_leaves),
180 .subtreeDepth = NULLIFIER_SUBTREE_HEIGHT,
181 .forkId = revision_.forkId });
182 break;
183 }
184 case MerkleTreeId::NOTE_HASH_TREE: {
185 std::vector<std::vector<uint8_t>> padding_leaves;
186 padding_leaves.reserve(num_leaves);
187 auto zero = avm2::FF(0);
188 for (size_t i = 0; i < num_leaves; i++) {
189 padding_leaves.push_back(serialize_to_msgpack(zero));
190 }
192 .treeId = MerkleTreeId::NOTE_HASH_TREE, .leaves = std::move(padding_leaves), .forkId = revision_.forkId });
193 break;
194 }
195 default:
196 throw std::runtime_error("Padding not supported for tree " + std::to_string(static_cast<uint64_t>(tree_id)));
197 }
199}
200
201// ---------------------------------------------------------------------------
202// Checkpoint methods
203// ---------------------------------------------------------------------------
204
206{
208 uint32_t current_id = checkpoint_stack_.top();
209 checkpoint_stack_.push(current_id + 1);
210}
211
218
225
227{
228 return checkpoint_stack_.top();
229}
230
231} // namespace bb::wsdb_client
#define NULLIFIER_SUBTREE_HEIGHT
Auto-generated IPC client.
void create_checkpoint(WsdbCreateCheckpoint cmd)
WsdbGetSiblingPath::Response get_sibling_path(WsdbGetSiblingPath cmd) const
WsdbBatchInsert::Response batch_insert(WsdbBatchInsert cmd) const
void commit_checkpoint(WsdbCommitCheckpoint cmd)
WsdbGetTreeInfo::Response get_tree_info(WsdbGetTreeInfo cmd) const
WsdbSequentialInsert::Response sequential_insert(WsdbSequentialInsert cmd) const
WsdbGetLeafValue::Response get_leaf_value(WsdbGetLeafValue cmd) const
void revert_checkpoint(WsdbRevertCheckpoint cmd)
WsdbFindLowLeaf::Response find_low_leaf(WsdbFindLowLeaf cmd) const
void append_leaves(WsdbAppendLeaves cmd) const
WsdbGetLeafPreimage::Response get_leaf_preimage(WsdbGetLeafPreimage cmd) const
avm2::TreeSnapshots get_tree_roots() const override
avm2::simulation::SiblingPath get_sibling_path(avm2::simulation::MerkleTreeId tree_id, avm2::simulation::index_t leaf_index) const override
static std::vector< uint8_t > serialize_to_msgpack(const T &value)
avm2::simulation::IndexedLeaf< avm2::simulation::PublicDataLeafValue > get_leaf_preimage_public_data_tree(avm2::simulation::index_t leaf_index) const override
std::optional< avm2::TreeSnapshots > cached_tree_roots_
crypto::merkle_tree::GetLowIndexedLeafResponse get_low_indexed_leaf(avm2::simulation::MerkleTreeId tree_id, const avm2::FF &value) const override
static T deserialize_from_msgpack(const std::vector< uint8_t > &bytes)
std::stack< uint32_t > checkpoint_stack_
avm2::simulation::SequentialInsertionResult< avm2::simulation::PublicDataLeafValue > insert_indexed_leaves_public_data_tree(const avm2::simulation::PublicDataLeafValue &leaf_value) override
void pad_tree(avm2::simulation::MerkleTreeId tree_id, size_t num_leaves) 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
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::FF get_leaf_value(avm2::simulation::MerkleTreeId tree_id, avm2::simulation::index_t leaf_index) const override
world_state::WorldStateRevision revision_
uint32_t get_checkpoint_id() const override
::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
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
NamedUnion command structs for the aztec-wsdb world state database API.
LowLevelMerkleDBInterface implementation backed by WSDB IPC.