Skip to content

Commit

Permalink
refactor!: nuking NoteHeader (#11942)
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan authored and AztecBot committed Feb 19, 2025
1 parent b22e8ff commit 5569b1a
Show file tree
Hide file tree
Showing 33 changed files with 379 additions and 385 deletions.
16 changes: 12 additions & 4 deletions address-note/src/address_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use dep::aztec::{
keys::getters::{get_nsk_app, get_public_keys},
macros::notes::note,
note::{
note_header::NoteHeader, note_interface::NullifiableNote,
note_interface::NullifiableNote, retrieved_note::RetrievedNote,
utils::compute_note_hash_for_nullify,
},
oracle::random::random,
Expand Down Expand Up @@ -41,8 +41,16 @@ impl NullifiableNote for AddressNote {
)
}

unconstrained fn compute_nullifier_without_context(self, storage_slot: Field) -> Field {
let note_hash_for_nullify = compute_note_hash_for_nullify(self, storage_slot);
unconstrained fn compute_nullifier_without_context(
self,
storage_slot: Field,
contract_address: AztecAddress,
note_nonce: Field,
) -> Field {
// We set the note_hash_counter to 0 as the note is assumed to be committed (and hence not transient).
let retrieved_note =
RetrievedNote { note: self, contract_address, nonce: note_nonce, note_hash_counter: 0 };
let note_hash_for_nullify = compute_note_hash_for_nullify(retrieved_note, storage_slot);
let owner_npk_m_hash = get_public_keys(self.owner).npk_m.hash();
let secret = get_nsk_app(owner_npk_m_hash);
poseidon2_hash_with_separator(
Expand All @@ -59,7 +67,7 @@ impl AddressNote {
// note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can
// therefore assume that the sender will cooperate in the random value generation.
let randomness = unsafe { random() };
AddressNote { address, owner, randomness, header: NoteHeader::empty() }
AddressNote { address, owner, randomness }
}
// docs:end:address_note_def
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::{
ecdh_shared_secret::derive_ecdh_shared_secret_using_aztec_address,
ephemeral::generate_ephemeral_key_pair,
},
note::{note_emission::NoteEmission, note_interface::NoteInterface},
note::{
note_emission::NoteEmission, note_interface::NoteInterface, retrieved_note::RetrievedNote,
},
oracle::{
notes::{get_app_tag_as_sender, increment_app_tagging_secret_index_as_sender},
random::random,
Expand Down Expand Up @@ -201,12 +203,7 @@ pub(crate) fn get_arr_of_size__log_bytes__from_PT<let PT: u32>() -> [u8; (((PT +
/********************************************************/

// TODO: it feels like this existence check is in the wrong place. In fact, why is it needed at all? Under what circumstances have we found a non-existent note being emitted accidentally?
fn assert_note_exists<Note, let N: u32>(context: PrivateContext, note: Note)
where
Note: NoteInterface<N>,
{
let note_header = note.get_header();
let note_hash_counter = note_header.note_hash_counter;
fn assert_note_exists<let N: u32>(context: PrivateContext, note_hash_counter: u32) {
// TODO(#8589): use typesystem to skip this check when not needed
let note_exists =
context.note_hashes.storage().any(|n: NoteHash| n.counter == note_hash_counter);
Expand All @@ -226,7 +223,6 @@ where
{
let packed_note = note.pack_content();

let note_header = note.get_header();
let storage_slot_bytes: [u8; 32] = storage_slot.to_be_bytes();

// TODO(#10952): The following can be reduced to 7 bits
Expand Down Expand Up @@ -441,9 +437,8 @@ where
|e: NoteEmission<Note>| {
let note = e.note;
let storage_slot = e.storage_slot;
assert_note_exists(*context, note);

let note_hash_counter = note.get_header().note_hash_counter;
let note_hash_counter = e.note_hash_counter;
assert_note_exists(*context, note_hash_counter);

let encrypted_log = compute_log(*context, note, storage_slot, recipient, sender);
context.emit_raw_note_log(encrypted_log, note_hash_counter);
Expand All @@ -465,10 +460,11 @@ where
|e: NoteEmission<Note>| {
let note = e.note;
let storage_slot = e.storage_slot;
assert_note_exists(*context, note);
let note_hash_counter = e.note_hash_counter;

let note_hash_counter = note.get_header().note_hash_counter;
assert_note_exists(*context, note_hash_counter);

// Unconstrained logs have both their content and encryption unconstrained - it could occur that the
// Unconstrained logs have both their content and encryption unconstrained - it could occur that the
// recipient is unable to decrypt the payload.
// Regarding the note hash counter, this is used for squashing. The kernel assumes that a given note can have
Expand Down Expand Up @@ -503,7 +499,7 @@ mod test {
); // This is an address copied to match the typescript one.

let storage_slot = 42;
let note = MockNote::new(1234).contract_address(context.this_address()).build();
let note = MockNote::new(1234).build_note();
let contract_address = context.this_address();

// All the values in this test were copied over from `encrypted_log_payload.test.ts`
Expand Down
20 changes: 16 additions & 4 deletions aztec/src/history/note_inclusion.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,34 @@ use dep::protocol_types::block_header::BlockHeader;
use dep::protocol_types::merkle_tree::root::root_from_sibling_path;

use crate::{
note::{note_interface::{NoteInterface, NullifiableNote}, utils::compute_note_hash_for_nullify},
note::{
note_interface::{NoteInterface, NullifiableNote},
retrieved_note::RetrievedNote,
utils::compute_note_hash_for_nullify,
},
oracle::get_membership_witness::get_note_hash_membership_witness,
};

trait ProveNoteInclusion {
fn prove_note_inclusion<Note, let N: u32>(header: BlockHeader, note: Note, storage_slot: Field)
fn prove_note_inclusion<Note, let N: u32>(
header: BlockHeader,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
)
where
Note: NoteInterface<N> + NullifiableNote;
}

impl ProveNoteInclusion for BlockHeader {
fn prove_note_inclusion<Note, let N: u32>(self, note: Note, storage_slot: Field)
fn prove_note_inclusion<Note, let N: u32>(
self,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
)
where
Note: NoteInterface<N> + NullifiableNote,
{
let note_hash = compute_note_hash_for_nullify(note, storage_slot);
let note_hash = compute_note_hash_for_nullify(retrieved_note, storage_slot);

// Safety: The witness is only used as a "magical value" that makes the merkle proof below pass. Hence it's safe.
let witness = unsafe {
Expand Down
13 changes: 8 additions & 5 deletions aztec/src/history/note_validity.nr
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::{context::PrivateContext, note::note_interface::{NoteInterface, NullifiableNote}};
use crate::{
context::PrivateContext,
note::{note_interface::{NoteInterface, NullifiableNote}, retrieved_note::RetrievedNote},
};

use dep::protocol_types::block_header::BlockHeader;

trait ProveNoteValidity {
fn prove_note_validity<Note, let N: u32>(
header: BlockHeader,
note: Note,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
context: &mut PrivateContext,
)
Expand All @@ -16,15 +19,15 @@ trait ProveNoteValidity {
impl ProveNoteValidity for BlockHeader {
fn prove_note_validity<Note, let N: u32>(
self,
note: Note,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
context: &mut PrivateContext,
)
where
Note: NoteInterface<N> + NullifiableNote,
{
self.prove_note_inclusion(note, storage_slot);
self.prove_note_not_nullified(note, storage_slot, context);
self.prove_note_inclusion(retrieved_note, storage_slot);
self.prove_note_not_nullified(retrieved_note, storage_slot, context);
}
}

12 changes: 8 additions & 4 deletions aztec/src/history/nullifier_inclusion.nr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use dep::protocol_types::merkle_tree::root::root_from_sibling_path;

use crate::{
context::PrivateContext,
note::{note_interface::{NoteInterface, NullifiableNote}, utils::compute_siloed_nullifier},
note::{
note_interface::{NoteInterface, NullifiableNote},
retrieved_note::RetrievedNote,
utils::compute_siloed_nullifier,
},
oracle::get_nullifier_membership_witness::get_nullifier_membership_witness,
};

Expand Down Expand Up @@ -41,7 +45,7 @@ impl ProveNullifierInclusion for BlockHeader {
trait ProveNoteIsNullified {
fn prove_note_is_nullified<Note, let N: u32>(
header: BlockHeader,
note: Note,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
context: &mut PrivateContext,
)
Expand All @@ -53,14 +57,14 @@ impl ProveNoteIsNullified for BlockHeader {
// docs:start:prove_note_is_nullified
fn prove_note_is_nullified<Note, let N: u32>(
self,
note: Note,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
context: &mut PrivateContext,
)
where
Note: NoteInterface<N> + NullifiableNote,
{
let nullifier = compute_siloed_nullifier(note, storage_slot, context);
let nullifier = compute_siloed_nullifier(retrieved_note, storage_slot, context);

self.prove_nullifier_inclusion(nullifier);
}
Expand Down
12 changes: 8 additions & 4 deletions aztec/src/history/nullifier_non_inclusion.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::{
context::PrivateContext,
note::{note_interface::{NoteInterface, NullifiableNote}, utils::compute_siloed_nullifier},
note::{
note_interface::{NoteInterface, NullifiableNote},
retrieved_note::RetrievedNote,
utils::compute_siloed_nullifier,
},
oracle::get_nullifier_membership_witness::get_low_nullifier_membership_witness,
};
use dep::protocol_types::{
Expand Down Expand Up @@ -54,7 +58,7 @@ impl ProveNullifierNonInclusion for BlockHeader {
trait ProveNoteNotNullified {
fn prove_note_not_nullified<Note, let N: u32>(
header: BlockHeader,
note: Note,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
context: &mut PrivateContext,
)
Expand All @@ -66,14 +70,14 @@ impl ProveNoteNotNullified for BlockHeader {
// docs:start:prove_note_not_nullified
fn prove_note_not_nullified<Note, let N: u32>(
self,
note: Note,
retrieved_note: RetrievedNote<Note>,
storage_slot: Field,
context: &mut PrivateContext,
)
where
Note: NoteInterface<N> + NullifiableNote,
{
let nullifier = compute_siloed_nullifier(note, storage_slot, context);
let nullifier = compute_siloed_nullifier(retrieved_note, storage_slot, context);

self.prove_nullifier_non_inclusion(nullifier);
}
Expand Down
3 changes: 1 addition & 2 deletions aztec/src/macros/events/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use protocol_types::meta::generate_serialize_to_fields;
comptime fn generate_event_interface(s: StructDefinition) -> Quoted {
let name = s.name();
let typ = s.as_type();
let (serialization_fields, _) =
generate_serialize_to_fields(quote { self }, typ, &[quote {self.header}], false);
let (serialization_fields, _) = generate_serialize_to_fields(quote { self }, typ, &[], false);
let content_len = serialization_fields.len();

let event_type_id = compute_event_selector(s);
Expand Down
12 changes: 6 additions & 6 deletions aztec/src/macros/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ comptime fn generate_compute_note_hash_and_optionally_a_nullifier() -> Quoted {
if_statements_list = if_statements_list.push_back(
quote {
$if_or_else_if note_type_id == $typ::get_note_type_id() {
aztec::note::utils::compute_note_hash_and_optionally_a_nullifier($typ::unpack_content, note_header, compute_nullifier, storage_slot, packed_note_content)
aztec::note::utils::compute_note_hash_and_optionally_a_nullifier($typ::unpack_content, contract_address, nonce, compute_nullifier, storage_slot, packed_note_content)
}
},
);
Expand All @@ -147,7 +147,6 @@ comptime fn generate_compute_note_hash_and_optionally_a_nullifier() -> Quoted {
let if_statements = if_statements_list.join(quote {});

quote {
let note_header = aztec::prelude::NoteHeader::new(contract_address, nonce);
$if_statements
else {
panic(f"Unknown note type ID: {note_type_id}")
Expand Down Expand Up @@ -184,12 +183,13 @@ comptime fn generate_process_log() -> Quoted {

// A typical implementation of the lambda looks something like this:
// ```
// |packed_note_content: BoundedVec<Field, MAX_NOTE_SERIALIZED_LEN>, note_header: NoteHeader, storage_slot: Field, note_type_id: Field| {
// |packed_note_content: BoundedVec<Field, MAX_NOTE_SERIALIZED_LEN>, contract_address: AztecAddress, nonce: Field, storage_slot: Field, note_type_id: Field| {
// let hashes = if note_type_id == MyNoteType::get_note_type_id() {
// assert(packed_note_content.len() == MY_NOTE_TYPE_SERIALIZATION_LENGTH);
// dep::aztec::note::utils::compute_note_hash_and_optionally_a_nullifier(
// MyNoteType::unpack_content,
// note_header,
// contract_address,
// nonce,
// true,
// storage_slot,
// packed_note_content.storage(),
Expand Down Expand Up @@ -235,7 +235,7 @@ comptime fn generate_process_log() -> Quoted {
f"Expected note content of length {expected_len} but got {actual_len} for note type id {note_type_id}"
);

aztec::note::utils::compute_note_hash_and_optionally_a_nullifier($typ::unpack_content, note_header, true, storage_slot, packed_note_content.storage())
aztec::note::utils::compute_note_hash_and_optionally_a_nullifier($typ::unpack_content, contract_address, nonce, true, storage_slot, packed_note_content.storage())
}
},
);
Expand All @@ -257,7 +257,7 @@ comptime fn generate_process_log() -> Quoted {
unique_note_hashes_in_tx,
first_nullifier_in_tx,
recipient,
|packed_note_content: BoundedVec<Field, _>, note_header, storage_slot, note_type_id| {
|packed_note_content: BoundedVec<Field, _>, contract_address, nonce, storage_slot, note_type_id| {
let hashes = $if_note_type_id_match_statements
else {
panic(f"Unknown note type id {note_type_id}")
Expand Down
Loading

0 comments on commit 5569b1a

Please sign in to comment.