Skip to content

Commit

Permalink
feat: remove note processor and trigger sync (#9794)
Browse files Browse the repository at this point in the history
Closes: #9370 
Closes #9575 
Closes #9786

Replaces the note processor with the tagging approach, supporting a
sliding window of indexes and partial notes

---------

Co-authored-by: Nicolás Venturo <[email protected]>
Co-authored-by: Santiago Palladino <[email protected]>
  • Loading branch information
3 people authored Nov 14, 2024
1 parent 188f60a commit b6c3048
Show file tree
Hide file tree
Showing 85 changed files with 938 additions and 2,101 deletions.
17 changes: 8 additions & 9 deletions noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use std::{
use crate::{
encrypted_logs::header::EncryptedLogHeader,
keys::point_to_symmetric_key::point_to_symmetric_key,
oracle::{notes::{get_app_tag_bytes, increment_app_tagging_secret}, random::random},
oracle::{
notes::{get_app_tag_bytes_as_sender, increment_app_tagging_secret_index_as_sender},
random::random,
},
utils::point::point_to_bytes,
};

Expand Down Expand Up @@ -128,8 +131,8 @@ fn compute_encrypted_log<let P: u32, let M: u32>(
// We assume that the sender wants for the recipient to find the tagged note, and therefore that they will cooperate
// and use the correct tag. Usage of a bad tag will result in the recipient not being able to find the note
// automatically.
let tag_bytes = unsafe { get_app_tag_bytes(sender, recipient) };
increment_app_tagging_secret(sender, recipient);
let tag_bytes = unsafe { get_app_tag_bytes_as_sender(sender, recipient) };
increment_app_tagging_secret_index_as_sender(sender, recipient);

for i in 0..32 {
encrypted_bytes[offset + i] = tag_bytes[i];
Expand Down Expand Up @@ -331,13 +334,9 @@ mod test {
0x25afb798ea6d0b8c1618e50fdeafa463059415013d3b7c75d46abf5e242be70c,
);

let _ = OracleMock::mock("getAppTaggingSecret").returns([
69420,
0x25afb798ea6d0b8c1618e50fdeafa463059415013d3b7c75d46abf5e242be70c,
1337,
]);
let _ = OracleMock::mock("getAppTaggingSecretAsSender").returns([69420, 1337]);

let _ = OracleMock::mock("incrementAppTaggingSecret");
let _ = OracleMock::mock("incrementAppTaggingSecretIndexAsSender").returns(());

let log = compute_private_log_payload(
contract_address,
Expand Down
10 changes: 10 additions & 0 deletions noir-projects/aztec-nr/aztec/src/macros/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ pub comptime fn aztec(m: Module) -> Quoted {
generate_compute_note_hash_and_optionally_a_nullifier();
let note_exports = generate_note_exports();
let public_dispatch = generate_public_dispatch(m);
let sync_notes = generate_sync_notes();
quote {
$note_exports
$interface
$compute_note_hash_and_optionally_a_nullifier
$public_dispatch
$sync_notes
}
}

Expand Down Expand Up @@ -173,3 +175,11 @@ comptime fn generate_note_exports() -> Quoted {
})
.join(quote {})
}

comptime fn generate_sync_notes() -> Quoted {
quote {
unconstrained fn sync_notes() {
aztec::oracle::notes::sync_notes();
}
}
}
1 change: 0 additions & 1 deletion noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,6 @@ comptime fn generate_finalization_payload(
// We append the public value to the log and emit it as unencrypted log
let mut finalization_log = [0; $finalization_log_byte_length];


// Iterate over the partial log and copy it to the final log
for i in 0..setup_log.len() {
finalization_log[i + 1] = setup_log[i];
Expand Down
44 changes: 24 additions & 20 deletions noir-projects/aztec-nr/aztec/src/oracle/notes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ pub unconstrained fn get_notes<Note, let N: u32, let M: u32, let S: u32, let NS:
where
Note: NoteInterface<N>,
{
sync_notes_oracle_wrapper();
let fields = get_notes_oracle_wrapper(
storage_slot,
num_selects,
Expand Down Expand Up @@ -203,27 +204,30 @@ pub unconstrained fn check_nullifier_exists(inner_nullifier: Field) -> bool {
#[oracle(checkNullifierExists)]
unconstrained fn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}

/// Same as `get_app_tagging_secret`, except it returns the derived tag as an array of bytes, ready to be included in a
/// Same as `get_app_tagging_secret_as_sender`, except it returns the derived tag as an array of bytes, ready to be included in a
/// log.
pub unconstrained fn get_app_tag_bytes(sender: AztecAddress, recipient: AztecAddress) -> [u8; 32] {
let tag = get_app_tagging_secret(sender, recipient).compute_tag();
pub unconstrained fn get_app_tag_bytes_as_sender(
sender: AztecAddress,
recipient: AztecAddress,
) -> [u8; 32] {
let tag = get_app_tagging_secret_as_sender(sender, recipient).compute_tag(recipient);
tag.to_be_bytes()
}

/// Returns the tagging secret for a given sender and recipient pair, siloed for the current contract address.
/// Includes the last known index used for tagging with this secret.
/// Includes the last known index used to send a note tagged with this secret.
/// For this to work, PXE must know the ivpsk_m of the sender.
/// For the recipient's side, only the address is needed.
pub unconstrained fn get_app_tagging_secret(
pub unconstrained fn get_app_tagging_secret_as_sender(
sender: AztecAddress,
recipient: AztecAddress,
) -> IndexedTaggingSecret {
let result = get_app_tagging_secret_oracle(sender, recipient);
let result = get_app_tagging_secret_as_sender_oracle(sender, recipient);
IndexedTaggingSecret::deserialize(result)
}

#[oracle(getAppTaggingSecret)]
unconstrained fn get_app_tagging_secret_oracle(
#[oracle(getAppTaggingSecretAsSender)]
unconstrained fn get_app_tagging_secret_as_sender_oracle(
_sender: AztecAddress,
_recipient: AztecAddress,
) -> [Field; INDEXED_TAGGING_SECRET_LENGTH] {}
Expand All @@ -233,38 +237,38 @@ unconstrained fn get_app_tagging_secret_oracle(
/// This change should only be persisted in a non-volatile database if the tagged log is found in an actual block -
/// otherwise e.g. a reverting transaction can cause the sender to accidentally skip indices and later produce notes
/// that are not found by the recipient.
pub fn increment_app_tagging_secret(sender: AztecAddress, recipient: AztecAddress) {
pub fn increment_app_tagging_secret_index_as_sender(sender: AztecAddress, recipient: AztecAddress) {
// This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.
unsafe {
increment_app_tagging_secret_wrapper(sender, recipient);
increment_app_tagging_secret_index_as_sender_wrapper(sender, recipient);
}
}

unconstrained fn increment_app_tagging_secret_wrapper(
unconstrained fn increment_app_tagging_secret_index_as_sender_wrapper(
sender: AztecAddress,
recipient: AztecAddress,
) {
increment_app_tagging_secret_oracle(sender, recipient);
increment_app_tagging_secret_index_as_sender_oracle(sender, recipient);
}

#[oracle(incrementAppTaggingSecret)]
unconstrained fn increment_app_tagging_secret_oracle(
#[oracle(incrementAppTaggingSecretIndexAsSender)]
unconstrained fn increment_app_tagging_secret_index_as_sender_oracle(
_sender: AztecAddress,
_recipient: AztecAddress,
) {}

/// Finds new notes that may have been sent to `recipient` in the current contract and makes them available
/// Finds new notes that may have been sent to all registered accounts in PXE in the current contract and makes them available
/// for later querying via the `get_notes` oracle.
pub fn sync_notes(recipient: AztecAddress) {
pub fn sync_notes() {
// This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call.
unsafe {
sync_notes_oracle_wrapper(recipient);
sync_notes_oracle_wrapper();
}
}

unconstrained fn sync_notes_oracle_wrapper(recipient: AztecAddress) {
sync_notes_oracle(recipient);
unconstrained fn sync_notes_oracle_wrapper() {
sync_notes_oracle();
}

#[oracle(syncNotes)]
unconstrained fn sync_notes_oracle(_recipient: AztecAddress) {}
unconstrained fn sync_notes_oracle() {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ use crate::traits::{Deserialize, Serialize};
use super::{address::aztec_address::AztecAddress, hash::poseidon2_hash};
use std::meta::derive;

pub global INDEXED_TAGGING_SECRET_LENGTH: u32 = 3;
pub global INDEXED_TAGGING_SECRET_LENGTH: u32 = 2;

#[derive(Serialize, Deserialize)]
pub struct IndexedTaggingSecret {
secret: Field,
recipient: AztecAddress,
index: u32,
}

impl IndexedTaggingSecret {
pub fn compute_tag(self) -> Field {
poseidon2_hash(
[self.secret, self.recipient.to_field(), self.index as Field],
)
pub fn compute_tag(self, recipient: AztecAddress) -> Field {
poseidon2_hash([self.secret, recipient.to_field(), self.index as Field])
}
}
6 changes: 3 additions & 3 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
type TxEffect,
type TxHash,
type TxReceipt,
type TxScopedEncryptedL2NoteLog,
type TxScopedL2Log,
type UnencryptedL2Log,
} from '@aztec/circuit-types';
import {
Expand Down Expand Up @@ -639,7 +639,7 @@ export class Archiver implements ArchiveSource {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
getLogsByTags(tags: Fr[]): Promise<TxScopedL2Log[][]> {
return this.store.getLogsByTags(tags);
}

Expand Down Expand Up @@ -955,7 +955,7 @@ class ArchiverStoreHelper
): Promise<L2BlockL2Logs<FromLogType<TLogType>>[]> {
return this.store.getLogs(from, limit, logType);
}
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]> {
getLogsByTags(tags: Fr[]): Promise<TxScopedL2Log[][]> {
return this.store.getLogsByTags(tags);
}
getUnencryptedLogs(filter: LogFilter): Promise<GetUnencryptedLogsResponse> {
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/archiver/src/archiver/archiver_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
type TxEffect,
type TxHash,
type TxReceipt,
type TxScopedEncryptedL2NoteLog,
type TxScopedL2Log,
} from '@aztec/circuit-types';
import {
type ContractClassPublic,
Expand Down Expand Up @@ -142,7 +142,7 @@ export interface ArchiverDataStore {
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
* that tag.
*/
getLogsByTags(tags: Fr[]): Promise<TxScopedEncryptedL2NoteLog[][]>;
getLogsByTags(tags: Fr[]): Promise<TxScopedL2Log[][]>;

/**
* Gets unencrypted logs based on the provided filter.
Expand Down
Loading

0 comments on commit b6c3048

Please sign in to comment.