Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 9 additions & 6 deletions noir-projects/aztec-nr/aztec/src/capsules/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ pub struct CapsuleArray<T> {
base_slot: Field,
}

impl<T, let N: u32> CapsuleArray<T>
where
T: Serialize<N> + Deserialize<N>,
{
impl<T> CapsuleArray<T> {
/// Returns a CapsuleArray connected to a contract's capsules at a base slot. Array elements are stored in
/// contiguous slots following the base slot, so there should be sufficient space between array base slots to
/// accommodate elements. A reasonable strategy is to make the base slot a hash of a unique value.
Expand All @@ -30,7 +27,10 @@ where
}

/// Stores a value at the end of the array.
pub unconstrained fn push(self, value: T) {
pub unconstrained fn push<let N: u32>(self, value: T)
where
T: Serialize<N>,
{
let current_length = self.len();

// The slot corresponding to the index `current_length` is the first slot immediately after the end of the
Expand All @@ -43,7 +43,10 @@ where
}

/// Retrieves the value stored in the array at `index`. Throws if the index is out of bounds.
pub unconstrained fn get(self, index: u32) -> T {
pub unconstrained fn get<let N: u32>(self, index: u32) -> T
where
T: Deserialize<N>,
{
assert(index < self.len(), "Attempted to read past the length of a CapsuleArray");

capsules::load(self.contract_address, self.slot_at(index)).unwrap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ impl<Note> PrivateImmutable<Note, &mut PrivateContext> {
// docs:end:get_note
}

impl<Note, let N: u32> PrivateImmutable<Note, UnconstrainedContext>
impl<Note> PrivateImmutable<Note, UnconstrainedContext>
where
Note: NoteType + NoteHash + Packable<N> + Eq,
Note: NoteType + NoteHash + Eq,
{
// docs:start:is_initialized
pub unconstrained fn is_initialized(self) -> bool {
Expand All @@ -95,7 +95,10 @@ where

// view_note does not actually use the context, but it calls oracles that are only available in private
// docs:start:view_note
pub unconstrained fn view_note(self) -> Note {
pub unconstrained fn view_note<let N: u32>(self) -> Note
where
Note: Packable<N>,
{
let mut options = NoteViewerOptions::new();
view_notes(self.storage_slot, options.set_limit(1)).get(0)
}
Expand Down
33 changes: 24 additions & 9 deletions noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,15 @@ impl<Note, Context> PrivateMutable<Note, Context> {
}
}

impl<Note, let N: u32> PrivateMutable<Note, &mut PrivateContext>
impl<Note> PrivateMutable<Note, &mut PrivateContext>
where
Note: NoteType + NoteHash + Packable<N>,
Note: NoteType + NoteHash,
{
// docs:start:initialize
pub fn initialize(self, note: Note) -> NoteEmission<Note> {
pub fn initialize<let N: u32>(self, note: Note) -> NoteEmission<Note>
where
Note: Packable<N>,
{
// Nullify the storage slot.
let nullifier = self.compute_initialization_nullifier();
self.context.push_nullifier(nullifier);
Expand All @@ -72,7 +75,10 @@ where
// docs:end:initialize

// docs:start:replace
pub fn replace(self, new_note: Note) -> NoteEmission<Note> {
pub fn replace<let N: u32>(self, new_note: Note) -> NoteEmission<Note>
where
Note: Packable<N>,
{
let (prev_retrieved_note, note_hash_for_read_request): (RetrievedNote<Note>, Field) =
get_note(self.context, self.storage_slot);

Expand All @@ -88,7 +94,10 @@ where
}
// docs:end:replace

pub fn initialize_or_replace(self, note: Note) -> NoteEmission<Note> {
pub fn initialize_or_replace<let N: u32>(self, note: Note) -> NoteEmission<Note>
where
Note: Packable<N>,
{
// Safety: `check_nullifier_exists` is an unconstrained function - we can constrain a true value
// by providing an inclusion proof of the nullifier, but cannot constrain a false value since
// a non-inclusion proof would only be valid if done in public.
Expand All @@ -111,7 +120,10 @@ where
}

// docs:start:get_note
pub fn get_note(self) -> NoteEmission<Note> {
pub fn get_note<let N: u32>(self) -> NoteEmission<Note>
where
Note: Packable<N>,
{
let mut (retrieved_note, note_hash_for_read_request) =
get_note(self.context, self.storage_slot);

Expand All @@ -125,17 +137,20 @@ where
// docs:end:get_note
}

impl<Note, let N: u32> PrivateMutable<Note, UnconstrainedContext>
impl<Note> PrivateMutable<Note, UnconstrainedContext>
where
Note: NoteType + NoteHash + Packable<N> + Eq,
Note: NoteType + NoteHash + Eq,
{
pub unconstrained fn is_initialized(self) -> bool {
let nullifier = self.compute_initialization_nullifier();
check_nullifier_exists(nullifier)
}

// docs:start:view_note
pub unconstrained fn view_note(self) -> Note {
pub unconstrained fn view_note<let N: u32>(self) -> Note
where
Note: Packable<N>,
{
let mut options = NoteViewerOptions::new();
view_notes(self.storage_slot, options.set_limit(1)).get(0)
}
Expand Down
34 changes: 23 additions & 11 deletions noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,26 @@ impl<Note, Context> PrivateSet<Note, Context> {
// docs:end:new
}

impl<Note, let N: u32> PrivateSet<Note, &mut PrivateContext>
impl<Note> PrivateSet<Note, &mut PrivateContext>
where
Note: NoteType + NoteHash + Eq + Packable<N>,
Note: NoteType + NoteHash + Eq,
{
// docs:start:insert
pub fn insert(self, note: Note) -> NoteEmission<Note> {
pub fn insert<let N: u32>(self, note: Note) -> NoteEmission<Note>
where
Note: Packable<N>,
{
create_note(self.context, self.storage_slot, note)
}
// docs:end:insert

pub fn pop_notes<PREPROCESSOR_ARGS, FILTER_ARGS>(
pub fn pop_notes<PREPROCESSOR_ARGS, FILTER_ARGS, let N: u32>(
self,
options: NoteGetterOptions<Note, N, PREPROCESSOR_ARGS, FILTER_ARGS>,
) -> BoundedVec<Note, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL> {
) -> BoundedVec<Note, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>
where
Note: Packable<N>,
{
let (retrieved_notes, note_hashes) = get_notes(self.context, self.storage_slot, options);
// We iterate in a range 0..options.limit instead of 0..notes.len() because options.limit is known at compile
// time and hence will result in less constraints when set to a lower value than
Expand Down Expand Up @@ -87,23 +93,29 @@ where

/// Note that if you later on remove the note it's much better to use `pop_notes` as `pop_notes` results
/// in significantly less constrains due to avoiding 1 read request check.
pub fn get_notes<PREPROCESSOR_ARGS, FILTER_ARGS>(
pub fn get_notes<PREPROCESSOR_ARGS, FILTER_ARGS, let N: u32>(
self,
options: NoteGetterOptions<Note, N, PREPROCESSOR_ARGS, FILTER_ARGS>,
) -> BoundedVec<RetrievedNote<Note>, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL> {
) -> BoundedVec<RetrievedNote<Note>, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>
where
Note: Packable<N>,
{
get_notes(self.context, self.storage_slot, options).0
}
}

impl<Note, let N: u32> PrivateSet<Note, UnconstrainedContext>
impl<Note> PrivateSet<Note, UnconstrainedContext>
where
Note: NoteType + NoteHash + Packable<N> + Eq,
Note: NoteType + NoteHash + Eq,
{
// docs:start:view_notes
pub unconstrained fn view_notes(
pub unconstrained fn view_notes<let N: u32>(
self,
options: NoteViewerOptions<Note, N>,
) -> BoundedVec<Note, MAX_NOTES_PER_PAGE> {
) -> BoundedVec<Note, MAX_NOTES_PER_PAGE>
where
Note: Packable<N>,
{
view_notes(self.storage_slot, options)
}
// docs:end:view_notes
Expand Down
35 changes: 19 additions & 16 deletions noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ impl<T, Context> PublicImmutable<T, Context> {
// docs:end:public_immutable_struct_new
}

impl<T, let T_PACKED_LEN: u32> PublicImmutable<T, &mut PublicContext>
where
T: Packable<T_PACKED_LEN> + Eq,
{
impl<T> PublicImmutable<T, &mut PublicContext> {
// docs:start:public_immutable_struct_write
pub fn initialize(self, value: T) {
pub fn initialize<let T_PACKED_LEN: u32>(self, value: T)
where
T: Packable<T_PACKED_LEN> + Eq,
{
// We check that the struct is not yet initialized by checking if the initialization slot is 0
let initialization_slot = INITIALIZATION_SLOT_SEPARATOR + self.storage_slot;
let init_field: Field = self.context.storage_read(initialization_slot);
Expand All @@ -83,26 +83,29 @@ where

// Note that we don't access the context, but we do call oracles that are only available in public
// docs:start:public_immutable_struct_read
pub fn read(self) -> T {
pub fn read<let T_PACKED_LEN: u32>(self) -> T
where
T: Packable<T_PACKED_LEN> + Eq,
{
WithHash::public_storage_read(*self.context, self.storage_slot)
}
// docs:end:public_immutable_struct_read
}

impl<T, let T_PACKED_LEN: u32> PublicImmutable<T, UnconstrainedContext>
where
T: Packable<T_PACKED_LEN> + Eq,
{
pub unconstrained fn read(self) -> T {
impl<T> PublicImmutable<T, UnconstrainedContext> {
pub unconstrained fn read<let T_PACKED_LEN: u32>(self) -> T
where
T: Packable<T_PACKED_LEN> + Eq,
{
WithHash::unconstrained_public_storage_read(self.context, self.storage_slot)
}
}

impl<T, let T_PACKED_LEN: u32> PublicImmutable<T, &mut PrivateContext>
where
T: Packable<T_PACKED_LEN> + Eq,
{
pub fn read(self) -> T {
impl<T> PublicImmutable<T, &mut PrivateContext> {
pub fn read<let T_PACKED_LEN: u32>(self) -> T
where
T: Packable<T_PACKED_LEN> + Eq,
{
WithHash::historical_public_storage_read(
self.context.get_block_header(),
self.context.this_address(),
Expand Down
25 changes: 14 additions & 11 deletions noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,31 @@ impl<T, Context> PublicMutable<T, Context> {
// docs:end:public_mutable_struct_new
}

impl<T, let T_PACKED_LEN: u32> PublicMutable<T, &mut PublicContext>
where
T: Packable<T_PACKED_LEN>,
{
impl<T> PublicMutable<T, &mut PublicContext> {
// docs:start:public_mutable_struct_read
pub fn read(self) -> T {
pub fn read<let T_PACKED_LEN: u32>(self) -> T
where
T: Packable<T_PACKED_LEN>,
{
self.context.storage_read(self.storage_slot)
}
// docs:end:public_mutable_struct_read

// docs:start:public_mutable_struct_write
pub fn write(self, value: T) {
pub fn write<let T_PACKED_LEN: u32>(self, value: T)
where
T: Packable<T_PACKED_LEN>,
{
self.context.storage_write(self.storage_slot, value);
}
// docs:end:public_mutable_struct_write
}

impl<T, let T_PACKED_LEN: u32> PublicMutable<T, UnconstrainedContext>
where
T: Packable<T_PACKED_LEN>,
{
pub unconstrained fn read(self) -> T {
impl<T> PublicMutable<T, UnconstrainedContext> {
pub unconstrained fn read<let T_PACKED_LEN: u32>(self) -> T
where
T: Packable<T_PACKED_LEN>,
{
self.context.storage_read(self.storage_slot)
}
}
Loading