Background / motivation
- The batch kernel should output the root of a
BatchNoteTree built over the batch's output notes,
- The block kernel then aggregates the per-batch
BatchNoteTrees into a single BlockNoteTree,
Before the kernel can output (and later verify) BATCH_NOTE_TREE_ROOT in MASM, the Rust side must actually construct the BatchNoteTree during batch construction.
Batch
What already exists:
BatchNoteTree is a wrapper over SimpleSmt<BATCH_NOTE_TREE_DEPTH>. It is built via BatchNoteTree::with_contiguous_leaves, which packs note IDs at contiguous leaf indices starting at 0; each leaf value is the note ID (hash(note_details_commitment || note_metadata_commitment)).
The gap:
BatchNoteTree is never constructed during batch building. ProposedBatch::new -> new_batch_inner uses NoteTracker to compute and erase output notes, then stores them only as a flat Vec<OutputNote> exposed via ProposedBatch::output_notes(). No BatchNoteTree and no batch-note-tree root is computed or stored on ProposedBatch.
Proposed change:
- Construct the
BatchNoteTree during batch construction. In ProposedBatch::new_batch_inner, after the NoteTracker finalizes and the final (non-erased) output_notes: Vec<OutputNote> is computed, build a BatchNoteTree from those output notes' headers and store it on ProposedBatch. Add an accessor (e.g. batch_note_tree()) and include it in into_parts.
Block
What already exists:
BlockNoteTree::insert_batch_note_subtree(batch_idx, batch_note_tree): inserts a BatchNoteTree as a subtree of the BlockNoteTree (depth 16) at batch_idx via SimpleSmt::set_subtree.
The gap:
- The above
BlockNoteTree::insert_batch_note_subtree is never used. At the block level, ProposedBlock currently rebuilds the whole note tree from individual notes, and so the per-batch trees are not used; OutputNoteBatch (= Vec<(usize, OutputNote)>) is the per-batch note list it keeps.
Proposed change:
- Build the
BlockNoteTree by inserting each batch's BatchNoteTree as a subtree via BlockNoteTree::insert_batch_note_subtree(batch_idx, batch_note_tree), instead of rebuilding it note-by-note
- Remove block-level note erasure: stop erasing output notes across batches. The
NoteTracker is still needed at the block level for duplicate detection, unauthenticated-note authentication, and the circular-dependency check, but it must no longer erase output notes (otherwise the per-batch BatchNoteTree roots would no longer match).
References
Background / motivation
BatchNoteTreebuilt over the batch's output notes,BatchNoteTrees into a singleBlockNoteTree,Before the kernel can output (and later verify)
BATCH_NOTE_TREE_ROOTin MASM, the Rust side must actually construct theBatchNoteTreeduring batch construction.Batch
What already exists:
BatchNoteTreeis a wrapper overSimpleSmt<BATCH_NOTE_TREE_DEPTH>. It is built viaBatchNoteTree::with_contiguous_leaves, which packs note IDs at contiguous leaf indices starting at 0; each leaf value is the note ID (hash(note_details_commitment || note_metadata_commitment)).The gap:
BatchNoteTreeis never constructed during batch building.ProposedBatch::new->new_batch_innerusesNoteTrackerto compute and erase output notes, then stores them only as a flatVec<OutputNote>exposed viaProposedBatch::output_notes(). NoBatchNoteTreeand no batch-note-tree root is computed or stored onProposedBatch.Proposed change:
BatchNoteTreeduring batch construction. InProposedBatch::new_batch_inner, after theNoteTrackerfinalizes and the final (non-erased)output_notes: Vec<OutputNote>is computed, build aBatchNoteTreefrom those output notes' headers and store it onProposedBatch. Add an accessor (e.g.batch_note_tree()) and include it ininto_parts.Block
What already exists:
BlockNoteTree::insert_batch_note_subtree(batch_idx, batch_note_tree): inserts aBatchNoteTreeas a subtree of theBlockNoteTree(depth 16) atbatch_idxviaSimpleSmt::set_subtree.The gap:
BlockNoteTree::insert_batch_note_subtreeis never used. At the block level,ProposedBlockcurrently rebuilds the whole note tree from individual notes, and so the per-batch trees are not used;OutputNoteBatch(=Vec<(usize, OutputNote)>) is the per-batch note list it keeps.Proposed change:
BlockNoteTreeby inserting each batch'sBatchNoteTreeas a subtree viaBlockNoteTree::insert_batch_note_subtree(batch_idx, batch_note_tree), instead of rebuilding it note-by-noteNoteTrackeris still needed at the block level for duplicate detection, unauthenticated-note authentication, and the circular-dependency check, but it must no longer erase output notes (otherwise the per-batchBatchNoteTreeroots would no longer match).References
INPUT_NOTES_COMMITMENT& note erasure #2905 (batch kernel wiring)