Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions noir-projects/aztec-nr/aztec/src/capsules/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,13 @@ impl<T> CapsuleArray<T> {
capsules::store(self.contract_address, self.base_slot, current_length - 1);
}

/// Iterates over the entire array, calling the callback with all values and their array index. The order in which
/// values are processed is arbitrary.
/// Calls a function on each element of the array.
///
/// The function `f` is called once with each array value and its corresponding index. The order in which values
/// are
/// processed is arbitrary.
///
/// ## Array Mutation
///
/// It is safe to delete the current element (and only the current element) from inside the callback via `remove`:
/// ```noir
Expand Down
63 changes: 43 additions & 20 deletions noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::protocol::{address::AztecAddress, logging::{debug_log, debug_log_format}};

pub mod nonce_discovery;
pub mod partial_notes;
pub mod private_events;
pub(crate) mod nonce_discovery;
pub(crate) mod partial_notes;
pub(crate) mod private_events;
pub mod private_notes;
pub mod process_message;

Expand All @@ -20,22 +20,40 @@ use crate::{
};

pub struct NoteHashAndNullifier {
/// The result of NoteHash::compute_note_hash
/// The result of [`crate::note::note_interface::NoteHash::compute_note_hash`].
pub note_hash: Field,
/// The result of NoteHash::compute_nullifier_unconstrained (since all of message discovery is unconstrained).
/// This is `None` if the nullifier cannot be computed (e.g., because the nullifier hiding key is not available).
/// The result of [`crate::note::note_interface::NoteHash::compute_nullifier_unconstrained`].
///
/// This value is unconstrained as all of message discovery is unconstrained. This is `None` if the nullifier

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change made the code un-compilable because the fields are directly used by generate_contract_library_method_compute_note_hash_and_nullifier.

Reverted this change as it makes sense to tackle in a followup.

/// cannot be computed (e.g., because the nullifier hiding key is not available).
pub inner_nullifier: Option<Field>,
}

/// A function which takes a note's packed content, address of the emitting contract, note nonce, storage slot and note
/// type ID and attempts to compute its note hash (not hashed by note nonce nor siloed by address) and inner nullifier
/// (not siloed by address).
/// A contract's way of computing note hashes and nullifiers.
///
/// This function must be user-provided as its implementation requires knowledge of how note type IDs are allocated in
/// a contract. The `#[aztec]` macro automatically creates such a contract library method called
/// `_compute_note_hash_and_nullifier`, which looks something like this:
/// Each contract in the network is free to compute their note's hash and nullifiers as they see fit - the hash
/// function
/// itself and the nullifier derivation are not enshrined or standardized. Some aztec-nr functions however do need to
/// know the details of this computation (e.g. when finding new notes), which is what this type represents.
///
/// ```
/// This function takes a note's packed content, storage slot, note type ID, address of the emitting contract,
/// randomness and note nonce, and attempts to compute its inner note hash (not siloed by address nor uniqued by nonce)
/// and inner nullifier (not siloed by address).
///
/// ## Transient Notes
///
/// This function is meant to always be used on **settled** notes, i.e. those that have been inserted into the trees
/// and
/// for which the nonce is known. It is never invoked in the context of a transient note, as those are not involved in
/// message processing.
///
/// ## Automatic Implementation
///
/// The [`[#aztec]`](crate::macros::aztec::aztec) macro automatically creates a correct implementation of this function
/// for each contract by inspecting all note types in use and the storage layout. This injected function is a
/// `#[contract_library_function]` called `_compute_note_hash_and_nullifier`, and it looks something like this:
///
/// ```noir
/// |packed_note, owner, storage_slot, note_type_id, contract_address, randomness, note_nonce| {
/// if note_type_id == MyNoteType::get_id() {
/// assert(packed_note.len() == MY_NOTE_TYPE_SERIALIZATION_LENGTH);
Expand Down Expand Up @@ -78,15 +96,15 @@ pub type CustomMessageHandler<Env> = unconstrained fn[Env](
/* msg_content */ BoundedVec<Field, MAX_MESSAGE_CONTENT_LEN>,
/* message_context */ MessageContext);

/// Performs the state synchronization process, in which private logs are downloaded and inspected to find new private
/// notes, partial notes and events, etc., and pending partial notes are processed to search for their completion logs.
/// This is the mechanism via which a contract updates its knowledge of its private state.
/// Synchronizes the contract's private state with the network.
///
/// Note that the state is synchronized up to the latest block synchronized by PXE (referred to as "anchor block").
/// That should be close to the chain tip as block synchronization is performed before contract function simulation is
/// done.
/// As blocks are mined, it is possible for a contract's private state to change (e.g. with new notes being created),
/// but because these changes are private they will be invisible to most actors. This is the function that processes
/// new
/// transactions in order to discover new notes, events, and other kinds of private state changes.
///
/// Receives the address of the contract on which discovery is performed along with the contract's configuration.
/// The private state will be synchronized up to the block that will be used for private transactions (i.e. the anchor
/// block. This will typically be close to the tip of the chain.
pub unconstrained fn do_sync_state<ComputeNoteHashAndNullifierEnv, CustomMessageHandlerEnv>(
contract_address: AztecAddress,
compute_note_hash_and_nullifier: ComputeNoteHashAndNullifier<ComputeNoteHashAndNullifierEnv>,
Expand All @@ -113,6 +131,11 @@ pub unconstrained fn do_sync_state<ComputeNoteHashAndNullifierEnv, CustomMessage
message_ciphertext,
pending_tagged_log.context,
);

