aztec_pxe/sync/
note_service.rs1use aztec_core::error::Error;
7use aztec_core::types::{AztecAddress, Fr};
8use aztec_node_client::AztecNode;
9
10use crate::stores::note_store::{NoteFilter, NoteStatus, StoredNote};
11use crate::stores::NoteStore;
12
13const MAX_RPC_LEN: usize = 128;
15
16pub struct NoteService<'a, N: AztecNode> {
18 node: &'a N,
19 note_store: &'a NoteStore,
20}
21
22impl<'a, N: AztecNode> NoteService<'a, N> {
23 pub fn new(node: &'a N, note_store: &'a NoteStore) -> Self {
24 Self { node, note_store }
25 }
26
27 pub async fn get_notes(&self, filter: &NoteFilter) -> Result<Vec<StoredNote>, Error> {
29 self.note_store.get_notes(filter).await
30 }
31
32 pub async fn sync_note_nullifiers(
40 &self,
41 contract_address: &AztecAddress,
42 scopes: &[AztecAddress],
43 anchor_block_number: u64,
44 ) -> Result<u64, Error> {
45 let filter = NoteFilter {
46 contract_address: Some(*contract_address),
47 status: NoteStatus::Active,
48 scopes: scopes.to_vec(),
49 ..Default::default()
50 };
51
52 let notes = self.note_store.get_notes(&filter).await?;
53 if notes.is_empty() {
54 return Ok(0);
55 }
56
57 let mut nullified_count = 0u64;
58
59 for chunk in notes.chunks(MAX_RPC_LEN) {
61 let nullifiers: Vec<Fr> = chunk.iter().map(|n| n.siloed_nullifier).collect();
62
63 let mut indexes: Vec<Option<u64>> = Vec::with_capacity(nullifiers.len());
65 for nullifier in &nullifiers {
66 let witness = self
67 .node
68 .get_nullifier_membership_witness(anchor_block_number, nullifier)
69 .await?;
70 indexes.push(witness.map(|_| 0));
71 }
72
73 let mut to_nullify = Vec::new();
75 for (i, maybe_index) in indexes.iter().enumerate() {
76 if maybe_index.is_some() {
77 to_nullify.push((chunk[i].siloed_nullifier, 0u64));
78 nullified_count += 1;
79 }
80 }
81
82 if !to_nullify.is_empty() {
83 self.note_store.apply_nullifiers(&to_nullify).await?;
84 }
85 }
86
87 if nullified_count > 0 {
88 tracing::debug!(
89 contract = %contract_address,
90 nullified = nullified_count,
91 "synced note nullifiers"
92 );
93 }
94
95 Ok(nullified_count)
96 }
97
98 pub async fn validate_and_store_note(
107 &self,
108 note: &StoredNote,
109 scope: &AztecAddress,
110 ) -> Result<(), Error> {
111 let nullifier_witness = self
117 .node
118 .get_nullifier_membership_witness(0, ¬e.siloed_nullifier)
119 .await?;
120
121 let mut stored = note.clone();
122 if nullifier_witness.is_some() {
123 stored.nullified = true;
124 stored.nullification_block_number = Some(0); }
126
127 self.note_store.add_notes(&[stored], scope).await?;
129
130 Ok(())
131 }
132}