@@ -38,10 +38,12 @@ TreeStates MerkleDB::get_tree_state() const
3838{
3939 // No event generated.
4040 TreeSnapshots tree_snapshots = raw_merkle_db.get_tree_roots ();
41+ TreeCounters tree_counters = tree_counters_stack.top ();
4142 return {
42- .noteHashTree = { .tree = tree_snapshots.noteHashTree , .counter = note_hash_counter },
43- .nullifierTree = { .tree = tree_snapshots.nullifierTree , .counter = nullifier_counter },
44- .l1ToL2MessageTree = { .tree = tree_snapshots.l1ToL2MessageTree , .counter = l2_to_l1_msg_counter },
43+ .noteHashTree = { .tree = tree_snapshots.noteHashTree , .counter = tree_counters.note_hash_counter },
44+ .nullifierTree = { .tree = tree_snapshots.nullifierTree , .counter = tree_counters.nullifier_counter },
45+ .l1ToL2MessageTree = { .tree = tree_snapshots.l1ToL2MessageTree ,
46+ .counter = tree_counters.l2_to_l1_msg_counter },
4547 .publicDataTree = { .tree = tree_snapshots.publicDataTree , .counter = written_public_data_slots.size () },
4648 };
4749}
@@ -143,6 +145,7 @@ bool MerkleDB::siloed_nullifier_write(const FF& nullifier)
143145
144146bool MerkleDB::nullifier_write_internal (std::optional<AztecAddress> contract_address, const FF& nullifier)
145147{
148+ uint32_t nullifier_counter = tree_counters_stack.top ().nullifier_counter ;
146149 FF siloed_nullifier = nullifier;
147150 if (contract_address.has_value ()) {
148151 // Unconstrained siloing to fetch the hint, since the hints are keyed by siloed data.
@@ -182,7 +185,7 @@ bool MerkleDB::nullifier_write_internal(std::optional<AztecAddress> contract_add
182185 assert (snapshot_after == raw_merkle_db.get_tree_roots ().nullifierTree );
183186
184187 if (!present) {
185- nullifier_counter++;
188+ tree_counters_stack. top (). nullifier_counter ++;
186189 }
187190
188191 return !present;
@@ -198,6 +201,8 @@ bool MerkleDB::note_hash_exists(uint64_t leaf_index, const FF& unique_note_hash)
198201
199202void MerkleDB::note_hash_write (const AztecAddress& contract_address, const FF& note_hash)
200203{
204+ uint32_t note_hash_counter = tree_counters_stack.top ().note_hash_counter ;
205+
201206 AppendOnlyTreeSnapshot snapshot_before = raw_merkle_db.get_tree_roots ().noteHashTree ;
202207 // Unconstrained siloing and uniqueness to fetch the hint, since the hints are keyed by the unique note hash.
203208 // The siloing and uniqueness will later be constrained in the note hash tree check gadget.
@@ -214,11 +219,13 @@ void MerkleDB::note_hash_write(const AztecAddress& contract_address, const FF& n
214219 // Sanity check.
215220 assert (snapshot_after == raw_merkle_db.get_tree_roots ().noteHashTree );
216221
217- note_hash_counter++;
222+ tree_counters_stack. top (). note_hash_counter ++;
218223}
219224
220225void MerkleDB::siloed_note_hash_write (const FF& siloed_note_hash)
221226{
227+
228+ uint32_t note_hash_counter = tree_counters_stack.top ().note_hash_counter ;
222229 AppendOnlyTreeSnapshot snapshot_before = raw_merkle_db.get_tree_roots ().noteHashTree ;
223230 // Unconstrained siloing and uniqueness to fetch the hint, since the hints are keyed by the unique note hash.
224231 // The siloing and uniqueness will later be constrained in the note hash tree check gadget.
@@ -233,11 +240,12 @@ void MerkleDB::siloed_note_hash_write(const FF& siloed_note_hash)
233240 // Sanity check.
234241 assert (snapshot_after == raw_merkle_db.get_tree_roots ().noteHashTree );
235242
236- note_hash_counter++;
243+ tree_counters_stack. top (). note_hash_counter ++;
237244}
238245
239246void MerkleDB::unique_note_hash_write (const FF& unique_note_hash)
240247{
248+ uint32_t note_hash_counter = tree_counters_stack.top ().note_hash_counter ;
241249 AppendOnlyTreeSnapshot snapshot_before = raw_merkle_db.get_tree_roots ().noteHashTree ;
242250 auto hint = raw_merkle_db.append_leaves (MerkleTreeId::NOTE_HASH_TREE, std::vector<FF>{ unique_note_hash })[0 ];
243251
@@ -248,7 +256,7 @@ void MerkleDB::unique_note_hash_write(const FF& unique_note_hash)
248256 // Sanity check.
249257 assert (snapshot_after == raw_merkle_db.get_tree_roots ().noteHashTree );
250258
251- note_hash_counter++;
259+ tree_counters_stack. top (). note_hash_counter ++;
252260}
253261
254262bool MerkleDB::l1_to_l2_msg_exists (uint64_t leaf_index, const FF& msg_hash) const
@@ -262,14 +270,17 @@ bool MerkleDB::l1_to_l2_msg_exists(uint64_t leaf_index, const FF& msg_hash) cons
262270void MerkleDB::pad_trees ()
263271{
264272 // The public data tree is not padded.
265- raw_merkle_db.pad_tree (MerkleTreeId::NOTE_HASH_TREE, MAX_NOTE_HASHES_PER_TX - note_hash_counter);
266- raw_merkle_db.pad_tree (MerkleTreeId::NULLIFIER_TREE, MAX_NULLIFIERS_PER_TX - nullifier_counter);
273+ raw_merkle_db.pad_tree (MerkleTreeId::NOTE_HASH_TREE,
274+ MAX_NOTE_HASHES_PER_TX - tree_counters_stack.top ().note_hash_counter );
275+ raw_merkle_db.pad_tree (MerkleTreeId::NULLIFIER_TREE,
276+ MAX_NULLIFIERS_PER_TX - tree_counters_stack.top ().nullifier_counter );
267277}
268278
269279void MerkleDB::create_checkpoint ()
270280{
271281 raw_merkle_db.create_checkpoint ();
272282 written_public_data_slots.create_checkpoint ();
283+ tree_counters_stack.push (tree_counters_stack.top ());
273284 for (auto & listener : checkpoint_listeners) {
274285 listener->on_checkpoint_created ();
275286 }
@@ -279,6 +290,9 @@ void MerkleDB::commit_checkpoint()
279290{
280291 raw_merkle_db.commit_checkpoint ();
281292 written_public_data_slots.commit_checkpoint ();
293+ TreeCounters current_counters = tree_counters_stack.top ();
294+ tree_counters_stack.pop ();
295+ tree_counters_stack.top () = current_counters;
282296 for (auto & listener : checkpoint_listeners) {
283297 listener->on_checkpoint_committed ();
284298 }
@@ -288,6 +302,7 @@ void MerkleDB::revert_checkpoint()
288302{
289303 raw_merkle_db.revert_checkpoint ();
290304 written_public_data_slots.revert_checkpoint ();
305+ tree_counters_stack.pop ();
291306 for (auto & listener : checkpoint_listeners) {
292307 listener->on_checkpoint_reverted ();
293308 }
0 commit comments