// We need to delete each log from the array so that we won't process them again. `CapsuleArray::for_each`
// allows deletion of the current element during iteration, so this is safe.
// Note that this (and all other database changes) will only be committed if contract execution succeeds,
// including any enqueued validation requests.
logs.remove(i);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ use crate::protocol::{

/// A struct with the discovered information of a complete note, required for delivery to PXE. Note that this is *not*
/// the complete note information, since it does not include content, storage slot, etc.
pub struct DiscoveredNoteInfo {
pub note_nonce: Field,
pub note_hash: Field,
pub inner_nullifier: Field,
pub(crate) struct DiscoveredNoteInfo {
pub(crate) note_nonce: Field,
pub(crate) note_hash: Field,
pub(crate) inner_nullifier: Field,
}

/// Searches for note nonces that will result in a note that was emitted in a transaction. While rare, it is possible
Expand All @@ -23,7 +23,7 @@ pub struct DiscoveredNoteInfo {
///
/// Due to how nonces are computed, this function requires knowledge of the transaction in which the note was created,
/// more specifically the list of all unique note hashes in it plus the value of its first nullifier.
pub unconstrained fn attempt_note_nonce_discovery<Env>(
pub(crate) unconstrained fn attempt_note_nonce_discovery<Env>(
unique_note_hashes_in_tx: BoundedVec<Field, MAX_NOTE_HASHES_PER_TX>,
first_nullifier_in_tx: Field,
compute_note_hash_and_nullifier: ComputeNoteHashAndNullifier<Env>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::protocol::{
};

/// The slot in the PXE capsules where we store a `CapsuleArray` of `DeliveredPendingPartialNote`.
pub global DELIVERED_PENDING_PARTIAL_NOTE_ARRAY_LENGTH_CAPSULES_SLOT: Field = sha256_to_field(
pub(crate) global DELIVERED_PENDING_PARTIAL_NOTE_ARRAY_LENGTH_CAPSULES_SLOT: Field = sha256_to_field(
"AZTEC_NR::DELIVERED_PENDING_PARTIAL_NOTE_ARRAY_LENGTH_CAPSULES_SLOT".as_bytes(),
);

Expand All @@ -37,7 +37,7 @@ pub(crate) struct DeliveredPendingPartialNote {
pub(crate) recipient: AztecAddress,
}

pub unconstrained fn process_partial_note_private_msg(
pub(crate) unconstrained fn process_partial_note_private_msg(
contract_address: AztecAddress,
recipient: AztecAddress,
msg_metadata: u64,
Expand Down Expand Up @@ -67,7 +67,7 @@ pub unconstrained fn process_partial_note_private_msg(

/// Searches for logs that would result in the completion of pending partial notes, ultimately resulting in the notes
/// being delivered to PXE if completed.
pub unconstrained fn fetch_and_process_partial_note_completion_logs<Env>(
pub(crate) unconstrained fn fetch_and_process_partial_note_completion_logs<Env>(
contract_address: AztecAddress,
compute_note_hash_and_nullifier: ComputeNoteHashAndNullifier<Env>,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
};
use crate::protocol::{address::AztecAddress, traits::ToField};

pub unconstrained fn process_private_event_msg(
pub(crate) unconstrained fn process_private_event_msg(
contract_address: AztecAddress,
recipient: AztecAddress,
msg_metadata: u64,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::messages::{
};
use crate::protocol::{address::AztecAddress, constants::MAX_NOTE_HASHES_PER_TX, logging::debug_log_format};

pub unconstrained fn process_private_note_msg<Env>(
pub(crate) unconstrained fn process_private_note_msg<Env>(
contract_address: AztecAddress,
tx_hash: Field,
unique_note_hashes_in_tx: BoundedVec<Field, MAX_NOTE_HASHES_PER_TX>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ pub unconstrained fn process_message_ciphertext<ComputeNoteHashAndNullifierEnv,
);
} else {
debug_log_format(
"Found invalid message from tx {0}, ignoring",
"Could not decrypt message ciphertext from tx {0}, ignoring",
[message_context.tx_hash],
);
}
}

pub unconstrained fn process_message_plaintext<ComputeNoteHashAndNullifierEnv, CustomMessageHandlerEnv>(
pub(crate) unconstrained fn process_message_plaintext<ComputeNoteHashAndNullifierEnv, CustomMessageHandlerEnv>(
contract_address: AztecAddress,
compute_note_hash_and_nullifier: ComputeNoteHashAndNullifier<ComputeNoteHashAndNullifierEnv>,
process_custom_message: Option<CustomMessageHandler<CustomMessageHandlerEnv>>,
Expand Down
Loading