From b61f93768f3f8a7faa0abcf1be126ff5f24e0104 Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 18 Jan 2024 14:44:50 +0000 Subject: [PATCH 01/56] serialize, deserialize, noteinterface as traits --- boxes/token/src/contracts/src/main.nr | 25 ++-- boxes/token/src/contracts/src/types.nr | 1 - .../src/contracts/src/types/balance_set.nr | 2 +- .../src/contracts/src/types/balances_map.nr | 3 +- .../src/types/safe_u120_serialization.nr | 18 --- .../src/contracts/src/types/token_note.nr | 80 ++++-------- .../contracts/src/types/transparent_note.nr | 112 +++++++---------- .../aztec-nr/address-note/src/address_note.nr | 91 +++++--------- yarn-project/aztec-nr/authwit/src/account.nr | 4 +- .../aztec-nr/authwit/src/entrypoint.nr | 25 ++-- yarn-project/aztec-nr/aztec/src/abi.nr | 15 ++- yarn-project/aztec-nr/aztec/src/context.nr | 6 +- .../aztec/src/history/note_inclusion.nr | 5 +- .../aztec/src/history/note_validity.nr | 7 +- .../src/history/nullifier_non_inclusion.nr | 5 +- .../aztec-nr/aztec/src/note/lifecycle.nr | 41 ++---- .../aztec-nr/aztec/src/note/note_getter.nr | 67 +++++----- .../aztec-nr/aztec/src/note/note_interface.nr | 19 ++- yarn-project/aztec-nr/aztec/src/note/utils.nr | 63 ++++------ .../src/oracle/get_public_data_witness.nr | 16 +-- .../aztec-nr/aztec/src/oracle/notes.nr | 17 +-- .../aztec-nr/aztec/src/oracle/storage.nr | 7 +- .../src/state_vars/immutable_singleton.nr | 15 +-- .../aztec/src/state_vars/public_state.nr | 15 +-- .../aztec-nr/aztec/src/state_vars/set.nr | 24 ++-- .../aztec/src/state_vars/singleton.nr | 28 ++--- yarn-project/aztec-nr/aztec/src/types.nr | 1 - .../aztec/src/types/type_serialization.nr | 15 --- .../address_serialization.nr | 22 ---- .../type_serialization/bool_serialization.nr | 16 --- .../type_serialization/field_serialization.nr | 18 --- .../type_serialization/u32_serialization.nr | 16 --- .../type_serialization/u8_serialization.nr | 16 --- .../src/compressed_string.nr | 38 +++--- .../aztec-nr/compressed-string/src/lib.nr | 2 +- .../src/easy_private_state.nr | 5 +- .../aztec-nr/field-note/src/field_note.nr | 74 ++++------- yarn-project/aztec-nr/safe-math/Nargo.toml | 3 +- yarn-project/aztec-nr/safe-math/src/lib.nr | 2 +- .../aztec-nr/safe-math/src/safe_u120.nr | 16 +++ .../slow-updates-tree/src/slow_map.nr | 28 ++--- .../aztec-nr/value-note/src/value_note.nr | 89 +++++-------- .../benchmarking_contract/src/main.nr | 12 +- .../contracts/card_game_contract/src/cards.nr | 3 +- .../contracts/card_game_contract/src/game.nr | 105 ++++++++-------- .../contracts/card_game_contract/src/main.nr | 8 +- .../contracts/child_contract/src/main.nr | 3 +- .../contracts/counter_contract/src/main.nr | 4 +- .../docs_example_contract/src/actions.nr | 2 +- .../docs_example_contract/src/main.nr | 25 ++-- .../src/types/card_note.nr | 84 +++++-------- .../src/types/profile_note.nr | 82 +++++------- .../docs_example_contract/src/types/queen.nr | 23 ++-- .../src/types/rules_note.nr | 86 +++++-------- .../easy_private_token_contract/src/main.nr | 6 +- .../easy_private_voting_contract/src/main.nr | 15 +-- .../src/ecdsa_public_key_note.nr | 116 ++++++++--------- .../ecdsa_account_contract/src/main.nr | 6 +- .../contracts/escrow_contract/src/main.nr | 5 +- .../inclusion_proofs_contract/src/main.nr | 26 +--- .../contracts/lending_contract/src/asset.nr | 49 ++++---- .../contracts/lending_contract/src/main.nr | 23 ++-- .../pending_commitments_contract/src/main.nr | 6 +- .../price_feed_contract/src/asset.nr | 23 ++-- .../contracts/price_feed_contract/src/main.nr | 3 +- .../contracts/reader_contract/src/main.nr | 2 +- .../schnorr_account_contract/src/main.nr | 6 +- .../src/public_key_note.nr | 97 ++++++-------- .../contracts/slow_tree_contract/src/main.nr | 6 +- .../stateful_test_contract/src/main.nr | 11 +- .../contracts/test_contract/src/main.nr | 6 +- .../token_blacklist_contract/src/main.nr | 33 ++--- .../token_blacklist_contract/src/types.nr | 1 - .../src/types/balance_set.nr | 3 +- .../src/types/safe_u120_serialization.nr | 18 --- .../src/types/token_note.nr | 81 ++++-------- .../src/types/transparent_note.nr | 112 +++++++---------- .../token_bridge_contract/src/main.nr | 4 +- .../contracts/token_contract/src/main.nr | 44 +++---- .../contracts/token_contract/src/types.nr | 1 - .../token_contract/src/types/balance_set.nr | 3 +- .../src/types/safe_u120_serialization.nr | 18 --- .../token_contract/src/types/token_note.nr | 83 +++++------- .../src/types/transparent_note.nr | 119 ++++++++---------- .../contracts/uniswap_contract/src/main.nr | 11 +- .../src/crates/types/src/abis/block_header.nr | 30 +++-- .../types/src/abis/function_selector.nr | 25 ++-- .../src/abis/private_circuit_public_inputs.nr | 4 +- .../src/crates/types/src/abis/side_effect.nr | 22 ++-- .../src/crates/types/src/address.nr | 49 ++++---- .../types/src/contrakt/deployment_data.nr | 7 +- .../src/contrakt/storage_update_request.nr | 8 +- .../src/crates/types/src/grumpkin_point.nr | 12 +- .../src/crates/types/src/lib.nr | 1 + .../src/crates/types/src/traits.nr | 8 ++ .../crates/types/src/type_serialization.nr | 56 +++++++++ 96 files changed, 1070 insertions(+), 1598 deletions(-) delete mode 100644 boxes/token/src/contracts/src/types/safe_u120_serialization.nr delete mode 100644 yarn-project/aztec-nr/aztec/src/types/type_serialization.nr delete mode 100644 yarn-project/aztec-nr/aztec/src/types/type_serialization/address_serialization.nr delete mode 100644 yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr delete mode 100644 yarn-project/aztec-nr/aztec/src/types/type_serialization/field_serialization.nr delete mode 100644 yarn-project/aztec-nr/aztec/src/types/type_serialization/u32_serialization.nr delete mode 100644 yarn-project/aztec-nr/aztec/src/types/type_serialization/u8_serialization.nr delete mode 100644 yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/safe_u120_serialization.nr delete mode 100644 yarn-project/noir-contracts/contracts/token_contract/src/types/safe_u120_serialization.nr create mode 100644 yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr diff --git a/boxes/token/src/contracts/src/main.nr b/boxes/token/src/contracts/src/main.nr index da7b7cb74caa..abfd639c0ff7 100644 --- a/boxes/token/src/contracts/src/main.nr +++ b/boxes/token/src/contracts/src/main.nr @@ -13,7 +13,7 @@ contract Token { // Libs use dep::std::option::Option; - use dep::safe_math::SafeU120; + use dep::safe_math::{SafeU120,SAFE_U120_SERIALIZED_LEN}; use dep::aztec::{ note::{ @@ -24,17 +24,13 @@ contract Token { context::{PrivateContext, PublicContext, Context}, hash::{compute_secret_hash}, state_vars::{map::Map, public_state::PublicState, set::Set}, - types::type_serialization::{ - field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, - address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, - }, protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, + type_serialization::{FIELD_SERIALIZED_LEN,BOOL_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN}, } }; - + // docs:start:import_authwit use dep::authwit::{ auth::{ @@ -45,10 +41,9 @@ contract Token { // docs:end:import_authwit use crate::types::{ - transparent_note::{TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN}, - token_note::{TokenNote, TokenNoteMethods, TOKEN_NOTE_LEN}, + transparent_note::{TransparentNote, TRANSPARENT_NOTE_LEN}, + token_note::{TokenNote, TOKEN_NOTE_LEN}, balances_map::{BalancesMap}, - safe_u120_serialization::{SafeU120SerializationMethods, SAFE_U120_SERIALIZED_LEN} }; // docs:end::imports @@ -79,7 +74,6 @@ contract Token { admin: PublicState::new( context, 1, - AddressSerializationMethods, ), // docs:end:storage_admin_init // docs:start:storage_minters_init @@ -90,7 +84,6 @@ contract Token { PublicState::new( context, slot, - BoolSerializationMethods, ) }, ), @@ -101,10 +94,9 @@ contract Token { total_supply: PublicState::new( context, 4, - SafeU120SerializationMethods, ), // docs:start:storage_pending_shields_init - pending_shields: Set::new(context, 5, TransparentNoteMethods), + pending_shields: Set::new(context, 5), // docs:end:storage_pending_shields_init public_balances: Map::new( context, @@ -113,7 +105,6 @@ contract Token { PublicState::new( context, slot, - SafeU120SerializationMethods, ) }, ), @@ -385,9 +376,9 @@ contract Token { ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); if (storage_slot == 5) { - note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) } else { - note_utils::compute_note_hash_and_nullifier(TokenNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) } } // docs:end:compute_note_hash_and_nullifier diff --git a/boxes/token/src/contracts/src/types.nr b/boxes/token/src/contracts/src/types.nr index e29a8151e9f3..d3b3b1c9e773 100644 --- a/boxes/token/src/contracts/src/types.nr +++ b/boxes/token/src/contracts/src/types.nr @@ -2,4 +2,3 @@ mod transparent_note; mod balance_set; mod balances_map; mod token_note; -mod safe_u120_serialization; diff --git a/boxes/token/src/contracts/src/types/balance_set.nr b/boxes/token/src/contracts/src/types/balance_set.nr index f81c33db5d48..6053cdb939da 100644 --- a/boxes/token/src/contracts/src/types/balance_set.nr +++ b/boxes/token/src/contracts/src/types/balance_set.nr @@ -24,7 +24,7 @@ use dep::aztec::oracle::{ get_public_key::get_public_key, }; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods}; +use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; // A set implementing standard manipulation of balances. // Does not require spending key, but only knowledge. diff --git a/boxes/token/src/contracts/src/types/balances_map.nr b/boxes/token/src/contracts/src/types/balances_map.nr index 9d6f92c0ac09..62a280d5a4c8 100644 --- a/boxes/token/src/contracts/src/types/balances_map.nr +++ b/boxes/token/src/contracts/src/types/balances_map.nr @@ -4,7 +4,7 @@ use crate::types::balance_set::BalanceSet; use dep::aztec::hash::pedersen_hash; use dep::aztec::protocol_types::address::AztecAddress; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods}; +use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; use dep::aztec::state_vars::{map::Map, set::Set}; struct BalancesMap { @@ -20,7 +20,6 @@ impl BalancesMap { Set { context, storage_slot, - note_interface: TokenNoteMethods, } }); Self { diff --git a/boxes/token/src/contracts/src/types/safe_u120_serialization.nr b/boxes/token/src/contracts/src/types/safe_u120_serialization.nr deleted file mode 100644 index 876007184fe1..000000000000 --- a/boxes/token/src/contracts/src/types/safe_u120_serialization.nr +++ /dev/null @@ -1,18 +0,0 @@ -use dep::aztec::types::type_serialization::TypeSerializationInterface; -use dep::safe_math::SafeU120; - -global SAFE_U120_SERIALIZED_LEN: Field = 1; - -// This is safe when reading from storage IF only correct safeu120 was written to storage -fn deserializeU120(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 { - SafeU120 { value: fields[0] as u120 } -} - -fn serializeU120(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] { - [value.value as Field] -} - -global SafeU120SerializationMethods = TypeSerializationInterface { - deserialize: deserializeU120, - serialize: serializeU120, -}; diff --git a/boxes/token/src/contracts/src/types/token_note.nr b/boxes/token/src/contracts/src/types/token_note.nr index ed22cfc0e98f..1a7a50dd1f8c 100644 --- a/boxes/token/src/contracts/src/types/token_note.nr +++ b/boxes/token/src/contracts/src/types/token_note.nr @@ -14,6 +14,7 @@ use dep::aztec::{ state_vars::set::Set, log::emit_encrypted_log, hash::pedersen_hash, + protocol_types::traits::{Serialize, Deserialize}, }; use dep::aztec::oracle::{ rand::rand, @@ -39,21 +40,14 @@ struct TokenNote { header: NoteHeader, } -impl TokenNote { - pub fn new(amount: SafeU120, owner: AztecAddress) -> Self { - Self { - amount, - owner, - randomness: rand(), - header: NoteHeader::empty(), - } - } - - pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { +impl Serialize for TokenNote { + fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { [self.amount.value as Field, self.owner.to_field(), self.randomness] } +} - pub fn deserialize(serialized_note: [Field; TOKEN_NOTE_LEN]) -> Self { +impl Deserialize for TokenNote { + fn deserialize(serialized_note: [Field; TOKEN_NOTE_LEN]) -> Self { Self { amount: SafeU120::new(serialized_note[0]), owner: AztecAddress::from_field(serialized_note[1]), @@ -61,8 +55,10 @@ impl TokenNote { header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for TokenNote { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount.value as Field, @@ -72,8 +68,8 @@ impl TokenNote { } // docs:start:nullifier - pub fn compute_nullifier(self) -> Field { - let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self); + fn compute_nullifier(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ @@ -84,12 +80,16 @@ impl TokenNote { } // docs:end:nullifier - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + fn get_header(self) -> NoteHeader { + self.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !self.amount.is_zero() { let encryption_pub_key = get_public_key(self.owner); @@ -104,41 +104,13 @@ impl TokenNote { } } -fn deserialize(serialized_note: [Field; TOKEN_NOTE_LEN]) -> TokenNote { - TokenNote::deserialize(serialized_note) -} - -fn serialize(note: TokenNote) -> [Field; TOKEN_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: TokenNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: TokenNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: TokenNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut TokenNote, header: NoteHeader) { - note.set_header(header) -} - -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: TokenNote) { - note.broadcast(context, slot); +impl TokenNote { + pub fn new(amount: SafeU120, owner: AztecAddress) -> Self { + Self { + amount, + owner, + randomness: rand(), + header: NoteHeader::empty(), + } + } } - -global TokenNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/boxes/token/src/contracts/src/types/transparent_note.nr b/boxes/token/src/contracts/src/types/transparent_note.nr index 034b4b3390f7..b5f24834a0e3 100644 --- a/boxes/token/src/contracts/src/types/transparent_note.nr +++ b/boxes/token/src/contracts/src/types/transparent_note.nr @@ -7,6 +7,7 @@ use dep::aztec::{ }, hash::{compute_secret_hash, pedersen_hash}, context::PrivateContext, + protocol_types::traits::{Serialize, Deserialize} }; global TRANSPARENT_NOTE_LEN: Field = 2; @@ -22,38 +23,14 @@ struct TransparentNote { header: NoteHeader, } -impl TransparentNote { - - // CONSTRUCTORS - - pub fn new(amount: Field, secret_hash: Field) -> Self { - TransparentNote { - amount: amount, - secret_hash: secret_hash, - secret: 0, - header: NoteHeader::empty(), - } - } - - // new oracle call primitive - // get me the secret corresponding to this hash - pub fn new_from_secret(amount: Field, secret: Field) -> Self { - TransparentNote { - amount: amount, - secret_hash: compute_secret_hash(secret), - secret: secret, - header: NoteHeader::empty(), - } - } - - - // STANDARD NOTE_INTERFACE FUNCTIONS - - pub fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] { +impl Serialize for TransparentNote { + fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] { [self.amount, self.secret_hash] } +} - pub fn deserialize(serialized_note: [Field; TRANSPARENT_NOTE_LEN]) -> Self { +impl Deserialize for TransparentNote { + fn deserialize(serialized_note: [Field; TRANSPARENT_NOTE_LEN]) -> Self { TransparentNote { amount: serialized_note[0], secret_hash: serialized_note[1], @@ -61,8 +38,11 @@ impl TransparentNote { header: NoteHeader::empty(), } } +} + +impl NoteInterface for TransparentNote { - pub fn compute_note_hash(self) -> Field { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount, @@ -70,61 +50,55 @@ impl TransparentNote { ],0) } - pub fn compute_nullifier(self) -> Field { + fn compute_nullifier(self) -> Field { // TODO(#1386): should use `compute_note_hash_for_read_or_nullify` once public functions inject nonce! - let siloed_note_hash = compute_siloed_note_hash(TransparentNoteMethods, self); + let siloed_note_hash = compute_siloed_note_hash(self); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([self.secret, siloed_note_hash],0) } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } - - // CUSTOM FUNCTIONS FOR THIS NOTE TYPE - - pub fn knows_secret(self, secret: Field) { - let hash = compute_secret_hash(secret); - assert(self.secret_hash == hash); + fn get_header(self) -> NoteHeader { + self.header } -} -fn deserialize(serialized_note: [Field; TRANSPARENT_NOTE_LEN]) -> TransparentNote { - TransparentNote::deserialize(serialized_note) + fn broadcast(self, context: &mut PrivateContext, slot: Field) { + assert(false, "TransparentNote does not support broadcast"); + } } -fn serialize(note: TransparentNote) -> [Field; TRANSPARENT_NOTE_LEN] { - note.serialize() -} +impl TransparentNote { -fn compute_note_hash(note: TransparentNote) -> Field { - note.compute_note_hash() -} + // CONSTRUCTORS -fn compute_nullifier(note: TransparentNote) -> Field { - note.compute_nullifier() -} + pub fn new(amount: Field, secret_hash: Field) -> Self { + TransparentNote { + amount: amount, + secret_hash: secret_hash, + secret: 0, + header: NoteHeader::empty(), + } + } -fn get_header(note: TransparentNote) -> NoteHeader { - note.header -} + // new oracle call primitive + // get me the secret corresponding to this hash + pub fn new_from_secret(amount: Field, secret: Field) -> Self { + TransparentNote { + amount: amount, + secret_hash: compute_secret_hash(secret), + secret: secret, + header: NoteHeader::empty(), + } + } -fn set_header(note: &mut TransparentNote, header: NoteHeader) { - note.set_header(header) -} + // CUSTOM FUNCTIONS FOR THIS NOTE TYPE -fn broadcast(context: &mut PrivateContext, slot: Field, note: TransparentNote) { - assert(false, "TransparentNote does not support broadcast"); + pub fn knows_secret(self, secret: Field) { + let hash = compute_secret_hash(secret); + assert(self.secret_hash == hash); + } } - -global TransparentNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; // docs:end:token_types_all \ No newline at end of file diff --git a/yarn-project/aztec-nr/address-note/src/address_note.nr b/yarn-project/aztec-nr/address-note/src/address_note.nr index dc5e0fa47d6e..5a6ac6421b15 100644 --- a/yarn-project/aztec-nr/address-note/src/address_note.nr +++ b/yarn-project/aztec-nr/address-note/src/address_note.nr @@ -2,7 +2,10 @@ use dep::aztec::log::emit_encrypted_log; // docs:end:encrypted_import use dep::aztec::{ - protocol_types::address::AztecAddress, + protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize, Empty} + }, note::{ note_header::NoteHeader, note_interface::NoteInterface, @@ -14,7 +17,7 @@ use dep::aztec::{ get_public_key::get_public_key, }, hash::pedersen_hash, - context::PrivateContext, + context::PrivateContext }; global ADDRESS_NOTE_LEN: Field = 3; @@ -28,24 +31,14 @@ struct AddressNote { header: NoteHeader, } -impl AddressNote { - pub fn new(address: AztecAddress, owner: AztecAddress) -> Self { - let randomness = rand(); - AddressNote { - address, - owner, - randomness, - header: NoteHeader::empty(), - } - } -// docs:end:address_note_def - - - pub fn serialize(self) -> [Field; ADDRESS_NOTE_LEN]{ +impl Serialize for AddressNote { + fn serialize(self) -> [Field; ADDRESS_NOTE_LEN]{ [self.address.to_field(), self.owner.to_field(), self.randomness] } +} - pub fn deserialize(serialized_note: [Field; ADDRESS_NOTE_LEN]) -> Self { +impl Deserialize for AddressNote { + fn deserialize(serialized_note: [Field; ADDRESS_NOTE_LEN]) -> Self { AddressNote { address: AztecAddress::from_field(serialized_note[0]), owner: AztecAddress::from_field(serialized_note[1]), @@ -53,14 +46,16 @@ impl AddressNote { header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for AddressNote { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash(self.serialize(), 0) } - pub fn compute_nullifier(self) -> Field { - let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(AddressNoteMethods, self); + fn compute_nullifier(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ @@ -70,12 +65,16 @@ impl AddressNote { ],0) } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + fn get_header(note: Self) -> NoteHeader { + note.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { let encryption_pub_key = get_public_key(self.owner); // docs:start:encrypted emit_encrypted_log( @@ -89,41 +88,15 @@ impl AddressNote { } } -fn deserialize(serialized_note: [Field; ADDRESS_NOTE_LEN]) -> AddressNote { - AddressNote::deserialize(serialized_note) -} - -fn serialize(note: AddressNote) -> [Field; ADDRESS_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: AddressNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: AddressNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: AddressNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut AddressNote, header: NoteHeader) { - note.set_header(header); -} - -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: AddressNote) { - note.broadcast(context, slot); +impl AddressNote { + pub fn new(address: AztecAddress, owner: AztecAddress) -> Self { + let randomness = rand(); + AddressNote { + address, + owner, + randomness, + header: NoteHeader::empty(), + } + } +// docs:end:address_note_def } - -global AddressNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/aztec-nr/authwit/src/account.nr b/yarn-project/aztec-nr/authwit/src/account.nr index 21c13e3c8efc..c612dd7de382 100644 --- a/yarn-project/aztec-nr/authwit/src/account.nr +++ b/yarn-project/aztec-nr/authwit/src/account.nr @@ -1,6 +1,6 @@ use dep::aztec::context::{PrivateContext, PublicContext, Context}; use dep::aztec::state_vars::{map::Map, public_state::PublicState}; -use dep::aztec::types::type_serialization::bool_serialization::{BoolSerializationMethods,BOOL_SERIALIZED_LEN}; +use dep::aztec::protocol_types::type_serialization::BOOL_SERIALIZED_LEN; use crate::entrypoint::EntrypointPayload; use crate::auth::IS_VALID_SELECTOR; @@ -20,7 +20,7 @@ impl AccountActions { context, approved_action_storage_slot, |context, slot| { - PublicState::new(context, slot, BoolSerializationMethods) + PublicState::new(context, slot) }, ), } diff --git a/yarn-project/aztec-nr/authwit/src/entrypoint.nr b/yarn-project/aztec-nr/authwit/src/entrypoint.nr index 82c3f5f6e2f3..05ca66240f01 100644 --- a/yarn-project/aztec-nr/authwit/src/entrypoint.nr +++ b/yarn-project/aztec-nr/authwit/src/entrypoint.nr @@ -12,6 +12,7 @@ use dep::aztec::protocol_types::{ address::AztecAddress, constants::GENERATOR_INDEX__SIGNATURE_PAYLOAD, hash::pedersen_hash, + traits::{Hash, Serialize} }; global ACCOUNT_MAX_CALLS: Field = 4; @@ -27,11 +28,13 @@ struct FunctionCall { is_public: bool, } -impl FunctionCall { +impl Serialize for FunctionCall { fn serialize(self) -> [Field; FUNCTION_CALL_SIZE] { [self.args_hash, self.function_selector.to_field(), self.target_address.to_field(), self.is_public as Field] } +} +impl FunctionCall { fn to_be_bytes(self) -> [u8; FUNCTION_CALL_SIZE_IN_BYTES] { let mut bytes: [u8; FUNCTION_CALL_SIZE_IN_BYTES] = [0; FUNCTION_CALL_SIZE_IN_BYTES]; let args_hash_bytes = self.args_hash.to_be_bytes(32); @@ -58,14 +61,7 @@ struct EntrypointPayload { } // docs:end:entrypoint-struct -impl EntrypointPayload { - fn hash(self) -> Field { - pedersen_hash( - self.serialize(), - GENERATOR_INDEX__SIGNATURE_PAYLOAD - ) - } - +impl Serialize for EntrypointPayload { // Serializes the entrypoint struct fn serialize(self) -> [Field; ENTRYPOINT_PAYLOAD_SIZE] { let mut fields: BoundedVec = BoundedVec::new(0); @@ -75,7 +71,18 @@ impl EntrypointPayload { fields.push(self.nonce); fields.storage } +} + +impl Hash for EntrypointPayload { + fn hash(self) -> Field { + pedersen_hash( + self.serialize(), + GENERATOR_INDEX__SIGNATURE_PAYLOAD + ) + } +} +impl EntrypointPayload { // Serializes the payload as an array of bytes. Useful for hashing with sha256. fn to_be_bytes(self) -> [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] { let mut bytes: [u8; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = [0; ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES]; diff --git a/yarn-project/aztec-nr/aztec/src/abi.nr b/yarn-project/aztec-nr/aztec/src/abi.nr index b6f5cfa92a97..4e656ce73470 100644 --- a/yarn-project/aztec-nr/aztec/src/abi.nr +++ b/yarn-project/aztec-nr/aztec/src/abi.nr @@ -7,6 +7,7 @@ use dep::protocol_types::{ }, contrakt::deployment_data::ContractDeploymentData, hash::hash_args, + traits::{Hash, Serialize}, }; // docs:start:private-global-variables @@ -16,7 +17,7 @@ struct PrivateGlobalVariables { } // docs:end:private-global-variables -impl PrivateGlobalVariables { +impl Serialize<2> for PrivateGlobalVariables { fn serialize(self) -> [Field; 2] { [self.chain_id, self.version] } @@ -31,7 +32,7 @@ struct PublicGlobalVariables { } // docs:end:public-global-variables -impl PublicGlobalVariables { +impl Serialize<4> for PublicGlobalVariables { fn serialize(self) -> [Field; 4] { [self.chain_id, self.version, self.block_number, self.timestamp] } @@ -61,6 +62,12 @@ struct Hasher { fields: [Field], } +impl Hash for Hasher { + fn hash(self) -> Field { + hash_args(self.fields) + } +} + impl Hasher { pub fn new()-> Self { Self { fields: [] } @@ -75,8 +82,4 @@ impl Hasher { self.fields = self.fields.push_back(fields[i]); } } - - pub fn hash(self) -> Field { - hash_args(self.fields) - } } diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index b89e570f53fd..2bfed8e716fc 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -293,9 +293,9 @@ impl PrivateContext { }, args_hash: reader.read(), return_values: reader.read_array([0; RETURN_VALUES_LENGTH]), // +1 - read_requests: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]), - new_commitments: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]), - new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialise, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]), + read_requests: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]), + new_commitments: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]), + new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialize, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]), private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]), public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]), new_l2_to_l1_msgs: reader.read_array([0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL]), diff --git a/yarn-project/aztec-nr/aztec/src/history/note_inclusion.nr b/yarn-project/aztec-nr/aztec/src/history/note_inclusion.nr index d156618d3260..b0ead5425603 100644 --- a/yarn-project/aztec-nr/aztec/src/history/note_inclusion.nr +++ b/yarn-project/aztec-nr/aztec/src/history/note_inclusion.nr @@ -30,12 +30,11 @@ pub fn prove_note_commitment_inclusion( } pub fn prove_note_inclusion( - note_interface: NoteInterface, note_with_header: Note, block_number: u32, // The block at which we'll prove that the note exists context: PrivateContext -) { - let note_commitment = compute_unique_siloed_note_hash(note_interface, note_with_header); +) where Note: NoteInterface { + let note_commitment = compute_unique_siloed_note_hash(note_with_header); prove_note_commitment_inclusion(note_commitment, block_number, context); } diff --git a/yarn-project/aztec-nr/aztec/src/history/note_validity.nr b/yarn-project/aztec-nr/aztec/src/history/note_validity.nr index d98a9e878318..45cb44564652 100644 --- a/yarn-project/aztec-nr/aztec/src/history/note_validity.nr +++ b/yarn-project/aztec-nr/aztec/src/history/note_validity.nr @@ -9,11 +9,10 @@ use crate::{ // A helper function that proves that a note is valid at the given block number pub fn prove_note_validity( - note_interface: NoteInterface, note_with_header: Note, block_number: u32, // The block at which we'll prove that the note exists context: PrivateContext -) { - prove_note_inclusion(note_interface, note_with_header, block_number, context); - prove_note_not_nullified(note_interface, note_with_header, block_number, context); +) where Note: NoteInterface { + prove_note_inclusion(note_with_header, block_number, context); + prove_note_not_nullified(note_with_header, block_number, context); } diff --git a/yarn-project/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr b/yarn-project/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr index 47036d2f9f3e..5686004d3939 100644 --- a/yarn-project/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr +++ b/yarn-project/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr @@ -50,12 +50,11 @@ pub fn prove_nullifier_non_inclusion( } pub fn prove_note_not_nullified( - note_interface: NoteInterface, note_with_header: Note, block_number: u32, // The block at which we'll prove that the note was not nullified context: PrivateContext -) { - let nullifier = compute_siloed_nullifier(note_interface, note_with_header); +) where Note: NoteInterface { + let nullifier = compute_siloed_nullifier(note_with_header); prove_nullifier_non_inclusion(nullifier, block_number, context); } diff --git a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr index 0eb21346f8d4..aa06cadcbd99 100644 --- a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr +++ b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr @@ -9,62 +9,47 @@ use crate::note::{ utils::compute_inner_note_hash, }; use crate::oracle::notes::{notify_created_note, notify_nullified_note}; +use dep::protocol_types::traits::{Serialize, Deserialize}; pub fn create_note( context: &mut PrivateContext, storage_slot: Field, note: &mut Note, - note_interface: NoteInterface, broadcast: bool -) { +) where Note: NoteInterface + Serialize + Deserialize { let contract_address = (*context).this_address(); let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true }; - let set_header = note_interface.set_header; - set_header(note, header); - let inner_note_hash = compute_inner_note_hash(note_interface, *note); + Note::set_header(note, header); + let inner_note_hash = compute_inner_note_hash(*note); - let serialize = note_interface.serialize; - let serialized_note = serialize(*note); + let serialized_note = Note::serialize(*note); assert(notify_created_note(storage_slot, serialized_note, inner_note_hash) == 0); context.push_new_note_hash(inner_note_hash); if broadcast { - let broadcast = note_interface.broadcast; - broadcast(context, storage_slot, *note); + Note::broadcast(*note, context, storage_slot); } } -pub fn create_note_hash_from_public( - context: &mut PublicContext, - storage_slot: Field, - note: &mut Note, - note_interface: NoteInterface -) { +pub fn create_note_hash_from_public(context: &mut PublicContext, storage_slot: Field, note: &mut Note) where Note: NoteInterface { let contract_address = (*context).this_address(); let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true }; - let set_header = note_interface.set_header; - set_header(note, header); - let inner_note_hash = compute_inner_note_hash(note_interface, *note); + Note::set_header(note, header); + let inner_note_hash = compute_inner_note_hash(*note); context.push_new_note_hash(inner_note_hash); } -pub fn destroy_note( - context: &mut PrivateContext, - note: Note, - note_interface: NoteInterface -) { +pub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface { let mut nullifier = 0; let mut nullified_commitment: Field = 0; - let compute_nullifier = note_interface.compute_nullifier; - nullifier = compute_nullifier(note); + nullifier = note.compute_nullifier(); // We also need the note commitment corresponding to the "nullifier" - let get_header = note_interface.get_header; - let header = get_header(note); + let header = note.get_header(); // `nullified_commitment` is used to inform the kernel which pending commitment // the nullifier corresponds to so they can be matched and both squashed/deleted. // nonzero nonce implies "persistable" nullifier (nullifies a persistent/in-tree @@ -72,7 +57,7 @@ pub fn destroy_note( // just siloes and forwards the nullifier to its output. if (header.is_transient) { // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`? - nullified_commitment = compute_inner_note_hash(note_interface, note); + nullified_commitment = compute_inner_note_hash(note); } assert(notify_nullified_note(nullifier, nullified_commitment) == 0); diff --git a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr index 15b98f89f301..9523d75002eb 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr @@ -1,10 +1,13 @@ use dep::std::option::Option; -use dep::protocol_types::constants::{ - MAX_READ_REQUESTS_PER_CALL, - GET_NOTE_ORACLE_RETURN_LENGTH, - GET_NOTES_ORACLE_RETURN_LENGTH, - MAX_NOTES_PER_PAGE, - VIEW_NOTE_ORACLE_RETURN_LENGTH, +use dep::protocol_types::{ + constants::{ + MAX_READ_REQUESTS_PER_CALL, + GET_NOTE_ORACLE_RETURN_LENGTH, + GET_NOTES_ORACLE_RETURN_LENGTH, + MAX_NOTES_PER_PAGE, + VIEW_NOTE_ORACLE_RETURN_LENGTH, + }, + traits::{Deserialize, Serialize} }; use crate::context::PrivateContext; use crate::note::{ @@ -19,11 +22,9 @@ use crate::types::vec::BoundedVec; fn check_note_header( context: PrivateContext, storage_slot: Field, - note_interface: NoteInterface, note: Note -) { - let get_header = note_interface.get_header; - let header = get_header(note); +) where Note: NoteInterface { + let header = note.get_header(); let contract_address = context.this_address(); assert(header.contract_address.eq(contract_address)); assert(header.storage_slot == storage_slot); @@ -55,14 +56,13 @@ fn check_notes_order( pub fn get_note( context: &mut PrivateContext, - storage_slot: Field, - note_interface: NoteInterface -) -> Note { - let note = get_note_internal(storage_slot, note_interface); + storage_slot: Field +) -> Note where Note: NoteInterface + Deserialize { + let note = get_note_internal(storage_slot); - check_note_header(*context, storage_slot, note_interface, note); + check_note_header(*context, storage_slot, note); - let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note); + let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note); context.push_read_request(note_hash_for_read_request); note @@ -71,26 +71,24 @@ pub fn get_note( pub fn get_notes( context: &mut PrivateContext, storage_slot: Field, - note_interface: NoteInterface, options: NoteGetterOptions -) -> [Option; MAX_READ_REQUESTS_PER_CALL] { - let opt_notes = get_notes_internal(storage_slot, note_interface, options); +) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface + Deserialize + Serialize { + let opt_notes = get_notes_internal(storage_slot, options); let mut num_notes = 0; let mut prev_fields = [0; N]; for i in 0..opt_notes.len() { let opt_note = opt_notes[i]; if opt_note.is_some() { let note = opt_note.unwrap_unchecked(); - let serialize = note_interface.serialize; - let fields = serialize(note); - check_note_header(*context, storage_slot, note_interface, note); + let fields = note.serialize(); + check_note_header(*context, storage_slot, note); check_note_fields(fields, options.selects); if i != 0 { check_notes_order(prev_fields, fields, options.sorts); } prev_fields = fields; - let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note); + let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure // failure if malicious oracle injects 0 nonce here for a "pre-existing" note. context.push_read_request(note_hash_for_read_request); @@ -104,12 +102,12 @@ pub fn get_notes( opt_notes } -unconstrained fn get_note_internal(storage_slot: Field, note_interface: NoteInterface) -> Note { +unconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface + Deserialize { let placeholder_note = [Option::none()]; let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH]; + let placeholder_note_length = [0; N]; oracle::notes::get_notes( storage_slot, - note_interface, 0, [], [], @@ -118,21 +116,21 @@ unconstrained fn get_note_internal(storage_slot: Field, note_interface: 1, // limit 0, // offset placeholder_note, - placeholder_fields + placeholder_fields, + placeholder_note_length )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular). } unconstrained fn get_notes_internal( storage_slot: Field, - note_interface: NoteInterface, options: NoteGetterOptions -) -> [Option; MAX_READ_REQUESTS_PER_CALL] { +) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface + Deserialize { let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts); let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL]; let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH]; + let placeholder_note_length = [0; N]; let opt_notes = oracle::notes::get_notes( storage_slot, - note_interface, num_selects, select_by, select_values, @@ -141,7 +139,8 @@ unconstrained fn get_notes_internal( options.limit, options.offset, placeholder_opt_notes, - placeholder_fields + placeholder_fields, + placeholder_note_length ); let filter = options.filter; @@ -151,15 +150,14 @@ unconstrained fn get_notes_internal( unconstrained pub fn view_notes( storage_slot: Field, - note_interface: NoteInterface, options: NoteViewerOptions -) -> [Option; MAX_NOTES_PER_PAGE] { +) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface + Deserialize { let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts); let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE]; let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH]; + let placeholder_note_length = [0; N]; oracle::notes::get_notes( storage_slot, - note_interface, num_selects, select_by, select_values, @@ -168,7 +166,8 @@ unconstrained pub fn view_notes( options.limit, options.offset, placeholder_opt_notes, - placeholder_fields + placeholder_fields, + placeholder_note_length ) } diff --git a/yarn-project/aztec-nr/aztec/src/note/note_interface.nr b/yarn-project/aztec-nr/aztec/src/note/note_interface.nr index b56d2030645a..4d5c13758026 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_interface.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_interface.nr @@ -1,20 +1,15 @@ use crate::context::PrivateContext; use crate::note::note_header::NoteHeader; -// docs:start:NoteInterface -struct NoteInterface { - deserialize: fn ([Field; N]) -> Note, +trait NoteInterface { + fn compute_note_hash(self) -> Field; - serialize: fn (Note) -> [Field; N], + fn compute_nullifier(self) -> Field; - compute_note_hash: fn (Note) -> Field, + fn get_header(self) -> NoteHeader; - compute_nullifier: fn (Note) -> Field, + fn set_header(&mut self, header: NoteHeader) -> (); - get_header: fn (Note) -> NoteHeader, - - set_header: fn (&mut Note, NoteHeader) -> (), - - broadcast: fn (&mut PrivateContext, Field, Note) -> (), + fn broadcast(self, context: &mut PrivateContext, slot: Field) -> (); } -// docs:end:NoteInterface \ No newline at end of file + diff --git a/yarn-project/aztec-nr/aztec/src/note/utils.nr b/yarn-project/aztec-nr/aztec/src/note/utils.nr index d9286fad1232..152f329cee3e 100644 --- a/yarn-project/aztec-nr/aztec/src/note/utils.nr +++ b/yarn-project/aztec-nr/aztec/src/note/utils.nr @@ -1,6 +1,7 @@ use dep::protocol_types::{ constants::GENERATOR_INDEX__OUTER_NULLIFIER, hash::pedersen_hash, + traits::{Deserialize, Serialize}, }; use crate::{ note::{ @@ -11,85 +12,71 @@ use crate::{ utils::arr_copy_slice, }; -pub fn compute_inner_note_hash(note_interface: NoteInterface, note: Note) -> Field { - let get_header = note_interface.get_header; - let header = get_header(note); - - let compute_note_hash = note_interface.compute_note_hash; - let note_hash = compute_note_hash(note); +pub fn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface { + let header = note.get_header(); + let note_hash = note.compute_note_hash(); compute_inner_hash(header.storage_slot, note_hash) } -pub fn compute_siloed_note_hash(note_interface: NoteInterface, note_with_header: Note) -> Field { - let get_header = note_interface.get_header; - let header = get_header(note_with_header); - - let inner_note_hash = compute_inner_note_hash(note_interface, note_with_header); +pub fn compute_siloed_note_hash(note: Note) -> Field where Note: NoteInterface { + let header = note.get_header(); + let inner_note_hash = compute_inner_note_hash(note); compute_siloed_hash(header.contract_address, inner_note_hash) } -pub fn compute_unique_siloed_note_hash(note_interface: NoteInterface, note_with_header: Note) -> Field { - let get_header = note_interface.get_header; - let header = get_header(note_with_header); - - let siloed_note_hash = compute_siloed_note_hash(note_interface, note_with_header); +pub fn compute_unique_siloed_note_hash(note: Note) -> Field where Note: NoteInterface { + let header = note.get_header(); + let siloed_note_hash = compute_siloed_note_hash(note); compute_unique_hash(header.nonce, siloed_note_hash) } -pub fn compute_siloed_nullifier(note_interface: NoteInterface, note_with_header: Note) -> Field { - let get_header = note_interface.get_header; - let header = get_header(note_with_header); - - let compute_nullifier = note_interface.compute_nullifier; - let inner_nullifier = compute_nullifier(note_with_header); +pub fn compute_siloed_nullifier(note: Note) -> Field where Note: NoteInterface { + let header = note.get_header(); + let inner_nullifier = note.compute_nullifier(); let input = [header.contract_address.to_field(), inner_nullifier]; pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER) } -pub fn compute_note_hash_for_read_or_nullify(note_interface: NoteInterface, note_with_header: Note) -> Field { - let get_header = note_interface.get_header; - let header = get_header(note_with_header); +pub fn compute_note_hash_for_read_or_nullify(note: Note) -> Field where Note: NoteInterface { + let header = note.get_header(); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) if (header.is_transient) { // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address). - compute_inner_note_hash(note_interface, note_with_header) + compute_inner_note_hash(note) } else if (header.nonce == 0) { // If not transient and nonce is zero, that means we are reading a public note. - compute_siloed_note_hash(note_interface, note_with_header) + compute_siloed_note_hash(note) } else { // When nonce is nonzero, that means we are reading a settled note (from tree) created in a // previous TX. So we need the unique_siloed_note_hash which has already been hashed with // contract address and then nonce. This hash will match the existing leaf in the private // data tree, so the kernel can just perform a membership check directly on this hash/leaf. - compute_unique_siloed_note_hash(note_interface, note_with_header) + compute_unique_siloed_note_hash(note) } } -pub fn compute_note_hash_and_nullifier( - note_interface: NoteInterface, +pub fn compute_note_hash_and_nullifier( + deserialize: fn([Field; N]) -> T, note_header: NoteHeader, serialized_note: [Field; S] -) -> [Field; 4] { - let deserialize = note_interface.deserialize; - let set_header = note_interface.set_header; +) -> [Field; 4] where T: NoteInterface { let mut note = deserialize(arr_copy_slice(serialized_note, [0; N], 0)); - set_header(&mut note, note_header); + // TODO: traits with &mut self are not supported + T::set_header((&mut note), note_header); - let compute_note_hash = note_interface.compute_note_hash; - let note_hash = compute_note_hash(note); + let note_hash = note.compute_note_hash(); let inner_note_hash = compute_inner_hash(note_header.storage_slot, note_hash); let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash); let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash); - let compute_nullifier = note_interface.compute_nullifier; - let inner_nullifier = compute_nullifier(note); + let inner_nullifier = note.compute_nullifier(); [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier] } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_public_data_witness.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_public_data_witness.nr index 555a80785801..f0c4ce2f8e9f 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_public_data_witness.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_public_data_witness.nr @@ -1,5 +1,8 @@ -use dep::protocol_types::constants::PUBLIC_DATA_TREE_HEIGHT; -use dep::protocol_types::hash::pedersen_hash; +use dep::protocol_types::{ + constants::PUBLIC_DATA_TREE_HEIGHT, + hash::pedersen_hash, + traits::{Hash, Serialize} +}; use crate::utils::arr_copy_slice; global LEAF_PREIMAGE_LENGTH: Field = 4; @@ -14,11 +17,13 @@ struct PublicDataTreeLeafPreimage { next_slot :Field, } -impl PublicDataTreeLeafPreimage { +impl Serialize for PublicDataTreeLeafPreimage { fn serialize(self) -> [Field; LEAF_PREIMAGE_LENGTH] { [self.slot, self.value, self.next_index as Field, self.next_slot] } +} +impl Hash for PublicDataTreeLeafPreimage { fn hash(self) -> Field { // Performs the same hashing as StandardIndexedTree::encodeLeaf(...) pedersen_hash(self.serialize(), 0) @@ -34,10 +39,7 @@ struct PublicDataWitness { #[oracle(getPublicDataTreeWitness)] fn get_public_data_witness_oracle(_block_number: u32, _leaf_slot: Field) -> [Field; PUBLIC_DATA_WITNESS] {} -unconstrained pub fn get_public_data_witness( - block_number: u32, - leaf_slot: Field -) -> PublicDataWitness { +unconstrained pub fn get_public_data_witness(block_number: u32, leaf_slot: Field) -> PublicDataWitness { let fields = get_public_data_witness_oracle(block_number, leaf_slot); PublicDataWitness { index: fields[0], diff --git a/yarn-project/aztec-nr/aztec/src/oracle/notes.nr b/yarn-project/aztec-nr/aztec/src/oracle/notes.nr index 88664e64dc88..2f2a5edce3a2 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/notes.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/notes.nr @@ -5,7 +5,10 @@ use crate::note::{ }; use crate::utils::arr_copy_slice; -use dep::protocol_types::address::AztecAddress; +use dep::protocol_types::{ + address::AztecAddress, + traits::Deserialize +}; #[oracle(notifyCreatedNote)] fn notify_created_note_oracle(_storage_slot: Field, _serialized_note: [Field; N], _inner_note_hash: Field) -> Field {} @@ -63,7 +66,6 @@ unconstrained fn get_notes_oracle_wrapper( unconstrained pub fn get_notes( storage_slot: Field, - note_interface: NoteInterface, num_selects: u8, select_by: [u8; M], select_values: [Field; M], @@ -72,8 +74,9 @@ unconstrained pub fn get_notes( limit: u32, offset: u32, mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array. - placeholder_fields: [Field; NS] // TODO: Remove it and use `limit` to initialize the note array. -) -> [Option; S] { + placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array. + _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter +) -> [Option; S] where Note: NoteInterface + Deserialize { let fields = get_notes_oracle_wrapper( storage_slot, num_selects, @@ -87,8 +90,6 @@ unconstrained pub fn get_notes( ); let num_notes = fields[0] as u32; let contract_address = AztecAddress::from_field(fields[1]); - let deserialize = note_interface.deserialize; - let set_header = note_interface.set_header; for i in 0..placeholder_opt_notes.len() { if i as u32 < num_notes { // lengths named as per typescript. @@ -99,8 +100,8 @@ unconstrained pub fn get_notes( let is_transient = fields[read_offset + 1] as bool; let header = NoteHeader { contract_address, nonce, storage_slot, is_transient }; let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2); - let mut note = deserialize(serialized_note); - set_header(&mut note, header); + let mut note = Note::deserialize(serialized_note); + Note::set_header(&mut note, header); placeholder_opt_notes[i] = Option::some(note); }; } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr index abb7766ba917..65a11b8eebe0 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr @@ -1,3 +1,5 @@ +use dep::protocol_types::traits::{Deserialize, Serialize}; + #[oracle(storageRead)] fn storage_read_oracle(_storage_slot: Field, _number_of_elements: Field) -> [Field; N] {} @@ -5,9 +7,8 @@ unconstrained fn storage_read_oracle_wrapper(_storage_slot: Field) -> [Field; storage_read_oracle(_storage_slot, N) } -pub fn storage_read(storage_slot: Field, deserialize: fn([Field; N]) -> T) -> T { - let fields = storage_read_oracle_wrapper(storage_slot); - deserialize(fields) +pub fn storage_read(storage_slot: Field) -> [Field; N] { + storage_read_oracle_wrapper(storage_slot) } #[oracle(storageWrite)] diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index e87555d5a82d..eb8806ec470e 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -1,6 +1,7 @@ use dep::std::option::Option; use dep::protocol_types::{ address::AztecAddress, + traits::{Serialize, Deserialize}, }; use crate::context::{PrivateContext, Context}; @@ -17,7 +18,6 @@ use crate::state_vars::singleton::compute_singleton_initialization_nullifier; struct ImmutableSingleton { context: Option<&mut PrivateContext>, storage_slot: Field, - note_interface: NoteInterface, compute_initialization_nullifier: fn (Field, Option) -> Field, } // docs:end:struct @@ -27,13 +27,11 @@ impl ImmutableSingleton { pub fn new( context: Context, storage_slot: Field, - note_interface: NoteInterface, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); ImmutableSingleton { context: context.private, storage_slot, - note_interface, compute_initialization_nullifier: compute_singleton_initialization_nullifier, } } @@ -53,7 +51,7 @@ impl ImmutableSingleton { note: &mut Note, owner: Option, broadcast: bool, - ) { + ) where Note: NoteInterface + Serialize + Deserialize { let context = self.context.unwrap(); // Nullify the storage slot. @@ -65,24 +63,23 @@ impl ImmutableSingleton { context, self.storage_slot, note, - self.note_interface, broadcast, ); } // docs:end:initialize // docs:start:get_note - pub fn get_note(self) -> Note { + pub fn get_note(self) -> Note where Note: NoteInterface + Deserialize { let context = self.context.unwrap(); let storage_slot = self.storage_slot; - get_note(context, storage_slot, self.note_interface) + get_note(context, storage_slot) } // docs:end:get_note // docs:start:view_note - unconstrained pub fn view_note(self) -> Note { + unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { let options = NoteViewerOptions::new().set_limit(1); - view_notes(self.storage_slot, self.note_interface, options)[0].unwrap() + view_notes(self.storage_slot, options)[0].unwrap() } // docs:end:view_note } diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr index b24c4a3323e0..8bcdf63ff877 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr @@ -1,14 +1,13 @@ use crate::context::{Context}; use crate::oracle::storage::storage_read; use crate::oracle::storage::storage_write; -use crate::types::type_serialization::TypeSerializationInterface; use dep::std::option::Option; +use dep::protocol_types::traits::{Deserialize, Serialize}; // docs:start:public_state_struct struct PublicState { context: Context, storage_slot: Field, - serialization_methods: TypeSerializationInterface, } // docs:end:public_state_struct @@ -18,29 +17,27 @@ impl PublicState { // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. context: Context, storage_slot: Field, - serialization_methods: TypeSerializationInterface, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); PublicState { context, storage_slot, - serialization_methods, } } // docs:end:public_state_struct_new // docs:start:public_state_struct_read - pub fn read(self) -> T { + pub fn read(self) -> T where T: Deserialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); - storage_read(self.storage_slot, self.serialization_methods.deserialize) + let fields = storage_read(self.storage_slot); + T::deserialize(fields) } // docs:end:public_state_struct_read // docs:start:public_state_struct_write - pub fn write(self, value: T) { + pub fn write(self, value: T) where T: Serialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); - let serialize = self.serialization_methods.serialize; - let fields = serialize(value); + let fields = T::serialize(value); storage_write(self.storage_slot, fields); } // docs:end:public_state_struct_write diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr index 1d873e1b149e..16e381977f9e 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr @@ -3,6 +3,7 @@ use crate::abi::PublicContextInputs; use dep::protocol_types::{ constants::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}, abis::side_effect::{SideEffect, SideEffectLinkedToNoteHash}, + traits::{Deserialize, Serialize}, }; use crate::context::{PrivateContext, PublicContext, Context}; use crate::note::{ @@ -19,22 +20,19 @@ use crate::note::{ struct Set { context: Context, storage_slot: Field, - note_interface: NoteInterface, } // docs:end:struct -impl Set { +impl Set { // docs:start:new pub fn new( context: Context, storage_slot: Field, - note_interface: NoteInterface, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Set { context, storage_slot, - note_interface, } } // docs:end:new @@ -43,24 +41,22 @@ impl Set { pub fn insert(self, note: &mut Note, broadcast: bool, - ) { + ) where Note: NoteInterface + Deserialize + Serialize { create_note( self.context.private.unwrap(), self.storage_slot, note, - self.note_interface, broadcast, ); } // docs:end:insert // docs:start:insert_from_public - pub fn insert_from_public(self, note: &mut Note) { + pub fn insert_from_public(self, note: &mut Note) where Note: NoteInterface { create_note_hash_from_public( self.context.public.unwrap(), self.storage_slot, note, - self.note_interface, ); } // docs:end:insert_from_public @@ -76,16 +72,15 @@ impl Set { } // docs:start:remove - pub fn remove(self, note: Note) { + pub fn remove(self, note: Note) where Note: NoteInterface { let context = self.context.private.unwrap(); - let note_hash = compute_note_hash_for_read_or_nullify(self.note_interface, note); + let note_hash = compute_note_hash_for_read_or_nullify(note); let has_been_read = context.read_requests.any(|r: SideEffect| r.value == note_hash); assert(has_been_read, "Can only remove a note that has been read from the set."); destroy_note( context, note, - self.note_interface, ); } // docs:end:remove @@ -94,12 +89,11 @@ impl Set { pub fn get_notes( self, options: NoteGetterOptions, - ) -> [Option; MAX_READ_REQUESTS_PER_CALL] { + ) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface + Serialize + Deserialize { let storage_slot = self.storage_slot; let opt_notes = get_notes( self.context.private.unwrap(), storage_slot, - self.note_interface, options, ); opt_notes @@ -110,8 +104,8 @@ impl Set { unconstrained pub fn view_notes( self, options: NoteViewerOptions, - ) -> [Option; MAX_NOTES_PER_PAGE] { - view_notes(self.storage_slot, self.note_interface, options) + ) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface + Deserialize { + view_notes(self.storage_slot, options) } // docs:end:view_notes } diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 28cd3ae23b8f..9de969bac43e 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -6,6 +6,7 @@ use dep::protocol_types::{ GENERATOR_INDEX__INITIALIZATION_NULLIFIER, }, hash::pedersen_hash, + traits::{Serialize, Deserialize}, }; use crate::context::{PrivateContext, PublicContext, Context}; @@ -36,7 +37,6 @@ pub fn compute_singleton_initialization_nullifier(storage_slot: Field, owner: Op struct Singleton { context: Option<&mut PrivateContext>, storage_slot: Field, - note_interface: NoteInterface, compute_initialization_nullifier: fn (Field, Option) -> Field, } // docs:end:struct @@ -46,13 +46,11 @@ impl Singleton { pub fn new( context: Context, storage_slot: Field, - note_interface: NoteInterface, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Singleton { context: context.private, storage_slot, - note_interface, compute_initialization_nullifier: compute_singleton_initialization_nullifier, } } @@ -72,7 +70,7 @@ impl Singleton { note: &mut Note, owner: Option, broadcast: bool, - ) { + ) where Note: NoteInterface + Serialize + Deserialize { let context = self.context.unwrap(); // Nullify the storage slot. @@ -80,7 +78,7 @@ impl Singleton { let nullifier = compute_initialization_nullifier(self.storage_slot, owner); context.push_new_nullifier(nullifier, 0); - create_note(context, self.storage_slot, note, self.note_interface, broadcast); + create_note(context, self.storage_slot, note, broadcast); } // docs:end:initialize @@ -89,38 +87,38 @@ impl Singleton { self, new_note: &mut Note, broadcast: bool, - ) { + ) where Note: NoteInterface + Serialize + Deserialize { let context = self.context.unwrap(); - let prev_note = get_note(context, self.storage_slot, self.note_interface); + let prev_note = get_note(context, self.storage_slot); // Nullify previous note. - destroy_note(context, prev_note, self.note_interface); + destroy_note(context, prev_note); // Add replacement note. - create_note(context, self.storage_slot, new_note, self.note_interface, broadcast); + create_note(context, self.storage_slot, new_note, broadcast); } // docs:end:replace // docs:start:get_note - pub fn get_note(self, broadcast: bool) -> Note { + pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface + Serialize + Deserialize { let context = self.context.unwrap(); - let mut note = get_note(context, self.storage_slot, self.note_interface); + let mut note = get_note(context, self.storage_slot); // Nullify current note to make sure it's reading the latest note. - destroy_note(context, note, self.note_interface); + destroy_note(context, note); // Add the same note again. // Because a nonce is added to every note in the kernel, its nullifier will be different. - create_note(context, self.storage_slot, &mut note, self.note_interface, broadcast); + create_note(context, self.storage_slot, &mut note, broadcast); note } // docs:end:get_note // docs:start:view_note - unconstrained pub fn view_note(self) -> Note { + unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { let options = NoteViewerOptions::new().set_limit(1); - view_notes(self.storage_slot, self.note_interface, options)[0].unwrap() + view_notes(self.storage_slot, options)[0].unwrap() } // docs:end:view_note } diff --git a/yarn-project/aztec-nr/aztec/src/types.nr b/yarn-project/aztec-nr/aztec/src/types.nr index 18f6888ae32f..ae46c9e0c88e 100644 --- a/yarn-project/aztec-nr/aztec/src/types.nr +++ b/yarn-project/aztec-nr/aztec/src/types.nr @@ -1,2 +1 @@ mod vec; // This can/should be moved out into an official noir library -mod type_serialization; diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization.nr deleted file mode 100644 index 016548a544f6..000000000000 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization.nr +++ /dev/null @@ -1,15 +0,0 @@ -mod bool_serialization; -mod field_serialization; -mod u8_serialization; -mod u32_serialization; -mod address_serialization; - -/** - * Before Noir supports traits, a way of specifying the serialization and deserialization methods for a type. - */ -// docs:start:TypeSerializationInterface -struct TypeSerializationInterface { - deserialize: fn ([Field; N]) -> T, - serialize: fn (T) -> [Field; N], -} -// docs:end:TypeSerializationInterface \ No newline at end of file diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization/address_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization/address_serialization.nr deleted file mode 100644 index 4994bdc0437b..000000000000 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization/address_serialization.nr +++ /dev/null @@ -1,22 +0,0 @@ -use crate::types::type_serialization::TypeSerializationInterface; -use dep::protocol_types::{ - address::{ - AztecAddress, - EthAddress - }, -}; - -global AZTEC_ADDRESS_SERIALIZED_LEN: Field = 1; - -fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> AztecAddress { - AztecAddress::from_field(fields[0]) -} - -fn serialize(value: AztecAddress) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] { - [value.to_field()] -} - -global AddressSerializationMethods = TypeSerializationInterface { - deserialize, - serialize, -}; diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr deleted file mode 100644 index 255f519234cb..000000000000 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization.nr +++ /dev/null @@ -1,16 +0,0 @@ -use crate::types::type_serialization::TypeSerializationInterface; - -global BOOL_SERIALIZED_LEN: Field = 1; - -fn deserializeBool(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool { - fields[0] as bool -} - -fn serializeBool(value: bool) -> [Field; BOOL_SERIALIZED_LEN] { - [value as Field] -} - -global BoolSerializationMethods = TypeSerializationInterface { - deserialize: deserializeBool, - serialize: serializeBool, -}; diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization/field_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization/field_serialization.nr deleted file mode 100644 index 3c13de1112e5..000000000000 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization/field_serialization.nr +++ /dev/null @@ -1,18 +0,0 @@ -use crate::types::type_serialization::TypeSerializationInterface; - -// docs:start:field_serialization -global FIELD_SERIALIZED_LEN: Field = 1; - -fn deserializeField(fields: [Field; FIELD_SERIALIZED_LEN]) -> Field { - fields[0] -} - -fn serializeField(value: Field) -> [Field; FIELD_SERIALIZED_LEN] { - [value] -} - -global FieldSerializationMethods = TypeSerializationInterface { - deserialize: deserializeField, - serialize: serializeField, -}; -// docs:end:field_serialization \ No newline at end of file diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization/u32_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization/u32_serialization.nr deleted file mode 100644 index 2517532b4203..000000000000 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization/u32_serialization.nr +++ /dev/null @@ -1,16 +0,0 @@ -use crate::types::type_serialization::TypeSerializationInterface; - -global U32_SERIALIZED_LEN: Field = 1; - -fn deserializeU32(fields: [Field; U32_SERIALIZED_LEN]) -> u32 { - fields[0] as u32 -} - -fn serializeU32(value: u32) -> [Field; U32_SERIALIZED_LEN] { - [value as Field] -} - -global U32SerializationMethods = TypeSerializationInterface { - deserialize: deserializeU32, - serialize: serializeU32, -}; diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization/u8_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization/u8_serialization.nr deleted file mode 100644 index 8011d02675c8..000000000000 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization/u8_serialization.nr +++ /dev/null @@ -1,16 +0,0 @@ -use crate::types::type_serialization::TypeSerializationInterface; - -global U8_SERIALIZED_LEN: Field = 1; - -fn deserializeU8(fields: [Field; U8_SERIALIZED_LEN]) -> u8 { - fields[0] as u8 -} - -fn serializeU8(value: u8) -> [Field; U8_SERIALIZED_LEN] { - [value as Field] -} - -global U8SerializationMethods = TypeSerializationInterface { - deserialize: deserializeU8, - serialize: serializeU8, -}; diff --git a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr index 0cf51b8edb2a..7240491f41fd 100644 --- a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr +++ b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr @@ -1,5 +1,7 @@ -use dep::aztec::types::type_serialization::TypeSerializationInterface; -use dep::aztec::protocol_types::utils::field::field_from_bytes; +use dep::aztec::protocol_types::{ + utils::field::field_from_bytes, + traits::{Serialize, Deserialize} +}; use dep::std; // A Fixedsize Compressed String. @@ -8,6 +10,18 @@ struct FieldCompressedString{ value: Field } +impl Serialize<1> for FieldCompressedString { + fn serialize(self) -> [Field; 1] { + [self.value] + } +} + +impl Deserialize<1> for FieldCompressedString { +fn deserialize(input: [Field; 1]) -> Self { + Self { value: input[0] } + } +} + impl FieldCompressedString{ pub fn is_eq(self, other: FieldCompressedString) -> bool { self.value == other.value @@ -29,28 +43,8 @@ impl FieldCompressedString{ } result } - - pub fn serialize(self) -> [Field; 1] { - [self.value] - } - - pub fn deserialize(input: [Field; 1]) -> Self { - Self { value: input[0] } - } } -fn deserialize(fields: [Field; 1]) -> FieldCompressedString { - FieldCompressedString { value: fields[0] } -} - -fn serialize(value: FieldCompressedString) -> [Field; 1] { - value.serialize() -} -global FieldCompressedStringSerializationMethods = TypeSerializationInterface { - deserialize, - serialize, -}; - // The general Compressed String. // Compresses M bytes into N fields. // Can be used for longer strings that don't fit in a single field. diff --git a/yarn-project/aztec-nr/compressed-string/src/lib.nr b/yarn-project/aztec-nr/compressed-string/src/lib.nr index aef2a573fdfe..b441f622b401 100644 --- a/yarn-project/aztec-nr/compressed-string/src/lib.nr +++ b/yarn-project/aztec-nr/compressed-string/src/lib.nr @@ -1,4 +1,4 @@ mod compressed_string; use crate::compressed_string::{CompressedString}; -use crate::compressed_string::{FieldCompressedString, FieldCompressedStringSerializationMethods}; +use crate::compressed_string::FieldCompressedString; diff --git a/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr b/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr index 29feeeb26b0d..26cbef677e92 100644 --- a/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr +++ b/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr @@ -6,7 +6,7 @@ use dep::aztec::{ }; use dep::value_note::{ filter::filter_notes_min_sum, - value_note::{ValueNote, ValueNoteMethods, VALUE_NOTE_LEN}, + value_note::{ValueNote, VALUE_NOTE_LEN}, }; struct EasyPrivateUint { @@ -23,8 +23,7 @@ impl EasyPrivateUint { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); let set = Set { context, - storage_slot, - note_interface: ValueNoteMethods, + storage_slot }; EasyPrivateUint { context, diff --git a/yarn-project/aztec-nr/field-note/src/field_note.nr b/yarn-project/aztec-nr/field-note/src/field_note.nr index 6267a7b6016e..9b451308b741 100644 --- a/yarn-project/aztec-nr/field-note/src/field_note.nr +++ b/yarn-project/aztec-nr/field-note/src/field_note.nr @@ -5,6 +5,7 @@ use dep::aztec::{ }, hash::pedersen_hash, context::PrivateContext, + protocol_types::traits::{Serialize, Deserialize}, }; global FIELD_NOTE_LEN: Field = 1; @@ -17,76 +18,53 @@ struct FieldNote { header: NoteHeader, } -impl FieldNote { - pub fn new(value: Field) -> Self { - FieldNote { - value, - header: NoteHeader::empty(), - } - } - - pub fn serialize(self) -> [Field; FIELD_NOTE_LEN]{ +impl Serialize for FieldNote { + fn serialize(self) -> [Field; FIELD_NOTE_LEN]{ [self.value] } +} - pub fn deserialize(serialized_note: [Field; FIELD_NOTE_LEN]) -> Self { +impl Deserialize for FieldNote { + fn deserialize(serialized_note: [Field; FIELD_NOTE_LEN]) -> Self { FieldNote { value: serialized_note[0], header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for FieldNote { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash(self.serialize(), 0) } - pub fn compute_nullifier(self) -> Field { + fn compute_nullifier(self) -> Field { // This note is expected to be shared between users and for this reason can't be nullified using a secret. 0 } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } -} - -fn deserialize(serialized_note: [Field; FIELD_NOTE_LEN]) -> FieldNote { - FieldNote::deserialize(serialized_note) -} - -fn serialize(note: FieldNote) -> [Field; FIELD_NOTE_LEN] { - note.serialize() -} -fn compute_note_hash(note: FieldNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: FieldNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: FieldNote) -> NoteHeader { - note.header -} + fn get_header(self) -> NoteHeader { + self.header + } -fn set_header(note: &mut FieldNote, header: NoteHeader) { - note.set_header(header); + fn broadcast(self, context: &mut PrivateContext, slot: Field) { + assert( + false, "FieldNote does not support broadcast. Add it to PXE directly using the `.addNote` function." + ); + } } -fn broadcast(context: &mut PrivateContext, slot: Field, note: FieldNote) { - assert( - false, "FieldNote does not support broadcast. Add it to PXE directly using the `.addNote` function." - ); +impl FieldNote { + pub fn new(value: Field) -> Self { + FieldNote { + value, + header: NoteHeader::empty(), + } + } } -global FieldNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/aztec-nr/safe-math/Nargo.toml b/yarn-project/aztec-nr/safe-math/Nargo.toml index 6625680128f0..aaa75e689774 100644 --- a/yarn-project/aztec-nr/safe-math/Nargo.toml +++ b/yarn-project/aztec-nr/safe-math/Nargo.toml @@ -4,4 +4,5 @@ authors = [""] compiler_version = ">=0.18.0" type = "lib" -[dependencies] \ No newline at end of file +[dependencies] +aztec = { path = "../aztec" } \ No newline at end of file diff --git a/yarn-project/aztec-nr/safe-math/src/lib.nr b/yarn-project/aztec-nr/safe-math/src/lib.nr index 7e29a39a85e1..79dd63eb4b8b 100644 --- a/yarn-project/aztec-nr/safe-math/src/lib.nr +++ b/yarn-project/aztec-nr/safe-math/src/lib.nr @@ -1,3 +1,3 @@ mod safe_u120; -use crate::safe_u120::SafeU120; +use crate::safe_u120::{SafeU120, SAFE_U120_SERIALIZED_LEN}; diff --git a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr index d1ce40a01a63..4ef341bf8393 100644 --- a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr +++ b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr @@ -1,4 +1,5 @@ use dep::std::cmp::Eq; +use dep::aztec::protocol_types::traits::{Deserialize, Serialize}; struct SafeU120 { value: u120, @@ -13,6 +14,21 @@ impl Eq for SafeU120 { } } +global SAFE_U120_SERIALIZED_LEN: Field = 1; + +impl Serialize for SafeU120 { + fn serialize(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] { + [value.value as Field] + } +} + +impl Deserialize for SafeU120 { + // This is safe when reading from storage IF only correct safeu120 was written to storage + fn deserialize(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 { + SafeU120 { value: fields[0] as u120 } + } +} + impl SafeU120 { pub fn min() -> Self { Self { diff --git a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr index d2dc5c67830b..065ab009197f 100644 --- a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr +++ b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr @@ -1,7 +1,6 @@ use dep::aztec::context::{PrivateContext, PublicContext, Context}; -use dep::aztec::types::type_serialization::TypeSerializationInterface; use dep::aztec::oracle::storage::{storage_read, storage_write}; - +use dep::aztec::protocol_types::traits::{Serialize, Deserialize}; use dep::std::hash::pedersen_hash; use dep::std::merkle::compute_merkle_root; use dep::std::option::Option; @@ -20,20 +19,15 @@ struct Leaf { after: Field, } -fn serialize_leaf(leaf: Leaf) -> [Field; 3] { - [leaf.next_change, leaf.before, leaf.after] -} - -fn deserialize_leaf(serialized: [Field; 3]) -> Leaf { - Leaf { next_change: serialized[0], before: serialized[1], after: serialized[2] } +impl Serialize<3> for Leaf { + fn serialize(leaf: Leaf) -> [Field; 3] { + [leaf.next_change, leaf.before, leaf.after] + } } -impl Leaf { - fn serialize(self: Self) -> [Field; 3] { - serialize_leaf(self) - } - fn deserialize(serialized: [Field; 3]) -> Self { - deserialize_leaf(serialized) +impl Deserialize<3> for Leaf { + fn deserialize(serialized: [Field; 3]) -> Leaf { + Leaf { next_change: serialized[0], before: serialized[1], after: serialized[2] } } } @@ -117,7 +111,8 @@ impl SlowMap { } pub fn read_root(self: Self) -> Leaf { - storage_read(self.storage_slot, deserialize_leaf) + let fields = storage_read(self.storage_slot); + Leaf::deserialize(fields) } // Beware that the initial root could include much state that is not shown by the public storage! @@ -147,7 +142,8 @@ impl SlowMap { // docs:start:read_leaf_at pub fn read_leaf_at(self: Self, key: Field) -> Leaf { let derived_storage_slot = pedersen_hash([self.storage_slot, key]); - storage_read(derived_storage_slot, deserialize_leaf) + let fields = storage_read(derived_storage_slot); + Leaf::deserialize(fields) } // docs:end:read_leaf_at diff --git a/yarn-project/aztec-nr/value-note/src/value_note.nr b/yarn-project/aztec-nr/value-note/src/value_note.nr index d02037e49982..f686385cf283 100644 --- a/yarn-project/aztec-nr/value-note/src/value_note.nr +++ b/yarn-project/aztec-nr/value-note/src/value_note.nr @@ -1,5 +1,8 @@ use dep::aztec::{ - protocol_types::address::AztecAddress, + protocol_types::{ + address::AztecAddress, + traits::{Deserialize, Serialize} + }, note::{ note_header::NoteHeader, note_interface::NoteInterface, @@ -26,23 +29,14 @@ struct ValueNote { } // docs:end:value-note-def -impl ValueNote { - pub fn new(value: Field, owner: AztecAddress) -> Self { - let randomness = rand(); - let header = NoteHeader::empty(); - ValueNote { - value, - owner, - randomness, - header, - } - } - - pub fn serialize(self) -> [Field; VALUE_NOTE_LEN] { +impl Serialize for ValueNote { + fn serialize(self) -> [Field; VALUE_NOTE_LEN] { [self.value, self.owner.to_field(), self.randomness] } +} - pub fn deserialize(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self { +impl Deserialize for ValueNote { + fn deserialize(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self { ValueNote { value: serialized_note[0], owner: AztecAddress::from_field(serialized_note[1]), @@ -50,16 +44,19 @@ impl ValueNote { header: NoteHeader::empty(), } } +} + +impl NoteInterface for ValueNote { - pub fn compute_note_hash(self) -> Field { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash(self.serialize(),0) } // docs:start:nullifier - pub fn compute_nullifier(self) -> Field { - let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(ValueNoteMethods, self); + fn compute_nullifier(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ @@ -71,12 +68,16 @@ impl ValueNote { // docs:end:nullifier - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + fn get_header(self) -> NoteHeader { + self.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { let encryption_pub_key = get_public_key(self.owner); emit_encrypted_log( context, @@ -88,41 +89,15 @@ impl ValueNote { } } -fn deserialize(serialized_note: [Field; VALUE_NOTE_LEN]) -> ValueNote { - ValueNote::deserialize(serialized_note) -} - -fn serialize(note: ValueNote) -> [Field; VALUE_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: ValueNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: ValueNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: ValueNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut ValueNote, header: NoteHeader) { - note.set_header(header) -} - -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: ValueNote) { - note.broadcast(context, slot); +impl ValueNote { + pub fn new(value: Field, owner: AztecAddress) -> Self { + let randomness = rand(); + let header = NoteHeader::empty(); + ValueNote { + value, + owner, + randomness, + header, + } + } } - -global ValueNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr index 2daab6e3ed68..e8f15bcc173d 100644 --- a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -7,19 +7,19 @@ contract Benchmarking { use dep::value_note::{ utils::{increment, decrement}, - value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, + value_note::{VALUE_NOTE_LEN, ValueNote}, }; use dep::aztec::{ protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, + type_serialization::FIELD_SERIALIZED_LEN }, context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, log::emit_unencrypted_log, state_vars::{map::Map, public_state::PublicState, set::Set}, - types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, }; struct Storage { @@ -28,10 +28,10 @@ contract Benchmarking { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { - notes: Map::new(context, 1, |context, slot| { Set::new(context, slot, ValueNoteMethods) }), - balances: Map::new(context, 2, |context, slot| { PublicState::new(context, slot, FieldSerializationMethods) }), + notes: Map::new(context, 1, |context, slot| { Set::new(context, slot) }), + balances: Map::new(context, 2, |context, slot| { PublicState::new(context, slot) }), } } } @@ -85,6 +85,6 @@ contract Benchmarking { serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr index 6672ad559bc4..e395f799cae2 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr @@ -20,7 +20,7 @@ use dep::std::{ option::Option, }; use dep::value_note::{ - value_note::{ValueNote, ValueNoteMethods, VALUE_NOTE_LEN}, + value_note::{ValueNote, VALUE_NOTE_LEN}, }; struct Card { @@ -126,7 +126,6 @@ impl Deck { let set = Set { context, storage_slot, - note_interface: ValueNoteMethods, }; Deck { set diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr index 63b50bcf783d..4e9c75a77f78 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr @@ -1,5 +1,7 @@ -use dep::aztec::protocol_types::address::AztecAddress; -use dep::aztec::types::type_serialization::TypeSerializationInterface; +use dep::aztec::protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize}, +}; use crate::cards::Card; global NUMBER_OF_PLAYERS = 2; @@ -31,59 +33,59 @@ struct Game { global GAME_SERIALIZED_LEN: Field = 15; -fn deserializeGame(fields: [Field; GAME_SERIALIZED_LEN]) -> Game { - let players = [ - PlayerEntry { - address: AztecAddress::from_field(fields[0]), - deck_strength: fields[1] as u32, - points: fields[2] as u120 - }, - PlayerEntry { - address: AztecAddress::from_field(fields[3]), - deck_strength: fields[4] as u32, - points: fields[5] as u120 - } - ]; - let rounds_cards = [ - Card::from_field(fields[6]), Card::from_field(fields[7]), - Card::from_field(fields[8]), Card::from_field(fields[9]) - ]; - Game { - players, - rounds_cards, - started: fields[10] as bool, - finished: fields[11] as bool, - claimed: fields[12] as bool, - current_player: fields[13] as u32, - current_round: fields[14] as u32 +impl Serialize for Game { + fn serialize(game: Game) -> [Field; GAME_SERIALIZED_LEN] { + [ + game.players[0].address.to_field(), + game.players[0].deck_strength as Field, + game.players[0].points as Field, + game.players[1].address.to_field(), + game.players[1].deck_strength as Field, + game.players[1].points as Field, + game.rounds_cards[0].to_field(), + game.rounds_cards[1].to_field(), + game.rounds_cards[2].to_field(), + game.rounds_cards[3].to_field(), + game.started as Field, + game.finished as Field, + game.claimed as Field, + game.current_player as Field, + game.current_round as Field + ] } } -fn serializeGame(game: Game) -> [Field; GAME_SERIALIZED_LEN] { - [ - game.players[0].address.to_field(), - game.players[0].deck_strength as Field, - game.players[0].points as Field, - game.players[1].address.to_field(), - game.players[1].deck_strength as Field, - game.players[1].points as Field, - game.rounds_cards[0].to_field(), - game.rounds_cards[1].to_field(), - game.rounds_cards[2].to_field(), - game.rounds_cards[3].to_field(), - game.started as Field, - game.finished as Field, - game.claimed as Field, - game.current_player as Field, - game.current_round as Field - ] +impl Deserialize for Game { + fn deserialize(fields: [Field; GAME_SERIALIZED_LEN]) -> Game { + let players = [ + PlayerEntry { + address: AztecAddress::from_field(fields[0]), + deck_strength: fields[1] as u32, + points: fields[2] as u120 + }, + PlayerEntry { + address: AztecAddress::from_field(fields[3]), + deck_strength: fields[4] as u32, + points: fields[5] as u120 + } + ]; + let rounds_cards = [ + Card::from_field(fields[6]), Card::from_field(fields[7]), + Card::from_field(fields[8]), Card::from_field(fields[9]) + ]; + Game { + players, + rounds_cards, + started: fields[10] as bool, + finished: fields[11] as bool, + claimed: fields[12] as bool, + current_player: fields[13] as u32, + current_round: fields[14] as u32 + } + } } impl Game { - pub fn serialize(self: Self) -> [Field; GAME_SERIALIZED_LEN] { - serializeGame(self) - } - pub fn add_player(&mut self, player_entry: PlayerEntry) -> bool { let mut added = false; @@ -166,8 +168,3 @@ impl Game { } } } - -global GameSerializationMethods = TypeSerializationInterface { - deserialize: deserializeGame, - serialize: serializeGame, -}; diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr index f0f85b6e0cd9..08c2d22597ca 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr @@ -20,7 +20,7 @@ contract CardGame { use dep::value_note::{ balance_utils, value_note::{ - ValueNoteMethods, + ValueNote, VALUE_NOTE_LEN, }, }; @@ -49,7 +49,6 @@ contract CardGame { PLAYABLE_CARDS, PlayerEntry, Game, - GameSerializationMethods, GAME_SERIALIZED_LEN }; @@ -96,8 +95,7 @@ contract CardGame { |context, slot| { PublicState::new( context, - slot, - GameSerializationMethods, + slot ) }, ) @@ -245,6 +243,6 @@ contract CardGame { serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/child_contract/src/main.nr b/yarn-project/noir-contracts/contracts/child_contract/src/main.nr index 49caabe92cff..c96b609a2ab6 100644 --- a/yarn-project/noir-contracts/contracts/child_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/child_contract/src/main.nr @@ -7,7 +7,7 @@ contract Child { context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, state_vars::public_state::PublicState, - types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, + protocol_types::type_serialization::FIELD_SERIALIZED_LEN }; use dep::aztec::protocol_types::{ abis::function_selector::FunctionSelector, @@ -24,7 +24,6 @@ contract Child { current_value: PublicState::new( context, 1, - FieldSerializationMethods, ), } } diff --git a/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr b/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr index 075585118164..e424fbda6937 100644 --- a/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr @@ -12,7 +12,7 @@ contract Counter { use dep::value_note::{ balance_utils, value_note::{ - ValueNoteMethods, + ValueNote, VALUE_NOTE_LEN, }, }; @@ -74,7 +74,7 @@ contract Counter { serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } // docs:end:nullifier } diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr index 9c9423f31ea8..16928b904605 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr @@ -1,6 +1,7 @@ use dep::aztec::protocol_types::{ address::AztecAddress, constants::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}, + type_serialization::BOOL_SERIALIZED_LEN }; use dep::aztec::note::{ note_getter_options::NoteGetterOptions, note_viewer_options::NoteViewerOptions, @@ -9,7 +10,6 @@ use dep::aztec::state_vars::{ immutable_singleton::ImmutableSingleton, map::Map, public_state::PublicState, set::Set, singleton::Singleton, }; -use dep::aztec::types::type_serialization::bool_serialization::BOOL_SERIALIZED_LEN; use dep::std::option::Option; use crate::types::{ diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index 8870c2972670..282635a4551f 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -7,6 +7,7 @@ contract DocsExample { use dep::aztec::protocol_types::{ address::AztecAddress, abis::function_selector::FunctionSelector, + type_serialization::BOOL_SERIALIZED_LEN }; use dep::std::option::Option; use dep::aztec::{ @@ -16,19 +17,14 @@ contract DocsExample { singleton::Singleton, }, }; - // docs:start:state_vars-PublicStateBoolImport - use dep::aztec::types::type_serialization::bool_serialization::{ - BoolSerializationMethods, BOOL_SERIALIZED_LEN, - }; - // docs:end:state_vars-PublicStateBoolImport use crate::account_contract_interface::AccountContractInterface; use crate::actions; use crate::options::create_account_card_getter_options; use crate::types::{ - card_note::{CardNote, CardNoteMethods, CARD_NOTE_LEN}, - profile_note::{ProfileNote, ProfileNoteMethods, PROFILE_NOTE_LEN}, - queen::{Queen, QueenSerializationMethods, QUEEN_SERIALIZED_LEN}, - rules_note::{RulesNote, RulesNoteMethods, RULES_NOTE_LEN}, + card_note::{CardNote, CARD_NOTE_LEN}, + profile_note::{ProfileNote, PROFILE_NOTE_LEN}, + queen::{Queen, QUEEN_SERIALIZED_LEN}, + rules_note::{RulesNote, RULES_NOTE_LEN}, }; // docs:start:storage-struct-declaration @@ -57,27 +53,26 @@ contract DocsExample { fn init(context: Context) -> Self { Storage { // highlight-next-line:state_vars-PublicState - locked: PublicState::new(context, 1, BoolSerializationMethods), + locked: PublicState::new(context, 1), // highlight-next-line:state_vars-PublicStateCustomStruct queen: PublicState::new( context, 2, - QueenSerializationMethods, ), // highlight-next-line:state_vars-ImmutableSingleton - game_rules: ImmutableSingleton::new(context, 3, RulesNoteMethods), + game_rules: ImmutableSingleton::new(context, 3), // highlight-next-line:state_vars-Singleton // docs:start:start_vars_singleton - legendary_card: Singleton::new(context, 4, CardNoteMethods), + legendary_card: Singleton::new(context, 4), // docs:end:start_vars_singleton // highlight-next-line:state_vars-Set - cards: Set::new(context, 5, CardNoteMethods), + cards: Set::new(context, 5), // highlight-next-line:state_vars-MapSingleton profiles: Map::new( context, 6, |context, slot| { - Singleton::new(context, slot, ProfileNoteMethods) + Singleton::new(context, slot) }, ), } diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr index 97da78e65192..b3536558ac29 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr @@ -1,4 +1,3 @@ -use dep::aztec::protocol_types::address::AztecAddress; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -12,6 +11,10 @@ use dep::aztec::{ log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext, + protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize, Empty} + } }; global CARD_NOTE_LEN: Field = 3; @@ -25,21 +28,14 @@ struct CardNote { } // docs:end:state_vars-CardNote -impl CardNote { - pub fn new(points: u8, secret: Field, owner: AztecAddress) -> Self { - CardNote { - points, - secret, - owner, - header: NoteHeader::empty(), - } - } - - pub fn serialize(self) -> [Field; CARD_NOTE_LEN] { +impl Serialize for CardNote { + fn serialize(self) -> [Field; CARD_NOTE_LEN] { [self.points as Field, self.secret, self.owner.to_field()] } +} - pub fn deserialize(serialized_note: [Field; CARD_NOTE_LEN]) -> Self { +impl Deserialize for CardNote { + fn deserialize(serialized_note: [Field; CARD_NOTE_LEN]) -> Self { CardNote { points: serialized_note[0] as u8, secret: serialized_note[1], @@ -47,8 +43,10 @@ impl CardNote { header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for CardNote { + fn compute_note_hash(self) -> Field { pedersen_hash([ self.points as Field, self.secret, @@ -56,8 +54,8 @@ impl CardNote { ],0) } - pub fn compute_nullifier(self) -> Field { - let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(CardNoteMethods, self); + fn compute_nullifier(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); let secret = get_secret_key(self.owner); pedersen_hash([ note_hash_for_nullify, @@ -66,12 +64,16 @@ impl CardNote { ],0) } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + fn get_header(note: CardNote) -> NoteHeader { + note.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { let encryption_pub_key = get_public_key(self.owner); emit_encrypted_log( context, @@ -83,41 +85,13 @@ impl CardNote { } } -fn deserialize(serialized_note: [Field; CARD_NOTE_LEN]) -> CardNote { - CardNote::deserialize(serialized_note) -} - -fn serialize(note: CardNote) -> [Field; CARD_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: CardNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: CardNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: CardNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut CardNote, header: NoteHeader) { - note.set_header(header) -} - -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: CardNote) { - note.broadcast(context, slot); +impl CardNote { + pub fn new(points: u8, secret: Field, owner: AztecAddress) -> Self { + CardNote { + points, + secret, + owner, + header: NoteHeader::empty(), + } + } } - -global CardNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr index 201c796c8052..989012b4c211 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr @@ -1,6 +1,9 @@ use dep::std::option::Option; use dep::aztec::{ - protocol_types::address::AztecAddress, + protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize, Empty} + }, note::{ note_header::NoteHeader, note_interface::NoteInterface, @@ -20,21 +23,14 @@ struct ProfileNote { header: NoteHeader, } -impl ProfileNote { - pub fn new(avatar: Field, xp: Field, maybe_owner: Option) -> Self { - ProfileNote { - avatar, - xp, - maybe_owner, - header: NoteHeader::empty(), - } - } - - pub fn serialize(self) -> [Field; PROFILE_NOTE_LEN] { +impl Serialize for ProfileNote { + fn serialize(self) -> [Field; PROFILE_NOTE_LEN] { [self.avatar, self.xp] } +} - pub fn deserialize(serialized_note: [Field; PROFILE_NOTE_LEN]) -> Self { +impl Deserialize for ProfileNote { + fn deserialize(serialized_note: [Field; PROFILE_NOTE_LEN]) -> Self { ProfileNote { avatar: serialized_note[0], xp: serialized_note[1], @@ -42,29 +38,31 @@ impl ProfileNote { header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for ProfileNote { + fn compute_note_hash(self) -> Field { pedersen_hash([ self.avatar, self.xp, ],0) } - pub fn compute_nullifier(_self: Self) -> Field { + fn compute_nullifier(_self: Self) -> Field { assert(false); // Not allowed. 0 } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } - pub fn set_owner(&mut self, owner: AztecAddress) { - self.maybe_owner = Option::some(owner); + fn get_header(self) -> NoteHeader { + self.header } // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { assert(self.maybe_owner.is_some(), "Note owner must be set when the broadcast flow is triggered."); let owner = self.maybe_owner.unwrap_unchecked(); @@ -79,41 +77,19 @@ impl ProfileNote { } } -fn deserialize(serialized_note: [Field; PROFILE_NOTE_LEN]) -> ProfileNote { - ProfileNote::deserialize(serialized_note) -} - -fn serialize(note: ProfileNote) -> [Field; PROFILE_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: ProfileNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: ProfileNote) -> Field { - note.compute_nullifier() -} +impl ProfileNote { + pub fn new(avatar: Field, xp: Field, maybe_owner: Option) -> Self { + ProfileNote { + avatar, + xp, + maybe_owner, + header: NoteHeader::empty(), + } + } -fn get_header(note: ProfileNote) -> NoteHeader { - note.header -} -fn set_header(note: &mut ProfileNote, header: NoteHeader) { - note.set_header(header) -} + pub fn set_owner(&mut self, owner: AztecAddress) { + self.maybe_owner = Option::some(owner); + } -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: ProfileNote) { - note.broadcast(context, slot); } - -global ProfileNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr index acd4ed0f7caf..039cdf2d6c0f 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr @@ -1,5 +1,7 @@ -use dep::aztec::protocol_types::address::AztecAddress; -use dep::aztec::types::type_serialization::TypeSerializationInterface; +use dep::aztec::protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize}, +}; // docs:start:state_vars-CustomStruct struct Queen { @@ -11,16 +13,15 @@ struct Queen { // docs:start:state_vars-PublicStateCustomStruct global QUEEN_SERIALIZED_LEN: Field = 2; -fn deserialize(fields: [Field; QUEEN_SERIALIZED_LEN]) -> Queen { - Queen { account: AztecAddress::from_field(fields[0]), points: fields[1] as u8 } +impl Serialize for Queen { + fn serialize(queen: Queen) -> [Field; QUEEN_SERIALIZED_LEN] { + [queen.account.to_field(), queen.points as Field] + } } -fn serialize(queen: Queen) -> [Field; QUEEN_SERIALIZED_LEN] { - [queen.account.to_field(), queen.points as Field] +impl Deserialize for Queen { + fn deserialize(fields: [Field; QUEEN_SERIALIZED_LEN]) -> Queen { + Queen { account: AztecAddress::from_field(fields[0]), points: fields[1] as u8 } + } } - -global QueenSerializationMethods = TypeSerializationInterface { - deserialize, - serialize, -}; // docs:end:state_vars-PublicStateCustomStruct diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr index d3abaecb5d18..b95c2fe63d09 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr @@ -1,6 +1,9 @@ use dep::std::option::Option; use dep::aztec::{ - protocol_types::address::AztecAddress, + protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize, Empty} + }, note::{ note_header::NoteHeader, note_interface::NoteInterface, @@ -20,51 +23,46 @@ struct RulesNote { header: NoteHeader, } -impl RulesNote { - pub fn new(min_points: u8, max_points: u8, maybe_owner: Option) -> Self { - RulesNote { - min_points, - max_points, - maybe_owner, - header: NoteHeader::empty(), - } - } - - pub fn serialize(self) -> [Field; RULES_NOTE_LEN] { +impl Serialize for RulesNote { + fn serialize(self) -> [Field; RULES_NOTE_LEN] { [self.min_points as Field, self.max_points as Field] } +} - pub fn deserialize(serialized_note: [Field; RULES_NOTE_LEN]) -> Self { - RulesNote { +impl Deserialize for RulesNote { + fn deserialize(serialized_note: [Field; RULES_NOTE_LEN]) -> Self { + RulesNote { min_points: serialized_note[0] as u8, max_points: serialized_note[1] as u8, maybe_owner: Option::none(), header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for RulesNote { + fn compute_note_hash(self) -> Field { pedersen_hash([ self.min_points as Field, self.max_points as Field, ],0) } - pub fn compute_nullifier(_self: Self) -> Field { + fn compute_nullifier(_self: Self) -> Field { // Not used 0 } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } - pub fn set_owner(&mut self, owner: AztecAddress) { - self.maybe_owner = Option::some(owner); + fn get_header(self) -> NoteHeader { + self.header } // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { assert(self.maybe_owner.is_some(), "Note owner must be set when the broadcast flow is triggered."); let owner = self.maybe_owner.unwrap_unchecked(); @@ -79,41 +77,17 @@ impl RulesNote { } } -fn deserialize(serialized_note: [Field; RULES_NOTE_LEN]) -> RulesNote { - RulesNote::deserialize(serialized_note) -} - -fn serialize(note: RulesNote) -> [Field; RULES_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: RulesNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: RulesNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: RulesNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut RulesNote, header: NoteHeader) { - note.set_header(header) -} +impl RulesNote { + pub fn new(min_points: u8, max_points: u8, maybe_owner: Option) -> Self { + RulesNote { + min_points, + max_points, + maybe_owner, + header: NoteHeader::empty(), + } + } -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: RulesNote) { - note.broadcast(context, slot); + pub fn set_owner(&mut self, owner: AztecAddress) { + self.maybe_owner = Option::some(owner); + } } - -global RulesNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr index 2a342aa3e882..c43aae116eaa 100644 --- a/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr @@ -13,7 +13,7 @@ contract EasyPrivateToken { use dep::value_note::{ balance_utils, value_note::{ - ValueNoteMethods, + ValueNote, VALUE_NOTE_LEN, }, }; @@ -24,7 +24,7 @@ contract EasyPrivateToken { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { balances: Map::new( context, @@ -82,7 +82,7 @@ contract EasyPrivateToken { serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } } // docs:end:easy_private_token_contract diff --git a/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index 54db9e4017a9..59ef061c7446 100644 --- a/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -4,15 +4,11 @@ contract EasyPrivateVoting { protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, + type_serialization::{BOOL_SERIALIZED_LEN, FIELD_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN}, }, context::{PrivateContext, Context}, oracle::get_secret_key::get_secret_key, // used to compute nullifier - state_vars::{ map::Map, public_state::PublicState,}, - types::type_serialization::{ // serialization methods for using booleans and aztec addresses - bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, - address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, - field_serialization::{ FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - }, + state_vars::{ map::Map, public_state::PublicState}, }; // docs:end:imports // docs:start:storage_struct @@ -29,7 +25,6 @@ contract EasyPrivateVoting { admin: PublicState::new( context, 1, // storage slot. this can be anything except 0. it is hashed, and hash on 0 = 0 - AddressSerializationMethods, ), tally: Map::new( context, @@ -37,15 +32,13 @@ contract EasyPrivateVoting { |context, slot| { PublicState::new( context, - slot, - FieldSerializationMethods, + slot, ) }, ), voteEnded: PublicState::new( context, - 3, - BoolSerializationMethods, + 3 ) } } } diff --git a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr index c0aea096b20b..a353be620ed0 100644 --- a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr +++ b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr @@ -12,6 +12,7 @@ use dep::aztec::{ log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext, + protocol_types::traits::{Serialize, Deserialize}, }; global ECDSA_PUBLIC_KEY_NOTE_LEN: Field = 5; @@ -25,23 +26,14 @@ struct EcdsaPublicKeyNote { header: NoteHeader, } -impl EcdsaPublicKeyNote { - pub fn new(x: [u8; 32], y: [u8; 32], owner: AztecAddress) -> Self { - EcdsaPublicKeyNote { - x, - y, - owner, - header: NoteHeader::empty(), - } - } - - // serialize the note as 5 fields where: +impl Serialize for EcdsaPublicKeyNote { + // serialize the note as 5 fields where: // [0] = x[0..31] (upper bound excluded) // [1] = x[31] // [2] = y[0..31] // [3] = y[31] // [4] = owner - pub fn serialize(self) -> [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] { + fn serialize(self) -> [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] { let mut x: Field = 0; let mut y: Field = 0; let mut mul: Field = 1; @@ -59,9 +51,37 @@ impl EcdsaPublicKeyNote { [x, last_x, y, last_y, self.owner.to_field()] } +} + +impl Deserialize for EcdsaPublicKeyNote { + fn deserialize(serialized_note: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN]) -> EcdsaPublicKeyNote { + let mut x: [u8; 32] = [0; 32]; + let mut y: [u8; 32] = [0; 32]; - pub fn compute_nullifier(self) -> Field { - let unique_siloed_note_hash = compute_unique_siloed_note_hash(EcdsaPublicKeyNoteInterface, self); + let part_x = serialized_note[0].to_be_bytes(32); + for i in 0..31 { + x[i] = part_x[i + 1]; + } + x[31] = serialized_note[1].to_be_bytes(32)[31]; + + let part_y = serialized_note[2].to_be_bytes(32); + for i in 0..31 { + y[i] = part_y[i + 1]; + } + y[31] = serialized_note[3].to_be_bytes(32)[31]; + + EcdsaPublicKeyNote { x, y, owner: AztecAddress::from_field(serialized_note[4]), header: NoteHeader::empty() } + } +} + +impl NoteInterface for EcdsaPublicKeyNote { + fn compute_note_hash(note: EcdsaPublicKeyNote) -> Field { + // TODO(#1205) Should use a non-zero generator index. + pedersen_hash(note.serialize(), 0) + } + + fn compute_nullifier(self) -> Field { + let unique_siloed_note_hash = compute_unique_siloed_note_hash(self); let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ @@ -71,12 +91,16 @@ impl EcdsaPublicKeyNote { ],0) } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + fn get_header(self) -> NoteHeader { + self.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { let encryption_pub_key = get_public_key(self.owner); emit_encrypted_log( context, @@ -88,57 +112,15 @@ impl EcdsaPublicKeyNote { } } -fn deserialize(serialized_note: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN]) -> EcdsaPublicKeyNote { - let mut x: [u8; 32] = [0; 32]; - let mut y: [u8; 32] = [0; 32]; - - let part_x = serialized_note[0].to_be_bytes(32); - for i in 0..31 { - x[i] = part_x[i + 1]; - } - x[31] = serialized_note[1].to_be_bytes(32)[31]; - - let part_y = serialized_note[2].to_be_bytes(32); - for i in 0..31 { - y[i] = part_y[i + 1]; +impl EcdsaPublicKeyNote { + pub fn new(x: [u8; 32], y: [u8; 32], owner: AztecAddress) -> Self { + EcdsaPublicKeyNote { + x, + y, + owner, + header: NoteHeader::empty(), + } } - y[31] = serialized_note[3].to_be_bytes(32)[31]; - - EcdsaPublicKeyNote { x, y, owner: AztecAddress::from_field(serialized_note[4]), header: NoteHeader::empty() } -} -fn serialize(note: EcdsaPublicKeyNote) -> [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] { - note.serialize() + } - -fn compute_note_hash(note: EcdsaPublicKeyNote) -> Field { - // TODO(#1205) Should use a non-zero generator index. - pedersen_hash(note.serialize(), 0) -} - -fn compute_nullifier(note: EcdsaPublicKeyNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: EcdsaPublicKeyNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut EcdsaPublicKeyNote, header: NoteHeader) { - note.set_header(header); -} - -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: EcdsaPublicKeyNote) { - note.broadcast(context, slot); -} - -global EcdsaPublicKeyNoteInterface = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index a12e0c02600f..cd97024d1bf2 100644 --- a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -23,7 +23,7 @@ contract EcdsaAccount { }; use crate::ecdsa_public_key_note::{ - EcdsaPublicKeyNote, EcdsaPublicKeyNoteInterface, ECDSA_PUBLIC_KEY_NOTE_LEN, + EcdsaPublicKeyNote, ECDSA_PUBLIC_KEY_NOTE_LEN, }; struct Storage { @@ -33,7 +33,7 @@ contract EcdsaAccount { impl Storage { fn init(context: Context) -> Self { Storage { - public_key: ImmutableSingleton::new(context, 1, EcdsaPublicKeyNoteInterface), + public_key: ImmutableSingleton::new(context, 1), } } } @@ -106,6 +106,6 @@ contract EcdsaAccount { ) -> pub [Field; 4] { assert(storage_slot == 1); let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(EcdsaPublicKeyNoteInterface, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(EcdsaPublicKeyNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr index cf7500c7fa63..a85115dbd14c 100644 --- a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr @@ -20,7 +20,6 @@ contract Escrow { use dep::address_note::address_note::{ AddressNote, - AddressNoteMethods, ADDRESS_NOTE_LEN, }; @@ -31,7 +30,7 @@ contract Escrow { impl Storage { fn init(context: Context) -> Self { Storage { - owners: Set::new(context, 1, AddressNoteMethods), + owners: Set::new(context, 1), } } } @@ -77,6 +76,6 @@ contract Escrow { ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); assert(storage_slot == 1); - note_utils::compute_note_hash_and_nullifier(AddressNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(AddressNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index f0882caff1b5..465996624291 100644 --- a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -14,9 +14,6 @@ contract InclusionProofs { set::Set, public_state::PublicState, }, - types::{ - type_serialization::field_serialization::FieldSerializationMethods, - }, context::Context, note::{ note_getter_options::NoteGetterOptions, @@ -47,7 +44,7 @@ contract InclusionProofs { }, }, }; - use dep::value_note::value_note::{ValueNote, ValueNoteMethods, VALUE_NOTE_LEN}; + use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN}; struct Storage { private_values: Map>, @@ -61,13 +58,12 @@ contract InclusionProofs { context, 1, // Storage slot |context, slot| { - Set::new(context, slot, ValueNoteMethods) + Set::new(context, slot) }, ), public_value: PublicState::new( context, 2, // Storage slot - FieldSerializationMethods, ), } } @@ -110,12 +106,7 @@ contract InclusionProofs { // 2) Prove the note inclusion if maybe_note.is_some() { - prove_note_inclusion( - ValueNoteMethods, - maybe_note.unwrap_unchecked(), - block_number, - context - ); + prove_note_inclusion(maybe_note.unwrap_unchecked(), block_number, context); } else { // Note was not found so we will prove inclusion of the spare commitment prove_note_commitment_inclusion(spare_commitment, block_number, context); @@ -140,12 +131,7 @@ contract InclusionProofs { // 3) Compute the nullifier from the note if maybe_note.is_some() { - prove_note_not_nullified( - ValueNoteMethods, - maybe_note.unwrap_unchecked(), - block_number, - context - ); + prove_note_not_nullified(maybe_note.unwrap_unchecked(), block_number, context); } else { // Note was not found so we will use the spare nullifier prove_nullifier_non_inclusion(spare_nullifier, block_number, context); @@ -164,7 +150,7 @@ contract InclusionProofs { let note = notes[0].unwrap(); // 2) Prove the note validity - prove_note_validity(ValueNoteMethods, note, block_number, context); + prove_note_validity(note, block_number, context); } #[aztec(private)] @@ -240,6 +226,6 @@ contract InclusionProofs { serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr b/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr index b71696a3a5fb..5fbbb83a855f 100644 --- a/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr +++ b/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr @@ -1,5 +1,7 @@ -use dep::aztec::protocol_types::address::AztecAddress; -use dep::aztec::types::type_serialization::TypeSerializationInterface; +use dep::aztec::protocol_types::{ + address::AztecAddress, + traits::{Deserialize, Serialize} +}; // Struct to be used to represent "totals". Generally, there should be one per asset. // It stores the global values that are shared among all users, such as an accumulator @@ -15,33 +17,26 @@ struct Asset { global ASSET_SERIALIZED_LEN: Field = 4; -// Right now we are wasting so many writes. If changing last_updated_ts -// we will end up rewriting all of them, wasting writes. -fn deserializeAsset(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { - Asset { - interest_accumulator: fields[0] as u120, - last_updated_ts: fields[1] as u120, - loan_to_value: fields[2] as u120, - oracle: AztecAddress::from_field(fields[3]) +impl Serialize for Asset { + fn serialize(asset: Asset) -> [Field; ASSET_SERIALIZED_LEN] { + [ + asset.interest_accumulator as Field, + asset.last_updated_ts as Field, + asset.loan_to_value as Field, + asset.oracle.to_field() + ] } } -fn serializeAsset(asset: Asset) -> [Field; ASSET_SERIALIZED_LEN] { - [ - asset.interest_accumulator as Field, - asset.last_updated_ts as Field, - asset.loan_to_value as Field, - asset.oracle.to_field() - ] -} - -impl Asset { - pub fn serialize(self: Self) -> [Field; ASSET_SERIALIZED_LEN] { - serializeAsset(self) +impl Deserialize for Asset { + // Right now we are wasting so many writes. If changing last_updated_ts + // we will end up rewriting all of them, wasting writes. + fn deserialize(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { + Asset { + interest_accumulator: fields[0] as u120, + last_updated_ts: fields[1] as u120, + loan_to_value: fields[2] as u120, + oracle: AztecAddress::from_field(fields[3]) + } } } - -global AssetSerializationMethods = TypeSerializationInterface { - deserialize: deserializeAsset, - serialize: serializeAsset, -}; diff --git a/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr b/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr index 1c80bf6e4a2f..e19b223d8070 100644 --- a/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr @@ -23,13 +23,9 @@ contract Lending { map::Map, public_state::PublicState, }, - types::type_serialization::{ - field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - TypeSerializationInterface, - address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, - }, + protocol_types::type_serialization::FIELD_SERIALIZED_LEN }; - use crate::asset::{ASSET_SERIALIZED_LEN, Asset, AssetSerializationMethods}; + use crate::asset::{ASSET_SERIALIZED_LEN, Asset}; use crate::interest_math::compute_multiplier; use crate::helpers::{covered_by_collateral, DebtReturn, debt_updates, debt_value, compute_identifier}; use crate::interfaces::{Token, Lending, PriceFeed}; @@ -48,13 +44,11 @@ contract Lending { Storage { collateral_asset: PublicState::new( context, - 1, - AddressSerializationMethods, + 1 ), stable_coin: PublicState::new( context, - 2, - AddressSerializationMethods, + 2 ), assets: Map::new( context, @@ -62,8 +56,7 @@ contract Lending { |context, slot| { PublicState::new( context, - slot, - AssetSerializationMethods, + slot ) }, ), @@ -73,8 +66,7 @@ contract Lending { |context, slot| { PublicState::new( context, - slot, - FieldSerializationMethods, + slot ) }, ), @@ -84,8 +76,7 @@ contract Lending { |context, slot| { PublicState::new( context, - slot, - FieldSerializationMethods, + slot ) }, ), diff --git a/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr b/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr index 6792fcef1cf6..c098794748e9 100644 --- a/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr @@ -8,7 +8,7 @@ contract PendingCommitments { use dep::value_note::{ balance_utils, filter::filter_notes_min_sum, - value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, + value_note::{VALUE_NOTE_LEN, ValueNote}, }; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, @@ -36,7 +36,7 @@ contract PendingCommitments { context, 1, // Storage slot |context, slot| { - Set::new(context, slot, ValueNoteMethods) + Set::new(context, slot) }, ), } @@ -296,6 +296,6 @@ contract PendingCommitments { serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr b/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr index 9d464eefddc2..047705a1ace9 100644 --- a/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr +++ b/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr @@ -1,4 +1,4 @@ -use dep::aztec::types::type_serialization::TypeSerializationInterface; +use dep::aztec::protocol_types::traits::{Serialize, Deserialize}; struct Asset { price: u120, @@ -6,21 +6,14 @@ struct Asset { global ASSET_SERIALIZED_LEN: Field = 1; -fn deserializeAsset(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { - Asset { price: fields[0] as u120 } -} - -fn serializeAsset(asset: Asset) -> [Field; ASSET_SERIALIZED_LEN] { - [asset.price as Field] +impl Serialize for Asset { + fn serialize(asset: Asset) -> [Field; ASSET_SERIALIZED_LEN] { + [asset.price as Field] + } } -impl Asset { - fn serialize(self: Self) -> [Field; ASSET_SERIALIZED_LEN] { - serializeAsset(self) +impl Deserialize for Asset { + fn deserialize(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { + Asset { price: fields[0] as u120 } } } - -global AssetSerializationMethods = TypeSerializationInterface { - deserialize: deserializeAsset, - serialize: serializeAsset, -}; diff --git a/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr b/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr index 4e3013594382..adce254f283f 100644 --- a/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr @@ -10,7 +10,7 @@ contract PriceFeed { }, }; use dep::aztec::protocol_types::address::AztecAddress; - use crate::asset::{ASSET_SERIALIZED_LEN, Asset, AssetSerializationMethods}; + use crate::asset::{ASSET_SERIALIZED_LEN, Asset}; // Storage structure, containing all storage, and specifying what slots they use. struct Storage { @@ -27,7 +27,6 @@ contract PriceFeed { PublicState::new( context, slot, - AssetSerializationMethods, ) }, ), diff --git a/yarn-project/noir-contracts/contracts/reader_contract/src/main.nr b/yarn-project/noir-contracts/contracts/reader_contract/src/main.nr index 931a5e255011..b8c65f95c67c 100644 --- a/yarn-project/noir-contracts/contracts/reader_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/reader_contract/src/main.nr @@ -4,7 +4,7 @@ contract Reader { abis::function_selector::FunctionSelector, }; - use dep::compressed_string::{FieldCompressedString, FieldCompressedStringSerializationMethods}; + use dep::compressed_string::FieldCompressedString; #[aztec(private)] diff --git a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr index 77203a70388a..25bb9e476869 100644 --- a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -20,7 +20,7 @@ contract SchnorrAccount { auth_witness::get_auth_witness, }; - use crate::public_key_note::{PublicKeyNote, PublicKeyNoteMethods, PUBLIC_KEY_NOTE_LEN}; + use crate::public_key_note::{PublicKeyNote, PUBLIC_KEY_NOTE_LEN}; struct Storage { // docs:start:storage @@ -32,7 +32,7 @@ contract SchnorrAccount { fn init(context: Context) -> Self { Storage { // docs:start:storage_init - signing_public_key: ImmutableSingleton::new(context, 1, PublicKeyNoteMethods), + signing_public_key: ImmutableSingleton::new(context, 1), // docs:end:storage_init } } @@ -113,6 +113,6 @@ contract SchnorrAccount { ) -> pub [Field; 4] { assert(storage_slot == 1); let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(PublicKeyNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(PublicKeyNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr index 3d3eb1ecfa1a..ecde4de17ed2 100644 --- a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr +++ b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr @@ -11,8 +11,11 @@ use dep::aztec::{ }, log::emit_encrypted_log, context::PrivateContext, + protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize}, + } }; -use dep::aztec::protocol_types::address::AztecAddress; global PUBLIC_KEY_NOTE_LEN: Field = 3; @@ -25,23 +28,26 @@ struct PublicKeyNote { header: NoteHeader, } -impl PublicKeyNote { - pub fn new(x: Field, y: Field, owner: AztecAddress) -> Self { - PublicKeyNote { - x, - y, - owner, - header: NoteHeader::empty(), - } +impl Serialize for PublicKeyNote { + fn serialize(self) -> [Field; PUBLIC_KEY_NOTE_LEN] { + [self.x, self.y, self.owner.to_field()] } +} - // serialize the note as 3 fields - pub fn serialize(self) -> [Field; PUBLIC_KEY_NOTE_LEN] { - [self.x, self.y, self.owner.to_field()] +impl Deserialize for PublicKeyNote { + fn deserialize(serialized_note: [Field; PUBLIC_KEY_NOTE_LEN]) -> PublicKeyNote { + PublicKeyNote { + x: serialized_note[0], + y: serialized_note[1], + owner: AztecAddress::from_field(serialized_note[2]), + header: NoteHeader::empty() + } } +} - pub fn compute_nullifier(self) -> Field { - let unique_siloed_note_hash = compute_unique_siloed_note_hash(PublicKeyNoteMethods, self); +impl NoteInterface for PublicKeyNote { + fn compute_nullifier(self) -> Field { + let unique_siloed_note_hash = compute_unique_siloed_note_hash(self); let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ @@ -51,12 +57,21 @@ impl PublicKeyNote { ],0) } - pub fn set_header(&mut self, header: NoteHeader) { + fn compute_note_hash(note: PublicKeyNote) -> Field { + // TODO(#1205) Should use a non-zero generator index. + pedersen_hash(note.serialize(), 0) + } + + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + fn get_header(self) -> NoteHeader { + self.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { let encryption_pub_key = get_public_key(self.owner); emit_encrypted_log( context, @@ -68,47 +83,13 @@ impl PublicKeyNote { } } -fn deserialize(serialized_note: [Field; PUBLIC_KEY_NOTE_LEN]) -> PublicKeyNote { - PublicKeyNote { - x: serialized_note[0], - y: serialized_note[1], - owner: AztecAddress::from_field(serialized_note[2]), - header: NoteHeader::empty() +impl PublicKeyNote { + pub fn new(x: Field, y: Field, owner: AztecAddress) -> Self { + PublicKeyNote { + x, + y, + owner, + header: NoteHeader::empty(), + } } } - -fn serialize(note: PublicKeyNote) -> [Field; PUBLIC_KEY_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: PublicKeyNote) -> Field { - // TODO(#1205) Should use a non-zero generator index. - pedersen_hash(note.serialize(), 0) -} - -fn compute_nullifier(note: PublicKeyNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: PublicKeyNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut PublicKeyNote, header: NoteHeader) { - note.set_header(header); -} - -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: PublicKeyNote) { - note.broadcast(context, slot); -} - -global PublicKeyNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr b/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr index b08f2800b788..625df2f07f66 100644 --- a/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr @@ -14,7 +14,7 @@ contract SlowTree { use dep::value_note::{ balance_utils, utils::{increment, decrement}, - value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, + value_note::{VALUE_NOTE_LEN, ValueNote}, }; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, @@ -23,9 +23,7 @@ contract SlowTree { utils as note_utils, }, state_vars::{map::Map, public_state::PublicState, set::Set}, - types::type_serialization::field_serialization::{ - FieldSerializationMethods, FIELD_SERIALIZED_LEN, - }, + protocol_types::type_serialization::FIELD_SERIALIZED_LEN, }; use dep::slow_updates_tree::slow_map::{ SlowMap, Leaf, SlowUpdateProof, compute_merkle_root, deserialize_slow_update_proof diff --git a/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr index 9f02dc97bb57..e5a85c860812 100644 --- a/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -5,7 +5,7 @@ contract StatefulTest { use dep::value_note::{ balance_utils, utils::{increment, decrement}, - value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, + value_note::{VALUE_NOTE_LEN, ValueNote}, }; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, @@ -14,9 +14,7 @@ contract StatefulTest { utils as note_utils, }, state_vars::{map::Map, public_state::PublicState, set::Set}, - types::type_serialization::field_serialization::{ - FieldSerializationMethods, FIELD_SERIALIZED_LEN, - }, + protocol_types::type_serialization::FIELD_SERIALIZED_LEN, }; struct Storage { @@ -31,7 +29,7 @@ contract StatefulTest { context, 1, // Storage slot |context, slot| { - Set::new(context, slot, ValueNoteMethods) + Set::new(context, slot) }, ), public_values: Map::new( @@ -41,7 +39,6 @@ contract StatefulTest { PublicState::new( context, slot, - FieldSerializationMethods, ) }, ), @@ -88,6 +85,6 @@ contract StatefulTest { serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index aac608c1bd82..c2b3b7b51f26 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -34,7 +34,7 @@ contract Test { types::vec::BoundedVec, }; use dep::token_portal_content_hash_lib::{get_mint_private_content_hash, get_mint_public_content_hash}; - use dep::field_note::field_note::{FieldNote, FieldNoteMethods, FIELD_NOTE_LEN}; + use dep::field_note::field_note::{FieldNote, FIELD_NOTE_LEN}; #[event] struct ExampleEvent { @@ -48,7 +48,7 @@ contract Test { impl Storage { fn init(context: Context) -> Self { Storage { - example_constant: ImmutableSingleton::new(context, 1, FieldNoteMethods), + example_constant: ImmutableSingleton::new(context, 1), } } } @@ -242,6 +242,6 @@ contract Test { ) -> pub [Field; 4] { assert(storage_slot == 1); let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(FieldNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(FieldNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr index 0845c0ec0daa..f7dd04a83124 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -16,7 +16,7 @@ contract TokenBlacklist { // Libs use dep::std::option::Option; - use dep::safe_math::SafeU120; + use dep::safe_math::{SafeU120,SAFE_U120_SERIALIZED_LEN}; use dep::aztec::protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, @@ -30,14 +30,10 @@ contract TokenBlacklist { context::{PrivateContext, PublicContext, Context}, hash::{compute_secret_hash}, state_vars::{map::Map, public_state::PublicState, set::Set, immutable_singleton::ImmutableSingleton}, - types::type_serialization::{ - field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, - address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, - }, + protocol_types::type_serialization::{FIELD_SERIALIZED_LEN, BOOL_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN}, }; - use dep::field_note::field_note::{FieldNote, FieldNoteMethods, FIELD_NOTE_LEN}; + use dep::field_note::field_note::{FieldNote, FIELD_NOTE_LEN}; use dep::authwit::{ auth::{ @@ -47,10 +43,9 @@ contract TokenBlacklist { }; use crate::types::{ - transparent_note::{TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN}, - token_note::{TokenNote, TokenNoteMethods, TOKEN_NOTE_LEN}, + transparent_note::{TransparentNote, TRANSPARENT_NOTE_LEN}, + token_note::{TokenNote, TOKEN_NOTE_LEN}, balances_map::{BalancesMap}, - safe_u120_serialization::{SafeU120SerializationMethods, SAFE_U120_SERIALIZED_LEN}, roles::UserFlags, }; // docs:start:interface @@ -73,33 +68,29 @@ contract TokenBlacklist { admin: PublicState::new( context, 1, - AddressSerializationMethods, ), balances: BalancesMap::new(context, 3), total_supply: PublicState::new( context, 4, - SafeU120SerializationMethods, ), - pending_shields: Set::new(context, 5, TransparentNoteMethods), + pending_shields: Set::new(context, 5), public_balances: Map::new( context, 6, |context, slot| { PublicState::new( context, - slot, - SafeU120SerializationMethods, + slot ) }, ), // Below is an abomination to have same value in private and public (immutable in solidity). // docs:start:slow_updates_storage - slow_update: ImmutableSingleton::new(context, 7, FieldNoteMethods), + slow_update: ImmutableSingleton::new(context, 7), public_slow_update: PublicState::new( context, - 8, - AddressSerializationMethods, + 8 ), // docs:end:slow_updates_storage @@ -393,11 +384,11 @@ contract TokenBlacklist { ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); if (storage_slot == 5) { - note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage) + note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, preimage) } else if (storage_slot == 7) { - note_utils::compute_note_hash_and_nullifier(FieldNoteMethods, note_header, preimage) + note_utils::compute_note_hash_and_nullifier(FieldNote::deserialize, note_header, preimage) } else { - note_utils::compute_note_hash_and_nullifier(TokenNoteMethods, note_header, preimage) + note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, preimage) } } } diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr index f5a3aeaa6fdf..3ba036583906 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr @@ -2,5 +2,4 @@ mod transparent_note; mod balance_set; mod balances_map; mod token_note; -mod safe_u120_serialization; mod roles; diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr index f0ecb0797296..d11e5bb3769d 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr @@ -22,7 +22,7 @@ use dep::aztec::oracle::{ get_public_key::get_public_key, }; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods}; +use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; // A set implementing standard manipulation of balances. // Does not require spending key, but only knowledge. @@ -39,7 +39,6 @@ impl BalanceSet { let set = Set { context, storage_slot, - note_interface: TokenNoteMethods, }; Self { context, diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/safe_u120_serialization.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/safe_u120_serialization.nr deleted file mode 100644 index 876007184fe1..000000000000 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/safe_u120_serialization.nr +++ /dev/null @@ -1,18 +0,0 @@ -use dep::aztec::types::type_serialization::TypeSerializationInterface; -use dep::safe_math::SafeU120; - -global SAFE_U120_SERIALIZED_LEN: Field = 1; - -// This is safe when reading from storage IF only correct safeu120 was written to storage -fn deserializeU120(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 { - SafeU120 { value: fields[0] as u120 } -} - -fn serializeU120(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] { - [value.value as Field] -} - -global SafeU120SerializationMethods = TypeSerializationInterface { - deserialize: deserializeU120, - serialize: serializeU120, -}; diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index 8a2275361911..dcc32a61f27e 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -10,6 +10,7 @@ use dep::aztec::{ state_vars::set::Set, log::emit_encrypted_log, hash::pedersen_hash, + protocol_types::traits::{Serialize, Deserialize} }; use dep::aztec::oracle::{ rand::rand, @@ -35,21 +36,14 @@ struct TokenNote { header: NoteHeader, } -impl TokenNote { - pub fn new(amount: SafeU120, owner: AztecAddress) -> Self { - Self { - amount, - owner, - randomness: rand(), - header: NoteHeader::empty(), - } - } - - pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { +impl Serialize for TokenNote { + fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { [self.amount.value as Field, self.owner.to_field(), self.randomness] } +} - pub fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> Self { +impl Deserialize for TokenNote { + fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> Self { Self { amount: SafeU120::new(preimage[0]), owner: AztecAddress::from_field(preimage[1]), @@ -57,8 +51,10 @@ impl TokenNote { header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for TokenNote { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount.value as Field, @@ -68,8 +64,8 @@ impl TokenNote { } // docs:start:nullifier - pub fn compute_nullifier(self) -> Field { - let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self); + fn compute_nullifier(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ @@ -80,12 +76,17 @@ impl TokenNote { } // docs:end:nullifier - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + + fn get_header(note: TokenNote) -> NoteHeader { + note.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !self.amount.is_zero() { let encryption_pub_key = get_public_key(self.owner); @@ -100,41 +101,13 @@ impl TokenNote { } } -fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> TokenNote { - TokenNote::deserialize(preimage) -} - -fn serialize(note: TokenNote) -> [Field; TOKEN_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: TokenNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: TokenNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: TokenNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut TokenNote, header: NoteHeader) { - note.set_header(header) -} - -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: TokenNote) { - note.broadcast(context, slot); +impl TokenNote { + pub fn new(amount: SafeU120, owner: AztecAddress) -> Self { + Self { + amount, + owner, + randomness: rand(), + header: NoteHeader::empty(), + } + } } - -global TokenNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr index 12772aed42fe..beaa61e6dd7c 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr @@ -7,6 +7,7 @@ use dep::aztec::{ }, hash::{compute_secret_hash, pedersen_hash}, context::PrivateContext, + protocol_types::traits::{Serialize, Deserialize} }; global TRANSPARENT_NOTE_LEN: Field = 2; @@ -22,38 +23,14 @@ struct TransparentNote { header: NoteHeader, } -impl TransparentNote { - - // CONSTRUCTORS - - pub fn new(amount: Field, secret_hash: Field) -> Self { - TransparentNote { - amount: amount, - secret_hash: secret_hash, - secret: 0, - header: NoteHeader::empty(), - } - } - - // new oracle call primitive - // get me the secret corresponding to this hash - pub fn new_from_secret(amount: Field, secret: Field) -> Self { - TransparentNote { - amount: amount, - secret_hash: compute_secret_hash(secret), - secret: secret, - header: NoteHeader::empty(), - } - } - - - // STANDARD NOTE_INTERFACE FUNCTIONS - - pub fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] { +impl Serialize for TransparentNote { + fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] { [self.amount, self.secret_hash] } +} - pub fn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> Self { +impl Deserialize for TransparentNote { + fn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> Self { TransparentNote { amount: preimage[0], secret_hash: preimage[1], @@ -61,8 +38,11 @@ impl TransparentNote { header: NoteHeader::empty(), } } +} + +impl NoteInterface for TransparentNote { - pub fn compute_note_hash(self) -> Field { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount, @@ -70,61 +50,55 @@ impl TransparentNote { ],0) } - pub fn compute_nullifier(self) -> Field { + fn compute_nullifier(self) -> Field { // TODO(#1386): should use `compute_note_hash_for_read_or_nullify` once public functions inject nonce! - let siloed_note_hash = compute_siloed_note_hash(TransparentNoteMethods, self); + let siloed_note_hash = compute_siloed_note_hash(self); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([self.secret, siloed_note_hash],0) } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } - - // CUSTOM FUNCTIONS FOR THIS NOTE TYPE - - pub fn knows_secret(self, secret: Field) { - let hash = compute_secret_hash(secret); - assert(self.secret_hash == hash); + fn get_header(self) -> NoteHeader { + self.header } -} -fn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> TransparentNote { - TransparentNote::deserialize(preimage) + fn broadcast(self, context: &mut PrivateContext, slot: Field) { + assert(false, "TransparentNote does not support broadcast"); + } } -fn serialize(note: TransparentNote) -> [Field; TRANSPARENT_NOTE_LEN] { - note.serialize() -} +impl TransparentNote { -fn compute_note_hash(note: TransparentNote) -> Field { - note.compute_note_hash() -} + // CONSTRUCTORS -fn compute_nullifier(note: TransparentNote) -> Field { - note.compute_nullifier() -} + pub fn new(amount: Field, secret_hash: Field) -> Self { + TransparentNote { + amount: amount, + secret_hash: secret_hash, + secret: 0, + header: NoteHeader::empty(), + } + } -fn get_header(note: TransparentNote) -> NoteHeader { - note.header -} + // new oracle call primitive + // get me the secret corresponding to this hash + pub fn new_from_secret(amount: Field, secret: Field) -> Self { + TransparentNote { + amount: amount, + secret_hash: compute_secret_hash(secret), + secret: secret, + header: NoteHeader::empty(), + } + } -fn set_header(note: &mut TransparentNote, header: NoteHeader) { - note.set_header(header) -} + // CUSTOM FUNCTIONS FOR THIS NOTE TYPE -fn broadcast(context: &mut PrivateContext, slot: Field, note: TransparentNote) { - assert(false, "TransparentNote does not support broadcast"); + pub fn knows_secret(self, secret: Field) { + let hash = compute_secret_hash(secret); + assert(self.secret_hash == hash); + } } - -global TransparentNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; // docs:end:token_types_all \ No newline at end of file diff --git a/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr index ebf6c279a95a..92e5ea379cef 100644 --- a/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -19,7 +19,6 @@ contract TokenBridge { context::{Context}, hash::{compute_secret_hash}, state_vars::{public_state::PublicState}, - types::type_serialization::address_serialization::AddressSerializationMethods, }; use dep::token_portal_content_hash_lib::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash}; @@ -38,8 +37,7 @@ contract TokenBridge { Storage { token: PublicState::new( context, - 1, - AddressSerializationMethods, + 1 ), } } diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index 6aa5c0f88d31..27db93806fe0 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -13,8 +13,8 @@ contract Token { // Libs use dep::std::option::Option; - use dep::safe_math::SafeU120; - use dep::compressed_string::{FieldCompressedString, FieldCompressedStringSerializationMethods}; + use dep::safe_math::{SafeU120, SAFE_U120_SERIALIZED_LEN}; + use dep::compressed_string::{FieldCompressedString}; use dep::aztec::{ note::{ @@ -25,16 +25,16 @@ contract Token { context::{PrivateContext, PublicContext, Context}, hash::{compute_secret_hash}, state_vars::{map::Map, public_state::PublicState, set::Set}, - types::type_serialization::{ - field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, - address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, - u8_serialization::{U8SerializationMethods, U8_SERIALIZED_LEN}, - }, - }; - use dep::aztec::protocol_types::{ - abis::function_selector::FunctionSelector, - address::AztecAddress, + protocol_types::{ + type_serialization::{ + FIELD_SERIALIZED_LEN, + BOOL_SERIALIZED_LEN, + U8_SERIALIZED_LEN, + AZTEC_ADDRESS_SERIALIZED_LEN + }, + abis::function_selector::FunctionSelector, + address::AztecAddress + } }; // docs:start:import_authwit @@ -47,10 +47,9 @@ contract Token { // docs:end:import_authwit use crate::types::{ - transparent_note::{TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN}, - token_note::{TokenNote, TokenNoteMethods, TOKEN_NOTE_LEN}, - balances_map::{BalancesMap}, - safe_u120_serialization::{SafeU120SerializationMethods, SAFE_U120_SERIALIZED_LEN} + transparent_note::{TransparentNote, TRANSPARENT_NOTE_LEN}, + token_note::{TokenNote, TOKEN_NOTE_LEN}, + balances_map::{BalancesMap} }; // docs:end::imports @@ -84,7 +83,6 @@ contract Token { admin: PublicState::new( context, 1, - AddressSerializationMethods, ), // docs:end:storage_admin_init // docs:start:storage_minters_init @@ -95,7 +93,6 @@ contract Token { PublicState::new( context, slot, - BoolSerializationMethods, ) }, ), @@ -106,10 +103,9 @@ contract Token { total_supply: PublicState::new( context, 4, - SafeU120SerializationMethods, ), // docs:start:storage_pending_shields_init - pending_shields: Set::new(context, 5, TransparentNoteMethods), + pending_shields: Set::new(context, 5), // docs:end:storage_pending_shields_init public_balances: Map::new( context, @@ -118,24 +114,20 @@ contract Token { PublicState::new( context, slot, - SafeU120SerializationMethods, ) }, ), symbol: PublicState::new( context, 7, - FieldCompressedStringSerializationMethods, ), name: PublicState::new( context, 8, - FieldCompressedStringSerializationMethods, ), decimals: PublicState::new( context, 9, - U8SerializationMethods, ), } } @@ -446,9 +438,9 @@ contract Token { ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); if (storage_slot == 5) { - note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) } else { - note_utils::compute_note_hash_and_nullifier(TokenNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) } } // docs:end:compute_note_hash_and_nullifier diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types.nr index e29a8151e9f3..d3b3b1c9e773 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types.nr @@ -2,4 +2,3 @@ mod transparent_note; mod balance_set; mod balances_map; mod token_note; -mod safe_u120_serialization; diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr index 80b6a2ceeddd..4162caca1bfa 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr @@ -24,7 +24,7 @@ use dep::aztec::oracle::{ get_public_key::get_public_key, }; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods}; +use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; // A set implementing standard manipulation of balances. // Does not require spending key, but only knowledge. @@ -41,7 +41,6 @@ impl BalanceSet { let set = Set { context, storage_slot, - note_interface: TokenNoteMethods, }; Self { context, diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/safe_u120_serialization.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/safe_u120_serialization.nr deleted file mode 100644 index 876007184fe1..000000000000 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/safe_u120_serialization.nr +++ /dev/null @@ -1,18 +0,0 @@ -use dep::aztec::types::type_serialization::TypeSerializationInterface; -use dep::safe_math::SafeU120; - -global SAFE_U120_SERIALIZED_LEN: Field = 1; - -// This is safe when reading from storage IF only correct safeu120 was written to storage -fn deserializeU120(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 { - SafeU120 { value: fields[0] as u120 } -} - -fn serializeU120(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] { - [value.value as Field] -} - -global SafeU120SerializationMethods = TypeSerializationInterface { - deserialize: deserializeU120, - serialize: serializeU120, -}; diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr index d2d9ef68f1fb..98064f8ed284 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -14,6 +14,10 @@ use dep::aztec::{ state_vars::set::Set, log::emit_encrypted_log, hash::pedersen_hash, + protocol_types::traits::{ + Serialize, + Deserialize + }, }; use dep::aztec::oracle::{ rand::rand, @@ -39,21 +43,14 @@ struct TokenNote { header: NoteHeader, } -impl TokenNote { - pub fn new(amount: SafeU120, owner: AztecAddress) -> Self { - Self { - amount, - owner, - randomness: rand(), - header: NoteHeader::empty(), - } - } - - pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { +impl Serialize for TokenNote { + fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { [self.amount.value as Field, self.owner.to_field(), self.randomness] } +} - pub fn deserialize(serialized_note: [Field; TOKEN_NOTE_LEN]) -> Self { +impl Deserialize for TokenNote { + fn deserialize(serialized_note: [Field; TOKEN_NOTE_LEN]) -> Self { Self { amount: SafeU120::new(serialized_note[0]), owner: AztecAddress::from_field(serialized_note[1]), @@ -61,8 +58,10 @@ impl TokenNote { header: NoteHeader::empty(), } } +} - pub fn compute_note_hash(self) -> Field { +impl NoteInterface for TokenNote { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount.value as Field, @@ -72,8 +71,8 @@ impl TokenNote { } // docs:start:nullifier - pub fn compute_nullifier(self) -> Field { - let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self); + fn compute_nullifier(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ @@ -84,12 +83,16 @@ impl TokenNote { } // docs:end:nullifier - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } + fn get_header(note: TokenNote) -> NoteHeader { + note.header + } + // Broadcasts the note as an encrypted log on L1. - pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !self.amount.is_zero() { let encryption_pub_key = get_public_key(self.owner); @@ -104,41 +107,15 @@ impl TokenNote { } } -fn deserialize(serialized_note: [Field; TOKEN_NOTE_LEN]) -> TokenNote { - TokenNote::deserialize(serialized_note) -} - -fn serialize(note: TokenNote) -> [Field; TOKEN_NOTE_LEN] { - note.serialize() -} - -fn compute_note_hash(note: TokenNote) -> Field { - note.compute_note_hash() -} - -fn compute_nullifier(note: TokenNote) -> Field { - note.compute_nullifier() -} - -fn get_header(note: TokenNote) -> NoteHeader { - note.header -} - -fn set_header(note: &mut TokenNote, header: NoteHeader) { - note.set_header(header) -} +impl TokenNote { + pub fn new(amount: SafeU120, owner: AztecAddress) -> Self { + Self { + amount, + owner, + randomness: rand(), + header: NoteHeader::empty(), + } + } -// Broadcasts the note as an encrypted log on L1. -fn broadcast(context: &mut PrivateContext, slot: Field, note: TokenNote) { - note.broadcast(context, slot); + } - -global TokenNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr index 034b4b3390f7..ae7fb93f8a52 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr @@ -7,6 +7,7 @@ use dep::aztec::{ }, hash::{compute_secret_hash, pedersen_hash}, context::PrivateContext, + protocol_types::traits::{Serialize, Deserialize, Empty} }; global TRANSPARENT_NOTE_LEN: Field = 2; @@ -22,38 +23,14 @@ struct TransparentNote { header: NoteHeader, } -impl TransparentNote { - - // CONSTRUCTORS - - pub fn new(amount: Field, secret_hash: Field) -> Self { - TransparentNote { - amount: amount, - secret_hash: secret_hash, - secret: 0, - header: NoteHeader::empty(), - } - } - - // new oracle call primitive - // get me the secret corresponding to this hash - pub fn new_from_secret(amount: Field, secret: Field) -> Self { - TransparentNote { - amount: amount, - secret_hash: compute_secret_hash(secret), - secret: secret, - header: NoteHeader::empty(), - } - } - - - // STANDARD NOTE_INTERFACE FUNCTIONS - - pub fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] { +impl Serialize for TransparentNote { + fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] { [self.amount, self.secret_hash] } +} - pub fn deserialize(serialized_note: [Field; TRANSPARENT_NOTE_LEN]) -> Self { +impl Deserialize for TransparentNote { + fn deserialize(serialized_note: [Field; TRANSPARENT_NOTE_LEN]) -> Self { TransparentNote { amount: serialized_note[0], secret_hash: serialized_note[1], @@ -61,8 +38,17 @@ impl TransparentNote { header: NoteHeader::empty(), } } +} + +impl Empty for TransparentNote { + fn empty() -> Self { + TransparentNote::new(0, 0) + } - pub fn compute_note_hash(self) -> Field { +} + +impl NoteInterface for TransparentNote { + fn compute_note_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount, @@ -70,61 +56,54 @@ impl TransparentNote { ],0) } - pub fn compute_nullifier(self) -> Field { + fn compute_nullifier(self) -> Field { // TODO(#1386): should use `compute_note_hash_for_read_or_nullify` once public functions inject nonce! - let siloed_note_hash = compute_siloed_note_hash(TransparentNoteMethods, self); + let siloed_note_hash = compute_siloed_note_hash(self); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([self.secret, siloed_note_hash],0) } - pub fn set_header(&mut self, header: NoteHeader) { + fn set_header(&mut self, header: NoteHeader) { self.header = header; } - - // CUSTOM FUNCTIONS FOR THIS NOTE TYPE - - pub fn knows_secret(self, secret: Field) { - let hash = compute_secret_hash(secret); - assert(self.secret_hash == hash); + fn get_header(note: TransparentNote) -> NoteHeader { + note.header } -} -fn deserialize(serialized_note: [Field; TRANSPARENT_NOTE_LEN]) -> TransparentNote { - TransparentNote::deserialize(serialized_note) -} - -fn serialize(note: TransparentNote) -> [Field; TRANSPARENT_NOTE_LEN] { - note.serialize() + fn broadcast(self, context: &mut PrivateContext, slot: Field) { + assert(false, "TransparentNote does not support broadcast"); + } } -fn compute_note_hash(note: TransparentNote) -> Field { - note.compute_note_hash() -} +impl TransparentNote { -fn compute_nullifier(note: TransparentNote) -> Field { - note.compute_nullifier() -} + // CONSTRUCTORS -fn get_header(note: TransparentNote) -> NoteHeader { - note.header -} + pub fn new(amount: Field, secret_hash: Field) -> Self { + TransparentNote { + amount: amount, + secret_hash: secret_hash, + secret: 0, + header: NoteHeader::empty(), + } + } + // new oracle call primitive + // get me the secret corresponding to this hash + pub fn new_from_secret(amount: Field, secret: Field) -> Self { + TransparentNote { + amount: amount, + secret_hash: compute_secret_hash(secret), + secret: secret, + header: NoteHeader::empty(), + } + } -fn set_header(note: &mut TransparentNote, header: NoteHeader) { - note.set_header(header) -} + // CUSTOM FUNCTIONS FOR THIS NOTE TYPE -fn broadcast(context: &mut PrivateContext, slot: Field, note: TransparentNote) { - assert(false, "TransparentNote does not support broadcast"); + pub fn knows_secret(self, secret: Field) { + let hash = compute_secret_hash(secret); + assert(self.secret_hash == hash); + } } - -global TransparentNoteMethods = NoteInterface { - deserialize, - serialize, - compute_note_hash, - compute_nullifier, - get_header, - set_header, - broadcast, -}; // docs:end:token_types_all \ No newline at end of file diff --git a/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr b/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr index 35a4d520af17..d15b22e8b2bc 100644 --- a/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -17,12 +17,7 @@ contract Uniswap { context::{PrivateContext, PublicContext, Context}, oracle::{context::get_portal_address}, state_vars::{map::Map, public_state::PublicState}, - types::type_serialization::bool_serialization::{ - BoolSerializationMethods, BOOL_SERIALIZED_LEN, - }, - types::type_serialization::field_serialization::{ - FieldSerializationMethods, FIELD_SERIALIZED_LEN, - }, + protocol_types::type_serialization::{BOOL_SERIALIZED_LEN,FIELD_SERIALIZED_LEN}, }; use dep::authwit::auth::{IS_VALID_SELECTOR, assert_current_call_valid_authwit_public, compute_authwit_message_hash}; @@ -45,10 +40,10 @@ contract Uniswap { context, 1, |context, slot| { - PublicState::new(context, slot, BoolSerializationMethods) + PublicState::new(context, slot) }, ), - nonce_for_burn_approval: PublicState::new(context, 2, FieldSerializationMethods), + nonce_for_burn_approval: PublicState::new(context, 2), } } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr index a850ff4814dd..c63635b67a34 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr @@ -5,7 +5,7 @@ use crate::{ }, hash::pedersen_hash, }; -use crate::traits::Empty; +use crate::traits::{Empty, Serialize, Deserialize}; // docs:start:block-header struct BlockHeader { @@ -25,17 +25,8 @@ impl Empty for BlockHeader { } } -impl BlockHeader { - pub fn assert_is_zero(self) { - assert(self.note_hash_tree_root == 0); - assert(self.nullifier_tree_root == 0); - assert(self.contract_tree_root == 0); - assert(self.l1_to_l2_message_tree_root == 0); - assert(self.archive_root == 0); - assert(self.public_data_tree_root == 0); - } - - pub fn serialize(self) -> [Field; BLOCK_HEADER_LENGTH] { +impl Serialize for BlockHeader { + fn serialize(self) -> [Field; BLOCK_HEADER_LENGTH] { // This comment was copied from the cpp codebase. // // TODO(#3441): Note private_kernel_vk_tree_root, is not included yet as @@ -50,8 +41,10 @@ impl BlockHeader { self.global_variables_hash ] } +} - pub fn deserialize(deserialized: [Field; BLOCK_HEADER_LENGTH]) -> Self { +impl Deserialize for BlockHeader { + fn deserialize(deserialized: [Field; BLOCK_HEADER_LENGTH]) -> Self { BlockHeader { note_hash_tree_root: deserialized[0], nullifier_tree_root: deserialized[1], @@ -62,6 +55,17 @@ impl BlockHeader { global_variables_hash: deserialized[6], } } +} + +impl BlockHeader { + pub fn assert_is_zero(self) { + assert(self.note_hash_tree_root == 0); + assert(self.nullifier_tree_root == 0); + assert(self.contract_tree_root == 0); + assert(self.l1_to_l2_message_tree_root == 0); + assert(self.archive_root == 0); + assert(self.public_data_tree_root == 0); + } pub fn note_hash_tree_root(self) -> Field { self.note_hash_tree_root diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr index c9ddf6da8bea..93538f5248e6 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr @@ -1,5 +1,6 @@ use crate::utils::field::field_from_bytes; use dep::std::cmp::Eq; +use crate::traits::{Serialize, Deserialize}; global SELECTOR_SIZE = 4; @@ -14,6 +15,20 @@ impl Eq for FunctionSelector { } } +impl Serialize<1> for FunctionSelector { + fn serialize(self: Self) -> [Field; 1] { + [self.inner as Field] + } +} + +impl Deserialize<1> for FunctionSelector { + fn deserialize(fields: [Field; 1]) -> Self { + Self { + inner: fields[0] as u32 + } + } +} + impl FunctionSelector { fn to_field(self) -> Field { self.inner as Field @@ -46,14 +61,4 @@ impl FunctionSelector { pub fn zero() -> Self { Self { inner: 0 } } - - pub fn serialize(self: Self) -> [Field; 1] { - [self.inner as Field] - } - - pub fn deserialize(fields: [Field; 1]) -> Self { - Self { - inner: fields[0] as u32 - } - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index 85b208776d36..d9604d7bc91f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -23,7 +23,7 @@ use crate::constants::{ PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS, }; -use crate::traits::Hash; +use crate::traits::{Hash, Serialize, Deserialize}; struct PrivateCircuitPublicInputs { call_context: CallContext, @@ -92,7 +92,7 @@ impl Hash for PrivateCircuitPublicInputs { } } -impl PrivateCircuitPublicInputs { +impl Serialize for PrivateCircuitPublicInputs { fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] { let mut fields: BoundedVec = BoundedVec::new(0); fields.push_array(self.call_context.serialize()); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr index 3303ef4539f8..f49b429a417c 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr @@ -1,6 +1,6 @@ use crate::constants::{GENERATOR_INDEX__SIDE_EFFECT}; use dep::std::cmp::Eq; -use crate::traits::{Empty, Hash}; +use crate::traits::{Empty, Hash, Serialize, Deserialize}; trait Ordered { fn counter(self) -> u32; @@ -40,18 +40,22 @@ impl Hash for SideEffect { } } -impl SideEffect { - pub fn serialize(self) -> [Field; 2] { +impl Serialize<2> for SideEffect { + fn serialize(self) -> [Field; 2] { [self.value, self.counter as Field] } +} - pub fn deserialise(values: [Field; 2]) -> Self { +impl Deserialize<2> for SideEffect { + fn deserialize(values: [Field; 2]) -> Self { Self { value: values[0], counter: values[1] as u32, } } +} +impl SideEffect { pub fn is_empty(self) -> bool { (self.value == 0) & (self.counter == 0) @@ -96,19 +100,23 @@ impl Hash for SideEffectLinkedToNoteHash { } } -impl SideEffectLinkedToNoteHash{ - pub fn serialize(self) -> [Field; 3] { +impl Serialize<3> for SideEffectLinkedToNoteHash { + fn serialize(self) -> [Field; 3] { [self.value, self.note_hash, self.counter as Field] } +} - pub fn deserialise(values: [Field; 3]) -> Self { +impl Deserialize<3> for SideEffectLinkedToNoteHash { + fn deserialize(values: [Field; 3]) -> Self { Self { value: values[0], note_hash: values[1], counter: values[2] as u32, } } +} +impl SideEffectLinkedToNoteHash{ pub fn is_empty(self) -> bool { (self.value == 0) & (self.note_hash == 0) diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr index 14706b5bd149..0f581c0507b4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr @@ -8,7 +8,8 @@ use crate::{ grumpkin_point::GrumpkinPoint, }; use dep::std::cmp::Eq; -use crate::traits::{Empty, ToField}; +use crate::traits::{Empty, ToField, Serialize, Deserialize}; +use crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN}; // Aztec address struct AztecAddress { @@ -35,6 +36,18 @@ impl ToField for AztecAddress { } } +impl Serialize for AztecAddress { + fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] { + [self.to_field()] + } +} + +impl Deserialize for AztecAddress { + fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self { + AztecAddress::from_field(fields[0]) + } +} + impl AztecAddress { pub fn zero() -> Self { Self { @@ -71,16 +84,6 @@ impl AztecAddress { inner : result } } - - pub fn serialize(self: Self) -> [Field; 1] { - [self.inner] - } - - pub fn deserialize(fields: [Field; 1]) -> Self { - Self { - inner: fields[0] - } - } } struct EthAddress{ @@ -107,6 +110,20 @@ impl ToField for EthAddress { } } +impl Serialize for EthAddress { + fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] { + [self.inner] + } +} + +impl Deserialize for EthAddress { + fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self { + Self { + inner: fields[0] + } + } +} + impl EthAddress{ pub fn zero() -> Self { Self { @@ -134,16 +151,6 @@ impl EthAddress{ inner : result } } - - pub fn serialize(self: Self) -> [Field; 1] { - [self.inner] - } - - pub fn deserialize(fields: [Field; 1]) -> Self { - Self { - inner: fields[0] - } - } } // Partial address diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr index a0ef079d69a2..040aec6e2d35 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr @@ -5,7 +5,7 @@ use crate::constants::{ }; use crate::hash::pedersen_hash; use crate::grumpkin_point::GrumpkinPoint; -use crate::traits::Hash; +use crate::traits::{Hash, Serialize}; // docs:start:contract-deployment-data struct ContractDeploymentData { @@ -23,7 +23,7 @@ impl Hash for ContractDeploymentData { } } -impl ContractDeploymentData { +impl Serialize for ContractDeploymentData { fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] { [ self.deployer_public_key.x, @@ -34,7 +34,10 @@ impl ContractDeploymentData { self.portal_contract_address.to_field(), ] } +} +impl ContractDeploymentData { + fn assert_is_zero(self) { self.deployer_public_key.assert_is_zero(); assert(self.constructor_vk_hash == 0); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr index 0cfbc1cabb1c..ecd535c96ff9 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr @@ -6,7 +6,7 @@ use crate::{ hash::pedersen_hash, }; use dep::std::cmp::Eq; -use crate::traits::{Hash, Empty}; +use crate::traits::{Hash, Empty, Serialize}; struct StorageUpdateRequest{ storage_slot : Field, @@ -39,11 +39,13 @@ impl Hash for StorageUpdateRequest { } } -impl StorageUpdateRequest { - pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] { +impl Serialize for StorageUpdateRequest { + fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] { [self.storage_slot, self.old_value, self.new_value] } +} +impl StorageUpdateRequest { pub fn is_empty(self) -> bool { self.storage_slot == 0 } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/grumpkin_point.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/grumpkin_point.nr index 364d19a15490..e2a040b52a25 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/grumpkin_point.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/grumpkin_point.nr @@ -1,3 +1,5 @@ +use crate::traits::{Serialize, Deserialize}; + global GRUMPKIN_POINT_SERIALIZED_LEN: Field = 2; struct GrumpkinPoint { @@ -5,6 +7,12 @@ struct GrumpkinPoint { y: Field, } +impl Serialize for GrumpkinPoint { + fn serialize(self) -> [Field; GRUMPKIN_POINT_SERIALIZED_LEN] { + [self.x, self.y] + } +} + impl GrumpkinPoint { pub fn new(x: Field, y: Field) -> Self { Self { x, y } @@ -17,10 +25,6 @@ impl GrumpkinPoint { } } - fn serialize(self) -> [Field; GRUMPKIN_POINT_SERIALIZED_LEN] { - [self.x, self.y] - } - // TODO(David): Would be quite careful here as (0,0) is not a point // on the curve. A boolean flag may be the better approach here, // would also cost less constraints. It seems like we don't need to diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr index 1c3c82c15f15..276fa9a8b71b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr @@ -12,6 +12,7 @@ mod constants; mod mocked; mod hash; mod traits; +mod type_serialization; mod header; diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr index 68ad8e56ff68..a971611fb0fa 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -44,3 +44,11 @@ impl ToField for Field { self } } + +trait Serialize { + fn serialize(self) -> [Field; N]; +} + +trait Deserialize { + fn deserialize(fields: [Field; N]) -> Self; +} diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr new file mode 100644 index 000000000000..7bc12f02d275 --- /dev/null +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr @@ -0,0 +1,56 @@ +use crate::traits::{Serialize, Deserialize}; + +global BOOL_SERIALIZED_LEN: Field = 1; +global U32_SERIALIZED_LEN: Field = 1; +global U8_SERIALIZED_LEN: Field = 1; +global FIELD_SERIALIZED_LEN: Field = 1; +global AZTEC_ADDRESS_SERIALIZED_LEN = 1; +global ETH_ADDRESS_SERIALIZED_LEN = 1; + +impl Serialize for u32 { + fn serialize(self) -> [Field; U32_SERIALIZED_LEN] { + [self as Field] + } +} + +impl Deserialize for u32 { + fn deserialize(fields: [Field; U32_SERIALIZED_LEN]) -> Self { + fields[0] as u32 + } +} + +impl Serialize for u8 { + fn serialize(self) -> [Field; U32_SERIALIZED_LEN] { + [self as Field] + } +} + +impl Deserialize for u8 { + fn deserialize(fields: [Field; U8_SERIALIZED_LEN]) -> Self { + fields[0] as u8 + } +} + +impl Serialize for Field { + fn serialize(self) -> [Field; U32_SERIALIZED_LEN] { + [self] + } +} + +impl Deserialize for Field { + fn deserialize(fields: [Field; FIELD_SERIALIZED_LEN]) -> Self { + fields[0] + } +} + +impl Serialize for bool { + fn serialize(self) -> [Field; BOOL_SERIALIZED_LEN] { + [self as Field] + } +} + +impl Deserialize for bool { + fn deserialize(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool { + fields[0] as bool + } +} From 5bf66e1889c91b2fac1c4a20dc04734d0ddf03ae Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 18 Jan 2024 16:47:39 +0000 Subject: [PATCH 02/56] workaround --- yarn-project/aztec-nr/aztec/src/note/lifecycle.nr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr index aa06cadcbd99..0b1899a1e332 100644 --- a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr +++ b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr @@ -16,7 +16,7 @@ pub fn create_note( storage_slot: Field, note: &mut Note, broadcast: bool -) where Note: NoteInterface + Serialize + Deserialize { +) -> [Field; N] where Note: NoteInterface + Serialize + Deserialize { let contract_address = (*context).this_address(); let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true }; @@ -31,6 +31,8 @@ pub fn create_note( if broadcast { Note::broadcast(*note, context, storage_slot); } + // TODO: Not returning the serialized not makes the compiler crash + serialized_note } pub fn create_note_hash_from_public(context: &mut PublicContext, storage_slot: Field, note: &mut Note) where Note: NoteInterface { From 326375b56309797d016990413658acb1e83e2a46 Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 19 Jan 2024 10:09:24 +0000 Subject: [PATCH 03/56] more workarounds --- yarn-project/aztec-nr/aztec/src/note/lifecycle.nr | 7 +++---- yarn-project/aztec-nr/aztec/src/note/note_getter.nr | 3 ++- yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr | 6 ++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr index 0b1899a1e332..20a45907baad 100644 --- a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr +++ b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr @@ -16,14 +16,15 @@ pub fn create_note( storage_slot: Field, note: &mut Note, broadcast: bool -) -> [Field; N] where Note: NoteInterface + Serialize + Deserialize { +) where Note: NoteInterface + Serialize + Deserialize { let contract_address = (*context).this_address(); let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true }; Note::set_header(note, header); let inner_note_hash = compute_inner_note_hash(*note); - let serialized_note = Note::serialize(*note); + // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 + let serialized_note: [Field; N] = Note::serialize(*note); assert(notify_created_note(storage_slot, serialized_note, inner_note_hash) == 0); context.push_new_note_hash(inner_note_hash); @@ -31,8 +32,6 @@ pub fn create_note( if broadcast { Note::broadcast(*note, context, storage_slot); } - // TODO: Not returning the serialized not makes the compiler crash - serialized_note } pub fn create_note_hash_from_public(context: &mut PublicContext, storage_slot: Field, note: &mut Note) where Note: NoteInterface { diff --git a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr index 9523d75002eb..80982612915d 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr @@ -80,7 +80,8 @@ pub fn get_notes( let opt_note = opt_notes[i]; if opt_note.is_some() { let note = opt_note.unwrap_unchecked(); - let fields = note.serialize(); + // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 + let fields: [Field; N] = note.serialize(); check_note_header(*context, storage_slot, note); check_note_fields(fields, options.selects); if i != 0 { diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr index 8bcdf63ff877..cf2977f495ee 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr @@ -29,7 +29,8 @@ impl PublicState { // docs:start:public_state_struct_read pub fn read(self) -> T where T: Deserialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); - let fields = storage_read(self.storage_slot); + // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 + let fields: [Field; T_SERIALIZED_LEN] = storage_read(self.storage_slot); T::deserialize(fields) } // docs:end:public_state_struct_read @@ -37,7 +38,8 @@ impl PublicState { // docs:start:public_state_struct_write pub fn write(self, value: T) where T: Serialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); - let fields = T::serialize(value); + // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 + let fields: [Field; T_SERIALIZED_LEN] = T::serialize(value); storage_write(self.storage_slot, fields); } // docs:end:public_state_struct_write From e5098b4707e7a542306e52a369b0071136d848a5 Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 19 Jan 2024 10:51:10 +0000 Subject: [PATCH 04/56] added issue comments --- yarn-project/aztec-nr/aztec/src/note/lifecycle.nr | 2 ++ yarn-project/aztec-nr/aztec/src/note/utils.nr | 2 +- yarn-project/aztec-nr/aztec/src/oracle/notes.nr | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr index 20a45907baad..38c40f7f72bf 100644 --- a/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr +++ b/yarn-project/aztec-nr/aztec/src/note/lifecycle.nr @@ -20,6 +20,7 @@ pub fn create_note( let contract_address = (*context).this_address(); let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true }; + // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed Note::set_header(note, header); let inner_note_hash = compute_inner_note_hash(*note); @@ -38,6 +39,7 @@ pub fn create_note_hash_from_public(context: &mut PublicContext, storag let contract_address = (*context).this_address(); let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true }; + // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed Note::set_header(note, header); let inner_note_hash = compute_inner_note_hash(*note); diff --git a/yarn-project/aztec-nr/aztec/src/note/utils.nr b/yarn-project/aztec-nr/aztec/src/note/utils.nr index 152f329cee3e..c16a71fc1c33 100644 --- a/yarn-project/aztec-nr/aztec/src/note/utils.nr +++ b/yarn-project/aztec-nr/aztec/src/note/utils.nr @@ -66,7 +66,7 @@ pub fn compute_note_hash_and_nullifier( serialized_note: [Field; S] ) -> [Field; 4] where T: NoteInterface { let mut note = deserialize(arr_copy_slice(serialized_note, [0; N], 0)); - // TODO: traits with &mut self are not supported + // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed T::set_header((&mut note), note_header); let note_hash = note.compute_note_hash(); diff --git a/yarn-project/aztec-nr/aztec/src/oracle/notes.nr b/yarn-project/aztec-nr/aztec/src/oracle/notes.nr index 2f2a5edce3a2..0bb78bddcffe 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/notes.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/notes.nr @@ -101,6 +101,7 @@ unconstrained pub fn get_notes( let header = NoteHeader { contract_address, nonce, storage_slot, is_transient }; let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2); let mut note = Note::deserialize(serialized_note); + // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed Note::set_header(&mut note, header); placeholder_opt_notes[i] = Option::some(note); }; From bc6bd95fe9f8101ce635a500de64bbd93427e98c Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 22 Jan 2024 10:30:26 +0000 Subject: [PATCH 05/56] remove public state length --- .../aztec-nr/address-note/src/address_note.nr | 4 ++++ .../aztec-nr/aztec/src/oracle/storage.nr | 9 ++++++--- .../aztec/src/state_vars/public_state.nr | 10 +++++----- .../compressed-string/src/compressed_string.nr | 6 +++++- .../aztec-nr/field-note/src/field_note.nr | 4 ++++ yarn-project/aztec-nr/safe-math/src/safe_u120.nr | 4 ++++ .../aztec-nr/slow-updates-tree/src/slow_map.nr | 3 +++ .../aztec-nr/value-note/src/value_note.nr | 3 +++ .../contracts/benchmarking_contract/src/main.nr | 2 +- .../src/crates/types/src/abis/block_header.nr | 4 ++++ .../crates/types/src/abis/function_selector.nr | 4 ++++ .../src/crates/types/src/abis/side_effect.nr | 8 ++++++++ .../src/crates/types/src/address.nr | 8 ++++++++ .../src/crates/types/src/traits.nr | 2 ++ .../src/crates/types/src/type_serialization.nr | 16 ++++++++++++++++ 15 files changed, 77 insertions(+), 10 deletions(-) diff --git a/yarn-project/aztec-nr/address-note/src/address_note.nr b/yarn-project/aztec-nr/address-note/src/address_note.nr index 5a6ac6421b15..c4203eed9f21 100644 --- a/yarn-project/aztec-nr/address-note/src/address_note.nr +++ b/yarn-project/aztec-nr/address-note/src/address_note.nr @@ -46,6 +46,10 @@ impl Deserialize for AddressNote { header: NoteHeader::empty(), } } + + fn _sample() -> [Field; ADDRESS_NOTE_LEN] { + [0; ADDRESS_NOTE_LEN] + } } impl NoteInterface for AddressNote { diff --git a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr index 65a11b8eebe0..a9d2c3996d16 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr @@ -3,12 +3,15 @@ use dep::protocol_types::traits::{Deserialize, Serialize}; #[oracle(storageRead)] fn storage_read_oracle(_storage_slot: Field, _number_of_elements: Field) -> [Field; N] {} -unconstrained fn storage_read_oracle_wrapper(_storage_slot: Field) -> [Field; N] { +unconstrained fn storage_read_oracle_wrapper( + _storage_slot: Field, + _sample: [Field; N] +) -> [Field; N] { storage_read_oracle(_storage_slot, N) } -pub fn storage_read(storage_slot: Field) -> [Field; N] { - storage_read_oracle_wrapper(storage_slot) +pub fn storage_read(storage_slot: Field, _sample: [Field; N]) -> [Field; N] { + storage_read_oracle_wrapper(storage_slot, _sample) } #[oracle(storageWrite)] diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr index cf2977f495ee..2449baa8eef6 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr @@ -5,13 +5,13 @@ use dep::std::option::Option; use dep::protocol_types::traits::{Deserialize, Serialize}; // docs:start:public_state_struct -struct PublicState { +struct PublicState { context: Context, storage_slot: Field, } // docs:end:public_state_struct -impl PublicState { +impl PublicState { // docs:start:public_state_struct_new pub fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. @@ -27,16 +27,16 @@ impl PublicState { // docs:end:public_state_struct_new // docs:start:public_state_struct_read - pub fn read(self) -> T where T: Deserialize { + pub fn read(self) -> T where T: Deserialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 - let fields: [Field; T_SERIALIZED_LEN] = storage_read(self.storage_slot); + let fields: [Field; T_SERIALIZED_LEN] = storage_read(self.storage_slot, T::_sample()); T::deserialize(fields) } // docs:end:public_state_struct_read // docs:start:public_state_struct_write - pub fn write(self, value: T) where T: Serialize { + pub fn write(self, value: T) where T: Serialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 let fields: [Field; T_SERIALIZED_LEN] = T::serialize(value); diff --git a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr index 7240491f41fd..88eb9d54b85c 100644 --- a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr +++ b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr @@ -17,9 +17,13 @@ impl Serialize<1> for FieldCompressedString { } impl Deserialize<1> for FieldCompressedString { -fn deserialize(input: [Field; 1]) -> Self { + fn deserialize(input: [Field; 1]) -> Self { Self { value: input[0] } } + + fn _sample() -> [Field; 1] { + [0; 1] + } } impl FieldCompressedString{ diff --git a/yarn-project/aztec-nr/field-note/src/field_note.nr b/yarn-project/aztec-nr/field-note/src/field_note.nr index 9b451308b741..4639296b9070 100644 --- a/yarn-project/aztec-nr/field-note/src/field_note.nr +++ b/yarn-project/aztec-nr/field-note/src/field_note.nr @@ -31,6 +31,10 @@ impl Deserialize for FieldNote { header: NoteHeader::empty(), } } + + fn _sample() -> [Field; 1] { + [0; 1] + } } impl NoteInterface for FieldNote { diff --git a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr index 4ef341bf8393..0ef71b51dbf7 100644 --- a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr +++ b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr @@ -27,6 +27,10 @@ impl Deserialize for SafeU120 { fn deserialize(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 { SafeU120 { value: fields[0] as u120 } } + + fn _sample() -> [Field; 1] { + [0; 1] + } } impl SafeU120 { diff --git a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr index 065ab009197f..1d7660615577 100644 --- a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr +++ b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr @@ -29,6 +29,9 @@ impl Deserialize<3> for Leaf { fn deserialize(serialized: [Field; 3]) -> Leaf { Leaf { next_change: serialized[0], before: serialized[1], after: serialized[2] } } + fn _sample() -> [Field; 3] { + [0; 3] + } } // Subset of the MembershipProof that is needed for the slow update. diff --git a/yarn-project/aztec-nr/value-note/src/value_note.nr b/yarn-project/aztec-nr/value-note/src/value_note.nr index f686385cf283..e85a117e413d 100644 --- a/yarn-project/aztec-nr/value-note/src/value_note.nr +++ b/yarn-project/aztec-nr/value-note/src/value_note.nr @@ -44,6 +44,9 @@ impl Deserialize for ValueNote { header: NoteHeader::empty(), } } + fn _sample() -> [Field; 3] { + [0; 3] + } } impl NoteInterface for ValueNote { diff --git a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr index e8f15bcc173d..0afbfccc8f45 100644 --- a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -24,7 +24,7 @@ contract Benchmarking { struct Storage { notes: Map>, - balances: Map>, + balances: Map>, } impl Storage { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr index c63635b67a34..d3f1e2976621 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr @@ -55,6 +55,10 @@ impl Deserialize for BlockHeader { global_variables_hash: deserialized[6], } } + + fn _sample() -> [Field; BLOCK_HEADER_LENGTH] { + [0; BLOCK_HEADER_LENGTH] + } } impl BlockHeader { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr index 93538f5248e6..7d792bb6c0c9 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr @@ -27,6 +27,10 @@ impl Deserialize<1> for FunctionSelector { inner: fields[0] as u32 } } + + fn _sample() -> [Field; 1] { + [0; 1] + } } impl FunctionSelector { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr index f49b429a417c..35efba11c8f3 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr @@ -53,6 +53,10 @@ impl Deserialize<2> for SideEffect { counter: values[1] as u32, } } + + fn _sample() -> [Field; 2] { + [0; 2] + } } impl SideEffect { @@ -114,6 +118,10 @@ impl Deserialize<3> for SideEffectLinkedToNoteHash { counter: values[2] as u32, } } + + fn _sample() -> [Field; 3] { + [0; 3] + } } impl SideEffectLinkedToNoteHash{ diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr index 0f581c0507b4..b7187c510329 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr @@ -46,6 +46,10 @@ impl Deserialize for AztecAddress { fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self { AztecAddress::from_field(fields[0]) } + + fn _sample() -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] { + [0; AZTEC_ADDRESS_SERIALIZED_LEN] + } } impl AztecAddress { @@ -122,6 +126,10 @@ impl Deserialize for EthAddress { inner: fields[0] } } + + fn _sample() -> [Field; ETH_ADDRESS_SERIALIZED_LEN] { + [0; ETH_ADDRESS_SERIALIZED_LEN] + } } impl EthAddress{ diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr index a971611fb0fa..1c196089d081 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -51,4 +51,6 @@ trait Serialize { trait Deserialize { fn deserialize(fields: [Field; N]) -> Self; + + fn _sample() -> [Field; N]; } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr index 7bc12f02d275..bc768b288c8c 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr @@ -17,6 +17,10 @@ impl Deserialize for u32 { fn deserialize(fields: [Field; U32_SERIALIZED_LEN]) -> Self { fields[0] as u32 } + + fn _sample() -> [Field; 1] { + [0] + } } impl Serialize for u8 { @@ -29,6 +33,10 @@ impl Deserialize for u8 { fn deserialize(fields: [Field; U8_SERIALIZED_LEN]) -> Self { fields[0] as u8 } + + fn _sample() -> [Field; 1] { + [0] + } } impl Serialize for Field { @@ -41,6 +49,10 @@ impl Deserialize for Field { fn deserialize(fields: [Field; FIELD_SERIALIZED_LEN]) -> Self { fields[0] } + + fn _sample() -> [Field; 1] { + [0] + } } impl Serialize for bool { @@ -53,4 +65,8 @@ impl Deserialize for bool { fn deserialize(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool { fields[0] as bool } + + fn _sample() -> [Field; 1] { + [0] + } } From fca8cf9583361a0c9326fb50d3ee4956a4dd1e0a Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 22 Jan 2024 11:26:22 +0000 Subject: [PATCH 06/56] fix: note len? --- .../aztec-nr/aztec/src/note/note_getter.nr | 3 +- .../aztec/src/note/note_getter_options.nr | 10 +++-- .../aztec/src/note/note_viewer_options.nr | 10 ++++- .../src/state_vars/immutable_singleton.nr | 11 +++--- .../aztec-nr/aztec/src/state_vars/set.nr | 10 ++--- .../aztec/src/state_vars/singleton.nr | 12 +++--- .../aztec-nr/value-note/src/balance_utils.nr | 4 +- yarn-project/aztec-nr/value-note/src/utils.nr | 16 ++------ .../benchmarking_contract/src/main.nr | 2 +- .../contracts/card_game_contract/src/cards.nr | 2 +- .../contracts/card_game_contract/src/game.nr | 4 ++ .../contracts/card_game_contract/src/main.nr | 7 ++-- .../docs_example_contract/src/actions.nr | 38 +++++++++---------- .../docs_example_contract/src/main.nr | 12 +++--- .../src/types/card_note.nr | 4 ++ .../src/types/profile_note.nr | 4 ++ .../docs_example_contract/src/types/queen.nr | 4 ++ .../src/types/rules_note.nr | 4 ++ .../contracts/test_contract/src/main.nr | 3 +- 19 files changed, 93 insertions(+), 67 deletions(-) diff --git a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr index 80982612915d..cd392e6cda84 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr @@ -56,8 +56,9 @@ fn check_notes_order( pub fn get_note( context: &mut PrivateContext, - storage_slot: Field + storage_slot: Field, ) -> Note where Note: NoteInterface + Deserialize { + let _sample: [Field; N] = Note::_sample(); let note = get_note_internal(storage_slot); check_note_header(*context, storage_slot, note); diff --git a/yarn-project/aztec-nr/aztec/src/note/note_getter_options.nr b/yarn-project/aztec-nr/aztec/src/note/note_getter_options.nr index 8ceca5eb03ea..342aad520a8b 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_getter_options.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_getter_options.nr @@ -1,6 +1,10 @@ use dep::std::option::Option; use crate::types::vec::BoundedVec; -use dep::protocol_types::constants::MAX_READ_REQUESTS_PER_CALL; +use dep::protocol_types::{ + constants::MAX_READ_REQUESTS_PER_CALL, + traits::Deserialize, +}; +use crate::note::note_interface::NoteInterface; struct Select { field_index: u8, @@ -58,7 +62,7 @@ struct NoteGetterOptions { // And finally, a custom filter to refine the outcome further. impl NoteGetterOptions { // This function initializes a NoteGetterOptions that simply returns the maximum number of notes allowed in a call. - pub fn new() -> NoteGetterOptions { + pub fn new() -> NoteGetterOptions where Note: NoteInterface + Deserialize { NoteGetterOptions { selects: BoundedVec::new(Option::none()), sorts: BoundedVec::new(Option::none()), @@ -74,7 +78,7 @@ impl NoteGetterOptions { pub fn with_filter( filter: fn ([Option; MAX_READ_REQUESTS_PER_CALL], FILTER_ARGS) -> [Option; MAX_READ_REQUESTS_PER_CALL], filter_args: FILTER_ARGS, - ) -> Self { + ) -> Self where Note: NoteInterface + Deserialize { NoteGetterOptions { selects: BoundedVec::new(Option::none()), sorts: BoundedVec::new(Option::none()), diff --git a/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr b/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr index 15d445d2c027..c3508e9c6608 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr @@ -1,7 +1,11 @@ use dep::std::option::Option; -use dep::protocol_types::constants::MAX_NOTES_PER_PAGE; use crate::note::note_getter_options::{Select, Sort}; use crate::types::vec::BoundedVec; +use dep::protocol_types::{ + constants::MAX_NOTES_PER_PAGE, + traits::Deserialize, +}; +use crate::note::note_interface::NoteInterface; // docs:start:NoteViewerOptions struct NoteViewerOptions { @@ -13,7 +17,9 @@ struct NoteViewerOptions { // docs:end:NoteViewerOptions impl NoteViewerOptions { - pub fn new() -> NoteViewerOptions { + pub fn new() -> NoteViewerOptions where Note: NoteInterface + Deserialize { + let _sample: [Field; N] = Note::_sample(); + NoteViewerOptions { selects: BoundedVec::new(Option::none()), sorts: BoundedVec::new(Option::none()), diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index eb8806ec470e..c44bdc65bbfa 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -15,14 +15,14 @@ use crate::oracle::notes::check_nullifier_exists; use crate::state_vars::singleton::compute_singleton_initialization_nullifier; // docs:start:struct -struct ImmutableSingleton { +struct ImmutableSingleton { context: Option<&mut PrivateContext>, storage_slot: Field, compute_initialization_nullifier: fn (Field, Option) -> Field, } // docs:end:struct -impl ImmutableSingleton { +impl ImmutableSingleton { // docs:start:new pub fn new( context: Context, @@ -46,7 +46,7 @@ impl ImmutableSingleton { // docs:end:is_initialized // docs:start:initialize - pub fn initialize( + pub fn initialize( self, note: &mut Note, owner: Option, @@ -69,7 +69,7 @@ impl ImmutableSingleton { // docs:end:initialize // docs:start:get_note - pub fn get_note(self) -> Note where Note: NoteInterface + Deserialize { + pub fn get_note(self) -> Note where Note: NoteInterface + Deserialize { let context = self.context.unwrap(); let storage_slot = self.storage_slot; get_note(context, storage_slot) @@ -77,7 +77,8 @@ impl ImmutableSingleton { // docs:end:get_note // docs:start:view_note - unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { + unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { + let _sample: [Field; N] = Note::_sample(); let options = NoteViewerOptions::new().set_limit(1); view_notes(self.storage_slot, options)[0].unwrap() } diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr index 16e381977f9e..489ccfad838d 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr @@ -17,13 +17,13 @@ use crate::note::{ }; // docs:start:struct -struct Set { +struct Set { context: Context, storage_slot: Field, } // docs:end:struct -impl Set { +impl Set { // docs:start:new pub fn new( context: Context, @@ -38,7 +38,7 @@ impl Set { // docs:end:new // docs:start:insert - pub fn insert(self, + pub fn insert(self, note: &mut Note, broadcast: bool, ) where Note: NoteInterface + Deserialize + Serialize { @@ -86,7 +86,7 @@ impl Set { // docs:end:remove // docs:start:get_notes - pub fn get_notes( + pub fn get_notes( self, options: NoteGetterOptions, ) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface + Serialize + Deserialize { @@ -101,7 +101,7 @@ impl Set { // docs:end:get_notes // docs:start:view_notes - unconstrained pub fn view_notes( + unconstrained pub fn view_notes( self, options: NoteViewerOptions, ) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface + Deserialize { diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 9de969bac43e..ab157f2f4cb6 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -34,14 +34,14 @@ pub fn compute_singleton_initialization_nullifier(storage_slot: Field, owner: Op } // docs:start:struct -struct Singleton { +struct Singleton { context: Option<&mut PrivateContext>, storage_slot: Field, compute_initialization_nullifier: fn (Field, Option) -> Field, } // docs:end:struct -impl Singleton { +impl Singleton { // docs:start:new pub fn new( context: Context, @@ -65,7 +65,7 @@ impl Singleton { // docs:end:is_initialized // docs:start:initialize - pub fn initialize( + pub fn initialize( self, note: &mut Note, owner: Option, @@ -83,7 +83,7 @@ impl Singleton { // docs:end:initialize // docs:start:replace - pub fn replace( + pub fn replace( self, new_note: &mut Note, broadcast: bool, @@ -100,7 +100,7 @@ impl Singleton { // docs:end:replace // docs:start:get_note - pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface + Serialize + Deserialize { + pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface + Serialize + Deserialize { let context = self.context.unwrap(); let mut note = get_note(context, self.storage_slot); @@ -116,7 +116,7 @@ impl Singleton { // docs:end:get_note // docs:start:view_note - unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { + unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { let options = NoteViewerOptions::new().set_limit(1); view_notes(self.storage_slot, options)[0].unwrap() } diff --git a/yarn-project/aztec-nr/value-note/src/balance_utils.nr b/yarn-project/aztec-nr/value-note/src/balance_utils.nr index cd577b97af7c..74c6c79272ee 100644 --- a/yarn-project/aztec-nr/value-note/src/balance_utils.nr +++ b/yarn-project/aztec-nr/value-note/src/balance_utils.nr @@ -5,11 +5,11 @@ use dep::aztec::note::{ use dep::aztec::state_vars::set::Set; use crate::value_note::{VALUE_NOTE_LEN, ValueNote}; -unconstrained pub fn get_balance(set: Set) -> Field { +unconstrained pub fn get_balance(set: Set) -> Field { get_balance_with_offset(set, 0) } -unconstrained pub fn get_balance_with_offset(set: Set, offset: u32) -> Field { +unconstrained pub fn get_balance_with_offset(set: Set, offset: u32) -> Field { let mut balance = 0; // docs:start:view_notes let options = NoteViewerOptions::new().set_offset(offset); diff --git a/yarn-project/aztec-nr/value-note/src/utils.nr b/yarn-project/aztec-nr/value-note/src/utils.nr index 277e0b114c3b..d7ef7c948dc5 100644 --- a/yarn-project/aztec-nr/value-note/src/utils.nr +++ b/yarn-project/aztec-nr/value-note/src/utils.nr @@ -17,7 +17,7 @@ pub fn create_note_getter_options_for_decreasing_balance(amount: Field) -> NoteG // Creates a new note for the recipient. // Inserts it to the recipient's set of notes. -pub fn increment(balance: Set, amount: Field, recipient: AztecAddress) { +pub fn increment(balance: Set, amount: Field, recipient: AztecAddress) { let mut note = ValueNote::new(amount, recipient); // Insert the new note to the owner's set of notes and emit the log if value is non-zero. balance.insert(&mut note, amount != 0); @@ -27,7 +27,7 @@ pub fn increment(balance: Set, amount: Field, recipie // Remove those notes. // If the value of the removed notes exceeds the requested `amount`, create a new note containing the excess value, so that exactly `amount` is removed. // Fail if the sum of the selected notes is less than the amount. -pub fn decrement(balance: Set, amount: Field, owner: AztecAddress) { +pub fn decrement(balance: Set, amount: Field, owner: AztecAddress) { let sum = decrement_by_at_most(balance, amount, owner); assert(sum == amount, "Balance too low"); } @@ -40,11 +40,7 @@ pub fn decrement(balance: Set, amount: Field, owner: // equal `amount`. // // It returns the decremented amount, which should be less than or equal to max_amount. -pub fn decrement_by_at_most( - balance: Set, - max_amount: Field, - owner: AztecAddress -) -> Field { +pub fn decrement_by_at_most(balance: Set, max_amount: Field, owner: AztecAddress) -> Field { let options = create_note_getter_options_for_decreasing_balance(max_amount); let opt_notes = balance.get_notes(options); @@ -68,11 +64,7 @@ pub fn decrement_by_at_most( // Removes the note from the owner's set of notes. // Returns the value of the destroyed note. -pub fn destroy_note( - balance: Set, - owner: AztecAddress, - note: ValueNote -) -> Field { +pub fn destroy_note(balance: Set, owner: AztecAddress, note: ValueNote) -> Field { // Ensure the note is actually owned by the owner (to prevent user from generating a valid proof while // spending someone else's notes). assert(note.owner.eq(owner)); diff --git a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr index 0afbfccc8f45..8b9bd1df4767 100644 --- a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -23,7 +23,7 @@ contract Benchmarking { }; struct Storage { - notes: Map>, + notes: Map>, balances: Map>, } diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr index e395f799cae2..bfd6ffecc091 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/cards.nr @@ -89,7 +89,7 @@ impl CardNote { } struct Deck { - set: Set, + set: Set, } pub fn filter_cards( diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr index 4e9c75a77f78..7ea6c9399e55 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr @@ -83,6 +83,10 @@ impl Deserialize for Game { current_round: fields[14] as u32 } } + + fn _sample() -> [Field; GAME_SERIALIZED_LEN] { + [0; GAME_SERIALIZED_LEN] + } } impl Game { diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr index 08c2d22597ca..bc1df87604d4 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr @@ -55,7 +55,7 @@ contract CardGame { struct Storage { collections: Map, game_decks: Map>, - games: Map>, + games: Map>, } impl Storage { @@ -242,7 +242,8 @@ contract CardGame { storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) + // let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + // note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) + dep::std::unsafe::zeroed() } } diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr index 16928b904605..56486b0e3681 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/actions.nr @@ -20,40 +20,40 @@ use crate::types::{ }; // docs:start:state_vars-PublicStateRead -pub fn is_locked(state_var: PublicState) -> bool { +pub fn is_locked(state_var: PublicState) -> bool { state_var.read() } // docs:end:state_vars-PublicStateRead // docs:start:state_vars-PublicStateWrite -pub fn lock(state_var: PublicState) { +pub fn lock(state_var: PublicState) { state_var.write(true); } // docs:end:state_vars-PublicStateWrite -pub fn unlock(state_var: PublicState) { +pub fn unlock(state_var: PublicState) { state_var.write(false); } // docs:start:state_vars-PublicStateReadCustom -pub fn get_current_queen(state_var: PublicState) -> Queen { +pub fn get_current_queen(state_var: PublicState) -> Queen { state_var.read() } // docs:end:state_vars-PublicStateReadCustom -pub fn can_replace_queen(state_var: PublicState, new_queen: Queen) -> bool { +pub fn can_replace_queen(state_var: PublicState, new_queen: Queen) -> bool { let current_queen = get_current_queen(state_var); new_queen.points > current_queen.points } // docs:start:state_vars-PublicStateWriteCustom -pub fn replace_queen(state_var: PublicState, new_queen: Queen) { +pub fn replace_queen(state_var: PublicState, new_queen: Queen) { state_var.write(new_queen); } // docs:end:state_vars-PublicStateWriteCustom // docs:start:state_vars-PublicStateReadWriteCustom -pub fn add_points_to_queen(state_var: PublicState, new_points: u8) { +pub fn add_points_to_queen(state_var: PublicState, new_points: u8) { let mut queen = state_var.read(); queen.points += new_points; state_var.write(queen); @@ -61,51 +61,51 @@ pub fn add_points_to_queen(state_var: PublicState, // docs:end:state_vars-PublicStateReadWriteCustom // docs:start:state_vars-SingletonInit -pub fn init_legendary_card(state_var: Singleton, card: &mut CardNote) { +pub fn init_legendary_card(state_var: Singleton, card: &mut CardNote) { state_var.initialize(card, Option::some(card.owner), true); } // docs:end:state_vars-SingletonInit // docs:start:state_vars-SingletonReplace -pub fn update_legendary_card(state_var: Singleton, card: &mut CardNote) { +pub fn update_legendary_card(state_var: Singleton, card: &mut CardNote) { state_var.replace(card, true); } // docs:end:state_vars-SingletonReplace // docs:start:state_vars-SingletonGet -pub fn get_legendary_card(state_var: Singleton) -> CardNote { +pub fn get_legendary_card(state_var: Singleton) -> CardNote { state_var.get_note(true) } // docs:end:state_vars-SingletonGet // docs:start:state_vars-ImmutableSingletonInit -pub fn init_game_rules(state_var: ImmutableSingleton, rules: &mut RulesNote) { +pub fn init_game_rules(state_var: ImmutableSingleton, rules: &mut RulesNote) { state_var.initialize(rules, Option::none(), true); } // docs:end:state_vars-ImmutableSingletonInit // docs:start:state_vars-ImmutableSingletonGet -pub fn is_valid_card(state_var: ImmutableSingleton, card: CardNote) -> bool { +pub fn is_valid_card(state_var: ImmutableSingleton, card: CardNote) -> bool { let rules = state_var.get_note(); card.points >= rules.min_points & card.points <= rules.max_points } // docs:end:state_vars-ImmutableSingletonGet // docs:start:state_vars-SetInsert -pub fn add_new_card(state_var: Set, card: &mut CardNote) { +pub fn add_new_card(state_var: Set, card: &mut CardNote) { state_var.insert(card, true); } // docs:end:state_vars-SetInsert // docs:start:state_vars-SetRemove -pub fn remove_card(state_var: Set, card: CardNote) { +pub fn remove_card(state_var: Set, card: CardNote) { state_var.remove(card); } // docs:end:state_vars-SetRemove // docs:start:state_vars-SetGet pub fn get_cards( - state_var: Set, + state_var: Set, options: NoteGetterOptions ) -> [Option; MAX_READ_REQUESTS_PER_CALL] { state_var.get_notes(options) @@ -114,14 +114,14 @@ pub fn get_cards( // docs:start:state_vars-SetView unconstrained pub fn view_cards( - state_var: Set, + state_var: Set, options: NoteViewerOptions ) -> [Option; MAX_NOTES_PER_PAGE] { state_var.view_notes(options) } // docs:end:state_vars-SetView -unconstrained pub fn get_total_points(state_var: Set, account: AztecAddress, offset: u32) -> u8 { +unconstrained pub fn get_total_points(state_var: Set, account: AztecAddress, offset: u32) -> u8 { let options = NoteViewerOptions::new().select(2, account.to_field()).set_offset(offset); let mut total_points = 0; let notes = view_cards(state_var, options); @@ -138,7 +138,7 @@ unconstrained pub fn get_total_points(state_var: Set, a // docs:start:state_vars-MapAtSingletonInit pub fn add_new_profile( - state_var: Map>, + state_var: Map>, account: AztecAddress, profile: &mut ProfileNote ) { @@ -148,7 +148,7 @@ pub fn add_new_profile( // docs:start:state_vars-MapAtSingletonGet pub fn get_profile( - state_var: Map>, + state_var: Map>, account: AztecAddress ) -> ProfileNote { state_var.at(account).get_note(true) diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index 282635a4551f..28c307f0f62f 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -29,15 +29,15 @@ contract DocsExample { // docs:start:storage-struct-declaration struct Storage { - locked: PublicState, - queen: PublicState, - game_rules: ImmutableSingleton, + locked: PublicState, + queen: PublicState, + game_rules: ImmutableSingleton, // docs:start:storage-singleton-declaration - legendary_card: Singleton, + legendary_card: Singleton, // docs:end:storage-singleton-declaration - cards: Set, + cards: Set, // docs:start:storage-map-singleton-declaration - profiles: Map>, + profiles: Map>, // docs:end:storage-map-singleton-declaration } // docs:end:storage-struct-declaration diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr index b3536558ac29..bd92dceb7bb5 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr @@ -43,6 +43,10 @@ impl Deserialize for CardNote { header: NoteHeader::empty(), } } + + fn _sample() -> [Field; CARD_NOTE_LEN] { + [0; CARD_NOTE_LEN] + } } impl NoteInterface for CardNote { diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr index 989012b4c211..532fdf695366 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr @@ -38,6 +38,10 @@ impl Deserialize for ProfileNote { header: NoteHeader::empty(), } } + + fn _sample() -> [Field; PROFILE_NOTE_LEN] { + [0; PROFILE_NOTE_LEN] + } } impl NoteInterface for ProfileNote { diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr index 039cdf2d6c0f..88eb8f05eb92 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr @@ -23,5 +23,9 @@ impl Deserialize for Queen { fn deserialize(fields: [Field; QUEEN_SERIALIZED_LEN]) -> Queen { Queen { account: AztecAddress::from_field(fields[0]), points: fields[1] as u8 } } + + fn _sample() -> [Field; QUEEN_SERIALIZED_LEN] { + [0; QUEEN_SERIALIZED_LEN] + } } // docs:end:state_vars-PublicStateCustomStruct diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr index b95c2fe63d09..43514ad002a1 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr @@ -38,6 +38,10 @@ impl Deserialize for RulesNote { header: NoteHeader::empty(), } } + + fn _sample() -> [Field; RULES_NOTE_LEN] { + [0; RULES_NOTE_LEN] + } } impl NoteInterface for RulesNote { diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index c2b3b7b51f26..acede1ab3133 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -42,7 +42,7 @@ contract Test { } struct Storage { - example_constant: ImmutableSingleton, + example_constant: ImmutableSingleton, } impl Storage { @@ -199,6 +199,7 @@ contract Test { unconstrained fn get_constant() -> pub Field { let constant = storage.example_constant.view_note(); constant.value + } // Purely exists for testing From 8e827e0729f970f5ce1cb5d61b2c8be794e91c5d Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 22 Jan 2024 15:00:32 +0100 Subject: [PATCH 07/56] compiler hints as workaround --- boxes/token/src/contracts/src/main.nr | 15 +++++++-------- .../src/contracts/src/types/balance_set.nr | 6 +++--- .../src/contracts/src/types/balances_map.nr | 4 ++-- .../src/contracts/src/types/token_note.nr | 5 +++++ .../contracts/src/types/transparent_note.nr | 5 +++++ .../aztec-nr/address-note/src/address_note.nr | 3 ++- yarn-project/aztec-nr/authwit/src/account.nr | 3 +-- .../aztec-nr/aztec/src/note/note_getter.nr | 5 +++-- .../aztec/src/note/note_viewer_options.nr | 2 -- .../aztec-nr/aztec/src/oracle/storage.nr | 6 +++--- .../src/state_vars/immutable_singleton.nr | 3 ++- .../aztec/src/state_vars/public_state.nr | 4 ++-- .../compressed-string/src/compressed_string.nr | 3 ++- .../src/easy_private_state.nr | 4 ++-- .../aztec-nr/field-note/src/field_note.nr | 3 ++- .../aztec-nr/safe-math/src/safe_u120.nr | 3 ++- .../aztec-nr/slow-updates-tree/src/slow_map.nr | 8 +++++--- .../aztec-nr/value-note/src/value_note.nr | 4 +++- .../contracts/card_game_contract/src/game.nr | 3 ++- .../contracts/child_contract/src/main.nr | 3 +-- .../src/types/card_note.nr | 3 ++- .../src/types/profile_note.nr | 3 ++- .../docs_example_contract/src/types/queen.nr | 3 ++- .../src/types/rules_note.nr | 3 ++- .../easy_private_voting_contract/src/main.nr | 9 ++++----- .../src/ecdsa_public_key_note.nr | 5 +++++ .../ecdsa_account_contract/src/main.nr | 2 +- .../contracts/escrow_contract/src/main.nr | 2 +- .../inclusion_proofs_contract/src/main.nr | 4 ++-- .../contracts/lending_contract/src/asset.nr | 5 +++++ .../contracts/lending_contract/src/main.nr | 15 +++++++-------- .../pending_commitments_contract/src/main.nr | 2 +- .../contracts/price_feed_contract/src/asset.nr | 5 +++++ .../contracts/price_feed_contract/src/main.nr | 4 ++-- .../schnorr_account_contract/src/main.nr | 2 +- .../src/public_key_note.nr | 5 +++++ .../stateful_test_contract/src/main.nr | 5 ++--- .../contracts/test_contract/src/main.nr | 1 - .../token_blacklist_contract/src/main.nr | 17 ++++++++--------- .../src/types/balance_set.nr | 4 ++-- .../src/types/token_note.nr | 5 +++++ .../src/types/transparent_note.nr | 5 +++++ .../token_bridge_contract/src/main.nr | 2 +- .../contracts/token_contract/src/main.nr | 18 +++++++++--------- .../token_contract/src/types/balance_set.nr | 4 ++-- .../token_contract/src/types/token_note.nr | 5 +++++ .../src/types/transparent_note.nr | 5 +++++ .../contracts/uniswap_contract/src/main.nr | 5 ++--- .../src/crates/types/src/abis/block_header.nr | 3 ++- .../crates/types/src/abis/function_selector.nr | 3 ++- .../src/crates/types/src/abis/side_effect.nr | 6 ++++-- .../src/crates/types/src/address.nr | 6 ++++-- .../src/crates/types/src/traits.nr | 3 ++- .../src/crates/types/src/type_serialization.nr | 12 ++++++++---- 54 files changed, 169 insertions(+), 104 deletions(-) diff --git a/boxes/token/src/contracts/src/main.nr b/boxes/token/src/contracts/src/main.nr index abfd639c0ff7..78f10d51da16 100644 --- a/boxes/token/src/contracts/src/main.nr +++ b/boxes/token/src/contracts/src/main.nr @@ -13,7 +13,7 @@ contract Token { // Libs use dep::std::option::Option; - use dep::safe_math::{SafeU120,SAFE_U120_SERIALIZED_LEN}; + use dep::safe_math::SafeU120; use dep::aztec::{ note::{ @@ -27,7 +27,6 @@ contract Token { protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, - type_serialization::{FIELD_SERIALIZED_LEN,BOOL_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN}, } }; @@ -41,7 +40,7 @@ contract Token { // docs:end:import_authwit use crate::types::{ - transparent_note::{TransparentNote, TRANSPARENT_NOTE_LEN}, + transparent_note::TransparentNote, token_note::{TokenNote, TOKEN_NOTE_LEN}, balances_map::{BalancesMap}, }; @@ -50,19 +49,19 @@ contract Token { // docs:start:storage_struct struct Storage { // docs:start:storage_admin - admin: PublicState, + admin: PublicState, // docs:end:storage_admin // docs:start:storage_minters - minters: Map>, + minters: Map>, // docs:end:storage_minters // docs:start:storage_balances balances: BalancesMap, // docs:end:storage_balances - total_supply: PublicState, + total_supply: PublicState, // docs:start:storage_pending_shields - pending_shields: Set, + pending_shields: Set, // docs:end:storage_pending_shields - public_balances: Map>, + public_balances: Map>, } // docs:end:storage_struct diff --git a/boxes/token/src/contracts/src/types/balance_set.nr b/boxes/token/src/contracts/src/types/balance_set.nr index 6053cdb939da..b52265b8ccd1 100644 --- a/boxes/token/src/contracts/src/types/balance_set.nr +++ b/boxes/token/src/contracts/src/types/balance_set.nr @@ -24,18 +24,18 @@ use dep::aztec::oracle::{ get_public_key::get_public_key, }; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; +use crate::types::token_note::TokenNote; // A set implementing standard manipulation of balances. // Does not require spending key, but only knowledge. // Spending key requirement should be enforced by the contract using this. struct BalanceSet { owner: AztecAddress, - set: Set + set: Set } impl BalanceSet { - pub fn new(set: Set, owner: AztecAddress) -> Self { + pub fn new(set: Set, owner: AztecAddress) -> Self { Self { owner, set, diff --git a/boxes/token/src/contracts/src/types/balances_map.nr b/boxes/token/src/contracts/src/types/balances_map.nr index 62a280d5a4c8..e8cb09f62a31 100644 --- a/boxes/token/src/contracts/src/types/balances_map.nr +++ b/boxes/token/src/contracts/src/types/balances_map.nr @@ -4,11 +4,11 @@ use crate::types::balance_set::BalanceSet; use dep::aztec::hash::pedersen_hash; use dep::aztec::protocol_types::address::AztecAddress; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; +use crate::types::token_note::TokenNote; use dep::aztec::state_vars::{map::Map, set::Set}; struct BalancesMap { - store: Map>, + store: Map>, } impl BalancesMap { diff --git a/boxes/token/src/contracts/src/types/token_note.nr b/boxes/token/src/contracts/src/types/token_note.nr index 1a7a50dd1f8c..d45c77fbcb50 100644 --- a/boxes/token/src/contracts/src/types/token_note.nr +++ b/boxes/token/src/contracts/src/types/token_note.nr @@ -55,6 +55,11 @@ impl Deserialize for TokenNote { header: NoteHeader::empty(), } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; TOKEN_NOTE_LEN] { + [0; TOKEN_NOTE_LEN] + } } impl NoteInterface for TokenNote { diff --git a/boxes/token/src/contracts/src/types/transparent_note.nr b/boxes/token/src/contracts/src/types/transparent_note.nr index b5f24834a0e3..df24ffd4e512 100644 --- a/boxes/token/src/contracts/src/types/transparent_note.nr +++ b/boxes/token/src/contracts/src/types/transparent_note.nr @@ -38,6 +38,11 @@ impl Deserialize for TransparentNote { header: NoteHeader::empty(), } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; TRANSPARENT_NOTE_LEN] { + [0; TRANSPARENT_NOTE_LEN] + } } impl NoteInterface for TransparentNote { diff --git a/yarn-project/aztec-nr/address-note/src/address_note.nr b/yarn-project/aztec-nr/address-note/src/address_note.nr index c4203eed9f21..213bbde9db56 100644 --- a/yarn-project/aztec-nr/address-note/src/address_note.nr +++ b/yarn-project/aztec-nr/address-note/src/address_note.nr @@ -47,7 +47,8 @@ impl Deserialize for AddressNote { } } - fn _sample() -> [Field; ADDRESS_NOTE_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; ADDRESS_NOTE_LEN] { [0; ADDRESS_NOTE_LEN] } } diff --git a/yarn-project/aztec-nr/authwit/src/account.nr b/yarn-project/aztec-nr/authwit/src/account.nr index c612dd7de382..790aee2b6621 100644 --- a/yarn-project/aztec-nr/authwit/src/account.nr +++ b/yarn-project/aztec-nr/authwit/src/account.nr @@ -1,6 +1,5 @@ use dep::aztec::context::{PrivateContext, PublicContext, Context}; use dep::aztec::state_vars::{map::Map, public_state::PublicState}; -use dep::aztec::protocol_types::type_serialization::BOOL_SERIALIZED_LEN; use crate::entrypoint::EntrypointPayload; use crate::auth::IS_VALID_SELECTOR; @@ -8,7 +7,7 @@ use crate::auth::IS_VALID_SELECTOR; struct AccountActions { context: Context, is_valid_impl: fn(&mut PrivateContext, Field) -> bool, - approved_action: Map>, + approved_action: Map>, } impl AccountActions { diff --git a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr index cd392e6cda84..4653204d7308 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr @@ -56,9 +56,10 @@ fn check_notes_order( pub fn get_note( context: &mut PrivateContext, - storage_slot: Field, + storage_slot: Field ) -> Note where Note: NoteInterface + Deserialize { - let _sample: [Field; N] = Note::_sample(); + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + let _deserialized_length_hint: [Field; N] = Note::_deserialized_length_hint(); let note = get_note_internal(storage_slot); check_note_header(*context, storage_slot, note); diff --git a/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr b/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr index c3508e9c6608..0c8fc9d20c21 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_viewer_options.nr @@ -18,8 +18,6 @@ struct NoteViewerOptions { impl NoteViewerOptions { pub fn new() -> NoteViewerOptions where Note: NoteInterface + Deserialize { - let _sample: [Field; N] = Note::_sample(); - NoteViewerOptions { selects: BoundedVec::new(Option::none()), sorts: BoundedVec::new(Option::none()), diff --git a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr index a9d2c3996d16..60e1b8521462 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr @@ -5,13 +5,13 @@ fn storage_read_oracle(_storage_slot: Field, _number_of_elements: Field) -> [ unconstrained fn storage_read_oracle_wrapper( _storage_slot: Field, - _sample: [Field; N] + _deserialized_length_hint: [Field; N] // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed ) -> [Field; N] { storage_read_oracle(_storage_slot, N) } -pub fn storage_read(storage_slot: Field, _sample: [Field; N]) -> [Field; N] { - storage_read_oracle_wrapper(storage_slot, _sample) +pub fn storage_read(storage_slot: Field, _deserialized_length_hint: [Field; N]) -> [Field; N] { + storage_read_oracle_wrapper(storage_slot, _deserialized_length_hint) } #[oracle(storageWrite)] diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index c44bdc65bbfa..17d87a489532 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -78,7 +78,8 @@ impl ImmutableSingleton { // docs:start:view_note unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { - let _sample: [Field; N] = Note::_sample(); + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + let _deserialized_length_hint: [Field; N] = Note::_deserialized_length_hint(); let options = NoteViewerOptions::new().set_limit(1); view_notes(self.storage_slot, options)[0].unwrap() } diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr index 2449baa8eef6..e843be8a0997 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr @@ -29,8 +29,8 @@ impl PublicState { // docs:start:public_state_struct_read pub fn read(self) -> T where T: Deserialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); - // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 - let fields: [Field; T_SERIALIZED_LEN] = storage_read(self.storage_slot, T::_sample()); + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + let fields: [Field; T_SERIALIZED_LEN] = storage_read(self.storage_slot, T::_deserialized_length_hint()); T::deserialize(fields) } // docs:end:public_state_struct_read diff --git a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr index 88eb9d54b85c..2cdc3226116e 100644 --- a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr +++ b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr @@ -21,7 +21,8 @@ impl Deserialize<1> for FieldCompressedString { Self { value: input[0] } } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0; 1] } } diff --git a/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr b/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr index 26cbef677e92..d6b6fbf650f4 100644 --- a/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr +++ b/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr @@ -6,12 +6,12 @@ use dep::aztec::{ }; use dep::value_note::{ filter::filter_notes_min_sum, - value_note::{ValueNote, VALUE_NOTE_LEN}, + value_note::ValueNote, }; struct EasyPrivateUint { context: Context, - set: Set, + set: Set, storage_slot: Field, } diff --git a/yarn-project/aztec-nr/field-note/src/field_note.nr b/yarn-project/aztec-nr/field-note/src/field_note.nr index 4639296b9070..5faeac602388 100644 --- a/yarn-project/aztec-nr/field-note/src/field_note.nr +++ b/yarn-project/aztec-nr/field-note/src/field_note.nr @@ -32,7 +32,8 @@ impl Deserialize for FieldNote { } } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0; 1] } } diff --git a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr index 0ef71b51dbf7..7f866d555d54 100644 --- a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr +++ b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr @@ -28,7 +28,8 @@ impl Deserialize for SafeU120 { SafeU120 { value: fields[0] as u120 } } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0; 1] } } diff --git a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr index 1d7660615577..3732cf3f06ea 100644 --- a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr +++ b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr @@ -29,7 +29,9 @@ impl Deserialize<3> for Leaf { fn deserialize(serialized: [Field; 3]) -> Leaf { Leaf { next_change: serialized[0], before: serialized[1], after: serialized[2] } } - fn _sample() -> [Field; 3] { + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 3] { [0; 3] } } @@ -114,7 +116,7 @@ impl SlowMap { } pub fn read_root(self: Self) -> Leaf { - let fields = storage_read(self.storage_slot); + let fields = storage_read(self.storage_slot, Leaf::_deserialized_length_hint()); Leaf::deserialize(fields) } @@ -145,7 +147,7 @@ impl SlowMap { // docs:start:read_leaf_at pub fn read_leaf_at(self: Self, key: Field) -> Leaf { let derived_storage_slot = pedersen_hash([self.storage_slot, key]); - let fields = storage_read(derived_storage_slot); + let fields = storage_read(derived_storage_slot, Leaf::_deserialized_length_hint()); Leaf::deserialize(fields) } // docs:end:read_leaf_at diff --git a/yarn-project/aztec-nr/value-note/src/value_note.nr b/yarn-project/aztec-nr/value-note/src/value_note.nr index e85a117e413d..76b908d6a973 100644 --- a/yarn-project/aztec-nr/value-note/src/value_note.nr +++ b/yarn-project/aztec-nr/value-note/src/value_note.nr @@ -44,7 +44,9 @@ impl Deserialize for ValueNote { header: NoteHeader::empty(), } } - fn _sample() -> [Field; 3] { + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 3] { [0; 3] } } diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr index 7ea6c9399e55..e355c45fc81d 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr @@ -84,7 +84,8 @@ impl Deserialize for Game { } } - fn _sample() -> [Field; GAME_SERIALIZED_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; GAME_SERIALIZED_LEN] { [0; GAME_SERIALIZED_LEN] } } diff --git a/yarn-project/noir-contracts/contracts/child_contract/src/main.nr b/yarn-project/noir-contracts/contracts/child_contract/src/main.nr index c96b609a2ab6..ee7213c46873 100644 --- a/yarn-project/noir-contracts/contracts/child_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/child_contract/src/main.nr @@ -7,7 +7,6 @@ contract Child { context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, state_vars::public_state::PublicState, - protocol_types::type_serialization::FIELD_SERIALIZED_LEN }; use dep::aztec::protocol_types::{ abis::function_selector::FunctionSelector, @@ -15,7 +14,7 @@ contract Child { }; struct Storage { - current_value: PublicState, + current_value: PublicState, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr index bd92dceb7bb5..59ab546725fb 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr @@ -44,7 +44,8 @@ impl Deserialize for CardNote { } } - fn _sample() -> [Field; CARD_NOTE_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; CARD_NOTE_LEN] { [0; CARD_NOTE_LEN] } } diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr index 532fdf695366..6c8e6e043df6 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/profile_note.nr @@ -39,7 +39,8 @@ impl Deserialize for ProfileNote { } } - fn _sample() -> [Field; PROFILE_NOTE_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; PROFILE_NOTE_LEN] { [0; PROFILE_NOTE_LEN] } } diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr index 88eb8f05eb92..b1a88e5ddd6b 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/queen.nr @@ -24,7 +24,8 @@ impl Deserialize for Queen { Queen { account: AztecAddress::from_field(fields[0]), points: fields[1] as u8 } } - fn _sample() -> [Field; QUEEN_SERIALIZED_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; QUEEN_SERIALIZED_LEN] { [0; QUEEN_SERIALIZED_LEN] } } diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr index 43514ad002a1..91644e40a416 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/rules_note.nr @@ -39,7 +39,8 @@ impl Deserialize for RulesNote { } } - fn _sample() -> [Field; RULES_NOTE_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; RULES_NOTE_LEN] { [0; RULES_NOTE_LEN] } } diff --git a/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index 59ef061c7446..c86460b469ca 100644 --- a/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -3,8 +3,7 @@ contract EasyPrivateVoting { use dep::aztec::{ protocol_types::{ abis::function_selector::FunctionSelector, - address::AztecAddress, - type_serialization::{BOOL_SERIALIZED_LEN, FIELD_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN}, + address::AztecAddress }, context::{PrivateContext, Context}, oracle::get_secret_key::get_secret_key, // used to compute nullifier @@ -13,9 +12,9 @@ contract EasyPrivateVoting { // docs:end:imports // docs:start:storage_struct struct Storage { - admin: PublicState, // admin can end vote - tally: Map>, // we will store candidate as key and number of votes as value - voteEnded: PublicState, // voteEnded is boolean + admin: PublicState, // admin can end vote + tally: Map>, // we will store candidate as key and number of votes as value + voteEnded: PublicState, // voteEnded is boolean } // docs:end:storage_struct // docs:start:storage_impl diff --git a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr index a353be620ed0..019b3e1fae24 100644 --- a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr +++ b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr @@ -72,6 +72,11 @@ impl Deserialize for EcdsaPublicKeyNote { EcdsaPublicKeyNote { x, y, owner: AztecAddress::from_field(serialized_note[4]), header: NoteHeader::empty() } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] { + [0; ECDSA_PUBLIC_KEY_NOTE_LEN] + } } impl NoteInterface for EcdsaPublicKeyNote { diff --git a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index cd97024d1bf2..4949cc7f5d15 100644 --- a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -27,7 +27,7 @@ contract EcdsaAccount { }; struct Storage { - public_key: ImmutableSingleton, + public_key: ImmutableSingleton, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr index a85115dbd14c..5ba68df9107c 100644 --- a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr @@ -24,7 +24,7 @@ contract Escrow { }; struct Storage { - owners: Set, + owners: Set, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index 465996624291..100d1d76212a 100644 --- a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -47,8 +47,8 @@ contract InclusionProofs { use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN}; struct Storage { - private_values: Map>, - public_value: PublicState, + private_values: Map>, + public_value: PublicState, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr b/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr index 5fbbb83a855f..449f8a3d467c 100644 --- a/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr +++ b/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr @@ -39,4 +39,9 @@ impl Deserialize for Asset { oracle: AztecAddress::from_field(fields[3]) } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; ASSET_SERIALIZED_LEN] { + [0; ASSET_SERIALIZED_LEN] + } } diff --git a/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr b/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr index e19b223d8070..9811f0919d13 100644 --- a/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr @@ -22,21 +22,20 @@ contract Lending { state_vars::{ map::Map, public_state::PublicState, - }, - protocol_types::type_serialization::FIELD_SERIALIZED_LEN + } }; - use crate::asset::{ASSET_SERIALIZED_LEN, Asset}; + use crate::asset::Asset; use crate::interest_math::compute_multiplier; use crate::helpers::{covered_by_collateral, DebtReturn, debt_updates, debt_value, compute_identifier}; use crate::interfaces::{Token, Lending, PriceFeed}; // Storage structure, containing all storage, and specifying what slots they use. struct Storage { - collateral_asset: PublicState, - stable_coin: PublicState, - assets: Map>, - collateral: Map>, - static_debt: Map>, // abusing keys very heavily + collateral_asset: PublicState, + stable_coin: PublicState, + assets: Map>, + collateral: Map>, + static_debt: Map>, // abusing keys very heavily } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr b/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr index c098794748e9..3878ae5134c5 100644 --- a/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr @@ -26,7 +26,7 @@ contract PendingCommitments { }; struct Storage { - balances: Map>, + balances: Map>, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr b/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr index 047705a1ace9..d320f53b99b2 100644 --- a/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr +++ b/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr @@ -16,4 +16,9 @@ impl Deserialize for Asset { fn deserialize(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { Asset { price: fields[0] as u120 } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; ASSET_SERIALIZED_LEN] { + [0; ASSET_SERIALIZED_LEN] + } } diff --git a/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr b/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr index adce254f283f..a72caab5e836 100644 --- a/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr @@ -10,11 +10,11 @@ contract PriceFeed { }, }; use dep::aztec::protocol_types::address::AztecAddress; - use crate::asset::{ASSET_SERIALIZED_LEN, Asset}; + use crate::asset::Asset; // Storage structure, containing all storage, and specifying what slots they use. struct Storage { - assets: Map>, + assets: Map>, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr index 25bb9e476869..2c18164c6a48 100644 --- a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -24,7 +24,7 @@ contract SchnorrAccount { struct Storage { // docs:start:storage - signing_public_key: ImmutableSingleton, + signing_public_key: ImmutableSingleton, // docs:end:storage } diff --git a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr index ecde4de17ed2..8bf8dc93915c 100644 --- a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr +++ b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr @@ -43,6 +43,11 @@ impl Deserialize for PublicKeyNote { header: NoteHeader::empty() } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; PUBLIC_KEY_NOTE_LEN] { + [0; PUBLIC_KEY_NOTE_LEN] + } } impl NoteInterface for PublicKeyNote { diff --git a/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr index e5a85c860812..cfca700e66e2 100644 --- a/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -14,12 +14,11 @@ contract StatefulTest { utils as note_utils, }, state_vars::{map::Map, public_state::PublicState, set::Set}, - protocol_types::type_serialization::FIELD_SERIALIZED_LEN, }; struct Storage { - notes: Map>, - public_values: Map>, + notes: Map>, + public_values: Map>, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index acede1ab3133..3cca00ff3d07 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -199,7 +199,6 @@ contract Test { unconstrained fn get_constant() -> pub Field { let constant = storage.example_constant.view_note(); constant.value - } // Purely exists for testing diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr index f7dd04a83124..a8aaca684473 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -16,7 +16,7 @@ contract TokenBlacklist { // Libs use dep::std::option::Option; - use dep::safe_math::{SafeU120,SAFE_U120_SERIALIZED_LEN}; + use dep::safe_math::SafeU120; use dep::aztec::protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, @@ -30,7 +30,6 @@ contract TokenBlacklist { context::{PrivateContext, PublicContext, Context}, hash::{compute_secret_hash}, state_vars::{map::Map, public_state::PublicState, set::Set, immutable_singleton::ImmutableSingleton}, - protocol_types::type_serialization::{FIELD_SERIALIZED_LEN, BOOL_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN}, }; use dep::field_note::field_note::{FieldNote, FIELD_NOTE_LEN}; @@ -43,7 +42,7 @@ contract TokenBlacklist { }; use crate::types::{ - transparent_note::{TransparentNote, TRANSPARENT_NOTE_LEN}, + transparent_note::TransparentNote, token_note::{TokenNote, TOKEN_NOTE_LEN}, balances_map::{BalancesMap}, roles::UserFlags, @@ -53,13 +52,13 @@ contract TokenBlacklist { // docs:end:interface struct Storage { - admin: PublicState, + admin: PublicState, balances: BalancesMap, - total_supply: PublicState, - pending_shields: Set, - public_balances: Map>, - slow_update: ImmutableSingleton, - public_slow_update: PublicState, + total_supply: PublicState, + pending_shields: Set, + public_balances: Map>, + slow_update: ImmutableSingleton, + public_slow_update: PublicState, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr index d11e5bb3769d..4e74017cda20 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balance_set.nr @@ -22,7 +22,7 @@ use dep::aztec::oracle::{ get_public_key::get_public_key, }; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; +use crate::types::token_note::TokenNote; // A set implementing standard manipulation of balances. // Does not require spending key, but only knowledge. @@ -30,7 +30,7 @@ use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; struct BalanceSet { context: Context, owner: AztecAddress, - set: Set + set: Set } impl BalanceSet { diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index dcc32a61f27e..f93098e90a39 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -51,6 +51,11 @@ impl Deserialize for TokenNote { header: NoteHeader::empty(), } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; TOKEN_NOTE_LEN] { + [0; TOKEN_NOTE_LEN] + } } impl NoteInterface for TokenNote { diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr index beaa61e6dd7c..83ca16f591d8 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr @@ -38,6 +38,11 @@ impl Deserialize for TransparentNote { header: NoteHeader::empty(), } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; TRANSPARENT_NOTE_LEN] { + [0; TRANSPARENT_NOTE_LEN] + } } impl NoteInterface for TransparentNote { diff --git a/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr index 92e5ea379cef..e7893ef8ceb5 100644 --- a/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -29,7 +29,7 @@ contract TokenBridge { // docs:start:token_bridge_storage_and_constructor // Storage structure, containing all storage, and specifying what slots they use. struct Storage { - token: PublicState, + token: PublicState, } impl Storage { diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index 27db93806fe0..b936c985b9b4 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -47,7 +47,7 @@ contract Token { // docs:end:import_authwit use crate::types::{ - transparent_note::{TransparentNote, TRANSPARENT_NOTE_LEN}, + transparent_note::TransparentNote, token_note::{TokenNote, TOKEN_NOTE_LEN}, balances_map::{BalancesMap} }; @@ -56,22 +56,22 @@ contract Token { // docs:start:storage_struct struct Storage { // docs:start:storage_admin - admin: PublicState, + admin: PublicState, // docs:end:storage_admin // docs:start:storage_minters - minters: Map>, + minters: Map>, // docs:end:storage_minters // docs:start:storage_balances balances: BalancesMap, // docs:end:storage_balances - total_supply: PublicState, + total_supply: PublicState, // docs:start:storage_pending_shields - pending_shields: Set, + pending_shields: Set, // docs:end:storage_pending_shields - public_balances: Map>, - symbol: PublicState, - name: PublicState, - decimals: PublicState, + public_balances: Map>, + symbol: PublicState, + name: PublicState, + decimals: PublicState, } // docs:end:storage_struct diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr index 4162caca1bfa..5dcb5e430421 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/balance_set.nr @@ -24,7 +24,7 @@ use dep::aztec::oracle::{ get_public_key::get_public_key, }; -use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; +use crate::types::token_note::TokenNote; // A set implementing standard manipulation of balances. // Does not require spending key, but only knowledge. @@ -32,7 +32,7 @@ use crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN}; struct BalanceSet { context: Context, owner: AztecAddress, - set: Set + set: Set } impl BalanceSet { diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr index 98064f8ed284..14bc2851f543 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -58,6 +58,11 @@ impl Deserialize for TokenNote { header: NoteHeader::empty(), } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; TOKEN_NOTE_LEN] { + [0; TOKEN_NOTE_LEN] + } } impl NoteInterface for TokenNote { diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr index ae7fb93f8a52..21c39e4cd58f 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr @@ -38,6 +38,11 @@ impl Deserialize for TransparentNote { header: NoteHeader::empty(), } } + + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; TRANSPARENT_NOTE_LEN] { + [0; TRANSPARENT_NOTE_LEN] + } } impl Empty for TransparentNote { diff --git a/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr b/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr index d15b22e8b2bc..c06630b6f922 100644 --- a/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -17,7 +17,6 @@ contract Uniswap { context::{PrivateContext, PublicContext, Context}, oracle::{context::get_portal_address}, state_vars::{map::Map, public_state::PublicState}, - protocol_types::type_serialization::{BOOL_SERIALIZED_LEN,FIELD_SERIALIZED_LEN}, }; use dep::authwit::auth::{IS_VALID_SELECTOR, assert_current_call_valid_authwit_public, compute_authwit_message_hash}; @@ -27,10 +26,10 @@ contract Uniswap { struct Storage { // like with account contracts, stores the approval message on a slot and tracks if they are active - approved_action: Map>, + approved_action: Map>, // tracks the nonce used to create the approval message for burning funds // gets incremented each time after use to prevent replay attacks - nonce_for_burn_approval: PublicState, + nonce_for_burn_approval: PublicState, } impl Storage { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr index d3f1e2976621..51f0c6ea8f63 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr @@ -56,7 +56,8 @@ impl Deserialize for BlockHeader { } } - fn _sample() -> [Field; BLOCK_HEADER_LENGTH] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; BLOCK_HEADER_LENGTH] { [0; BLOCK_HEADER_LENGTH] } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr index 7d792bb6c0c9..9f75985051af 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr @@ -28,7 +28,8 @@ impl Deserialize<1> for FunctionSelector { } } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0; 1] } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr index 35efba11c8f3..a783d6d88186 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr @@ -54,7 +54,8 @@ impl Deserialize<2> for SideEffect { } } - fn _sample() -> [Field; 2] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 2] { [0; 2] } } @@ -119,7 +120,8 @@ impl Deserialize<3> for SideEffectLinkedToNoteHash { } } - fn _sample() -> [Field; 3] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 3] { [0; 3] } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr index b7187c510329..356e5efbb8af 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr @@ -47,7 +47,8 @@ impl Deserialize for AztecAddress { AztecAddress::from_field(fields[0]) } - fn _sample() -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] { [0; AZTEC_ADDRESS_SERIALIZED_LEN] } } @@ -127,7 +128,8 @@ impl Deserialize for EthAddress { } } - fn _sample() -> [Field; ETH_ADDRESS_SERIALIZED_LEN] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; ETH_ADDRESS_SERIALIZED_LEN] { [0; ETH_ADDRESS_SERIALIZED_LEN] } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr index 1c196089d081..836267af638f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -52,5 +52,6 @@ trait Serialize { trait Deserialize { fn deserialize(fields: [Field; N]) -> Self; - fn _sample() -> [Field; N]; + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; N]; } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr index bc768b288c8c..265dff5b93f5 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr @@ -18,7 +18,8 @@ impl Deserialize for u32 { fields[0] as u32 } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0] } } @@ -34,7 +35,8 @@ impl Deserialize for u8 { fields[0] as u8 } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0] } } @@ -50,7 +52,8 @@ impl Deserialize for Field { fields[0] } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0] } } @@ -66,7 +69,8 @@ impl Deserialize for bool { fields[0] as bool } - fn _sample() -> [Field; 1] { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + fn _deserialized_length_hint() -> [Field; 1] { [0] } } From 84f448ef385066c42fccae345116604c9ccaee63 Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 22 Jan 2024 15:57:49 +0100 Subject: [PATCH 08/56] removed comment --- .../noir-contracts/contracts/card_game_contract/src/main.nr | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr index bc1df87604d4..545ee4afe162 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr @@ -242,8 +242,7 @@ contract CardGame { storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN] ) -> pub [Field; 4] { - // let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - // note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) - dep::std::unsafe::zeroed() + let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize, note_header, serialized_note) } } From ccb2ef2c1f5d9bd033969b04edaa92219be1b1b9 Mon Sep 17 00:00:00 2001 From: thunkar Date: Tue, 23 Jan 2024 08:22:40 +0100 Subject: [PATCH 09/56] merge changes --- .../contracts/docs_example_contract/src/main.nr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index 983179e6077b..398bf697e3d6 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -16,7 +16,7 @@ contract DocsExample { use dep::aztec::protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, - };∫ + }; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -28,13 +28,13 @@ contract DocsExample { // how to import methods from other files/folders within your workspace use crate::options::create_account_card_getter_options; use crate::types::{ - card_note::{CardNote, CardNoteMethods}, + card_note::{CardNote, CARD_NOTE_LEN}, leader::Leader, }; struct Storage { // Shows how to create a custom struct in Public - leader: PublicState, + leader: PublicState, // docs:start:storage-singleton-declaration legendary_card: Singleton, // docs:end:storage-singleton-declaration @@ -119,7 +119,7 @@ contract DocsExample { serialized_note: [Field; CARD_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(CardNoteMethods, note_header, serialized_note) + note_utils::compute_note_hash_and_nullifier(CardNote::deserialize, note_header, serialized_note) } /// Macro equivalence section From c4f65259d01b64f623b97b872e09ea685f3075df Mon Sep 17 00:00:00 2001 From: thunkar Date: Tue, 23 Jan 2024 12:24:19 +0100 Subject: [PATCH 10/56] WIP --- noir/aztec_macros/src/lib.rs | 80 +++++++++++++++++++ .../benchmarking_contract/src/main.nr | 16 ++-- .../contracts/test_contract/src/main.nr | 14 ++-- 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 7c62f8f81692..defd6ab4098a 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -13,6 +13,7 @@ use noirc_frontend::macros_api::{ use noirc_frontend::macros_api::{CrateId, FileId}; use noirc_frontend::macros_api::{MacroError, MacroProcessor}; use noirc_frontend::macros_api::{ModuleDefId, NodeInterner, SortedModule, StructId}; +use noirc_frontend::ConstructorExpression; pub struct AztecMacro; @@ -273,6 +274,17 @@ fn check_for_storage_definition(module: &SortedModule) -> bool { module.types.iter().any(|r#struct| r#struct.name.0.contents == "Storage") } +// Check to see if the user has defined a storage struct +fn check_for_storage_implementation(module: &SortedModule) -> bool { + module.impls.iter().any(|r#impl| match r#impl.object_type.typ.clone() { + UnresolvedTypeData::Named(path, _) => { + println!("{}", r#impl.methods[0].def.body); + path.segments.last().unwrap().0.contents == "Storage" + } + _ => false, + }) +} + // Check if "compute_note_hash_and_nullifier(AztecAddress,Field,Field,[Field; N]) -> [Field; 4]" is defined fn check_for_compute_note_hash_and_nullifier_definition(module: &SortedModule) -> bool { module.functions.iter().any(|func| { @@ -329,6 +341,12 @@ fn transform_module( // Check for a user defined storage struct let storage_defined = check_for_storage_definition(module); + let storage_implemented = check_for_storage_implementation(module); + + if storage_defined && !storage_implemented { + generate_storage_implementation(module); + } + if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(module) { let crate_graph = &context.crate_graph[crate_id]; return Err(( @@ -389,6 +407,68 @@ fn transform_module( Ok(has_transformed_module) } +fn generate_storage_implementation(module: &mut SortedModule) { + let definition = + module.types.iter().find(|r#struct| r#struct.name.0.contents == "Storage").unwrap(); + + println!("Storage definition: {:?}", definition); + + let storage_constructor_statement = + make_statement(StatementKind::Expression(expression(ExpressionKind::constructor(( + chained_path!("Storage"), + definition + .fields + .iter() + .map(|f| { + if let UnresolvedTypeData::Named(path, _args) = &f.1.typ { + let mut new_path = path.clone(); + new_path.segments.push(ident("new")); + let expression = call( + variable_path(new_path), + vec![], // args + ); + Some((f.0.clone(), expression)) + } else { + None + } + }) + .flatten() + .collect(), + ))))); + + let init = NoirFunction::normal(FunctionDefinition::normal( + &ident("init"), + &vec![], + &vec![( + ident("context"), + UnresolvedType { + typ: UnresolvedTypeData::Named( + chained_path!("aztec", "context", "Context"), + vec![], + ), + span: Some(Span::default()), + }, + )], + &BlockExpression(vec![storage_constructor_statement]), + &vec![], + &FunctionReturnType::Ty(UnresolvedType { + typ: UnresolvedTypeData::Named(chained_path!("Self"), vec![]), + span: Some(Span::default()), + }), + )); + + let storage_impl = TypeImpl { + object_type: UnresolvedType { + typ: UnresolvedTypeData::Named(chained_path!("Storage"), vec![]), + span: Some(Span::default()), + }, + type_span: Span::default(), + generics: vec![], + methods: vec![init], + }; + module.impls.push(storage_impl); +} + /// If it does, it will insert the following things: /// - A new Input that is provided for a kernel app circuit, named: {Public/Private}ContextInputs /// - Hashes all of the function input variables diff --git a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr index 8b9bd1df4767..86dc770fcf44 100644 --- a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -27,14 +27,14 @@ contract Benchmarking { balances: Map>, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - notes: Map::new(context, 1, |context, slot| { Set::new(context, slot) }), - balances: Map::new(context, 2, |context, slot| { PublicState::new(context, slot) }), - } - } - } + // impl Storage { + // fn init(context: Context) -> Self { + // Storage { + // notes: Map::new(context, 1, |context, slot| { Set::new(context, slot) }), + // balances: Map::new(context, 2, |context, slot| { PublicState::new(context, slot) }), + // } + // } + // } #[aztec(private)] fn constructor() {} diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index 3cca00ff3d07..50a89097fde8 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -45,13 +45,13 @@ contract Test { example_constant: ImmutableSingleton, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - example_constant: ImmutableSingleton::new(context, 1), - } - } - } + // impl Storage { + // fn init(context: Context) -> Self { + // Storage { + // example_constant: ImmutableSingleton::new(context, 1), + // } + // } + // } #[aztec(private)] // docs:start:empty-constructor From 792d0d6639897014e0ea50605790a3920736a996 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 15:31:56 +0100 Subject: [PATCH 11/56] initial auto storage implementation --- noir/aztec_macros/src/lib.rs | 304 ++++++++++++++++-- .../noirc_frontend/src/node_interner.rs | 29 +- .../benchmarking_contract/src/main.nr | 9 - .../contracts/child_contract/src/main.nr | 11 - .../contracts/counter_contract/src/main.nr | 16 - .../docs_example_contract/src/main.nr | 24 -- .../easy_private_token_contract/src/main.nr | 16 +- .../easy_private_voting_contract/src/main.nr | 26 +- .../ecdsa_account_contract/src/main.nr | 8 - .../contracts/escrow_contract/src/main.nr | 8 - .../inclusion_proofs_contract/src/main.nr | 18 -- .../contracts/lending_contract/src/main.nr | 45 --- .../pending_commitments_contract/src/main.nr | 14 - .../contracts/price_feed_contract/src/main.nr | 17 - .../schnorr_account_contract/src/main.nr | 10 - .../contracts/slow_tree_contract/src/main.nr | 17 - .../stateful_test_contract/src/main.nr | 24 -- .../contracts/test_contract/src/main.nr | 8 - .../token_bridge_contract/src/main.nr | 11 - .../contracts/token_contract/src/main.nr | 26 +- .../contracts/uniswap_contract/src/main.nr | 15 - 21 files changed, 313 insertions(+), 343 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index defd6ab4098a..a542da50e5be 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -1,5 +1,6 @@ -use iter_extended::vecmap; +use std::borrow::{Borrow, BorrowMut}; +use iter_extended::vecmap; use noirc_frontend::macros_api::FieldElement; use noirc_frontend::macros_api::{ BlockExpression, CallExpression, CastExpression, Distinctness, Expression, ExpressionKind, @@ -13,7 +14,8 @@ use noirc_frontend::macros_api::{ use noirc_frontend::macros_api::{CrateId, FileId}; use noirc_frontend::macros_api::{MacroError, MacroProcessor}; use noirc_frontend::macros_api::{ModuleDefId, NodeInterner, SortedModule, StructId}; -use noirc_frontend::ConstructorExpression; +use noirc_frontend::node_interner::{TraitId, TraitImplKind}; +use noirc_frontend::Lambda; pub struct AztecMacro; @@ -42,6 +44,8 @@ pub enum AztecMacroError { AztecContractHasTooManyFunctions { span: Span }, AztecContractConstructorMissing { span: Span }, UnsupportedFunctionArgumentType { span: Span, typ: UnresolvedTypeData }, + UnsupportedStorageType { span: Option, typ: UnresolvedTypeData }, + CouldNotAssignStorageSlots { secondary_message: Option }, } impl From for MacroError { @@ -72,6 +76,16 @@ impl From for MacroError { secondary_message: None, span: Some(span), }, + AztecMacroError::UnsupportedStorageType { span, typ } => MacroError { + primary_message: format!("Provided storage type `{typ:?}` is not directly supported in Aztec. Please provide a custom storage implementation"), + secondary_message: None, + span, + }, + AztecMacroError::CouldNotAssignStorageSlots { secondary_message } => MacroError { + primary_message: format!("Could not assign storage slots, please provide a custom storage implementation"), + secondary_message, + span: None, + }, } } } @@ -238,6 +252,7 @@ fn transform( /// Completes the Hir with data gathered from type resolution fn transform_hir(crate_id: &CrateId, context: &mut HirContext) { transform_events(crate_id, context); + assign_storage_slots(crate_id, context).unwrap(); } /// Includes an import to the aztec library if it has not been included yet @@ -277,10 +292,7 @@ fn check_for_storage_definition(module: &SortedModule) -> bool { // Check to see if the user has defined a storage struct fn check_for_storage_implementation(module: &SortedModule) -> bool { module.impls.iter().any(|r#impl| match r#impl.object_type.typ.clone() { - UnresolvedTypeData::Named(path, _) => { - println!("{}", r#impl.methods[0].def.body); - path.segments.last().unwrap().0.contents == "Storage" - } + UnresolvedTypeData::Named(path, _) => path.segments.last().unwrap().0.contents == "Storage", _ => false, }) } @@ -340,15 +352,17 @@ fn transform_module( // Check for a user defined storage struct let storage_defined = check_for_storage_definition(module); - let storage_implemented = check_for_storage_implementation(module); + let crate_graph = &context.crate_graph[crate_id]; + if storage_defined && !storage_implemented { - generate_storage_implementation(module); + if let Err(err) = generate_storage_implementation(module) { + return Err((err.into(), crate_graph.root_file_id)); + } } if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(module) { - let crate_graph = &context.crate_graph[crate_id]; return Err(( AztecMacroError::AztecComputeNoteHashAndNullifierNotFound { span: Span::default() } .into(), @@ -407,34 +421,93 @@ fn transform_module( Ok(has_transformed_module) } -fn generate_storage_implementation(module: &mut SortedModule) { +fn generate_storage_field_constructor( + fields: &Vec<(Ident, UnresolvedType)>, +) -> Result, AztecMacroError> { + let mut field_constructors = vec![]; + + for field in fields.iter() { + if let UnresolvedTypeData::Named(path, args) = &field.1.typ { + let args = match path.segments.last().unwrap().0.contents.as_str() { + "PublicState" | "Set" | "Singleton" | "ImmutableSingleton" => { + vec![ + variable("context"), + expression(ExpressionKind::Literal(Literal::Integer( + FieldElement::from(i128::from(0)), + false, + ))), + ] + } + "Map" => { + let mut mapped_struct_path = match args + .last() + .and_then(|unresolved_type| Some(unresolved_type.typ.clone())) + { + Some(UnresolvedTypeData::Named(path, _)) => Ok(path), + _ => Err(AztecMacroError::UnsupportedStorageType { + typ: field.1.typ.clone(), + span: field.1.span, + }), + }?; + + mapped_struct_path.segments.push(ident("new")); + + vec![ + variable("context"), + expression(ExpressionKind::Literal(Literal::Integer( + FieldElement::from(i128::from(0)), + false, + ))), + expression(ExpressionKind::Lambda(Box::new(Lambda { + parameters: vec![ + ( + Pattern::Identifier(ident("context")), + make_type(UnresolvedTypeData::Named( + chained_path!("aztec", "context", "Context"), + vec![], + )), + ), + ( + Pattern::Identifier(ident("slot")), + make_type(UnresolvedTypeData::FieldElement), + ), + ], + return_type: UnresolvedType { + typ: UnresolvedTypeData::Unspecified, + span: Some(Span::default()), + }, + body: call( + variable_path(mapped_struct_path), + vec![variable("context"), variable("slot")], + ), + }))), + ] + } + _ => { + return Err(AztecMacroError::UnsupportedStorageType { + typ: field.1.typ.clone(), + span: field.1.span, + }) + } + }; + let mut new_path = path.clone(); + new_path.segments.push(ident("new")); + let expression = call(variable_path(new_path), args); + field_constructors.push((field.0.clone(), expression)); + } + } + Ok(field_constructors) +} + +fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), AztecMacroError> { let definition = module.types.iter().find(|r#struct| r#struct.name.0.contents == "Storage").unwrap(); - println!("Storage definition: {:?}", definition); - - let storage_constructor_statement = - make_statement(StatementKind::Expression(expression(ExpressionKind::constructor(( - chained_path!("Storage"), - definition - .fields - .iter() - .map(|f| { - if let UnresolvedTypeData::Named(path, _args) = &f.1.typ { - let mut new_path = path.clone(); - new_path.segments.push(ident("new")); - let expression = call( - variable_path(new_path), - vec![], // args - ); - Some((f.0.clone(), expression)) - } else { - None - } - }) - .flatten() - .collect(), - ))))); + let field_constructors = generate_storage_field_constructor(&definition.fields)?; + + let storage_constructor_statement = make_statement(StatementKind::Expression(expression( + ExpressionKind::constructor((chained_path!("Storage"), field_constructors)), + ))); let init = NoirFunction::normal(FunctionDefinition::normal( &ident("init"), @@ -467,6 +540,8 @@ fn generate_storage_implementation(module: &mut SortedModule) { methods: vec![init], }; module.impls.push(storage_impl); + + Ok(()) } /// If it does, it will insert the following things: @@ -550,6 +625,23 @@ fn collect_crate_structs(crate_id: &CrateId, context: &HirContext) -> Vec Vec { + let crates = context.crates(); + crates + .flat_map(|crate_id| context.def_map(&crate_id).and_then(|def_map| Some(def_map.modules()))) + .flatten() + .flat_map(|(_, module)| { + module.type_definitions().filter_map(|typ| { + if let ModuleDefId::TraitId(struct_id) = typ { + Some(struct_id) + } else { + None + } + }) + }) + .collect() +} + /// Substitutes the signature literal that was introduced in the selector method previously with the actual signature. fn transform_event(struct_id: StructId, interner: &mut NodeInterner) { let struct_type = interner.get_struct(struct_id); @@ -611,6 +703,150 @@ fn transform_events(crate_id: &CrateId, context: &mut HirContext) { } } +fn get_serialized_length( + serialize_traits: &Vec, + typ: &Type, + interner: &NodeInterner, +) -> Result { + let stored_in_state = match typ { + Type::Struct(_, generics) => Ok(generics[0].clone()), + _ => Err(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some("State storage variable must be a struct".to_string()), + }), + }?; + let trait_impl_kind = serialize_traits + .iter() + .filter_map(|&s_trait_id| { + interner + .lookup_all_trait_implementations(stored_in_state.clone(), s_trait_id) + .into_iter() + .nth(0) + }) + .nth(0) + .ok_or(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some("Stored data must implement Serialize trait".to_string()), + })?; + + let trait_impl_id = match trait_impl_kind { + TraitImplKind::Normal(trait_impl_id) => Ok(trait_impl_id), + _ => Err(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: None }), + }?; + + let trait_impl_shared = interner.get_trait_implementation(trait_impl_id); + let trait_impl = trait_impl_shared.borrow(); + + match trait_impl.trait_generics.get(0).unwrap() { + Type::Constant(value) => Ok(value.clone()), + _ => Err(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: None }), + } +} + +fn assign_storage_slots( + crate_id: &CrateId, + context: &mut HirContext, +) -> Result<(), AztecMacroError> { + let serialize_traits: Vec<_> = collect_traits(context) + .iter() + .filter(|trait_id| { + let r#trait = context.def_interner.get_trait(**trait_id); + r#trait.borrow().name.0.contents == "Serialize" && r#trait.borrow().generics.len() == 1 + }) + .cloned() + .collect(); + for struct_id in collect_crate_structs(crate_id, context) { + let interner: &mut NodeInterner = context.def_interner.borrow_mut(); + let r#struct = interner.get_struct(struct_id); + if r#struct.borrow().name.0.contents == "Storage" && r#struct.borrow().id.krate().is_root() + { + let init_id = interner + .lookup_method( + &Type::Struct(interner.get_struct(struct_id), vec![]), + struct_id, + "init", + false, + ) + .ok_or(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage struct must have an init function".to_string(), + ), + })?; + let init_function = interner.function(&init_id).block(interner); + let init_function_statement_id = init_function.statements().first().ok_or( + AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some("Init storage statement not found".to_string()), + }, + )?; + let storage_constructor_statement = interner.statement(init_function_statement_id); + + let storage_constructor_expression = match storage_constructor_statement { + HirStatement::Expression(expression_id) => { + match interner.expression(&expression_id) { + HirExpression::Constructor(hir_constructor_expression) => { + Ok(hir_constructor_expression) + } + _ => Err(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage constructor statement must be a constructor expression" + .to_string(), + ), + }), + } + } + _ => Err(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage constructor statement must be an expression".to_string(), + ), + }), + }?; + + let mut storage_slot: u64 = 1; + for (index, (_, expr_id)) in storage_constructor_expression.fields.iter().enumerate() { + let fields = r#struct.borrow().get_fields(&[]); + let (_, field_type) = fields.get(index).unwrap(); + let new_call_expression = match interner.expression(expr_id) { + HirExpression::Call(hir_call_expression) => Ok(hir_call_expression), + _ => Err(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage field initialization expression is not a call expression" + .to_string(), + ), + }), + }?; + + let slot_arg_expression = interner.expression(&new_call_expression.arguments[1]); + + let current_storage_slot = match slot_arg_expression { + HirExpression::Literal(HirLiteral::Integer(slot, _)) => { + Ok(slot.borrow().to_u128()) + } + _ => Err(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage slot argument expression must be a literal integer" + .to_string(), + ), + }), + }?; + + if current_storage_slot != 0 { + continue; + } + + let type_serialized_len = + get_serialized_length(&serialize_traits, field_type, interner)?; + interner.update_expression(new_call_expression.arguments[1], |expr| { + *expr = HirExpression::Literal(HirLiteral::Integer( + FieldElement::from(u128::from(storage_slot)), + false, + )); + }); + + storage_slot += type_serialized_len; + } + } + } + Ok(()) +} + const SIGNATURE_PLACEHOLDER: &str = "SIGNATURE_PLACEHOLDER"; /// Generates the impl for an event selector diff --git a/noir/compiler/noirc_frontend/src/node_interner.rs b/noir/compiler/noirc_frontend/src/node_interner.rs index e734161e360e..06bf585a823f 100644 --- a/noir/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/compiler/noirc_frontend/src/node_interner.rs @@ -1,4 +1,6 @@ +use std::borrow::Borrow; use std::collections::HashMap; +use std::ops::Deref; use arena::{Arena, Index}; use fm::FileId; @@ -1033,6 +1035,32 @@ impl NodeInterner { Ok(impl_kind) } + pub fn lookup_all_trait_implementations( + &self, + object_type: Type, + trait_id: TraitId, + ) -> Vec { + let trait_impl = self.trait_implementation_map.get(&trait_id); + + trait_impl + .map(|trait_impl| { + trait_impl + .iter() + .filter_map(|(typ, impl_kind)| match &typ { + Type::Forall(_, typ) => { + if typ.deref() == &object_type { + Some(impl_kind.clone()) + } else { + None + } + } + _ => None, + }) + .collect() + }) + .unwrap_or(vec![]) + } + /// Similar to `lookup_trait_implementation` but does not apply any type bindings on success. pub fn try_lookup_trait_implementation( &self, @@ -1255,7 +1283,6 @@ impl NodeInterner { force_type_check: bool, ) -> Option { let methods = self.struct_methods.get(&(id, method_name.to_owned())); - // If there is only one method, just return it immediately. // It will still be typechecked later. if !force_type_check { diff --git a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr index 86dc770fcf44..ff78e2c8f365 100644 --- a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -27,15 +27,6 @@ contract Benchmarking { balances: Map>, } - // impl Storage { - // fn init(context: Context) -> Self { - // Storage { - // notes: Map::new(context, 1, |context, slot| { Set::new(context, slot) }), - // balances: Map::new(context, 2, |context, slot| { PublicState::new(context, slot) }), - // } - // } - // } - #[aztec(private)] fn constructor() {} diff --git a/yarn-project/noir-contracts/contracts/child_contract/src/main.nr b/yarn-project/noir-contracts/contracts/child_contract/src/main.nr index ee7213c46873..1298819f326f 100644 --- a/yarn-project/noir-contracts/contracts/child_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/child_contract/src/main.nr @@ -17,17 +17,6 @@ contract Child { current_value: PublicState, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - current_value: PublicState::new( - context, - 1, - ), - } - } - } - #[aztec(private)] fn constructor() {} diff --git a/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr b/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr index e424fbda6937..e07b793c403f 100644 --- a/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/counter_contract/src/main.nr @@ -27,22 +27,6 @@ contract Counter { // docs:end:storage_struct - // docs:start:storage_init - impl Storage { - fn init(context: Context) -> Self { - Storage { - counters: Map::new( - context, - 1, - |context, slot| { - EasyPrivateUint::new(context, slot) - }, - ), - } - } - } - // docs:end:storage_init - // docs:start:constructor #[aztec(private)] fn constructor(headstart: u120, owner: AztecAddress) { diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index 398bf697e3d6..d0b6f86db1c9 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -44,30 +44,6 @@ contract DocsExample { // docs:end:storage-map-singleton-declaration } - impl Storage { - fn init(context: Context) -> Self { - Storage { - leader: PublicState::new( - context, - 1 - ), - // docs:start:start_vars_singleton - legendary_card: Singleton::new(context, 2), - // docs:end:start_vars_singleton - // just used for docs example (not for game play): - // docs:start:state_vars-MapSingleton - profiles: Map::new( - context, - 3, - |context, slot| { - Singleton::new(context, slot) - }, - ), - // docs:end:state_vars-MapSingleton - } - } - } - #[aztec(private)] fn constructor() {} diff --git a/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr index c43aae116eaa..f4d61f1bf670 100644 --- a/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr @@ -22,21 +22,7 @@ contract EasyPrivateToken { struct Storage { balances: Map, } - - impl Storage { - fn init(context: Context) -> Self { - Storage { - balances: Map::new( - context, - 1, - |context, slot| { - EasyPrivateUint::new(context, slot) - }, - ), - } - } - } - + /** * initialize the contract's initial state variables. */ diff --git a/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index 5cc3606d39e5..731976633cc0 100644 --- a/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -16,31 +16,7 @@ contract EasyPrivateVoting { voteEnded: PublicState, // voteEnded is boolean } // docs:end:storage_struct - // docs:start:storage_impl - impl Storage { - fn init(context: Context) -> Self { - Storage { - admin: PublicState::new( - context, - 1, // storage slot. this can be anything except 0. it is hashed, and hash on 0 = 0 - ), - tally: Map::new( - context, - 2, - |context, slot| { - PublicState::new( - context, - slot, - ) - }, - ), - voteEnded: PublicState::new( - context, - 3 - ) - } } - } - // docs:end:storage_impl + // docs:start:constructor #[aztec(private)] // annotation to mark function as private and expose private context fn constructor(admin: AztecAddress) { // called when contract is deployed diff --git a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index 4949cc7f5d15..0c9f669907c2 100644 --- a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -30,14 +30,6 @@ contract EcdsaAccount { public_key: ImmutableSingleton, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - public_key: ImmutableSingleton::new(context, 1), - } - } - } - global ACCOUNT_ACTIONS_STORAGE_SLOT = 2; // Creates a new account out of an ECDSA public key to use for signature verification diff --git a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr index 5ba68df9107c..ced59ce4e28f 100644 --- a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr @@ -27,14 +27,6 @@ contract Escrow { owners: Set, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - owners: Set::new(context, 1), - } - } - } - // Creates a new instance // docs:start:constructor #[aztec(private)] diff --git a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index c4c2f63bae24..809239760ffb 100644 --- a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -51,24 +51,6 @@ contract InclusionProofs { public_value: PublicState, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - private_values: Map::new( - context, - 1, // Storage slot - |context, slot| { - Set::new(context, slot) - }, - ), - public_value: PublicState::new( - context, - 2, // Storage slot - ), - } - } - } - #[aztec(private)] fn constructor(public_value: Field) { let selector = FunctionSelector::from_signature("_initialize(Field)"); diff --git a/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr b/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr index 9811f0919d13..2dd9bc1c16a9 100644 --- a/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/lending_contract/src/main.nr @@ -38,51 +38,6 @@ contract Lending { static_debt: Map>, // abusing keys very heavily } - impl Storage { - fn init(context: Context) -> Self { - Storage { - collateral_asset: PublicState::new( - context, - 1 - ), - stable_coin: PublicState::new( - context, - 2 - ), - assets: Map::new( - context, - 3, - |context, slot| { - PublicState::new( - context, - slot - ) - }, - ), - collateral: Map::new( - context, - 4, - |context, slot| { - PublicState::new( - context, - slot - ) - }, - ), - static_debt: Map::new( - context, - 5, - |context, slot| { - PublicState::new( - context, - slot - ) - }, - ), - } - } - } - struct Position { collateral: Field, static_debt: Field, diff --git a/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr b/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr index 3878ae5134c5..2c163a14184f 100644 --- a/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/pending_commitments_contract/src/main.nr @@ -29,20 +29,6 @@ contract PendingCommitments { balances: Map>, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - balances: Map::new( - context, - 1, // Storage slot - |context, slot| { - Set::new(context, slot) - }, - ), - } - } - } - // TODO(dbanks12): consolidate code into internal helper functions // (once Noir's support for this is more robust) diff --git a/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr b/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr index a72caab5e836..b1ee56c89913 100644 --- a/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/price_feed_contract/src/main.nr @@ -17,23 +17,6 @@ contract PriceFeed { assets: Map>, } - impl Storage { - fn init(context: Context) -> pub Self { - Storage { - assets: Map::new( - context, - 1, - |context, slot| { - PublicState::new( - context, - slot, - ) - }, - ), - } - } - } - #[aztec(private)] fn constructor() {} diff --git a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr index 2c18164c6a48..c89b1e6c4d24 100644 --- a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -28,16 +28,6 @@ contract SchnorrAccount { // docs:end:storage } - impl Storage { - fn init(context: Context) -> Self { - Storage { - // docs:start:storage_init - signing_public_key: ImmutableSingleton::new(context, 1), - // docs:end:storage_init - } - } - } - global ACCOUNT_ACTIONS_STORAGE_SLOT = 2; // Constructs the contract diff --git a/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr b/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr index 625df2f07f66..ecad26f1bb6e 100644 --- a/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr @@ -44,23 +44,6 @@ contract SlowTree { } // docs:end:constants_and_storage - impl Storage { - fn init(context: Context) -> Self { - Storage { - trees: Map::new( - context, - 1, - |context, slot| { - SlowMap::new( - context, - slot, - ) - } - ), - } - } - } - #[aztec(private)] fn constructor() {} // docs:start:initialize diff --git a/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr index cfca700e66e2..93aa50f18b9b 100644 --- a/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -21,30 +21,6 @@ contract StatefulTest { public_values: Map>, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - notes: Map::new( - context, - 1, // Storage slot - |context, slot| { - Set::new(context, slot) - }, - ), - public_values: Map::new( - context, - 2, - |context, slot| { - PublicState::new( - context, - slot, - ) - }, - ), - } - } - } - #[aztec(private)] fn constructor(owner: AztecAddress, value: Field) { let loc = storage.notes.at(owner); diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index 50a89097fde8..024eb77c260f 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -45,14 +45,6 @@ contract Test { example_constant: ImmutableSingleton, } - // impl Storage { - // fn init(context: Context) -> Self { - // Storage { - // example_constant: ImmutableSingleton::new(context, 1), - // } - // } - // } - #[aztec(private)] // docs:start:empty-constructor fn constructor() {} diff --git a/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr index e7893ef8ceb5..489c95cb26c9 100644 --- a/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -32,17 +32,6 @@ contract TokenBridge { token: PublicState, } - impl Storage { - fn init(context: Context) -> pub Self { - Storage { - token: PublicState::new( - context, - 1 - ), - } - } - } - // Constructs the contract. #[aztec(private)] fn constructor(token: AztecAddress) { diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index b936c985b9b4..a738d19d19d1 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -430,19 +430,19 @@ contract Token { // Computes note hash and nullifier. // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. - unconstrained fn compute_note_hash_and_nullifier( - contract_address: AztecAddress, - nonce: Field, - storage_slot: Field, - serialized_note: [Field; TOKEN_NOTE_LEN] - ) -> pub [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - if (storage_slot == 5) { - note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) - } else { - note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) - } - } + // unconstrained fn compute_note_hash_and_nullifier( + // contract_address: AztecAddress, + // nonce: Field, + // storage_slot: Field, + // serialized_note: [Field; TOKEN_NOTE_LEN] + // ) -> pub [Field; 4] { + // let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + // if (storage_slot == 5) { + // note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) + // } else { + // note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) + // } + // } // docs:end:compute_note_hash_and_nullifier } // docs:end:token_all diff --git a/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr b/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr index c06630b6f922..65f9a8ea5904 100644 --- a/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -32,21 +32,6 @@ contract Uniswap { nonce_for_burn_approval: PublicState, } - impl Storage { - fn init(context: Context) -> Self { - Storage { - approved_action: Map::new( - context, - 1, - |context, slot| { - PublicState::new(context, slot) - }, - ), - nonce_for_burn_approval: PublicState::new(context, 2), - } - } - } - #[aztec(private)] fn constructor() {} // docs:end:uniswap_setup From 594dfe24a1a5ae3afe398f356cff501cc29d0705 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 16:05:34 +0100 Subject: [PATCH 12/56] merge conflicts --- .../aztec-nr/aztec/src/state_vars/immutable_singleton.nr | 1 - yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index 89a95188e166..17861cbf4d1e 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -31,7 +31,6 @@ impl ImmutableSingleton { Self { context: context.private, storage_slot, - compute_initialization_nullifier: compute_singleton_initialization_nullifier, } } // docs:end:new diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 336e645fde69..591759ea80ae 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -24,8 +24,7 @@ use crate::oracle::{ // docs:start:struct struct Singleton { context: Option<&mut PrivateContext>, - storage_slot: Field, - compute_initialization_nullifier: fn (Field, Option, Option<&mut PrivateContext>) -> Field, + storage_slot: Field } // docs:end:struct From 19a53139a94173600063d76a6f4ad5ac27578079 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 16:23:40 +0100 Subject: [PATCH 13/56] merge conflicts --- .../aztec-nr/aztec/src/state_vars/immutable_singleton.nr | 5 ++++- yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index 17861cbf4d1e..08cc2798abd3 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -2,6 +2,10 @@ use dep::std::option::Option; use dep::protocol_types::{ address::AztecAddress, traits::{Serialize, Deserialize}, + constants::{ + GENERATOR_INDEX__INITIALIZATION_NULLIFIER, + }, + hash::pedersen_hash, }; use crate::context::{PrivateContext, Context}; @@ -17,7 +21,6 @@ use crate::oracle::notes::check_nullifier_exists; struct ImmutableSingleton { context: Option<&mut PrivateContext>, storage_slot: Field, - compute_initialization_nullifier: fn (Field, Option, Option<&mut PrivateContext>) -> Field, } // docs:end:struct diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 591759ea80ae..19b4e91bb5ca 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -38,7 +38,6 @@ impl Singleton { Self { context: context.private, storage_slot, - compute_initialization_nullifier: compute_singleton_initialization_nullifier, } } // docs:end:new From 182facab0c1f78f1e4955ed089088190c85f13ef Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 16:31:05 +0100 Subject: [PATCH 14/56] uncommented method --- .../contracts/token_contract/src/main.nr | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index a738d19d19d1..b936c985b9b4 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -430,19 +430,19 @@ contract Token { // Computes note hash and nullifier. // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. - // unconstrained fn compute_note_hash_and_nullifier( - // contract_address: AztecAddress, - // nonce: Field, - // storage_slot: Field, - // serialized_note: [Field; TOKEN_NOTE_LEN] - // ) -> pub [Field; 4] { - // let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - // if (storage_slot == 5) { - // note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) - // } else { - // note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) - // } - // } + unconstrained fn compute_note_hash_and_nullifier( + contract_address: AztecAddress, + nonce: Field, + storage_slot: Field, + serialized_note: [Field; TOKEN_NOTE_LEN] + ) -> pub [Field; 4] { + let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + if (storage_slot == 5) { + note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) + } else { + note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) + } + } // docs:end:compute_note_hash_and_nullifier } // docs:end:token_all From 5fd184c08a490daa2945123084bd0f85e1aa51ef Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 16:32:28 +0100 Subject: [PATCH 15/56] adapt new interface --- .../contracts/docs_example_contract/src/main.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index ffaa34b85394..6baf0e0d782c 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -42,7 +42,7 @@ contract DocsExample { // docs:start:storage-map-singleton-declaration profiles: Map>, // docs:end:storage-map-singleton-declaration - imm_singleton: ImmutableSingleton, + imm_singleton: ImmutableSingleton, } impl Storage { @@ -65,7 +65,7 @@ contract DocsExample { }, ), // docs:end:state_vars-MapSingleton - imm_singleton: ImmutableSingleton::new(context, 4, CardNoteMethods), + imm_singleton: ImmutableSingleton::new(context, 4), } } } From 85cd6cdcc4413dcd648566a242f435e124d2ea7e Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 17:01:51 +0100 Subject: [PATCH 16/56] more deserialization hints --- yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 19b4e91bb5ca..676fee86b647 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -112,6 +112,8 @@ impl Singleton { // docs:start:view_note unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { + // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed + let _deserialized_length_hint: [Field; N] = Note::_deserialized_length_hint(); let options = NoteViewerOptions::new().set_limit(1); view_notes(self.storage_slot, options)[0].unwrap() } From d17cb5e09b0d3eb0702bb348f6540d01d4b8546d Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 17:05:18 +0100 Subject: [PATCH 17/56] manually called format --- .../cpp/src/barretenberg/common/fuzzer.hpp | 97 +++++++++---------- .../barretenberg/relations/relation_types.hpp | 8 +- .../cpp/src/barretenberg/relations/utils.hpp | 3 +- .../circuit_builders/circuit_builders.hpp | 3 +- .../barretenberg/transcript/transcript.hpp | 6 +- 5 files changed, 57 insertions(+), 60 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp b/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp index 9ffa30975f04..a22d8038ebae 100644 --- a/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp +++ b/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp @@ -89,10 +89,10 @@ class FastRandom { */ template concept SimpleRng = requires(T a) { - { - a.next() - } -> std::convertible_to; - }; + { + a.next() + } -> std::convertible_to; +}; /** * @brief Concept for forcing ArgumentSizes to be size_t * @@ -100,27 +100,27 @@ concept SimpleRng = requires(T a) { */ template concept InstructionArgumentSizes = requires { - { - std::make_tuple(T::CONSTANT, - T::WITNESS, - T::CONSTANT_WITNESS, - T::ADD, - T::SUBTRACT, - T::MULTIPLY, - T::DIVIDE, - T::ADD_TWO, - T::MADD, - T::MULT_MADD, - T::MSUB_DIV, - T::SQR, - T::SQR_ADD, - T::SUBTRACT_WITH_CONSTRAINT, - T::DIVIDE_WITH_CONSTRAINTS, - T::SLICE, - T::ASSERT_ZERO, - T::ASSERT_NOT_ZERO) - } -> std::same_as>; - }; + { + std::make_tuple(T::CONSTANT, + T::WITNESS, + T::CONSTANT_WITNESS, + T::ADD, + T::SUBTRACT, + T::MULTIPLY, + T::DIVIDE, + T::ADD_TWO, + T::MADD, + T::MULT_MADD, + T::MSUB_DIV, + T::SQR, + T::SQR_ADD, + T::SUBTRACT_WITH_CONSTRAINT, + T::DIVIDE_WITH_CONSTRAINTS, + T::SLICE, + T::ASSERT_ZERO, + T::ASSERT_NOT_ZERO) + } -> std::same_as>; +}; /** * @brief Concept for Havoc Configurations @@ -128,13 +128,12 @@ concept InstructionArgumentSizes = requires { * @tparam T */ template -concept HavocConfigConstraint = - requires { - { - std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) - } -> std::same_as>; - T::GEN_MUTATION_COUNT_LOG <= 7; - }; +concept HavocConfigConstraint = requires { + { + std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) + } -> std::same_as>; + T::GEN_MUTATION_COUNT_LOG <= 7; +}; /** * @brief Concept specifying the class used by the fuzzer * @@ -142,12 +141,12 @@ concept HavocConfigConstraint = */ template concept ArithmeticFuzzHelperConstraint = requires { - typename T::ArgSizes; - typename T::Instruction; - typename T::ExecutionState; - typename T::ExecutionHandler; - InstructionArgumentSizes; - }; + typename T::ArgSizes; + typename T::Instruction; + typename T::ExecutionState; + typename T::ExecutionHandler; + InstructionArgumentSizes; +}; /** * @brief Fuzzer uses only composers with check_circuit function @@ -156,10 +155,10 @@ concept ArithmeticFuzzHelperConstraint = requires { */ template concept CheckableComposer = requires(T a) { - { - a.check_circuit() - } -> std::same_as; - }; + { + a.check_circuit() + } -> std::same_as; +}; /** * @brief The fuzzer can use a postprocessing function that is specific to the type being fuzzed @@ -170,10 +169,10 @@ concept CheckableComposer = requires(T a) { */ template concept PostProcessingEnabled = requires(Composer composer, Context context) { - { - T::postProcess(&composer, context) - } -> std::same_as; - }; + { + T::postProcess(&composer, context) + } -> std::same_as; +}; /** * @brief This concept is used when we want to limit the number of executions of certain instructions (for example, @@ -183,9 +182,9 @@ concept PostProcessingEnabled = requires(Composer composer, Context context) { */ template concept InstructionWeightsEnabled = requires { - typename T::InstructionWeights; - T::InstructionWeights::_LIMIT; - }; + typename T::InstructionWeights; + T::InstructionWeights::_LIMIT; +}; /** * @brief Mutate the value of a field element diff --git a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp index be4b87322548..1c4c69077ed7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp @@ -23,10 +23,10 @@ using GetParameterView = std::conditional_t, template concept HasSubrelationLinearlyIndependentMember = requires(T) { - { - std::get(T::SUBRELATION_LINEARLY_INDEPENDENT) - } -> std::convertible_to; - }; + { + std::get(T::SUBRELATION_LINEARLY_INDEPENDENT) + } -> std::convertible_to; +}; template concept HasParameterLengthAdjustmentsMember = requires { T::TOTAL_LENGTH_ADJUSTMENTS; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/relations/utils.hpp index 331967359f3e..63c8dad303e7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/utils.hpp @@ -113,8 +113,7 @@ template class RelationUtils { template static constexpr void add_tuples(std::tuple& tuple_1, const std::tuple& tuple_2) { - auto add_tuples_helper = [&](std::index_sequence) - { + auto add_tuples_helper = [&](std::index_sequence) { ((std::get(tuple_1) += std::get(tuple_2)), ...); }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp index 050fe337f8f2..6444cbaa8145 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp @@ -13,5 +13,4 @@ concept HasPlookup = bb::IsAnyOf concept IsGoblinBuilder = bb::IsAnyOf; template -concept IsNotGoblinBuilder = ! -IsGoblinBuilder; +concept IsNotGoblinBuilder = !IsGoblinBuilder; diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp index cf791175c98e..a396eb774cce 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp @@ -10,9 +10,9 @@ namespace bb::honk { template -concept Loggable = (std::same_as || std::same_as || - std::same_as || std::same_as || - std::same_as); +concept Loggable = + (std::same_as || std::same_as || std::same_as || + std::same_as || std::same_as); // class TranscriptManifest; class TranscriptManifest { From f4efc6bab1540d56b4d434dcb14c7f6f86726877 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 17:06:27 +0100 Subject: [PATCH 18/56] manually called format --- .../cpp/src/barretenberg/common/fuzzer.hpp | 97 +++++++++---------- .../barretenberg/relations/relation_types.hpp | 8 +- .../cpp/src/barretenberg/relations/utils.hpp | 3 +- .../circuit_builders/circuit_builders.hpp | 3 +- .../barretenberg/transcript/transcript.hpp | 6 +- 5 files changed, 57 insertions(+), 60 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp b/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp index 9ffa30975f04..a22d8038ebae 100644 --- a/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp +++ b/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp @@ -89,10 +89,10 @@ class FastRandom { */ template concept SimpleRng = requires(T a) { - { - a.next() - } -> std::convertible_to; - }; + { + a.next() + } -> std::convertible_to; +}; /** * @brief Concept for forcing ArgumentSizes to be size_t * @@ -100,27 +100,27 @@ concept SimpleRng = requires(T a) { */ template concept InstructionArgumentSizes = requires { - { - std::make_tuple(T::CONSTANT, - T::WITNESS, - T::CONSTANT_WITNESS, - T::ADD, - T::SUBTRACT, - T::MULTIPLY, - T::DIVIDE, - T::ADD_TWO, - T::MADD, - T::MULT_MADD, - T::MSUB_DIV, - T::SQR, - T::SQR_ADD, - T::SUBTRACT_WITH_CONSTRAINT, - T::DIVIDE_WITH_CONSTRAINTS, - T::SLICE, - T::ASSERT_ZERO, - T::ASSERT_NOT_ZERO) - } -> std::same_as>; - }; + { + std::make_tuple(T::CONSTANT, + T::WITNESS, + T::CONSTANT_WITNESS, + T::ADD, + T::SUBTRACT, + T::MULTIPLY, + T::DIVIDE, + T::ADD_TWO, + T::MADD, + T::MULT_MADD, + T::MSUB_DIV, + T::SQR, + T::SQR_ADD, + T::SUBTRACT_WITH_CONSTRAINT, + T::DIVIDE_WITH_CONSTRAINTS, + T::SLICE, + T::ASSERT_ZERO, + T::ASSERT_NOT_ZERO) + } -> std::same_as>; +}; /** * @brief Concept for Havoc Configurations @@ -128,13 +128,12 @@ concept InstructionArgumentSizes = requires { * @tparam T */ template -concept HavocConfigConstraint = - requires { - { - std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) - } -> std::same_as>; - T::GEN_MUTATION_COUNT_LOG <= 7; - }; +concept HavocConfigConstraint = requires { + { + std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) + } -> std::same_as>; + T::GEN_MUTATION_COUNT_LOG <= 7; +}; /** * @brief Concept specifying the class used by the fuzzer * @@ -142,12 +141,12 @@ concept HavocConfigConstraint = */ template concept ArithmeticFuzzHelperConstraint = requires { - typename T::ArgSizes; - typename T::Instruction; - typename T::ExecutionState; - typename T::ExecutionHandler; - InstructionArgumentSizes; - }; + typename T::ArgSizes; + typename T::Instruction; + typename T::ExecutionState; + typename T::ExecutionHandler; + InstructionArgumentSizes; +}; /** * @brief Fuzzer uses only composers with check_circuit function @@ -156,10 +155,10 @@ concept ArithmeticFuzzHelperConstraint = requires { */ template concept CheckableComposer = requires(T a) { - { - a.check_circuit() - } -> std::same_as; - }; + { + a.check_circuit() + } -> std::same_as; +}; /** * @brief The fuzzer can use a postprocessing function that is specific to the type being fuzzed @@ -170,10 +169,10 @@ concept CheckableComposer = requires(T a) { */ template concept PostProcessingEnabled = requires(Composer composer, Context context) { - { - T::postProcess(&composer, context) - } -> std::same_as; - }; + { + T::postProcess(&composer, context) + } -> std::same_as; +}; /** * @brief This concept is used when we want to limit the number of executions of certain instructions (for example, @@ -183,9 +182,9 @@ concept PostProcessingEnabled = requires(Composer composer, Context context) { */ template concept InstructionWeightsEnabled = requires { - typename T::InstructionWeights; - T::InstructionWeights::_LIMIT; - }; + typename T::InstructionWeights; + T::InstructionWeights::_LIMIT; +}; /** * @brief Mutate the value of a field element diff --git a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp index be4b87322548..1c4c69077ed7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp @@ -23,10 +23,10 @@ using GetParameterView = std::conditional_t, template concept HasSubrelationLinearlyIndependentMember = requires(T) { - { - std::get(T::SUBRELATION_LINEARLY_INDEPENDENT) - } -> std::convertible_to; - }; + { + std::get(T::SUBRELATION_LINEARLY_INDEPENDENT) + } -> std::convertible_to; +}; template concept HasParameterLengthAdjustmentsMember = requires { T::TOTAL_LENGTH_ADJUSTMENTS; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/relations/utils.hpp index 331967359f3e..63c8dad303e7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/utils.hpp @@ -113,8 +113,7 @@ template class RelationUtils { template static constexpr void add_tuples(std::tuple& tuple_1, const std::tuple& tuple_2) { - auto add_tuples_helper = [&](std::index_sequence) - { + auto add_tuples_helper = [&](std::index_sequence) { ((std::get(tuple_1) += std::get(tuple_2)), ...); }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp index 050fe337f8f2..6444cbaa8145 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp @@ -13,5 +13,4 @@ concept HasPlookup = bb::IsAnyOf concept IsGoblinBuilder = bb::IsAnyOf; template -concept IsNotGoblinBuilder = ! -IsGoblinBuilder; +concept IsNotGoblinBuilder = !IsGoblinBuilder; diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp index cf791175c98e..a396eb774cce 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp @@ -10,9 +10,9 @@ namespace bb::honk { template -concept Loggable = (std::same_as || std::same_as || - std::same_as || std::same_as || - std::same_as); +concept Loggable = + (std::same_as || std::same_as || std::same_as || + std::same_as || std::same_as); // class TranscriptManifest; class TranscriptManifest { From 8788c67691f583aca88b1754807c6f4a5ba4eeb4 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 17:17:54 +0100 Subject: [PATCH 19/56] restored bb changes From 48002d4876211da251b4c64c6721cad7c9a5f4d2 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 17:25:12 +0100 Subject: [PATCH 20/56] reverted barretenberg to master From 9966206798f7624633111843ff884223d62fac59 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 17:26:43 +0100 Subject: [PATCH 21/56] reverted barretenberg to master --- .../cpp/src/barretenberg/common/fuzzer.hpp | 97 ++++++++++--------- .../barretenberg/relations/relation_types.hpp | 8 +- .../cpp/src/barretenberg/relations/utils.hpp | 3 +- .../stdlib/primitives/bool/bool.test.cpp | 8 +- .../circuit_builders/circuit_builders.hpp | 3 +- .../barretenberg/transcript/transcript.hpp | 6 +- 6 files changed, 64 insertions(+), 61 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp b/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp index a22d8038ebae..9ffa30975f04 100644 --- a/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp +++ b/barretenberg/cpp/src/barretenberg/common/fuzzer.hpp @@ -89,10 +89,10 @@ class FastRandom { */ template concept SimpleRng = requires(T a) { - { - a.next() - } -> std::convertible_to; -}; + { + a.next() + } -> std::convertible_to; + }; /** * @brief Concept for forcing ArgumentSizes to be size_t * @@ -100,27 +100,27 @@ concept SimpleRng = requires(T a) { */ template concept InstructionArgumentSizes = requires { - { - std::make_tuple(T::CONSTANT, - T::WITNESS, - T::CONSTANT_WITNESS, - T::ADD, - T::SUBTRACT, - T::MULTIPLY, - T::DIVIDE, - T::ADD_TWO, - T::MADD, - T::MULT_MADD, - T::MSUB_DIV, - T::SQR, - T::SQR_ADD, - T::SUBTRACT_WITH_CONSTRAINT, - T::DIVIDE_WITH_CONSTRAINTS, - T::SLICE, - T::ASSERT_ZERO, - T::ASSERT_NOT_ZERO) - } -> std::same_as>; -}; + { + std::make_tuple(T::CONSTANT, + T::WITNESS, + T::CONSTANT_WITNESS, + T::ADD, + T::SUBTRACT, + T::MULTIPLY, + T::DIVIDE, + T::ADD_TWO, + T::MADD, + T::MULT_MADD, + T::MSUB_DIV, + T::SQR, + T::SQR_ADD, + T::SUBTRACT_WITH_CONSTRAINT, + T::DIVIDE_WITH_CONSTRAINTS, + T::SLICE, + T::ASSERT_ZERO, + T::ASSERT_NOT_ZERO) + } -> std::same_as>; + }; /** * @brief Concept for Havoc Configurations @@ -128,12 +128,13 @@ concept InstructionArgumentSizes = requires { * @tparam T */ template -concept HavocConfigConstraint = requires { - { - std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) - } -> std::same_as>; - T::GEN_MUTATION_COUNT_LOG <= 7; -}; +concept HavocConfigConstraint = + requires { + { + std::make_tuple(T::GEN_MUTATION_COUNT_LOG, T::GEN_STRUCTURAL_MUTATION_PROBABILITY) + } -> std::same_as>; + T::GEN_MUTATION_COUNT_LOG <= 7; + }; /** * @brief Concept specifying the class used by the fuzzer * @@ -141,12 +142,12 @@ concept HavocConfigConstraint = requires { */ template concept ArithmeticFuzzHelperConstraint = requires { - typename T::ArgSizes; - typename T::Instruction; - typename T::ExecutionState; - typename T::ExecutionHandler; - InstructionArgumentSizes; -}; + typename T::ArgSizes; + typename T::Instruction; + typename T::ExecutionState; + typename T::ExecutionHandler; + InstructionArgumentSizes; + }; /** * @brief Fuzzer uses only composers with check_circuit function @@ -155,10 +156,10 @@ concept ArithmeticFuzzHelperConstraint = requires { */ template concept CheckableComposer = requires(T a) { - { - a.check_circuit() - } -> std::same_as; -}; + { + a.check_circuit() + } -> std::same_as; + }; /** * @brief The fuzzer can use a postprocessing function that is specific to the type being fuzzed @@ -169,10 +170,10 @@ concept CheckableComposer = requires(T a) { */ template concept PostProcessingEnabled = requires(Composer composer, Context context) { - { - T::postProcess(&composer, context) - } -> std::same_as; -}; + { + T::postProcess(&composer, context) + } -> std::same_as; + }; /** * @brief This concept is used when we want to limit the number of executions of certain instructions (for example, @@ -182,9 +183,9 @@ concept PostProcessingEnabled = requires(Composer composer, Context context) { */ template concept InstructionWeightsEnabled = requires { - typename T::InstructionWeights; - T::InstructionWeights::_LIMIT; -}; + typename T::InstructionWeights; + T::InstructionWeights::_LIMIT; + }; /** * @brief Mutate the value of a field element diff --git a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp index 1c4c69077ed7..be4b87322548 100644 --- a/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/relation_types.hpp @@ -23,10 +23,10 @@ using GetParameterView = std::conditional_t, template concept HasSubrelationLinearlyIndependentMember = requires(T) { - { - std::get(T::SUBRELATION_LINEARLY_INDEPENDENT) - } -> std::convertible_to; -}; + { + std::get(T::SUBRELATION_LINEARLY_INDEPENDENT) + } -> std::convertible_to; + }; template concept HasParameterLengthAdjustmentsMember = requires { T::TOTAL_LENGTH_ADJUSTMENTS; }; diff --git a/barretenberg/cpp/src/barretenberg/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/relations/utils.hpp index 63c8dad303e7..331967359f3e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/utils.hpp @@ -113,7 +113,8 @@ template class RelationUtils { template static constexpr void add_tuples(std::tuple& tuple_1, const std::tuple& tuple_2) { - auto add_tuples_helper = [&](std::index_sequence) { + auto add_tuples_helper = [&](std::index_sequence) + { ((std::get(tuple_1) += std::get(tuple_2)), ...); }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp index e356505b458e..d9f87cd59ab4 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp @@ -148,7 +148,7 @@ TYPED_TEST(BoolTest, And) for (size_t i = 0; i < 32; ++i) { bool_ct a = witness_ct(&builder, (bool)(i % 1)); bool_ct b = witness_ct(&builder, (bool)(i % 2 == 1)); - a & b; + a& b; } bool result = builder.check_circuit(); @@ -163,17 +163,17 @@ TYPED_TEST(BoolTest, AndConstants) for (size_t i = 0; i < 32; ++i) { bool_ct a = witness_ct(&builder, (bool)(i % 2)); bool_ct b = witness_ct(&builder, (bool)(i % 3 == 1)); - a & b; + a& b; } for (size_t i = 0; i < 32; ++i) { if (i % 2 == 0) { bool_ct a = witness_ct(&builder, (bool)(i % 2)); bool_ct b(&builder, (bool)(i % 3 == 1)); - a & b; + a& b; } else { bool_ct a(&builder, (bool)(i % 2)); bool_ct b = witness_ct(&builder, (bool)(i % 3 == 1)); - a & b; + a& b; } } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp index 6444cbaa8145..050fe337f8f2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp @@ -13,4 +13,5 @@ concept HasPlookup = bb::IsAnyOf concept IsGoblinBuilder = bb::IsAnyOf; template -concept IsNotGoblinBuilder = !IsGoblinBuilder; +concept IsNotGoblinBuilder = ! +IsGoblinBuilder; diff --git a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp index a396eb774cce..cf791175c98e 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/transcript/transcript.hpp @@ -10,9 +10,9 @@ namespace bb::honk { template -concept Loggable = - (std::same_as || std::same_as || std::same_as || - std::same_as || std::same_as); +concept Loggable = (std::same_as || std::same_as || + std::same_as || std::same_as || + std::same_as); // class TranscriptManifest; class TranscriptManifest { From c6e3b5c9f80636d43b9c0938922b6600f1ad1a0b Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 18:09:03 +0100 Subject: [PATCH 22/56] refactor to allow recursive maps --- noir/aztec_macros/src/lib.rs | 136 ++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 67 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index a542da50e5be..38fbb882a88d 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -422,26 +422,22 @@ fn transform_module( } fn generate_storage_field_constructor( - fields: &Vec<(Ident, UnresolvedType)>, -) -> Result, AztecMacroError> { - let mut field_constructors = vec![]; - - for field in fields.iter() { - if let UnresolvedTypeData::Named(path, args) = &field.1.typ { - let args = match path.segments.last().unwrap().0.contents.as_str() { - "PublicState" | "Set" | "Singleton" | "ImmutableSingleton" => { - vec![ - variable("context"), - expression(ExpressionKind::Literal(Literal::Integer( - FieldElement::from(i128::from(0)), - false, - ))), - ] - } - "Map" => { - let mut mapped_struct_path = match args - .last() - .and_then(|unresolved_type| Some(unresolved_type.typ.clone())) + field: (Ident, UnresolvedType), +) -> Result<(Ident, Expression), AztecMacroError> { + let field_constructor = if let UnresolvedTypeData::Named(path, args) = &field.1.typ { + let args = match path.segments.last().unwrap().0.contents.as_str() { + "PublicState" | "Set" | "Singleton" | "ImmutableSingleton" => { + vec![ + variable("context"), + expression(ExpressionKind::Literal(Literal::Integer( + FieldElement::from(i128::from(0)), + false, + ))), + ] + } + "Map" => { + let mut mapped_struct_path = + match args.last().and_then(|unresolved_type| Some(unresolved_type.typ.clone())) { Some(UnresolvedTypeData::Named(path, _)) => Ok(path), _ => Err(AztecMacroError::UnsupportedStorageType { @@ -450,60 +446,66 @@ fn generate_storage_field_constructor( }), }?; - mapped_struct_path.segments.push(ident("new")); - - vec![ - variable("context"), - expression(ExpressionKind::Literal(Literal::Integer( - FieldElement::from(i128::from(0)), - false, - ))), - expression(ExpressionKind::Lambda(Box::new(Lambda { - parameters: vec![ - ( - Pattern::Identifier(ident("context")), - make_type(UnresolvedTypeData::Named( - chained_path!("aztec", "context", "Context"), - vec![], - )), - ), - ( - Pattern::Identifier(ident("slot")), - make_type(UnresolvedTypeData::FieldElement), - ), - ], - return_type: UnresolvedType { - typ: UnresolvedTypeData::Unspecified, - span: Some(Span::default()), - }, - body: call( - variable_path(mapped_struct_path), - vec![variable("context"), variable("slot")], + mapped_struct_path.segments.push(ident("new")); + + vec![ + variable("context"), + expression(ExpressionKind::Literal(Literal::Integer( + FieldElement::from(i128::from(0)), + false, + ))), + expression(ExpressionKind::Lambda(Box::new(Lambda { + parameters: vec![ + ( + Pattern::Identifier(ident("context")), + make_type(UnresolvedTypeData::Named( + chained_path!("aztec", "context", "Context"), + vec![], + )), ), - }))), - ] - } - _ => { - return Err(AztecMacroError::UnsupportedStorageType { - typ: field.1.typ.clone(), - span: field.1.span, - }) - } - }; - let mut new_path = path.clone(); - new_path.segments.push(ident("new")); - let expression = call(variable_path(new_path), args); - field_constructors.push((field.0.clone(), expression)); - } - } - Ok(field_constructors) + ( + Pattern::Identifier(ident("slot")), + make_type(UnresolvedTypeData::FieldElement), + ), + ], + return_type: UnresolvedType { + typ: UnresolvedTypeData::Unspecified, + span: Some(Span::default()), + }, + body: call( + variable_path(mapped_struct_path), + vec![variable("context"), variable("slot")], + ), + }))), + ] + } + _ => { + return Err(AztecMacroError::UnsupportedStorageType { + typ: field.1.typ.clone(), + span: field.1.span, + }) + } + }; + let mut new_path = path.clone(); + new_path.segments.push(ident("new")); + let expression = call(variable_path(new_path), args); + (field.0.clone(), expression) + } else { + return Err(AztecMacroError::UnsupportedStorageType { + typ: field.1.typ.clone(), + span: field.1.span, + }); + }; + + Ok(field_constructor) } fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), AztecMacroError> { let definition = module.types.iter().find(|r#struct| r#struct.name.0.contents == "Storage").unwrap(); - let field_constructors = generate_storage_field_constructor(&definition.fields)?; + let field_constructors = + definition.fields.iter().map(|field| generate_storage_field_constructor(*field)?).collect(); let storage_constructor_statement = make_statement(StatementKind::Expression(expression( ExpressionKind::constructor((chained_path!("Storage"), field_constructors)), From 708c4f7deae46d97211fc8850b99091b2d1ed8c9 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 18:10:18 +0100 Subject: [PATCH 23/56] format --- .../contracts/inclusion_proofs_contract/src/main.nr | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index 6e5a7fb6cffc..9ff8b848cd22 100644 --- a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -95,11 +95,7 @@ contract InclusionProofs { // 2) Prove the note inclusion if maybe_note.is_some() { // docs:start:prove_note_inclusion - prove_note_inclusion( - maybe_note.unwrap_unchecked(), - block_number, - context - ); + prove_note_inclusion(maybe_note.unwrap_unchecked(), block_number, context); // docs:end:prove_note_inclusion } else { // Note was not found so we will prove inclusion of the spare commitment @@ -126,11 +122,7 @@ contract InclusionProofs { // 3) Compute the nullifier from the note if maybe_note.is_some() { // docs:start:prove_note_not_nullified - prove_note_not_nullified( - maybe_note.unwrap_unchecked(), - block_number, - &mut context - ); + prove_note_not_nullified(maybe_note.unwrap_unchecked(), block_number, &mut context); // docs:end:prove_note_not_nullified } else { // Note was not found so we will use the spare nullifier From b3f820e642e6b5b4949900978a42b744dfc0dfd1 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 18:10:46 +0100 Subject: [PATCH 24/56] format --- .../contracts/inclusion_proofs_contract/src/main.nr | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index cec2ca41d805..832c4c95a9d9 100644 --- a/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -113,11 +113,7 @@ contract InclusionProofs { // 2) Prove the note inclusion if maybe_note.is_some() { // docs:start:prove_note_inclusion - prove_note_inclusion( - maybe_note.unwrap_unchecked(), - block_number, - context - ); + prove_note_inclusion(maybe_note.unwrap_unchecked(), block_number, context); // docs:end:prove_note_inclusion } else { // Note was not found so we will prove inclusion of the spare commitment @@ -144,11 +140,7 @@ contract InclusionProofs { // 3) Compute the nullifier from the note if maybe_note.is_some() { // docs:start:prove_note_not_nullified - prove_note_not_nullified( - maybe_note.unwrap_unchecked(), - block_number, - &mut context - ); + prove_note_not_nullified(maybe_note.unwrap_unchecked(), block_number, &mut context); // docs:end:prove_note_not_nullified } else { // Note was not found so we will use the spare nullifier From c4d18487c26a40643de0a3e0b50513e3282ace5f Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 24 Jan 2024 19:18:10 +0100 Subject: [PATCH 25/56] better custom type support --- noir/aztec_macros/src/lib.rs | 112 +++++++++++++----- .../contracts/card_game_contract/src/main.nr | 44 ------- 2 files changed, 83 insertions(+), 73 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 38fbb882a88d..bdeeb9db0da1 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -421,30 +421,80 @@ fn transform_module( Ok(has_transformed_module) } +fn generate_map_field_constructor(typ: UnresolvedTypeData) -> Result { + match &typ { + UnresolvedTypeData::Named(path, generics) => { + let mut new_path = path.clone().to_owned(); + new_path.segments.push(ident("new")); + match path.segments.last().unwrap().0.contents.as_str() { + "Map" => { + println!( + "nesting! {} - {:?}", + new_path, + generics.iter().cloned().last().unwrap().typ + ); + Ok(call( + variable_path(new_path), + vec![ + variable("context"), + variable("slot"), + expression(ExpressionKind::Lambda(Box::new(Lambda { + parameters: vec![ + ( + Pattern::Identifier(ident("context")), + make_type(UnresolvedTypeData::Named( + chained_path!("aztec", "context", "Context"), + vec![], + )), + ), + ( + Pattern::Identifier(ident("slot")), + make_type(UnresolvedTypeData::FieldElement), + ), + ], + return_type: UnresolvedType { + typ: UnresolvedTypeData::Unspecified, + span: Some(Span::default()), + }, + body: generate_map_field_constructor( + generics.iter().cloned().last().unwrap().typ, + )?, + }))), + ], + )) + } + _ => { + println!("Generating args - {}", new_path); + Ok(call(variable_path(new_path), vec![variable("context"), variable("slot")])) + } + } + } + _ => { + return Err(AztecMacroError::UnsupportedStorageType { + typ: typ.clone(), + span: Some(Span::default()), + }) + } + } +} + fn generate_storage_field_constructor( field: (Ident, UnresolvedType), ) -> Result<(Ident, Expression), AztecMacroError> { - let field_constructor = if let UnresolvedTypeData::Named(path, args) = &field.1.typ { + let field_constructor = if let UnresolvedTypeData::Named(path, generics) = &field.1.typ { let args = match path.segments.last().unwrap().0.contents.as_str() { - "PublicState" | "Set" | "Singleton" | "ImmutableSingleton" => { - vec![ - variable("context"), - expression(ExpressionKind::Literal(Literal::Integer( - FieldElement::from(i128::from(0)), - false, - ))), - ] - } "Map" => { - let mut mapped_struct_path = - match args.last().and_then(|unresolved_type| Some(unresolved_type.typ.clone())) - { - Some(UnresolvedTypeData::Named(path, _)) => Ok(path), - _ => Err(AztecMacroError::UnsupportedStorageType { - typ: field.1.typ.clone(), - span: field.1.span, - }), - }?; + let mapped_struct = generics + .last() + .and_then(|unresolved_type| Some(unresolved_type.typ.clone())) + .unwrap(); + let mut mapped_struct_path = match mapped_struct { + UnresolvedTypeData::Named(ref path, _) => Ok(path.clone()), + _ => Err(AztecMacroError::UnsupportedStorageType { + typ: field.1.typ.clone(), + span: field.1.span, + }), + }?; mapped_struct_path.segments.push(ident("new")); @@ -472,18 +522,18 @@ fn generate_storage_field_constructor( typ: UnresolvedTypeData::Unspecified, span: Some(Span::default()), }, - body: call( - variable_path(mapped_struct_path), - vec![variable("context"), variable("slot")], - ), + body: generate_map_field_constructor(mapped_struct)?, }))), ] } _ => { - return Err(AztecMacroError::UnsupportedStorageType { - typ: field.1.typ.clone(), - span: field.1.span, - }) + vec![ + variable("context"), + expression(ExpressionKind::Literal(Literal::Integer( + FieldElement::from(i128::from(0)), + false, + ))), + ] } }; let mut new_path = path.clone(); @@ -504,8 +554,12 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte let definition = module.types.iter().find(|r#struct| r#struct.name.0.contents == "Storage").unwrap(); - let field_constructors = - definition.fields.iter().map(|field| generate_storage_field_constructor(*field)?).collect(); + let field_constructors = definition + .fields + .iter() + .map(|field| generate_storage_field_constructor(field.clone())) + .flatten() + .collect(); let storage_constructor_statement = make_statement(StatementKind::Expression(expression( ExpressionKind::constructor((chained_path!("Storage"), field_constructors)), diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr index df143229104c..173e7bfdb942 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr @@ -58,50 +58,6 @@ contract CardGame { games: Map>, } - impl Storage { - fn init( - context: Context, - ) -> Self { - Storage { - collections: Map::new( - context, - 1, - |context, slot| { - Deck::new( - context, - slot, - ) - }, - ), - game_decks: Map::new( - context, - 2, - |context, slot| { - Map::new( - context, - slot, - |context, slot|{ - Deck::new( - context, - slot, - ) - } - ) - }, - ), - games: Map::new( - context, - 3, - |context, slot| { - PublicState::new( - context, - slot - ) - }, - ) - } - } - } #[aztec(private)] fn constructor() {} From d6ab45e36196db6fa92b08a74a5850a7a6047cef Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 29 Jan 2024 12:42:57 +0100 Subject: [PATCH 26/56] formatting --- noir/compiler/noirc_frontend/src/node_interner.rs | 1 - .../noir-contracts/contracts/card_game_contract/src/main.nr | 1 - .../contracts/easy_private_token_contract/src/main.nr | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/noir/compiler/noirc_frontend/src/node_interner.rs b/noir/compiler/noirc_frontend/src/node_interner.rs index 06bf585a823f..87f355077ee5 100644 --- a/noir/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/compiler/noirc_frontend/src/node_interner.rs @@ -1,4 +1,3 @@ -use std::borrow::Borrow; use std::collections::HashMap; use std::ops::Deref; diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr index 173e7bfdb942..d046e92d82f5 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/main.nr @@ -58,7 +58,6 @@ contract CardGame { games: Map>, } - #[aztec(private)] fn constructor() {} diff --git a/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr index f4d61f1bf670..26dbdc4ae2f2 100644 --- a/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr @@ -22,7 +22,7 @@ contract EasyPrivateToken { struct Storage { balances: Map, } - + /** * initialize the contract's initial state variables. */ From 4e9fa918e353263ee4648161bbea3d6ea1ec9bbc Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 29 Jan 2024 15:26:48 +0100 Subject: [PATCH 27/56] removed length hints --- .../src/contracts/src/types/token_note.nr | 5 ---- .../contracts/src/types/transparent_note.nr | 5 ---- .../classes/BarretenbergBackend.md | 25 ++++++++++++++++--- .../aztec-nr/address-note/src/address_note.nr | 5 ---- .../aztec-nr/aztec/src/note/note_getter.nr | 2 -- .../aztec-nr/aztec/src/oracle/storage.nr | 10 +++----- .../src/state_vars/immutable_singleton.nr | 2 -- .../aztec/src/state_vars/public_state.nr | 6 ++--- .../aztec/src/state_vars/singleton.nr | 2 -- .../src/compressed_string.nr | 5 ---- .../aztec-nr/field-note/src/field_note.nr | 5 ---- .../aztec-nr/safe-math/src/safe_u120.nr | 5 ---- .../slow-updates-tree/src/slow_map.nr | 9 ++----- .../aztec-nr/value-note/src/value_note.nr | 5 ---- .../contracts/card_game_contract/src/game.nr | 5 ---- .../src/types/card_note.nr | 5 ---- .../docs_example_contract/src/types/leader.nr | 4 --- .../src/ecdsa_public_key_note.nr | 5 ---- .../contracts/lending_contract/src/asset.nr | 5 ---- .../price_feed_contract/src/asset.nr | 5 ---- .../src/public_key_note.nr | 5 ---- .../src/types/token_note.nr | 5 ---- .../src/types/transparent_note.nr | 5 ---- .../token_contract/src/types/token_note.nr | 5 ---- .../src/types/transparent_note.nr | 5 ---- .../src/crates/types/src/abis/block_header.nr | 5 ---- .../types/src/abis/function_selector.nr | 5 ---- .../abis/nullifier_key_validation_request.nr | 8 ------ .../src/crates/types/src/abis/side_effect.nr | 10 -------- .../src/crates/types/src/address.nr | 10 -------- .../src/crates/types/src/traits.nr | 3 --- .../crates/types/src/type_serialization.nr | 20 --------------- 32 files changed, 28 insertions(+), 178 deletions(-) diff --git a/boxes/token/src/contracts/src/types/token_note.nr b/boxes/token/src/contracts/src/types/token_note.nr index 3d4786f206b8..2f27cf4cb6dc 100644 --- a/boxes/token/src/contracts/src/types/token_note.nr +++ b/boxes/token/src/contracts/src/types/token_note.nr @@ -55,11 +55,6 @@ impl Deserialize for TokenNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; TOKEN_NOTE_LEN] { - [0; TOKEN_NOTE_LEN] - } } impl NoteInterface for TokenNote { diff --git a/boxes/token/src/contracts/src/types/transparent_note.nr b/boxes/token/src/contracts/src/types/transparent_note.nr index 02b072b881de..4408e20dee42 100644 --- a/boxes/token/src/contracts/src/types/transparent_note.nr +++ b/boxes/token/src/contracts/src/types/transparent_note.nr @@ -38,11 +38,6 @@ impl Deserialize for TransparentNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; TRANSPARENT_NOTE_LEN] { - [0; TRANSPARENT_NOTE_LEN] - } } impl NoteInterface for TransparentNote { diff --git a/noir/docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md b/noir/docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md index 5cbe9421b92d..af4a7558cdf6 100644 --- a/noir/docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md +++ b/noir/docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md @@ -51,6 +51,9 @@ Destroys the backend generateFinalProof(decompressedWitness): Promise ``` +Generate a final proof. This is the proof for the circuit which will verify +intermediate proofs and or can be seen as the proof created for regular circuits. + #### Parameters | Parameter | Type | @@ -65,10 +68,6 @@ generateFinalProof(decompressedWitness): Promise [`Backend`](../interfaces/Backend.md).[`generateFinalProof`](../interfaces/Backend.md#generatefinalproof) -#### Description - -Generates a final proof (not meant to be verified in another circuit) - *** ### generateIntermediateProof() @@ -77,6 +76,14 @@ Generates a final proof (not meant to be verified in another circuit) generateIntermediateProof(witness): Promise ``` +Generates an intermediate proof. This is the proof that can be verified +in another circuit. + +This is sometimes referred to as a recursive proof. +We avoid this terminology as the only property of this proof +that matters is the fact that it is easy to verify in another circuit. +We _could_ choose to verify this proof outside of a circuit just as easily. + #### Parameters | Parameter | Type | @@ -105,6 +112,16 @@ const intermediateProof = await backend.generateIntermediateProof(witness); generateIntermediateProofArtifacts(proofData, numOfPublicInputs): Promise ``` +Generates artifacts that will be passed to a circuit that will verify this proof. + +Instead of passing the proof and verification key as a byte array, we pass them +as fields which makes it cheaper to verify in a circuit. + +The proof that is passed here will have been created using the `generateIntermediateProof` +method. + +The number of public inputs denotes how many public inputs are in the inner proof. + #### Parameters | Parameter | Type | Default value | diff --git a/yarn-project/aztec-nr/address-note/src/address_note.nr b/yarn-project/aztec-nr/address-note/src/address_note.nr index fa6817f04cde..3dc945793f2e 100644 --- a/yarn-project/aztec-nr/address-note/src/address_note.nr +++ b/yarn-project/aztec-nr/address-note/src/address_note.nr @@ -46,11 +46,6 @@ impl Deserialize for AddressNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; ADDRESS_NOTE_LEN] { - [0; ADDRESS_NOTE_LEN] - } } impl NoteInterface for AddressNote { diff --git a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr index 175b3c9bb8b5..a5a085c0e2b7 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr @@ -75,8 +75,6 @@ pub fn get_note( context: &mut PrivateContext, storage_slot: Field ) -> Note where Note: NoteInterface + Deserialize { - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - let _deserialized_length_hint: [Field; N] = Note::_deserialized_length_hint(); let note = get_note_internal(storage_slot); check_note_header(*context, storage_slot, note); diff --git a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr index 60e1b8521462..72bec83be3a3 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/storage.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/storage.nr @@ -3,21 +3,17 @@ use dep::protocol_types::traits::{Deserialize, Serialize}; #[oracle(storageRead)] fn storage_read_oracle(_storage_slot: Field, _number_of_elements: Field) -> [Field; N] {} -unconstrained fn storage_read_oracle_wrapper( - _storage_slot: Field, - _deserialized_length_hint: [Field; N] // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed -) -> [Field; N] { +unconstrained fn storage_read_oracle_wrapper(_storage_slot: Field) -> [Field; N] { storage_read_oracle(_storage_slot, N) } -pub fn storage_read(storage_slot: Field, _deserialized_length_hint: [Field; N]) -> [Field; N] { - storage_read_oracle_wrapper(storage_slot, _deserialized_length_hint) +pub fn storage_read(storage_slot: Field) -> [Field; N] { + storage_read_oracle_wrapper(storage_slot) } #[oracle(storageWrite)] fn storage_write_oracle(_storage_slot: Field, _values: [Field; N]) -> [Field; N] {} -// TODO: Remove return value. unconstrained pub fn storage_write(storage_slot: Field, fields: [Field; N]) { let _hash = storage_write_oracle(storage_slot, fields); } diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index 08cc2798abd3..187feca45fc6 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -86,8 +86,6 @@ impl ImmutableSingleton { // docs:start:view_note unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - let _deserialized_length_hint: [Field; N] = Note::_deserialized_length_hint(); let options = NoteViewerOptions::new().set_limit(1); view_notes(self.storage_slot, options)[0].unwrap() } diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr index e843be8a0997..9309f3d9d490 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr @@ -29,8 +29,7 @@ impl PublicState { // docs:start:public_state_struct_read pub fn read(self) -> T where T: Deserialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - let fields: [Field; T_SERIALIZED_LEN] = storage_read(self.storage_slot, T::_deserialized_length_hint()); + let fields = storage_read(self.storage_slot); T::deserialize(fields) } // docs:end:public_state_struct_read @@ -38,8 +37,7 @@ impl PublicState { // docs:start:public_state_struct_write pub fn write(self, value: T) where T: Serialize { assert(self.context.private.is_none(), "Public state writes only supported in public functions"); - // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088 - let fields: [Field; T_SERIALIZED_LEN] = T::serialize(value); + let fields = T::serialize(value); storage_write(self.storage_slot, fields); } // docs:end:public_state_struct_write diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 676fee86b647..19b4e91bb5ca 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -112,8 +112,6 @@ impl Singleton { // docs:start:view_note unconstrained pub fn view_note(self) -> Note where Note: NoteInterface + Deserialize { - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - let _deserialized_length_hint: [Field; N] = Note::_deserialized_length_hint(); let options = NoteViewerOptions::new().set_limit(1); view_notes(self.storage_slot, options)[0].unwrap() } diff --git a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr index 2cdc3226116e..7f7945d1cfc1 100644 --- a/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr +++ b/yarn-project/aztec-nr/compressed-string/src/compressed_string.nr @@ -20,11 +20,6 @@ impl Deserialize<1> for FieldCompressedString { fn deserialize(input: [Field; 1]) -> Self { Self { value: input[0] } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0; 1] - } } impl FieldCompressedString{ diff --git a/yarn-project/aztec-nr/field-note/src/field_note.nr b/yarn-project/aztec-nr/field-note/src/field_note.nr index 7fa81fc8a664..45b2ba612084 100644 --- a/yarn-project/aztec-nr/field-note/src/field_note.nr +++ b/yarn-project/aztec-nr/field-note/src/field_note.nr @@ -31,11 +31,6 @@ impl Deserialize for FieldNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0; 1] - } } impl NoteInterface for FieldNote { diff --git a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr index 7f866d555d54..4ef341bf8393 100644 --- a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr +++ b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr @@ -27,11 +27,6 @@ impl Deserialize for SafeU120 { fn deserialize(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 { SafeU120 { value: fields[0] as u120 } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0; 1] - } } impl SafeU120 { diff --git a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr index 3732cf3f06ea..065ab009197f 100644 --- a/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr +++ b/yarn-project/aztec-nr/slow-updates-tree/src/slow_map.nr @@ -29,11 +29,6 @@ impl Deserialize<3> for Leaf { fn deserialize(serialized: [Field; 3]) -> Leaf { Leaf { next_change: serialized[0], before: serialized[1], after: serialized[2] } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 3] { - [0; 3] - } } // Subset of the MembershipProof that is needed for the slow update. @@ -116,7 +111,7 @@ impl SlowMap { } pub fn read_root(self: Self) -> Leaf { - let fields = storage_read(self.storage_slot, Leaf::_deserialized_length_hint()); + let fields = storage_read(self.storage_slot); Leaf::deserialize(fields) } @@ -147,7 +142,7 @@ impl SlowMap { // docs:start:read_leaf_at pub fn read_leaf_at(self: Self, key: Field) -> Leaf { let derived_storage_slot = pedersen_hash([self.storage_slot, key]); - let fields = storage_read(derived_storage_slot, Leaf::_deserialized_length_hint()); + let fields = storage_read(derived_storage_slot); Leaf::deserialize(fields) } // docs:end:read_leaf_at diff --git a/yarn-project/aztec-nr/value-note/src/value_note.nr b/yarn-project/aztec-nr/value-note/src/value_note.nr index e25a825f4372..db0516f8306d 100644 --- a/yarn-project/aztec-nr/value-note/src/value_note.nr +++ b/yarn-project/aztec-nr/value-note/src/value_note.nr @@ -44,11 +44,6 @@ impl Deserialize for ValueNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 3] { - [0; 3] - } } impl NoteInterface for ValueNote { diff --git a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr index e355c45fc81d..4e9c75a77f78 100644 --- a/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr +++ b/yarn-project/noir-contracts/contracts/card_game_contract/src/game.nr @@ -83,11 +83,6 @@ impl Deserialize for Game { current_round: fields[14] as u32 } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; GAME_SERIALIZED_LEN] { - [0; GAME_SERIALIZED_LEN] - } } impl Game { diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr index 32e8717db768..0f38b9bc34a0 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr @@ -56,11 +56,6 @@ impl Deserialize for CardNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; CARD_NOTE_LEN] { - [0; CARD_NOTE_LEN] - } } impl NoteInterface for CardNote { diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/leader.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/leader.nr index b97eae225468..7be0ef86dbf8 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/leader.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/types/leader.nr @@ -15,10 +15,6 @@ impl Deserialize for Leader { fn deserialize(fields: [Field; LEADER_SERIALIZED_LEN]) -> Self { Leader { account: AztecAddress::from_field(fields[0]), points: fields[1] as u8 } } - - fn _deserialized_length_hint() -> [Field; LEADER_SERIALIZED_LEN] { - [0; LEADER_SERIALIZED_LEN] - } } impl Serialize for Leader { diff --git a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr index 9bb56364a08e..28d7c84fe795 100644 --- a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr +++ b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr @@ -72,11 +72,6 @@ impl Deserialize for EcdsaPublicKeyNote { EcdsaPublicKeyNote { x, y, owner: AztecAddress::from_field(serialized_note[4]), header: NoteHeader::empty() } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] { - [0; ECDSA_PUBLIC_KEY_NOTE_LEN] - } } impl NoteInterface for EcdsaPublicKeyNote { diff --git a/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr b/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr index 449f8a3d467c..5fbbb83a855f 100644 --- a/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr +++ b/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr @@ -39,9 +39,4 @@ impl Deserialize for Asset { oracle: AztecAddress::from_field(fields[3]) } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; ASSET_SERIALIZED_LEN] { - [0; ASSET_SERIALIZED_LEN] - } } diff --git a/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr b/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr index d320f53b99b2..047705a1ace9 100644 --- a/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr +++ b/yarn-project/noir-contracts/contracts/price_feed_contract/src/asset.nr @@ -16,9 +16,4 @@ impl Deserialize for Asset { fn deserialize(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { Asset { price: fields[0] as u120 } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; ASSET_SERIALIZED_LEN] { - [0; ASSET_SERIALIZED_LEN] - } } diff --git a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr index f2d73334c71d..ff9f1b78be0c 100644 --- a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr +++ b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr @@ -43,11 +43,6 @@ impl Deserialize for PublicKeyNote { header: NoteHeader::empty() } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; PUBLIC_KEY_NOTE_LEN] { - [0; PUBLIC_KEY_NOTE_LEN] - } } impl NoteInterface for PublicKeyNote { diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index f22f703120fe..235c121637af 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -51,11 +51,6 @@ impl Deserialize for TokenNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; TOKEN_NOTE_LEN] { - [0; TOKEN_NOTE_LEN] - } } impl NoteInterface for TokenNote { diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr index fd554ba39a48..0d5922db6954 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr @@ -38,11 +38,6 @@ impl Deserialize for TransparentNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; TRANSPARENT_NOTE_LEN] { - [0; TRANSPARENT_NOTE_LEN] - } } impl NoteInterface for TransparentNote { diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr index 69b3bae9ca41..ad0567bf28ef 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -58,11 +58,6 @@ impl Deserialize for TokenNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; TOKEN_NOTE_LEN] { - [0; TOKEN_NOTE_LEN] - } } impl NoteInterface for TokenNote { diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr index 515b1db07b5f..0c5ea2a724e0 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/transparent_note.nr @@ -38,11 +38,6 @@ impl Deserialize for TransparentNote { header: NoteHeader::empty(), } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; TRANSPARENT_NOTE_LEN] { - [0; TRANSPARENT_NOTE_LEN] - } } impl Empty for TransparentNote { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr index 51f0c6ea8f63..c63635b67a34 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr @@ -55,11 +55,6 @@ impl Deserialize for BlockHeader { global_variables_hash: deserialized[6], } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; BLOCK_HEADER_LENGTH] { - [0; BLOCK_HEADER_LENGTH] - } } impl BlockHeader { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr index 9f75985051af..93538f5248e6 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr @@ -27,11 +27,6 @@ impl Deserialize<1> for FunctionSelector { inner: fields[0] as u32 } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0; 1] - } } impl FunctionSelector { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_key_validation_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_key_validation_request.nr index b893e1a83dbe..b43754493d13 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_key_validation_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_key_validation_request.nr @@ -48,10 +48,6 @@ impl Deserialize for NullifierK secret_key: GrumpkinPrivateKey::new(fields[2], fields[3]), } } - - fn _deserialized_length_hint() -> [Field; NULLIFIER_KEY_VALIDATION_REQUEST_SERIALIZED_LEN] { - [0; NULLIFIER_KEY_VALIDATION_REQUEST_SERIALIZED_LEN] - } } impl NullifierKeyValidationRequest { @@ -108,9 +104,5 @@ impl Deserialize for Nu contract_address: AztecAddress::from_field(fields[4]), } } - - fn _deserialized_length_hint() -> [Field; NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_SERIALIZED_LEN] { - [0; NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_SERIALIZED_LEN] - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr index a783d6d88186..f49b429a417c 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr @@ -53,11 +53,6 @@ impl Deserialize<2> for SideEffect { counter: values[1] as u32, } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 2] { - [0; 2] - } } impl SideEffect { @@ -119,11 +114,6 @@ impl Deserialize<3> for SideEffectLinkedToNoteHash { counter: values[2] as u32, } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 3] { - [0; 3] - } } impl SideEffectLinkedToNoteHash{ diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr index 356e5efbb8af..0f581c0507b4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr @@ -46,11 +46,6 @@ impl Deserialize for AztecAddress { fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self { AztecAddress::from_field(fields[0]) } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] { - [0; AZTEC_ADDRESS_SERIALIZED_LEN] - } } impl AztecAddress { @@ -127,11 +122,6 @@ impl Deserialize for EthAddress { inner: fields[0] } } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; ETH_ADDRESS_SERIALIZED_LEN] { - [0; ETH_ADDRESS_SERIALIZED_LEN] - } } impl EthAddress{ diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr index 836267af638f..a971611fb0fa 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -51,7 +51,4 @@ trait Serialize { trait Deserialize { fn deserialize(fields: [Field; N]) -> Self; - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; N]; } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr index 265dff5b93f5..7bc12f02d275 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/type_serialization.nr @@ -17,11 +17,6 @@ impl Deserialize for u32 { fn deserialize(fields: [Field; U32_SERIALIZED_LEN]) -> Self { fields[0] as u32 } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0] - } } impl Serialize for u8 { @@ -34,11 +29,6 @@ impl Deserialize for u8 { fn deserialize(fields: [Field; U8_SERIALIZED_LEN]) -> Self { fields[0] as u8 } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0] - } } impl Serialize for Field { @@ -51,11 +41,6 @@ impl Deserialize for Field { fn deserialize(fields: [Field; FIELD_SERIALIZED_LEN]) -> Self { fields[0] } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0] - } } impl Serialize for bool { @@ -68,9 +53,4 @@ impl Deserialize for bool { fn deserialize(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool { fields[0] as bool } - - // TODO: Remove this once https://github.com/noir-lang/noir/issues/4088 is fixed - fn _deserialized_length_hint() -> [Field; 1] { - [0] - } } From 8386cc631c2babf9d971d58dcf94816871fb351d Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 29 Jan 2024 15:46:52 +0100 Subject: [PATCH 28/56] updated docs --- .../contracts/syntax/storage/private_state.md | 8 +++++--- .../contracts/syntax/storage/public_state.md | 15 ++++++--------- docs/docs/developers/testing/cheat_codes.md | 6 +++--- .../tutorials/writing_token_contract.md | 4 +--- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/docs/docs/developers/contracts/syntax/storage/private_state.md b/docs/docs/developers/contracts/syntax/storage/private_state.md index e1b2064dfa0d..7265226fbe4b 100644 --- a/docs/docs/developers/contracts/syntax/storage/private_state.md +++ b/docs/docs/developers/contracts/syntax/storage/private_state.md @@ -32,9 +32,11 @@ Unlike public state variables, which can be arbitrary types, private state varia Notes are the fundamental elements in the private world. -A note should conform to the following interface: +A note should implement the following traits: #include_code NoteInterface /yarn-project/aztec-nr/aztec/src/note/note_interface.nr rust +#include_code Serialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L48-L50 rust +#include_code Deserialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L52-L54 rust The interplay between a private state variable and its notes can be confusing. Here's a summary to aid intuition: @@ -66,7 +68,7 @@ Interestingly, if a developer requires a private state to be modifiable by users Singleton is a private state variable that is unique in a way. When a Singleton is initialized, a note is created to represent its value. And the way to update the value is to destroy the current note, and create a new one with the updated value. -Like for public state, we define the struct to have context, a storage slot and `note_interface` specifying how the note should be constructed and manipulated. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr). +Like for public state, we define the struct to have context and a storage slot. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr). An example of singleton usage in the account contracts is keeping track of public keys. The `Singleton` is added to the `Storage` struct as follows: @@ -74,7 +76,7 @@ An example of singleton usage in the account contracts is keeping track of publi ### `new` -As part of the initialization of the `Storage` struct, the `Singleton` is created as follows, here at the specified storage slot and with the `NoteInterface` for `CardNote`. +As part of the initialization of the `Storage` struct, the `Singleton` is created as follows at the specified storage slot. #include_code start_vars_singleton /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust diff --git a/docs/docs/developers/contracts/syntax/storage/public_state.md b/docs/docs/developers/contracts/syntax/storage/public_state.md index fa66f66ec6fc..f39b7642aa4a 100644 --- a/docs/docs/developers/contracts/syntax/storage/public_state.md +++ b/docs/docs/developers/contracts/syntax/storage/public_state.md @@ -8,17 +8,14 @@ For a higher level overview of the state model in Aztec, see the [state model](. ## Overview -The `PublicState` struct is generic over the variable type `T` and its serialized size `T_SERIALIZED_LEN`. +The `PublicState` struct is generic over the variable type `T`. The type *must* implement Serialize and Deserialize traits, as specified here: -:::info -Currently, the length of the types must be specified when declaring the storage struct but the intention is that this will be inferred in the future. -::: +#include_code Serialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L48-L50 rust +#include_code Deserialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L52-L54 rust The struct contains a `storage_slot` which, similar to Ethereum, is used to figure out _where_ in storage the variable is located. Notice that while we don't have the exact same [state model](../../../../learn/concepts/hybrid_state/main.md) as EVM chains it will look similar from the contract developers point of view. -Beyond the struct, the `PublicState` also contains `serialization_methods`, which is a struct with methods that instruct the `PublicState` how to serialize and deserialize the variable. You can find the details of `PublicState` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr). - -The Aztec.nr library provides serialization methods for various common types. +You can find the details of `PublicState` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr). :::info An example using a larger struct can be found in the [lending example](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-contracts/contracts/lending_contract)'s use of an [`Asset`](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/yarn-project/noir-contracts/contracts/lending_contract/src/asset.nr). @@ -26,7 +23,7 @@ An example using a larger struct can be found in the [lending example](https://g ### `new` -When declaring the storage for `T` as a persistent public storage variable, we use the `PublicState::new()` constructor. As seen below, this takes the `storage_slot` and the `serialization_methods` as arguments along with the [`Context`](../context.mdx), which in this case is used to share interface with other structures. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr). +When declaring the storage for `T` as a persistent public storage variable, we use the `PublicState::new()` constructor. As seen below, this takes the `storage_slot` and the [`Context`](../context.mdx), which in this case is used to share interface with other structures. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr). #### Single value example @@ -68,7 +65,7 @@ mapping(address => bool) internal minters; ### `read` -On the `PublicState` structs we have a `read` method to read the value at the location in storage and using the specified deserialization method to deserialize it. +On the `PublicState` structs we have a `read` method to read the value at the location in storage. #### Reading from our `admin` example diff --git a/docs/docs/developers/testing/cheat_codes.md b/docs/docs/developers/testing/cheat_codes.md index d789872625ec..f37b7d4f815e 100644 --- a/docs/docs/developers/testing/cheat_codes.md +++ b/docs/docs/developers/testing/cheat_codes.md @@ -468,7 +468,7 @@ struct Storage { impl Storage { fn init() -> Self { Storage { - balances: Map::new(1, |slot| PublicState::new(slot, FieldSerializationMethods)), + balances: Map::new(1, |slot| PublicState::new(slot)), } } } @@ -500,13 +500,13 @@ Note: One Field element occupies a storage slot. Hence, structs with multiple fi ```rust struct Storage { - balances: Map>, + balances: Map>, } impl Storage { fn init() -> Self { Storage { - balances: Map::new(1, |slot| PublicState::new(slot, FieldSerializationMethods)), + balances: Map::new(context, 1, |context, slot| PublicState::new(context, slot)), } } } diff --git a/docs/docs/developers/tutorials/writing_token_contract.md b/docs/docs/developers/tutorials/writing_token_contract.md index fe3b71421e4f..76ccb63e5e3a 100644 --- a/docs/docs/developers/tutorials/writing_token_contract.md +++ b/docs/docs/developers/tutorials/writing_token_contract.md @@ -234,7 +234,7 @@ Below the dependencies, paste the following Storage struct: Reading through the storage variables: -- `admin` a single Field value stored in public state. `FIELD_SERIALIZED_LEN` indicates the length of the variable, which is 1 in this case because it's a single Field element. A `Field` is basically an unsigned integer with a maximum value determined by the underlying cryptographic curve. +- `admin` a single Field value stored in public state. A `Field` is basically an unsigned integer with a maximum value determined by the underlying cryptographic curve. - `minters` is a mapping of Fields in public state. This will store whether an account is an approved minter on the contract. - `balances` is a mapping of private balances. Private balances are stored in a `Set` of `ValueNote`s. The balance is the sum of all of an account's `ValueNote`s. - `total_supply` is a Field value stored in public state and represents the total number of tokens minted. @@ -247,8 +247,6 @@ You can read more about it [here](../contracts/syntax/storage/main.md). Once we have Storage defined, we need to specify how to initialize it. The `init` method creates and initializes an instance of `Storage`. We define an initialization method for each of the storage variables defined above. Storage initialization is generic and can largely be reused for similar types, across different contracts, but it is important to note that each storage variable specifies it's storage slot, starting at 1. -Also, the public storage variables define the type that they store by passing the methods by which they are serialized. Because all `PublicState` in this contract is storing Field elements, each storage variable takes `FieldSerializationMethods`. - #include_code storage_init /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust ## Functions From 900d622167b8440818d07ced73377f9ccb833ee0 Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 29 Jan 2024 16:05:56 +0100 Subject: [PATCH 29/56] fixed docs --- .../developers/contracts/syntax/storage/private_state.md | 8 +++++--- .../developers/contracts/syntax/storage/public_state.md | 4 ++-- yarn-project/aztec-nr/aztec/src/note/note_interface.nr | 2 ++ .../noir-protocol-circuits/src/crates/types/src/traits.nr | 4 ++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/docs/developers/contracts/syntax/storage/private_state.md b/docs/docs/developers/contracts/syntax/storage/private_state.md index 7265226fbe4b..d2b4a31c08b6 100644 --- a/docs/docs/developers/contracts/syntax/storage/private_state.md +++ b/docs/docs/developers/contracts/syntax/storage/private_state.md @@ -34,9 +34,11 @@ Notes are the fundamental elements in the private world. A note should implement the following traits: -#include_code NoteInterface /yarn-project/aztec-nr/aztec/src/note/note_interface.nr rust -#include_code Serialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L48-L50 rust -#include_code Deserialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L52-L54 rust +#include_code note_interface /yarn-project/aztec-nr/aztec/src/note/note_interface.nr rust + +#include_code serialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr rust + +#include_code deserialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr rust The interplay between a private state variable and its notes can be confusing. Here's a summary to aid intuition: diff --git a/docs/docs/developers/contracts/syntax/storage/public_state.md b/docs/docs/developers/contracts/syntax/storage/public_state.md index f39b7642aa4a..3218d9a7bab1 100644 --- a/docs/docs/developers/contracts/syntax/storage/public_state.md +++ b/docs/docs/developers/contracts/syntax/storage/public_state.md @@ -10,8 +10,8 @@ For a higher level overview of the state model in Aztec, see the [state model](. The `PublicState` struct is generic over the variable type `T`. The type *must* implement Serialize and Deserialize traits, as specified here: -#include_code Serialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L48-L50 rust -#include_code Deserialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr#L52-L54 rust +#include_code serialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr rust +#include_code deserialize /yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr rust The struct contains a `storage_slot` which, similar to Ethereum, is used to figure out _where_ in storage the variable is located. Notice that while we don't have the exact same [state model](../../../../learn/concepts/hybrid_state/main.md) as EVM chains it will look similar from the contract developers point of view. diff --git a/yarn-project/aztec-nr/aztec/src/note/note_interface.nr b/yarn-project/aztec-nr/aztec/src/note/note_interface.nr index b79963b29021..48bd234e035a 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_interface.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_interface.nr @@ -1,6 +1,7 @@ use crate::context::PrivateContext; use crate::note::note_header::NoteHeader; +// docs:start:note_interface trait NoteInterface { fn compute_note_hash(self) -> Field; @@ -14,4 +15,5 @@ trait NoteInterface { fn broadcast(self, context: &mut PrivateContext, slot: Field) -> (); } +// docs:end:note_interface diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr index a971611fb0fa..e4cd56320cc4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -45,10 +45,14 @@ impl ToField for Field { } } +// docs:start:serialize trait Serialize { fn serialize(self) -> [Field; N]; } +// docs:end:serialize +// docs:start:deserialize trait Deserialize { fn deserialize(fields: [Field; N]) -> Self; } +// docs:end:deserialize \ No newline at end of file From 29672e7c312840d90e1b868b63ad988c1d3c6f97 Mon Sep 17 00:00:00 2001 From: thunkar Date: Mon, 29 Jan 2024 16:46:20 +0100 Subject: [PATCH 30/56] added migration notes --- docs/docs/misc/migration_notes.md | 298 ++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 54a95d598f92..9ee18b9bc03e 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -6,6 +6,304 @@ keywords: [sandbox, cli, aztec, notes, migration, updating, upgrading] Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them. +## 0.21.0 + +### [Aztec.nr] `Serialize`, `Deserialize`, `NoteInterface` as Traits, removal of SerializationMethods and SERIALIZED_LEN + +Storage definition and initialization has been simplified. Previously: + +```rust +struct Storage { + leader: PublicState, + legendary_card: Singleton, + profiles: Map>, + test: Set, + imm_singleton: ImmutableSingleton, +} + +impl Storage { + fn init(context: Context) -> Self { + Storage { + leader: PublicState::new( + context, + 1, + LeaderSerializationMethods, + ), + legendary_card: Singleton::new(context, 2, CardNoteMethods), + profiles: Map::new( + context, + 3, + |context, slot| { + Singleton::new(context, slot, CardNoteMethods) + }, + ), + test: Set::new(context, 4, CardNoteMethods), + imm_singleton: ImmutableSingleton::new(context, 4, CardNoteMethods), + } + } + } +``` + +Now: + +```rust +struct Storage { + leader: PublicState, + legendary_card: Singleton, + profiles: Map>, + test: Set, + imm_singleton: ImmutableSingleton, +} + +impl Storage { + fn init(context: Context) -> Self { + Storage { + leader: PublicState::new( + context, + 1 + ), + legendary_card: Singleton::new(context, 2), + profiles: Map::new( + context, + 3, + |context, slot| { + Singleton::new(context, slot) + }, + ), + test: Set::new(context, 4), + imm_singleton: ImmutableSingleton::new(context, 4), + } + } +} +``` + +For this to work, Notes must implement Serialize, Deserialize and NoteInterface Traits. Previously: + +```rust +use dep::aztec::protocol_types::address::AztecAddress; +use dep::aztec::{ + note::{ + note_header::NoteHeader, + note_interface::NoteInterface, + utils::compute_note_hash_for_read_or_nullify, + }, + oracle::{ + nullifier_key::get_nullifier_secret_key, + get_public_key::get_public_key, + }, + log::emit_encrypted_log, + hash::pedersen_hash, + context::PrivateContext, +}; + +// Shows how to create a custom note + +global CARD_NOTE_LEN: Field = 1; + +impl CardNote { + pub fn new(owner: AztecAddress) -> Self { + CardNote { + owner, + } + } + + pub fn serialize(self) -> [Field; CARD_NOTE_LEN] { + [self.owner.to_field()] + } + + pub fn deserialize(serialized_note: [Field; CARD_NOTE_LEN]) -> Self { + CardNote { + owner: AztecAddress::from_field(serialized_note[1]), + } + } + + pub fn compute_note_hash(self) -> Field { + pedersen_hash([ + self.owner.to_field(), + ],0) + } + + pub fn compute_nullifier(self, context: &mut PrivateContext) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(CardNoteMethods, self); + let secret = context.request_nullifier_secret_key(self.owner); + pedersen_hash([ + note_hash_for_nullify, + secret.high, + secret.low, + ],0) + } + + pub fn compute_nullifier_without_context(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(CardNoteMethods, self); + let secret = get_nullifier_secret_key(self.owner); + pedersen_hash([ + note_hash_for_nullify, + secret.high, + secret.low, + ],0) + } + + pub fn set_header(&mut self, header: NoteHeader) { + self.header = header; + } + + // Broadcasts the note as an encrypted log on L1. + pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { + let encryption_pub_key = get_public_key(self.owner); + emit_encrypted_log( + context, + (*context).this_address(), + slot, + encryption_pub_key, + self.serialize(), + ); + } +} + +fn deserialize(serialized_note: [Field; CARD_NOTE_LEN]) -> CardNote { + CardNote::deserialize(serialized_note) +} + +fn serialize(note: CardNote) -> [Field; CARD_NOTE_LEN] { + note.serialize() +} + +fn compute_note_hash(note: CardNote) -> Field { + note.compute_note_hash() +} + +fn compute_nullifier(note: CardNote, context: &mut PrivateContext) -> Field { + note.compute_nullifier(context) +} + +fn compute_nullifier_without_context(note: CardNote) -> Field { + note.compute_nullifier_without_context() +} + +fn get_header(note: CardNote) -> NoteHeader { + note.header +} + +fn set_header(note: &mut CardNote, header: NoteHeader) { + note.set_header(header) +} + +// Broadcasts the note as an encrypted log on L1. +fn broadcast(context: &mut PrivateContext, slot: Field, note: CardNote) { + note.broadcast(context, slot); +} + +global CardNoteMethods = NoteInterface { + deserialize, + serialize, + compute_note_hash, + compute_nullifier, + compute_nullifier_without_context, + get_header, + set_header, + broadcast, +}; +``` + +Now: + +```rust +use dep::aztec::{ + note::{ + note_header::NoteHeader, + note_interface::NoteInterface, + utils::compute_note_hash_for_read_or_nullify, + }, + oracle::{ + nullifier_key::get_nullifier_secret_key, + get_public_key::get_public_key, + }, + log::emit_encrypted_log, + hash::pedersen_hash, + context::PrivateContext, + protocol_types::{ + address::AztecAddress, + traits::{Serialize, Deserialize, Empty} + } +}; + +// Shows how to create a custom note + +global CARD_NOTE_LEN: Field = 1; + +impl CardNote { + pub fn new(owner: AztecAddress) -> Self { + CardNote { + owner, + } + } +} + +impl Serialize for CardNote { + fn serialize(self) -> [Field; CARD_NOTE_LEN] { + [self.owner.to_field()] + } +} + +impl Deserialize for CardNote { + fn deserialize(serialized_note: [Field; CARD_NOTE_LEN]) -> Self { + CardNote { + owner: AztecAddress::from_field(serialized_note[2]), + } + } +} + +impl NoteInterface for CardNote { + fn compute_note_hash(self) -> Field { + pedersen_hash([ + self.owner.to_field(), + ],0) + } + + fn compute_nullifier(self, context: &mut PrivateContext) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); + let secret = context.request_nullifier_secret_key(self.owner); + pedersen_hash([ + note_hash_for_nullify, + secret.high, + secret.low, + ],0) + } + + fn compute_nullifier_without_context(self) -> Field { + let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(self); + let secret = get_nullifier_secret_key(self.owner); + pedersen_hash([ + note_hash_for_nullify, + secret.high, + secret.low, + ],0) + } + + fn set_header(&mut self, header: NoteHeader) { + self.header = header; + } + + fn get_header(note: CardNote) -> NoteHeader { + note.header + } + + // Broadcasts the note as an encrypted log on L1. + fn broadcast(self, context: &mut PrivateContext, slot: Field) { + let encryption_pub_key = get_public_key(self.owner); + emit_encrypted_log( + context, + (*context).this_address(), + slot, + encryption_pub_key, + self.serialize(), + ); + } +} +``` + +Public state must implement Serialize and Deserialize traits. + ## 0.20.0 ### [Aztec.nr] Changes to `NoteInterface` From 9b7d069c29ed40dc539e15d09acf471c297aee9a Mon Sep 17 00:00:00 2001 From: thunkar Date: Tue, 30 Jan 2024 12:27:41 +0100 Subject: [PATCH 31/56] comments and better error handling in macros --- noir/aztec_macros/src/lib.rs | 197 +++++++++++------- .../src/hir/def_collector/dc_crate.rs | 14 +- noir/compiler/noirc_frontend/src/lib.rs | 6 +- 3 files changed, 141 insertions(+), 76 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 75e8a1cf302e..f9f45bc8656f 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -29,7 +29,11 @@ impl MacroProcessor for AztecMacro { transform(ast, crate_id, context) } - fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext) { + fn process_typed_ast( + &self, + crate_id: &CrateId, + context: &mut HirContext, + ) -> Result<(), (MacroError, FileId)> { transform_hir(crate_id, context) } } @@ -252,9 +256,9 @@ fn transform( // /// Completes the Hir with data gathered from type resolution -fn transform_hir(crate_id: &CrateId, context: &mut HirContext) { +fn transform_hir(crate_id: &CrateId, context: &mut HirContext) -> Result<(), (MacroError, FileId)> { transform_events(crate_id, context); - assign_storage_slots(crate_id, context).unwrap(); + assign_storage_slots(crate_id, context).map_err(|(err, file_id)| (err.into(), file_id)) } /// Includes an import to the aztec library if it has not been included yet @@ -422,52 +426,44 @@ fn transform_module( Ok(has_transformed_module) } +/// Auxiliary function to generate constructors in the storage struct for Maps, using +/// the Storage struct definition as a reference. Supports nesting. fn generate_map_field_constructor(typ: UnresolvedTypeData) -> Result { match &typ { UnresolvedTypeData::Named(path, generics) => { let mut new_path = path.clone().to_owned(); new_path.segments.push(ident("new")); match path.segments.last().unwrap().0.contents.as_str() { - "Map" => { - println!( - "nesting! {} - {:?}", - new_path, - generics.iter().cloned().last().unwrap().typ - ); - Ok(call( - variable_path(new_path), - vec![ - variable("context"), - variable("slot"), - expression(ExpressionKind::Lambda(Box::new(Lambda { - parameters: vec![ - ( - Pattern::Identifier(ident("context")), - make_type(UnresolvedTypeData::Named( - chained_path!("aztec", "context", "Context"), - vec![], - )), - ), - ( - Pattern::Identifier(ident("slot")), - make_type(UnresolvedTypeData::FieldElement), - ), - ], - return_type: UnresolvedType { - typ: UnresolvedTypeData::Unspecified, - span: Some(Span::default()), - }, - body: generate_map_field_constructor( - generics.iter().cloned().last().unwrap().typ, - )?, - }))), - ], - )) - } - _ => { - println!("Generating args - {}", new_path); - Ok(call(variable_path(new_path), vec![variable("context"), variable("slot")])) - } + "Map" => Ok(call( + variable_path(new_path), + vec![ + variable("context"), + variable("slot"), + expression(ExpressionKind::Lambda(Box::new(Lambda { + parameters: vec![ + ( + Pattern::Identifier(ident("context")), + make_type(UnresolvedTypeData::Named( + chained_path!("aztec", "context", "Context"), + vec![], + )), + ), + ( + Pattern::Identifier(ident("slot")), + make_type(UnresolvedTypeData::FieldElement), + ), + ], + return_type: UnresolvedType { + typ: UnresolvedTypeData::Unspecified, + span: Some(Span::default()), + }, + body: generate_map_field_constructor( + generics.iter().cloned().last().unwrap().typ, + )?, + }))), + ], + )), + _ => Ok(call(variable_path(new_path), vec![variable("context"), variable("slot")])), } } _ => { @@ -479,6 +475,8 @@ fn generate_map_field_constructor(typ: UnresolvedTypeData) -> Result Result<(Ident, Expression), AztecMacroError> { @@ -551,6 +549,35 @@ fn generate_storage_field_constructor( Ok(field_constructor) } +// Generates the Storage implementation block from the Storage struct definition if it does not exist +/// From: +/// +/// struct Storage { +/// a_map: Map>, +/// a_nested_map: Map>>, +/// a_field: SomeStoragePrimitive, +/// } +/// +/// To: +/// +/// impl Storage { +/// fn init(context: Context) -> Self { +/// Storage { +/// a_map: Map::new(context, 0, |context, slot| { +/// SomeStoragePrimitive::new(context, slot) +/// }), +/// a_nested_map: Map::new(context, 0, |context, slot| { +/// Map::new(context, slot, |context, slot| { +/// SomeStoragePrimitive::new(context, slot) +/// }) +/// }), +/// a_field: SomeStoragePrimitive::new(context, 0), +/// } +/// } +/// } +/// +/// Storage slots are generated as 0 and will be populated using the information from the HIR +/// at a later stage. fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), AztecMacroError> { let definition = module.types.iter().find(|r#struct| r#struct.name.0.contents == "Storage").unwrap(); @@ -760,17 +787,24 @@ fn transform_events(crate_id: &CrateId, context: &mut HirContext) { } } +/// Obtains the serialized length of a type that implements the Serialize trait. fn get_serialized_length( serialize_traits: &Vec, typ: &Type, interner: &NodeInterner, ) -> Result { - let stored_in_state = match typ { - Type::Struct(_, generics) => Ok(generics[0].clone()), + let maybe_stored_in_state = match typ { + Type::Struct(_, generics) => Ok(generics.get(0)), _ => Err(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: Some("State storage variable must be a struct".to_string()), }), }?; + let stored_in_state = match maybe_stored_in_state { + Some(stored_in_state) => Ok(stored_in_state), + None => Err(AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some("State storage variable must be generic".to_string()), + }), + }?; let trait_impl_kind = serialize_traits .iter() .filter_map(|&s_trait_id| { @@ -798,10 +832,12 @@ fn get_serialized_length( } } +/// Assigns storage slots to the storage struct fields based on the serialized length of the types. This automatic assignment +/// will only trigger if the assigned storage slot is invalid (0 as generated by generate_storage_implementation) fn assign_storage_slots( crate_id: &CrateId, context: &mut HirContext, -) -> Result<(), AztecMacroError> { +) -> Result<(), (AztecMacroError, FileId)> { let serialize_traits: Vec<_> = collect_traits(context) .iter() .filter(|trait_id| { @@ -813,6 +849,7 @@ fn assign_storage_slots( for struct_id in collect_crate_structs(crate_id, context) { let interner: &mut NodeInterner = context.def_interner.borrow_mut(); let r#struct = interner.get_struct(struct_id); + let file_id = r#struct.borrow().location.file; if r#struct.borrow().name.0.contents == "Storage" && r#struct.borrow().id.krate().is_root() { let init_id = interner @@ -822,17 +859,21 @@ fn assign_storage_slots( "init", false, ) - .ok_or(AztecMacroError::CouldNotAssignStorageSlots { - secondary_message: Some( - "Storage struct must have an init function".to_string(), - ), - })?; + .ok_or(( + AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage struct must have an init function".to_string(), + ), + }, + file_id, + ))?; let init_function = interner.function(&init_id).block(interner); - let init_function_statement_id = init_function.statements().first().ok_or( + let init_function_statement_id = init_function.statements().first().ok_or(( AztecMacroError::CouldNotAssignStorageSlots { secondary_message: Some("Init storage statement not found".to_string()), }, - )?; + file_id, + ))?; let storage_constructor_statement = interner.statement(init_function_statement_id); let storage_constructor_expression = match storage_constructor_statement { @@ -841,19 +882,22 @@ fn assign_storage_slots( HirExpression::Constructor(hir_constructor_expression) => { Ok(hir_constructor_expression) } - _ => Err(AztecMacroError::CouldNotAssignStorageSlots { + _ => Err((AztecMacroError::CouldNotAssignStorageSlots { secondary_message: Some( "Storage constructor statement must be a constructor expression" .to_string(), ), - }), + }, file_id)) } } - _ => Err(AztecMacroError::CouldNotAssignStorageSlots { - secondary_message: Some( - "Storage constructor statement must be an expression".to_string(), - ), - }), + _ => Err(( + AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage constructor statement must be an expression".to_string(), + ), + }, + file_id, + )), }?; let mut storage_slot: u64 = 1; @@ -862,12 +906,15 @@ fn assign_storage_slots( let (_, field_type) = fields.get(index).unwrap(); let new_call_expression = match interner.expression(expr_id) { HirExpression::Call(hir_call_expression) => Ok(hir_call_expression), - _ => Err(AztecMacroError::CouldNotAssignStorageSlots { - secondary_message: Some( - "Storage field initialization expression is not a call expression" - .to_string(), - ), - }), + _ => Err(( + AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage field initialization expression is not a call expression" + .to_string(), + ), + }, + file_id, + )), }?; let slot_arg_expression = interner.expression(&new_call_expression.arguments[1]); @@ -876,12 +923,15 @@ fn assign_storage_slots( HirExpression::Literal(HirLiteral::Integer(slot, _)) => { Ok(slot.borrow().to_u128()) } - _ => Err(AztecMacroError::CouldNotAssignStorageSlots { - secondary_message: Some( - "Storage slot argument expression must be a literal integer" - .to_string(), - ), - }), + _ => Err(( + AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Storage slot argument expression must be a literal integer" + .to_string(), + ), + }, + file_id, + )), }?; if current_storage_slot != 0 { @@ -889,7 +939,8 @@ fn assign_storage_slots( } let type_serialized_len = - get_serialized_length(&serialize_traits, field_type, interner)?; + get_serialized_length(&serialize_traits, field_type, interner) + .map_err(|err| (err.into(), file_id))?; interner.update_expression(new_call_expression.arguments[1], |expr| { *expr = HirExpression::Literal(HirLiteral::Integer( FieldElement::from(u128::from(storage_slot)), diff --git a/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index a6ab6b1d825b..35a3eb54d722 100644 --- a/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/noir/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -14,7 +14,7 @@ use crate::hir::resolution::{ use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; use crate::hir::Context; -use crate::macros_api::MacroProcessor; +use crate::macros_api::{MacroError, MacroProcessor}; use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; use crate::parser::{ParserError, SortedModule}; @@ -155,6 +155,12 @@ impl From for CustomDiagnostic { } } +impl From for CompilationError { + fn from(value: MacroError) -> Self { + CompilationError::DefinitionError(DefCollectorErrorKind::MacroError(value)) + } +} + impl From for CompilationError { fn from(value: ParserError) -> Self { CompilationError::ParseError(value) @@ -359,7 +365,11 @@ impl DefCollector { errors.extend(resolved_globals.errors); for macro_processor in macro_processors { - macro_processor.process_typed_ast(&crate_id, context); + let macro_result = macro_processor.process_typed_ast(&crate_id, context); + if macro_result.is_err() { + let (error, file_id) = macro_result.unwrap_err(); + errors.push((error.into(), file_id)); + } } errors.extend(type_check_globals(&mut context.def_interner, resolved_globals.globals)); diff --git a/noir/compiler/noirc_frontend/src/lib.rs b/noir/compiler/noirc_frontend/src/lib.rs index 9582b80dcba4..b6d4c5683345 100644 --- a/noir/compiler/noirc_frontend/src/lib.rs +++ b/noir/compiler/noirc_frontend/src/lib.rs @@ -75,6 +75,10 @@ pub mod macros_api { ) -> Result; /// Function to manipulate the AST after type checking has been completed. /// The AST after type checking has been done is called the HIR. - fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext); + fn process_typed_ast( + &self, + crate_id: &CrateId, + context: &mut HirContext, + ) -> Result<(), (MacroError, FileId)>; } } From dff29018be5eec2c963c99b592067eac419fe5e3 Mon Sep 17 00:00:00 2001 From: thunkar Date: Tue, 30 Jan 2024 13:24:41 +0100 Subject: [PATCH 32/56] docs update --- docs/docs/developers/testing/cheat_codes.md | 2 +- docs/docs/misc/migration_notes.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/developers/testing/cheat_codes.md b/docs/docs/developers/testing/cheat_codes.md index f37b7d4f815e..982020d4ae10 100644 --- a/docs/docs/developers/testing/cheat_codes.md +++ b/docs/docs/developers/testing/cheat_codes.md @@ -504,7 +504,7 @@ struct Storage { } impl Storage { - fn init() -> Self { + fn init(context: Context) -> Self { Storage { balances: Map::new(context, 1, |context, slot| PublicState::new(context, slot)), } diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 9ee18b9bc03e..bea84d5c980a 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -6,7 +6,7 @@ keywords: [sandbox, cli, aztec, notes, migration, updating, upgrading] Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them. -## 0.21.0 +## 0.22.0 ### [Aztec.nr] `Serialize`, `Deserialize`, `NoteInterface` as Traits, removal of SerializationMethods and SERIALIZED_LEN From 28514d4ee229df84319a38a57b3530439417f19b Mon Sep 17 00:00:00 2001 From: thunkar Date: Tue, 30 Jan 2024 14:18:48 +0100 Subject: [PATCH 33/56] updated docs and migration guide --- .../contracts/syntax/storage/main.md | 20 ++++---- .../contracts/syntax/storage/private_state.md | 8 +--- .../aztecnr-getting-started.md | 12 ----- .../writing_private_voting_contract.md | 14 +----- docs/docs/misc/migration_notes.md | 48 ++++++++++--------- 5 files changed, 39 insertions(+), 63 deletions(-) diff --git a/docs/docs/developers/contracts/syntax/storage/main.md b/docs/docs/developers/contracts/syntax/storage/main.md index 7e9b382f82d5..1d2335362353 100644 --- a/docs/docs/developers/contracts/syntax/storage/main.md +++ b/docs/docs/developers/contracts/syntax/storage/main.md @@ -46,7 +46,15 @@ If you don't yet have any private state variables defined you can use this place #include_code compute_note_hash_and_nullifier_placeholder /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr rust ::: -Since Aztec.nr is written in Noir, which is state-less, we need to specify how the storage struct should be initialized to read and write data correctly. This is done by specifying an `init` function that is run in functions that rely on reading or altering the state variables. This `init` function must declare the Storage struct with an instantiation defining how variables are accessed and manipulated. The function MUST be called `init` for the Aztec.nr library to properly handle it (this will be relaxed in the future). +Since Aztec.nr is written in Noir, which is state-less, we need to specify how the storage struct should be initialized to read and write data correctly. In most cases, the initialization of the storage is handled by the Aztec.nr library, which creates a default implementation based on the provided `Storage` struct. + +:::danger +The automatic initialization has some limitations. Using any combination of the provided storage primitives (`PublicState`, `Singleton`, `ImmutableSingleton`, `Set`, `Map`, including nested ones) will ensure that the library will be able to handle it on its own. + +Custom structures are also supported as long as they are generic over `T`, where `T` implements `Serialize` and `Deserialize` in the case it represents public state and additionally `NoteInterface` for private state. +::: + +Custom initialization of the storage is also possible. This is done by specifying an `init` function that is run in functions that rely on reading or altering the state variables. This `init` function must declare the Storage struct with an instantiation defining how variables are accessed and manipulated. The function MUST be called `init` for the Aztec.nr library to properly handle it (this will be relaxed in the future). ```rust impl Storage { @@ -79,7 +87,7 @@ You can view the implementation in the Aztec.nr library [here](https://github.co ### `new` -When declaring the storage for a map, we use the `Map::new()` constructor. As seen below, this takes the `storage_slot` and the `start_var_constructor` along with the [`Context`](../context.mdx). +When declaring the storage for a map, we use the `Map::new()` constructor. This takes the `storage_slot` and the `start_var_constructor` along with the [`Context`](../context.mdx). We will see examples of map constructors for public and private variables in later sections. @@ -91,10 +99,6 @@ In the Storage struct: #include_code storage-map-singleton-declaration /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust -In the `Storage::init` function: - -#include_code state_vars-MapSingleton /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust - #### Public Example When declaring a public mapping in Storage, we have to specify that the type is public by declaring it as `PublicState` instead of specifying a note type like with private storage above. @@ -103,10 +107,6 @@ In the Storage struct: #include_code storage_minters /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust -In the `Storage::init` function: - -#include_code storage_minters_init /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust - ### `at` When dealing with a Map, we can access the value at a given key using the `::at` method. This takes the key as an argument and returns the value at that key. diff --git a/docs/docs/developers/contracts/syntax/storage/private_state.md b/docs/docs/developers/contracts/syntax/storage/private_state.md index d2b4a31c08b6..2f2401bdcd6c 100644 --- a/docs/docs/developers/contracts/syntax/storage/private_state.md +++ b/docs/docs/developers/contracts/syntax/storage/private_state.md @@ -78,9 +78,7 @@ An example of singleton usage in the account contracts is keeping track of publi ### `new` -As part of the initialization of the `Storage` struct, the `Singleton` is created as follows at the specified storage slot. - -#include_code start_vars_singleton /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust +As part of the initialization of the `Storage` struct, the `Singleton` is created at the specified storage slot. ### `initialize` @@ -138,9 +136,7 @@ Functionally similar to [`get_note`](#get_note), but executed in unconstrained f ### `new` -As part of the initialization of the `Storage` struct, the `Singleton` is created as follows, here at storage slot 1 and with the `NoteInterface` for `PublicKeyNote`. - -#include_code storage_init /yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr rust +As part of the initialization of the `Storage` struct, the `Singleton` is created. ### `initialize` diff --git a/docs/docs/developers/getting_started/aztecnr-getting-started.md b/docs/docs/developers/getting_started/aztecnr-getting-started.md index 599c50d84e06..cb4163061a2a 100644 --- a/docs/docs/developers/getting_started/aztecnr-getting-started.md +++ b/docs/docs/developers/getting_started/aztecnr-getting-started.md @@ -92,18 +92,6 @@ We are also using `balance_utils` from this import, a useful library that allows This allows us to store our counter in a way that acts as an integer, abstracting the note logic. -## Implement a Storage struct - -In this step, we will initiate a `Storage` struct to store balances in a private way. The vast majority Aztec.nr smart contracts will need this. - -#include_code storage_struct /yarn-project/noir-contracts/contracts/counter_contract/src/main.nr rust - -We are only storing one variable - `counts` as a `Map` of `EasyPrivateUint`. This means our `count` will act as a private integer, and we can map it to an address. - -#include_code storage_init /yarn-project/noir-contracts/contracts/counter_contract/src/main.nr rust - -This `init` method is creating and initializing a `Storage` instance. This instance includes a `Map` named `counters`. Each entry in this `Map` represents an account's counter. - ## Keep the counter private Now we’ve got a mechanism for storing our private state, we can start using it to ensure the privacy of balances. diff --git a/docs/docs/developers/tutorials/writing_private_voting_contract.md b/docs/docs/developers/tutorials/writing_private_voting_contract.md index 82f46f860de2..649e0ece4341 100644 --- a/docs/docs/developers/tutorials/writing_private_voting_contract.md +++ b/docs/docs/developers/tutorials/writing_private_voting_contract.md @@ -80,11 +80,7 @@ We are using various utils within the Aztec library: ## Set up storage -Under these imports, we need to set up our contract storage. This is done in two steps: - -1. Storage struct -2. Storage impl block with init function - +Under these imports, we need to set up our contract storage. Define the storage struct like so: #include_code storage_struct yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr rust @@ -95,14 +91,6 @@ In this contract, we will store three vars: 2. tally, as a map with key as the persona and value as the number (in Field) held in public state 3. voteEnded, as a boolean held in public state -Under the struct, define the impl block like this: - -#include_code storage_impl yarn-project/noir-contracts/contracts/easy_private_voting_contract/src/main.nr rust - -The `impl` block must define one function `init` that explains how to access and manipulate our variables. We pass context, a storage slot, and serialization methods we imported earlier. - -This `init` function will be called every time we access `storage` in our functions. - ## Constructor The next step is to initialize the contract with a constructor. The constructor will take an address as a parameter and set the admin. diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index bea84d5c980a..aae2a0d0cdd0 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -54,27 +54,6 @@ struct Storage { test: Set, imm_singleton: ImmutableSingleton, } - -impl Storage { - fn init(context: Context) -> Self { - Storage { - leader: PublicState::new( - context, - 1 - ), - legendary_card: Singleton::new(context, 2), - profiles: Map::new( - context, - 3, - |context, slot| { - Singleton::new(context, slot) - }, - ), - test: Set::new(context, 4), - imm_singleton: ImmutableSingleton::new(context, 4), - } - } -} ``` For this to work, Notes must implement Serialize, Deserialize and NoteInterface Traits. Previously: @@ -302,7 +281,32 @@ impl NoteInterface for CardNote { } ``` -Public state must implement Serialize and Deserialize traits. +Public state must implement Serialize and Deserialize traits. + +It is still possible to manually implement the storage initialization (for custom storage wrappers or internal types that don't implement the required traits). For the above example, the `impl Storage` section would look like this: + +```rust +impl Storage { + fn init(context: Context) -> Self { + Storage { + leader: PublicState::new( + context, + 1 + ), + legendary_card: Singleton::new(context, 2), + profiles: Map::new( + context, + 3, + |context, slot| { + Singleton::new(context, slot) + }, + ), + test: Set::new(context, 4), + imm_singleton: ImmutableSingleton::new(context, 4), + } + } +} +``` ## 0.20.0 From ac1efebcd246d46e19a93e3bbf2aa5164cc7c47b Mon Sep 17 00:00:00 2001 From: thunkar Date: Tue, 30 Jan 2024 15:33:27 +0100 Subject: [PATCH 34/56] fixed test --- yarn-project/end-to-end/src/e2e_note_getter.test.ts | 10 +++++----- .../noir-contracts/contracts/test_contract/src/main.nr | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index ed00016612ac..ac4d9e33f5e1 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -167,22 +167,22 @@ describe('e2e_note_getter', () => { async function assertNoteIsReturned(storageSlot: number, expectedValue: number, activeOrNullified: boolean) { const viewNotesResult = await contract.methods.call_view_notes(storageSlot, activeOrNullified).view(); - const getNotesResult = await callGetNotes(storageSlot, activeOrNullified); + const getNoteResult = await callGetNote(storageSlot, activeOrNullified); - expect(viewNotesResult).toEqual(getNotesResult); + expect(viewNotesResult).toEqual(getNoteResult); expect(viewNotesResult).toEqual(BigInt(expectedValue)); } async function assertNoReturnValue(storageSlot: number, activeOrNullified: boolean) { await expect(contract.methods.call_view_notes(storageSlot, activeOrNullified).view()).rejects.toThrow('is_some'); - await expect(contract.methods.call_get_notes(storageSlot, activeOrNullified).send().wait()).rejects.toThrow( + await expect(contract.methods.call_get_note(storageSlot, activeOrNullified).send().wait()).rejects.toThrow( 'is_some', ); } - async function callGetNotes(storageSlot: number, activeOrNullified: boolean): Promise { + async function callGetNote(storageSlot: number, activeOrNullified: boolean): Promise { // call_get_notes exposes the return value via an event since we cannot use view() with it. - const tx = contract.methods.call_get_notes(storageSlot, activeOrNullified).send(); + const tx = contract.methods.call_get_note(storageSlot, activeOrNullified).send(); await tx.wait(); const logs = (await tx.getUnencryptedLogs()).logs; diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index 3d27b6924003..23b2502141db 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -103,7 +103,7 @@ contract Test { } #[aztec(private)] - fn call_get_note(storage_slot: Field, active_or_nullified: bool) { + fn call_get_note(storage_slot: Field, active_or_nullified: bool) { assert(storage_slot != 1, "storage slot 1 is reserved for example_constant"); let mut options = NoteGetterOptions::new(); From 5caf8961c49fd23aa482b9f76a59ea2c7de9e737 Mon Sep 17 00:00:00 2001 From: thunkar Date: Tue, 30 Jan 2024 15:34:49 +0100 Subject: [PATCH 35/56] reverted name change --- yarn-project/end-to-end/src/e2e_note_getter.test.ts | 10 +++++----- .../noir-contracts/contracts/test_contract/src/main.nr | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index ac4d9e33f5e1..ed00016612ac 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -167,22 +167,22 @@ describe('e2e_note_getter', () => { async function assertNoteIsReturned(storageSlot: number, expectedValue: number, activeOrNullified: boolean) { const viewNotesResult = await contract.methods.call_view_notes(storageSlot, activeOrNullified).view(); - const getNoteResult = await callGetNote(storageSlot, activeOrNullified); + const getNotesResult = await callGetNotes(storageSlot, activeOrNullified); - expect(viewNotesResult).toEqual(getNoteResult); + expect(viewNotesResult).toEqual(getNotesResult); expect(viewNotesResult).toEqual(BigInt(expectedValue)); } async function assertNoReturnValue(storageSlot: number, activeOrNullified: boolean) { await expect(contract.methods.call_view_notes(storageSlot, activeOrNullified).view()).rejects.toThrow('is_some'); - await expect(contract.methods.call_get_note(storageSlot, activeOrNullified).send().wait()).rejects.toThrow( + await expect(contract.methods.call_get_notes(storageSlot, activeOrNullified).send().wait()).rejects.toThrow( 'is_some', ); } - async function callGetNote(storageSlot: number, activeOrNullified: boolean): Promise { + async function callGetNotes(storageSlot: number, activeOrNullified: boolean): Promise { // call_get_notes exposes the return value via an event since we cannot use view() with it. - const tx = contract.methods.call_get_note(storageSlot, activeOrNullified).send(); + const tx = contract.methods.call_get_notes(storageSlot, activeOrNullified).send(); await tx.wait(); const logs = (await tx.getUnencryptedLogs()).logs; diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index 23b2502141db..14d7a7f6ee62 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -103,7 +103,7 @@ contract Test { } #[aztec(private)] - fn call_get_note(storage_slot: Field, active_or_nullified: bool) { + fn call_get_notes(storage_slot: Field, active_or_nullified: bool) { assert(storage_slot != 1, "storage slot 1 is reserved for example_constant"); let mut options = NoteGetterOptions::new(); From 9e6c8cc7e7f4588efac436c56df5e3e0d2ce9476 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 31 Jan 2024 12:35:35 +0100 Subject: [PATCH 36/56] refactor for simplyfication --- noir/aztec_macros/src/lib.rs | 126 ++++++++++------------------------- 1 file changed, 36 insertions(+), 90 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index f9f45bc8656f..575848026320 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -175,6 +175,17 @@ fn member_access(lhs: &str, rhs: &str) -> Expression { }))) } +fn lambda(parameters: Vec<(Pattern, UnresolvedType)>, body: Expression) -> Expression { + expression(ExpressionKind::Lambda(Box::new(Lambda { + parameters, + return_type: UnresolvedType { + typ: UnresolvedTypeData::Unspecified, + span: Some(Span::default()), + }, + body, + }))) +} + macro_rules! chained_path { ( $base:expr $(, $tail:expr)* ) => { { @@ -426,9 +437,13 @@ fn transform_module( Ok(has_transformed_module) } -/// Auxiliary function to generate constructors in the storage struct for Maps, using -/// the Storage struct definition as a reference. Supports nesting. -fn generate_map_field_constructor(typ: UnresolvedTypeData) -> Result { +/// Auxiliary function to generate the storage constructor for a given field, using +/// the Storage definition as a reference. Supports nesting. +fn generate_storage_field_constructor( + (type_ident, unresolved_type): (Ident, UnresolvedType), + slot: Expression, +) -> Result { + let typ = unresolved_type.typ; match &typ { UnresolvedTypeData::Named(path, generics) => { let mut new_path = path.clone().to_owned(); @@ -438,9 +453,9 @@ fn generate_map_field_constructor(typ: UnresolvedTypeData) -> Result Result Ok(call(variable_path(new_path), vec![variable("context"), variable("slot")])), + _ => Ok(call(variable_path(new_path), vec![variable("context"), slot])), } } _ => { return Err(AztecMacroError::UnsupportedStorageType { typ: typ.clone(), - span: Some(Span::default()), + span: Some(type_ident.span()), }) } } } -/// Auxiliary function to generate the storage constructor for a given field, using -/// the Storage definition as a reference. Supports nesting. -fn generate_storage_field_constructor( - field: (Ident, UnresolvedType), -) -> Result<(Ident, Expression), AztecMacroError> { - let field_constructor = if let UnresolvedTypeData::Named(path, generics) = &field.1.typ { - let args = match path.segments.last().unwrap().0.contents.as_str() { - "Map" => { - let mapped_struct = generics - .last() - .and_then(|unresolved_type| Some(unresolved_type.typ.clone())) - .unwrap(); - let mut mapped_struct_path = match mapped_struct { - UnresolvedTypeData::Named(ref path, _) => Ok(path.clone()), - _ => Err(AztecMacroError::UnsupportedStorageType { - typ: field.1.typ.clone(), - span: field.1.span, - }), - }?; - - mapped_struct_path.segments.push(ident("new")); - - vec![ - variable("context"), - expression(ExpressionKind::Literal(Literal::Integer( - FieldElement::from(i128::from(0)), - false, - ))), - expression(ExpressionKind::Lambda(Box::new(Lambda { - parameters: vec![ - ( - Pattern::Identifier(ident("context")), - make_type(UnresolvedTypeData::Named( - chained_path!("aztec", "context", "Context"), - vec![], - )), - ), - ( - Pattern::Identifier(ident("slot")), - make_type(UnresolvedTypeData::FieldElement), - ), - ], - return_type: UnresolvedType { - typ: UnresolvedTypeData::Unspecified, - span: Some(Span::default()), - }, - body: generate_map_field_constructor(mapped_struct)?, - }))), - ] - } - _ => { - vec![ - variable("context"), - expression(ExpressionKind::Literal(Literal::Integer( - FieldElement::from(i128::from(0)), - false, - ))), - ] - } - }; - let mut new_path = path.clone(); - new_path.segments.push(ident("new")); - let expression = call(variable_path(new_path), args); - (field.0.clone(), expression) - } else { - return Err(AztecMacroError::UnsupportedStorageType { - typ: field.1.typ.clone(), - span: field.1.span, - }); - }; - - Ok(field_constructor) -} - // Generates the Storage implementation block from the Storage struct definition if it does not exist /// From: /// @@ -582,10 +520,18 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte let definition = module.types.iter().find(|r#struct| r#struct.name.0.contents == "Storage").unwrap(); + let slot_zero = expression(ExpressionKind::Literal(Literal::Integer( + FieldElement::from(i128::from(0)), + false, + ))); + let field_constructors = definition .fields .iter() - .map(|field| generate_storage_field_constructor(field.clone())) + .map(|field| { + generate_storage_field_constructor(field.clone(), slot_zero.clone()) + .map(|expression| (field.0.clone(), expression)) + }) .flatten() .collect(); From 4dd510ff5bdaa47bfc0c7b90f557cae47c87b82d Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 31 Jan 2024 20:09:56 +0100 Subject: [PATCH 37/56] completely remove balanceset --- .../contracts/token_blacklist_contract/src/types.nr | 1 - .../contracts/token_blacklist_contract/src/types/balances_map.nr | 1 - .../noir-contracts/contracts/token_contract/src/types.nr | 1 - .../contracts/token_contract/src/types/balances_map.nr | 1 - 4 files changed, 4 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr index 3ba036583906..149d823a3393 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types.nr @@ -1,5 +1,4 @@ mod transparent_note; -mod balance_set; mod balances_map; mod token_note; mod roles; diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr index ea0b4ec37bba..7b2f15a5b73b 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -1,5 +1,4 @@ use dep::std::option::Option; -use crate::types::balance_set::BalanceSet; use dep::safe_math::SafeU120; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types.nr index d3b3b1c9e773..62a1bb2a363e 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types.nr @@ -1,4 +1,3 @@ mod transparent_note; -mod balance_set; mod balances_map; mod token_note; diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr index ea0b4ec37bba..7b2f15a5b73b 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -1,5 +1,4 @@ use dep::std::option::Option; -use crate::types::balance_set::BalanceSet; use dep::safe_math::SafeU120; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, From 92c41c4b3020578c4a053845fa540cf799fac982 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 31 Jan 2024 20:32:27 +0100 Subject: [PATCH 38/56] fixed slots --- .../token_blacklist_contract/src/main.nr | 16 +++++++-------- .../contracts/token_contract/src/main.nr | 20 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr index 7ee54bec5801..f8be509ecfe1 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -52,12 +52,12 @@ contract TokenBlacklist { // docs:end:interface struct Storage { - admin: PublicState, - balances: BalancesMap, - total_supply: PublicState, - pending_shields: Set, - public_balances: Map>, - slow_update: ImmutableSingleton, + admin: PublicState, + balances: BalancesMap, // slot 2 + total_supply: PublicState, + pending_shields: Set, // slot 6 + public_balances: Map>, + slow_update: ImmutableSingleton, // slot 9 public_slow_update: PublicState, } @@ -347,9 +347,9 @@ contract TokenBlacklist { preimage: [Field; TOKEN_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - if (storage_slot == 5) { + if (storage_slot == 6) { note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, preimage) - } else if (storage_slot == 7) { + } else if (storage_slot == 9) { note_utils::compute_note_hash_and_nullifier(FieldNote::deserialize, note_header, preimage) } else { note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, preimage) diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index 65d19c449467..21687a5f60ae 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -56,22 +56,22 @@ contract Token { // docs:start:storage_struct struct Storage { // docs:start:storage_admin - admin: PublicState, + admin: PublicState, 1 // docs:end:storage_admin // docs:start:storage_minters - minters: Map>, + minters: Map>, 2 // docs:end:storage_minters // docs:start:storage_balances - balances: BalancesMap, + balances: BalancesMap, 3 // docs:end:storage_balances - total_supply: PublicState, + total_supply: PublicState, 6 // docs:start:storage_pending_shields - pending_shields: Set, + pending_shields: Set, 7 // docs:end:storage_pending_shields - public_balances: Map>, - symbol: PublicState, - name: PublicState, - decimals: PublicState, + public_balances: Map>, 9 + symbol: PublicState, 10 + name: PublicState, 11 + decimals: PublicState, 12 } // docs:end:storage_struct @@ -378,7 +378,7 @@ contract Token { serialized_note: [Field; TOKEN_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - if (storage_slot == 5) { + if (storage_slot == 7) { note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) } else { note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) From b81fa5dd8e768a13f5d76b010e1a84d8e2a3d01c Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 31 Jan 2024 20:40:10 +0100 Subject: [PATCH 39/56] actually saved file --- .../contracts/token_contract/src/main.nr | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index 21687a5f60ae..2a480f890d93 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -56,22 +56,22 @@ contract Token { // docs:start:storage_struct struct Storage { // docs:start:storage_admin - admin: PublicState, 1 + admin: PublicState, // docs:end:storage_admin // docs:start:storage_minters - minters: Map>, 2 + minters: Map>, // docs:end:storage_minters // docs:start:storage_balances - balances: BalancesMap, 3 + balances: BalancesMap, // slot 3 // docs:end:storage_balances - total_supply: PublicState, 6 + total_supply: PublicState, // docs:start:storage_pending_shields - pending_shields: Set, 7 + pending_shields: Set, // slot 7 // docs:end:storage_pending_shields - public_balances: Map>, 9 - symbol: PublicState, 10 - name: PublicState, 11 - decimals: PublicState, 12 + public_balances: Map>, + symbol: PublicState, + name: PublicState, + decimals: PublicState, } // docs:end:storage_struct From e858bad4a63e571213acbe6536c1fc53f91d26ca Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 31 Jan 2024 21:10:16 +0100 Subject: [PATCH 40/56] merge conflicts --- noir/aztec_macros/src/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 81ecf22514fb..eea51c9cbf3c 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -273,9 +273,11 @@ fn transform( // /// Completes the Hir with data gathered from type resolution -fn transform_hir(crate_id: &CrateId, context: &mut HirContext) -> Result<(), (MacroError, FileId)> { - transform_events(crate_id, context)?; - assign_storage_slots(crate_id, context) +fn transform_hir( + crate_id: &CrateId, + context: &mut HirContext, +) -> Result<(), (AztecMacroError, FileId)> { + transform_events(crate_id, context).and(assign_storage_slots(crate_id, context)) } /// Includes an import to the aztec library if it has not been included yet From 1fc7b9b8299b9d548289eb44d224de3804af6644 Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 31 Jan 2024 22:01:48 +0100 Subject: [PATCH 41/56] cleanup --- .../token_blacklist_contract/src/types/balances_map.nr | 2 -- .../contracts/token_contract/src/main.nr | 10 ++-------- .../contracts/token_contract/src/types/balances_map.nr | 2 -- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr index 7b2f15a5b73b..bf62e3788193 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -22,7 +22,6 @@ use crate::types::token_note::{TokenNote, OwnedNote}; struct BalancesMap { context: Context, - storage_slot: Field, set: Set } @@ -34,7 +33,6 @@ impl BalancesMap { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { context, - storage_slot, set: Set::new(context, storage_slot) } } diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index 2a480f890d93..44a46adf9c9d 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -13,8 +13,8 @@ contract Token { // Libs use dep::std::option::Option; - use dep::safe_math::{SafeU120, SAFE_U120_SERIALIZED_LEN}; - use dep::compressed_string::{FieldCompressedString}; + use dep::safe_math::SafeU120; + use dep::compressed_string::FieldCompressedString; use dep::aztec::{ note::{ @@ -26,12 +26,6 @@ contract Token { hash::{compute_secret_hash}, state_vars::{map::Map, public_state::PublicState, set::Set}, protocol_types::{ - type_serialization::{ - FIELD_SERIALIZED_LEN, - BOOL_SERIALIZED_LEN, - U8_SERIALIZED_LEN, - AZTEC_ADDRESS_SERIALIZED_LEN - }, abis::function_selector::FunctionSelector, address::AztecAddress } diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr index 7b2f15a5b73b..bf62e3788193 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -22,7 +22,6 @@ use crate::types::token_note::{TokenNote, OwnedNote}; struct BalancesMap { context: Context, - storage_slot: Field, set: Set } @@ -34,7 +33,6 @@ impl BalancesMap { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { context, - storage_slot, set: Set::new(context, storage_slot) } } From 0465b02bb32ddb8c75a1709b37133f26dd3905ec Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 12:38:18 +0100 Subject: [PATCH 42/56] simplified constructor --- .../src/types/balances_map.nr | 18 +++++++++-------- .../token_contract/src/types/balances_map.nr | 20 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr index bf62e3788193..a1e41d16bcfa 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -8,21 +8,23 @@ use dep::aztec::{ constants::MAX_READ_REQUESTS_PER_CALL, traits::{Serialize, Deserialize} }, - state_vars::set::Set, + state_vars::{ + set::Set, + map::Map + }, note::{ note_getter::view_notes, note_getter_options::{NoteGetterOptions, SortOrder}, note_viewer_options::NoteViewerOptions, note_header::NoteHeader, note_interface::NoteInterface, - utils::compute_note_hash_for_read_or_nullify, } }; use crate::types::token_note::{TokenNote, OwnedNote}; struct BalancesMap { context: Context, - set: Set + map: Map> } impl BalancesMap { @@ -33,7 +35,7 @@ impl BalancesMap { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { context, - set: Set::new(context, storage_slot) + map: Map::new(context, storage_slot, |context, slot| Set::new(context, slot)) } } @@ -46,7 +48,7 @@ impl BalancesMap { let mut balance = SafeU120::min(); // docs:start:view_notes let options = NoteViewerOptions::new().set_offset(offset); - let opt_notes = self.set.view_notes(options); + let opt_notes = self.map.at(owner).view_notes(options); // docs:end:view_notes let len = opt_notes.len(); for i in 0..len { @@ -65,14 +67,14 @@ impl BalancesMap { let mut addend_note = T::new(addend, owner); // docs:start:insert - self.set.insert(&mut addend_note, true); + self.map.at(owner).insert(&mut addend_note, true); // docs:end:insert } pub fn sub(self: Self, owner: AztecAddress, subtrahend: SafeU120) where T: Deserialize + Serialize + NoteInterface + OwnedNote{ // docs:start:get_notes let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend); - let maybe_notes = self.set.get_notes(options); + let maybe_notes = self.map.at(owner).get_notes(options); // docs:end:get_notes let mut minuend: SafeU120 = SafeU120::min(); @@ -85,7 +87,7 @@ impl BalancesMap { // which require knowledge of the secret key (currently the users encryption key). // The contract logic must ensure that the spending key is used as well. // docs:start:remove - self.set.remove(note); + self.map.at(owner).remove(note); // docs:end:remove minuend = minuend.add(note.get_amount()); diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr index bf62e3788193..2f5835248a04 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -8,21 +8,22 @@ use dep::aztec::{ constants::MAX_READ_REQUESTS_PER_CALL, traits::{Serialize, Deserialize} }, - state_vars::set::Set, + state_vars::{ + set::Set, + map::Map + }, note::{ note_getter::view_notes, note_getter_options::{NoteGetterOptions, SortOrder}, note_viewer_options::NoteViewerOptions, note_header::NoteHeader, note_interface::NoteInterface, - utils::compute_note_hash_for_read_or_nullify, } }; use crate::types::token_note::{TokenNote, OwnedNote}; struct BalancesMap { - context: Context, - set: Set + map: Map> } impl BalancesMap { @@ -32,8 +33,7 @@ impl BalancesMap { ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { - context, - set: Set::new(context, storage_slot) + map: Map::new(context, storage_slot, |context, slot| Set::new(context, slot)) } } @@ -46,7 +46,7 @@ impl BalancesMap { let mut balance = SafeU120::min(); // docs:start:view_notes let options = NoteViewerOptions::new().set_offset(offset); - let opt_notes = self.set.view_notes(options); + let opt_notes = self.map.at(owner).view_notes(options); // docs:end:view_notes let len = opt_notes.len(); for i in 0..len { @@ -65,14 +65,14 @@ impl BalancesMap { let mut addend_note = T::new(addend, owner); // docs:start:insert - self.set.insert(&mut addend_note, true); + self.map.at(owner).insert(&mut addend_note, true); // docs:end:insert } pub fn sub(self: Self, owner: AztecAddress, subtrahend: SafeU120) where T: Deserialize + Serialize + NoteInterface + OwnedNote{ // docs:start:get_notes let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend); - let maybe_notes = self.set.get_notes(options); + let maybe_notes = self.map.at(owner).get_notes(options); // docs:end:get_notes let mut minuend: SafeU120 = SafeU120::min(); @@ -85,7 +85,7 @@ impl BalancesMap { // which require knowledge of the secret key (currently the users encryption key). // The contract logic must ensure that the spending key is used as well. // docs:start:remove - self.set.remove(note); + self.map.at(owner).remove(note); // docs:end:remove minuend = minuend.add(note.get_amount()); From a16f0bea86a0359225ba771ba2bab3ff951f1861 Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 15:09:38 +0100 Subject: [PATCH 43/56] finally fixed slots --- avm-transpiler/rust-toolchain.toml | 2 +- boxes/token/src/contracts/src/main.nr | 2 +- docs/docs/developers/testing/cheat_codes.md | 2 +- noir/aztec_macros/src/lib.rs | 56 ++++++++++++------- yarn-project/aztec-nr/aztec/src/state_vars.nr | 1 + .../src/state_vars/immutable_singleton.nr | 3 + .../aztec-nr/aztec/src/state_vars/map.nr | 3 + .../aztec/src/state_vars/public_state.nr | 3 + .../aztec-nr/aztec/src/state_vars/set.nr | 4 +- .../aztec/src/state_vars/singleton.nr | 3 + .../src/state_vars/stable_public_state.nr | 3 + .../aztec-nr/aztec/src/state_vars/store.nr | 8 +++ .../ecdsa_account_contract/src/main.nr | 2 +- .../contracts/escrow_contract/src/main.nr | 2 +- .../schnorr_account_contract/src/main.nr | 2 +- .../contracts/test_contract/src/main.nr | 2 +- .../token_blacklist_contract/src/main.nr | 10 ++-- .../contracts/token_contract/src/main.nr | 6 +- 18 files changed, 78 insertions(+), 36 deletions(-) create mode 100644 yarn-project/aztec-nr/aztec/src/state_vars/store.nr diff --git a/avm-transpiler/rust-toolchain.toml b/avm-transpiler/rust-toolchain.toml index 6ed42dc02c29..eb89935c774d 100644 --- a/avm-transpiler/rust-toolchain.toml +++ b/avm-transpiler/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.71.1" +channel = "1.72" components = [ "rust-src" ] targets = [] profile = "default" diff --git a/boxes/token/src/contracts/src/main.nr b/boxes/token/src/contracts/src/main.nr index 5b85b2e4d74a..65ce0ce07718 100644 --- a/boxes/token/src/contracts/src/main.nr +++ b/boxes/token/src/contracts/src/main.nr @@ -374,7 +374,7 @@ contract Token { serialized_note: [Field; TOKEN_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - if (storage_slot == 5) { + if (storage_slot == storage.pending_shields.get_storage_slot()) { note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) } else { note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) diff --git a/docs/docs/developers/testing/cheat_codes.md b/docs/docs/developers/testing/cheat_codes.md index 982020d4ae10..834685210f8a 100644 --- a/docs/docs/developers/testing/cheat_codes.md +++ b/docs/docs/developers/testing/cheat_codes.md @@ -462,7 +462,7 @@ The baseSlot is specified in the Aztec.nr contract. ```rust struct Storage { - balances: Map>, + balances: Map>, } impl Storage { diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index eea51c9cbf3c..a8912f3cf1e8 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -1,4 +1,5 @@ use std::borrow::{Borrow, BorrowMut}; +use std::vec; use iter_extended::vecmap; use noirc_frontend::macros_api::FieldElement; @@ -774,12 +775,14 @@ fn transform_events( /// Obtains the serialized length of a type that implements the Serialize trait. fn get_serialized_length( - serialize_traits: &Vec, + traits: &Vec, typ: &Type, interner: &NodeInterner, ) -> Result { - let maybe_stored_in_state = match typ { - Type::Struct(_, generics) => Ok(generics.get(0)), + let (struct_name, maybe_stored_in_state) = match typ { + Type::Struct(struct_type, generics) => { + Ok((struct_type.borrow().name.0.contents.clone(), generics.get(0))) + } _ => Err(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: Some("State storage variable must be a struct".to_string()), }), @@ -790,13 +793,34 @@ fn get_serialized_length( secondary_message: Some("State storage variable must be generic".to_string()), }), }?; - let trait_impl_kind = serialize_traits + + let is_note = traits.iter().any(|&trait_id| { + let r#trait = interner.get_trait(trait_id); + r#trait.borrow().name.0.contents == "NoteInterface" + && !interner + .lookup_all_trait_implementations(stored_in_state.clone(), trait_id) + .is_empty() + }); + + // Maps and (private) Notes always occupy a single slot. Someone could store a Note in PublicState for whatever reason though. + if struct_name == "Map" || (is_note && struct_name != "PublicState") { + return Ok(1); + } + + let trait_impl_kind = traits .iter() - .filter_map(|&s_trait_id| { - interner - .lookup_all_trait_implementations(stored_in_state.clone(), s_trait_id) - .into_iter() - .nth(0) + .filter_map(|&trait_id| { + let r#trait = interner.get_trait(trait_id); + if r#trait.borrow().name.0.contents == "Serialize" + && r#trait.borrow().generics.len() == 1 + { + interner + .lookup_all_trait_implementations(stored_in_state.clone(), trait_id) + .into_iter() + .nth(0) + } else { + None + } }) .nth(0) .ok_or(AztecMacroError::CouldNotAssignStorageSlots { @@ -823,14 +847,7 @@ fn assign_storage_slots( crate_id: &CrateId, context: &mut HirContext, ) -> Result<(), (AztecMacroError, FileId)> { - let serialize_traits: Vec<_> = collect_traits(context) - .iter() - .filter(|trait_id| { - let r#trait = context.def_interner.get_trait(**trait_id); - r#trait.borrow().name.0.contents == "Serialize" && r#trait.borrow().generics.len() == 1 - }) - .cloned() - .collect(); + let traits: Vec<_> = collect_traits(context).iter().cloned().collect(); for struct_id in collect_crate_structs(crate_id, context) { let interner: &mut NodeInterner = context.def_interner.borrow_mut(); let r#struct = interner.get_struct(struct_id); @@ -923,9 +940,8 @@ fn assign_storage_slots( continue; } - let type_serialized_len = - get_serialized_length(&serialize_traits, field_type, interner) - .map_err(|err| (err.into(), file_id))?; + let type_serialized_len = get_serialized_length(&traits, field_type, interner) + .map_err(|err| (err.into(), file_id))?; interner.update_expression(new_call_expression.arguments[1], |expr| { *expr = HirExpression::Literal(HirLiteral::Integer( FieldElement::from(u128::from(storage_slot)), diff --git a/yarn-project/aztec-nr/aztec/src/state_vars.nr b/yarn-project/aztec-nr/aztec/src/state_vars.nr index d8213bb1ef04..8e186bc2ef86 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars.nr @@ -4,3 +4,4 @@ mod public_state; mod set; mod singleton; mod stable_public_state; +mod store; diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index 187feca45fc6..9368436bcc26 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -16,6 +16,7 @@ use crate::note::{ note_viewer_options::NoteViewerOptions, }; use crate::oracle::notes::check_nullifier_exists; +use crate::state_vars::store::Store; // docs:start:struct struct ImmutableSingleton { @@ -24,6 +25,8 @@ struct ImmutableSingleton { } // docs:end:struct +impl Store for ImmutableSingleton {} + impl ImmutableSingleton { // docs:start:new pub fn new( diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/map.nr b/yarn-project/aztec-nr/aztec/src/state_vars/map.nr index fefa84ea00e7..90c6ee3a1888 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/map.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/map.nr @@ -4,6 +4,7 @@ use dep::protocol_types::{ hash::pedersen_hash, traits::{ToField} }; +use crate::state_vars::store::Store; // docs:start:map struct Map { @@ -13,6 +14,8 @@ struct Map { } // docs:end:map +impl Store for Map {} + impl Map { // docs:start:new pub fn new( diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr index 9309f3d9d490..fa8387d377ac 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr @@ -3,6 +3,7 @@ use crate::oracle::storage::storage_read; use crate::oracle::storage::storage_write; use dep::std::option::Option; use dep::protocol_types::traits::{Deserialize, Serialize}; +use crate::state_vars::store::Store; // docs:start:public_state_struct struct PublicState { @@ -11,6 +12,8 @@ struct PublicState { } // docs:end:public_state_struct +impl Store for PublicState {} + impl PublicState { // docs:start:public_state_struct_new pub fn new( diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr index 03e53b33d7a2..e0f82bbea02d 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr @@ -15,6 +15,7 @@ use crate::note::{ note_viewer_options::NoteViewerOptions, utils::compute_note_hash_for_consumption, }; +use crate::state_vars::store::Store; // docs:start:struct struct Set { @@ -23,6 +24,8 @@ struct Set { } // docs:end:struct +impl Store for Set {} + impl Set { // docs:start:new pub fn new( @@ -36,7 +39,6 @@ impl Set { } } // docs:end:new - // docs:start:insert pub fn insert(self, note: &mut Note, diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 19b4e91bb5ca..0c141b1e53b4 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -20,6 +20,7 @@ use crate::oracle::{ nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists, }; +use crate::state_vars::store::Store; // docs:start:struct struct Singleton { @@ -28,6 +29,8 @@ struct Singleton { } // docs:end:struct +impl Store for Singleton {} + impl Singleton { // docs:start:new pub fn new( diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr index 013f059aef08..8482890a54ff 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr @@ -5,12 +5,15 @@ use crate::oracle::{ use crate::history::public_value_inclusion::prove_public_value_inclusion; use dep::std::option::Option; use dep::protocol_types::traits::{Deserialize, Serialize}; +use crate::state_vars::store::Store; struct StablePublicState{ context: Context, storage_slot: Field, } +impl Store for StablePublicState {} + impl StablePublicState { pub fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/store.nr b/yarn-project/aztec-nr/aztec/src/state_vars/store.nr new file mode 100644 index 000000000000..966c55911294 --- /dev/null +++ b/yarn-project/aztec-nr/aztec/src/state_vars/store.nr @@ -0,0 +1,8 @@ +use crate::context::{Context}; +use dep::protocol_types::traits::{Deserialize, Serialize}; + +trait Store where T: Serialize + Deserialize { + fn get_storage_slot(self) -> Field { + self.storage_slot + } +} diff --git a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index 702d6f97049c..d74016d2f2d1 100644 --- a/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -96,7 +96,7 @@ contract EcdsaAccount { storage_slot: Field, serialized_note: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] ) -> pub [Field; 4] { - assert(storage_slot == 1); + assert(storage_slot == storage.public_key.get_storage_slot()); let note_header = NoteHeader::new(contract_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(EcdsaPublicKeyNote::deserialize, note_header, serialized_note) } diff --git a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr index 5f3e35bf2c92..b479e6593caa 100644 --- a/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/escrow_contract/src/main.nr @@ -67,7 +67,7 @@ contract Escrow { serialized_note: [Field; ADDRESS_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - assert(storage_slot == 1); + assert(storage_slot == storage.owners.get_storage_slot()); note_utils::compute_note_hash_and_nullifier(AddressNote::deserialize, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr index 9396af0519a3..c412146f82e0 100644 --- a/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -101,7 +101,7 @@ contract SchnorrAccount { storage_slot: Field, serialized_note: [Field; PUBLIC_KEY_NOTE_LEN] ) -> pub [Field; 4] { - assert(storage_slot == 1); + assert(storage_slot == storage.signing_public_key.get_storage_slot()); let note_header = NoteHeader::new(contract_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(PublicKeyNote::deserialize, note_header, serialized_note) } diff --git a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr index 7a493f584e2e..d1a18eea77b7 100644 --- a/yarn-project/noir-contracts/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/test_contract/src/main.nr @@ -325,7 +325,7 @@ contract Test { storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN] // must fit either a FieldNote or a ValueNote ) -> pub [Field; 4] { - if (storage_slot == 1) { + if (storage_slot == storage.example_constant.get_storage_slot()) { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(FieldNote::deserialize, note_header, serialized_note) } else { diff --git a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr index f8be509ecfe1..f6558115fc31 100644 --- a/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -53,11 +53,11 @@ contract TokenBlacklist { struct Storage { admin: PublicState, - balances: BalancesMap, // slot 2 + balances: BalancesMap, total_supply: PublicState, - pending_shields: Set, // slot 6 + pending_shields: Set, public_balances: Map>, - slow_update: ImmutableSingleton, // slot 9 + slow_update: ImmutableSingleton, public_slow_update: PublicState, } @@ -347,9 +347,9 @@ contract TokenBlacklist { preimage: [Field; TOKEN_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - if (storage_slot == 6) { + if (storage_slot == storage.pending_shields.get_storage_slot()) { note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, preimage) - } else if (storage_slot == 9) { + } else if (storage_slot == storage.slow_update.get_storage_slot()) { note_utils::compute_note_hash_and_nullifier(FieldNote::deserialize, note_header, preimage) } else { note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, preimage) diff --git a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr index 77c57793afb7..aa6ad831fcb9 100644 --- a/yarn-project/noir-contracts/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/token_contract/src/main.nr @@ -56,11 +56,11 @@ contract Token { minters: Map>, // docs:end:storage_minters // docs:start:storage_balances - balances: BalancesMap, // slot 3 + balances: BalancesMap, // docs:end:storage_balances total_supply: PublicState, // docs:start:storage_pending_shields - pending_shields: Set, // slot 7 + pending_shields: Set, // docs:end:storage_pending_shields public_balances: Map>, symbol: StablePublicState, @@ -395,7 +395,7 @@ contract Token { serialized_note: [Field; TOKEN_NOTE_LEN] ) -> pub [Field; 4] { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - if (storage_slot == 7) { + if (storage_slot == storage.pending_shields.get_storage_slot()) { note_utils::compute_note_hash_and_nullifier(TransparentNote::deserialize, note_header, serialized_note) } else { note_utils::compute_note_hash_and_nullifier(TokenNote::deserialize, note_header, serialized_note) From 58c35ea4f9b5a9c3ae13a88f455d1d76d8925c30 Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 16:19:56 +0100 Subject: [PATCH 44/56] fixed docs --- .../contracts/syntax/storage/private_state.md | 18 ++++-- .../contracts/syntax/storage/public_state.md | 20 ++++-- .../docs_example_contract/src/main.nr | 63 +++++++++++++++++-- 3 files changed, 86 insertions(+), 15 deletions(-) diff --git a/docs/docs/developers/contracts/syntax/storage/private_state.md b/docs/docs/developers/contracts/syntax/storage/private_state.md index 79b919c911c4..c60590612c12 100644 --- a/docs/docs/developers/contracts/syntax/storage/private_state.md +++ b/docs/docs/developers/contracts/syntax/storage/private_state.md @@ -78,7 +78,9 @@ An example of singleton usage in the account contracts is keeping track of publi ### `new` -As part of the initialization of the `Storage` struct, the `Singleton` is created at the specified storage slot. +As part of the initialization of the `Storage` struct, the `Singleton` is created as follows at the specified storage slot. + +#include_code start_vars_singleton /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `initialize` @@ -136,7 +138,9 @@ Functionally similar to [`get_note`](#get_note), but executed in unconstrained f ### `new` -As part of the initialization of the `Storage` struct, the `Singleton` is created. +As part of the initialization of the `Storage` struct, the `Singleton` is created as follows, here at storage slot 1. + +#include_code storage-immutable-singleton-declaration /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `initialize` @@ -150,7 +154,7 @@ For example, if the storage slot depends on the an address then it is possible t Set the value of an ImmutableSingleton by calling the `initialize` method: -#include_code initialize /yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr rust +#include_code initialize-immutable-singleton /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust Once initialized, an ImmutableSingleton's value remains unchangeable. This method can only be called once. @@ -164,7 +168,7 @@ Similar to the `Singleton`, we can use the `get_note` method to read the value o Use this method to retrieve the value of an initialized ImmutableSingleton. -#include_code get_note /yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr rust +#include_code get_note-immutable-singleton /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust Unlike a `Singleton`, the `get_note` function for an ImmutableSingleton doesn't nullify the current note in the background. This means that multiple accounts can concurrently call this function to read the value. @@ -182,12 +186,16 @@ You can view the implementation [here](https://github.com/AztecProtocol/aztec-pa And can be added to the `Storage` struct as follows. Here adding a set for a custom note, the TransparentNote (useful for [public -> private communication](../functions/calling_functions.md#public---private)). -#include_code storage_pending_shields /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust +#include_code storage-set-declaration /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `new` The `new` method tells the contract how to operate on the underlying storage. +We can initialize the set as follows: + +#include_code storage-set-init /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust + ### `insert` Allows us to modify the storage by inserting a note into the set. diff --git a/docs/docs/developers/contracts/syntax/storage/public_state.md b/docs/docs/developers/contracts/syntax/storage/public_state.md index 4689c3e78271..8c2a16bfe41b 100644 --- a/docs/docs/developers/contracts/syntax/storage/public_state.md +++ b/docs/docs/developers/contracts/syntax/storage/public_state.md @@ -29,9 +29,13 @@ When declaring the storage for `T` as a persistent public storage variable, we u Say that we wish to add `admin` public state variable into our storage struct. In the struct we can define it as: -#include_code storage_admin /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust +#include_code storage-leader-declaration /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust -We have specified that we are storing a `Field`. This is just a single value, and is similar to the following in solidity: +And then when initializing it in the `Storage::init` function we can do: + +#include_code storage-leader-init /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust + +We have specified that we are storing a `Field` that should be placed in storage slot `1`. This is just a single value, and is similar to the following in solidity: ```solidity address internal admin; @@ -41,9 +45,13 @@ address internal admin; Say we want to have a group of `minters` that are able to mint assets in our contract, and we want them in public storage, because [access control in private is quite cumbersome](../../../../learn/concepts/communication/cross_chain_calls.md#a-note-on-l2-access-control). In the `Storage` struct we can add it as follows: -#include_code storage_minters /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust +#include_code storage-minters-declaration /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust + +And then when initializing it in the `Storage::init` function we can do it as follows: + +#include_code storage-minters-init /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust -In this case, specifying that we are dealing with a map of Fields. +In this case, specifying that we are dealing with a map of Fields, and that it should be put at slot 2. This would be similar to the following in solidity: @@ -96,9 +104,9 @@ You can find the details of `StablePublicState` in the implementation [here](htt ### `new` Is done exactly like the `PublicState` struct, but with the `StablePublicState` struct. -#include_code storage_decimals /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust +#include_code storage-stable-declaration /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust -#include_code storage_decimals_init /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust +#include_code storage-stable-init /yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `initialize` diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index 3ee372ef1609..349d72a54adc 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -35,8 +35,10 @@ contract DocsExample { }; struct Storage { - // Shows how to create a custom struct in Public + // Shows how to create a custom struct in PublicState + // docs:start:storage-leader-declaration leader: PublicState, + // docs:end:storage-leader-declaration // docs:start:storage-singleton-declaration legendary_card: Singleton, // docs:end:storage-singleton-declaration @@ -44,11 +46,60 @@ contract DocsExample { // docs:start:storage-map-singleton-declaration profiles: Map>, // docs:end:storage-map-singleton-declaration + // docs:start:storage-set-declaration test: Set, + // docs:end:storage-set-declaration + // docs:start:storage-immutable-singleton-declaration imm_singleton: ImmutableSingleton, - // docs:start:start_vars_stable + // docs:end:storage-immutable-singleton-declaration + // docs:start:storage-stable-declaration stable_value: StablePublicState, - // docs:end:start_vars_stable + // docs:end:storage-stable-declaration + // docs:start:storage-minters-declaration + minters: Map>, + // docs:end:storage-minters-declaration + } + + impl Storage { + fn init(context: Context) -> Self { + Storage { + // docs:start:storage-leader-init + leader: PublicState::new( + context, + 1 + ), + // docs:end:storage-leader-init + // docs:start:start_vars_singleton + legendary_card: Singleton::new(context, 3), + // docs:end:start_vars_singleton + // just used for docs example (not for game play): + // docs:start:state_vars-MapSingleton + profiles: Map::new( + context, + 4, + |context, slot| { + Singleton::new(context, slot) + }, + ), + // docs:end:state_vars-MapSingleton + // docs:start:storage-set-init + set: Set::new(context, 5), + // docs:end:storage-set-init + imm_singleton: ImmutableSingleton::new(context, 6), + // docs:start:storage-stable-init + stable_value: StablePublicState::new(context, 7), + // docs:end:storage-stable-init + // docs:start:storage-minters-init + minters: Map::new( + context, + 8, + |context, slot| { + PublicState::new(context, slot) + }, + ), + // docs:end:storage-minters-init + } + } } #[aztec(private)] @@ -73,11 +124,13 @@ contract DocsExample { storage.stable_value.read_public() } + // docs:start:initialize-immutable-singleton #[aztec(private)] fn initialize_immutable_singleton(randomness: Field, points: u8) { let mut new_card = CardNote::new(points, randomness, context.msg_sender()); storage.imm_singleton.initialize(&mut new_card, true); } + // docs:end:initialize-immutable-singleton #[aztec(private)] // msg_sender() is 0 at deploy time. So created another function @@ -165,9 +218,11 @@ contract DocsExample { } // docs:end:singleton_is_initialized + // docs:start:get_note-immutable-singleton unconstrained fn get_imm_card() -> pub CardNote { - storage.imm_singleton.view_note() + storage.imm_singleton.get_note() } + // docs:end:get_note-immutable-singleton unconstrained fn is_imm_initialized() -> pub bool { storage.imm_singleton.is_initialized() From 82a7763dc4a9f46456dd2ab63027266d3a7ca2a9 Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 16:29:58 +0100 Subject: [PATCH 45/56] fix --- .../noir-contracts/contracts/docs_example_contract/src/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index 349d72a54adc..a075bb5eef46 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -47,7 +47,7 @@ contract DocsExample { profiles: Map>, // docs:end:storage-map-singleton-declaration // docs:start:storage-set-declaration - test: Set, + set: Set, // docs:end:storage-set-declaration // docs:start:storage-immutable-singleton-declaration imm_singleton: ImmutableSingleton, From 6f2ffa3635511cc435cb1e874f65832abdb1e29d Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 16:32:38 +0100 Subject: [PATCH 46/56] fix --- .../contracts/docs_example_contract/src/main.nr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index a075bb5eef46..98e5d185eeba 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -144,20 +144,20 @@ contract DocsExample { fn insert_notes(amounts: [u8; 10]) { for i in 0..amounts.len() { let mut note = CardNote::new(amounts[i], 1, context.msg_sender()); - storage.test.insert(&mut note, true); + storage.set.insert(&mut note, true); } } #[aztec(private)] fn insert_note(amount: u8, randomness: Field) { let mut note = CardNote::new(amount, randomness, context.msg_sender()); - storage.test.insert(&mut note, true); + storage.set.insert(&mut note, true); } // docs:start:state_vars-NoteGetterOptionsComparatorExampleNoir unconstrained fn read_note(amount: Field, comparator: u3) -> pub [Option; 10] { let options = NoteViewerOptions::new().select(0, amount, Option::some(comparator)); - let notes = storage.test.view_notes(options); + let notes = storage.set.view_notes(options); notes } From ca22d64433caf2da1688c007c6c0f75319f5879e Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 16:42:02 +0100 Subject: [PATCH 47/56] added comment --- noir/compiler/noirc_frontend/src/node_interner.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/noir/compiler/noirc_frontend/src/node_interner.rs b/noir/compiler/noirc_frontend/src/node_interner.rs index f3b3063ce578..b3f302dce126 100644 --- a/noir/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/compiler/noirc_frontend/src/node_interner.rs @@ -1043,6 +1043,8 @@ impl NodeInterner { Ok(impl_kind) } + /// Given a `ObjectType: TraitId` pair, find all implementations without taking constraints into account or + /// applying any type bindings. Useful to look for a specific trait in a type that is used in a macro. pub fn lookup_all_trait_implementations( &self, object_type: Type, From 8bbcff74dd0a11c5356b80106362c44a0b294662 Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 17:38:40 +0100 Subject: [PATCH 48/56] fixed tests --- .../end-to-end/src/e2e_blacklist_token_contract.test.ts | 2 +- yarn-project/end-to-end/src/e2e_state_vars.test.ts | 4 ++-- .../contracts/docs_example_contract/src/main.nr | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts index a434f91f0905..40bec73a9225 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts @@ -87,7 +87,7 @@ describe('e2e_blacklist_token_contract', () => { }; const addPendingShieldNoteToPXE = async (accountIndex: number, amount: bigint, secretHash: Fr, txHash: TxHash) => { - const storageSlot = new Fr(5); // The storage slot of `pending_shields` is 5. + const storageSlot = new Fr(4); // The storage slot of `pending_shields` is 4. const note = new Note([new Fr(amount), secretHash]); const extendedNote = new ExtendedNote(note, accounts[accountIndex].address, asset.address, storageSlot, txHash); await wallets[accountIndex].addNote(extendedNote); diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 0ad3a75a04e6..dcf986415615 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -127,7 +127,7 @@ describe('e2e_state_vars', () => { describe('Immutable Singleton', () => { it('fail to read uninitialized singleton', async () => { expect(await contract.methods.is_imm_initialized().view()).toEqual(false); - await expect(contract.methods.get_imm_card().view()).rejects.toThrowError(); + await expect(contract.methods.view_imm_card().view()).rejects.toThrowError(); }); it('initialize singleton', async () => { @@ -152,7 +152,7 @@ describe('e2e_state_vars', () => { it('read initialized singleton', async () => { expect(await contract.methods.is_imm_initialized().view()).toEqual(true); - const { points, randomness } = await contract.methods.get_imm_card().view(); + const { points, randomness } = await contract.methods.view_imm_card().view(); expect(points).toEqual(POINTS); expect(randomness).toEqual(RANDOMNESS); }); diff --git a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr index 98e5d185eeba..cd184bd27a4e 100644 --- a/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -224,6 +224,10 @@ contract DocsExample { } // docs:end:get_note-immutable-singleton + unconstrained fn view_imm_card() -> pub CardNote { + storage.imm_singleton.view_note() + } + unconstrained fn is_imm_initialized() -> pub bool { storage.imm_singleton.is_initialized() } From 1ebd83f1d8d5738bf18ae4b337c62f6e54c36ef0 Mon Sep 17 00:00:00 2001 From: thunkar Date: Thu, 1 Feb 2024 20:29:07 +0100 Subject: [PATCH 49/56] yet another hardcoded storageSlot --- .../end-to-end/src/e2e_blacklist_token_contract.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts index 40bec73a9225..b48a074c9328 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts @@ -112,7 +112,7 @@ describe('e2e_blacklist_token_contract', () => { // Add the note const note = new Note([slowTree.address.toField()]); - const storageSlot = new Fr(7); + const storageSlot = new Fr(6); for (const wallet of wallets) { const extendedNote = new ExtendedNote( From 0f732b504b114841e7f4efe45729e4c3cd28ad0c Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 2 Feb 2024 09:14:51 +0100 Subject: [PATCH 50/56] pr review comments --- noir/aztec_macros/src/lib.rs | 51 +++++++++---------- yarn-project/aztec-nr/aztec/src/state_vars.nr | 2 +- .../src/state_vars/immutable_singleton.nr | 4 +- .../aztec-nr/aztec/src/state_vars/map.nr | 4 +- .../aztec/src/state_vars/public_state.nr | 4 +- .../aztec-nr/aztec/src/state_vars/set.nr | 4 +- .../aztec/src/state_vars/singleton.nr | 4 +- .../src/state_vars/stable_public_state.nr | 4 +- .../src/state_vars/{store.nr => storage.nr} | 2 +- .../benchmarking_contract/src/main.nr | 1 - 10 files changed, 38 insertions(+), 42 deletions(-) rename yarn-project/aztec-nr/aztec/src/state_vars/{store.nr => storage.nr} (74%) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index a8912f3cf1e8..2be9cb603773 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -223,7 +223,7 @@ fn cast(lhs: Expression, ty: UnresolvedTypeData) -> Expression { } fn make_type(typ: UnresolvedTypeData) -> UnresolvedType { - UnresolvedType { typ, span: None } + UnresolvedType { typ, span: Some(Span::default()) } } fn index_array(array: Ident, index: &str) -> Expression { @@ -278,7 +278,8 @@ fn transform_hir( crate_id: &CrateId, context: &mut HirContext, ) -> Result<(), (AztecMacroError, FileId)> { - transform_events(crate_id, context).and(assign_storage_slots(crate_id, context)) + transform_events(crate_id, context)?; + assign_storage_slots(crate_id, context) } /// Includes an import to the aztec library if it has not been included yet @@ -317,8 +318,10 @@ fn check_for_storage_definition(module: &SortedModule) -> bool { // Check to see if the user has defined a storage struct fn check_for_storage_implementation(module: &SortedModule) -> bool { - module.impls.iter().any(|r#impl| match r#impl.object_type.typ.clone() { - UnresolvedTypeData::Named(path, _) => path.segments.last().unwrap().0.contents == "Storage", + module.impls.iter().any(|r#impl| match &r#impl.object_type.typ { + UnresolvedTypeData::Named(path, _) => { + path.segments.last().is_some_and(|segment| segment.0.contents == "Storage") + } _ => false, }) } @@ -383,9 +386,8 @@ fn transform_module( let crate_graph = &context.crate_graph[crate_id]; if storage_defined && !storage_implemented { - if let Err(err) = generate_storage_implementation(module) { - return Err((err.into(), crate_graph.root_file_id)); - } + generate_storage_implementation(module) + .map_err(|err| (err.into(), crate_graph.root_file_id))?; } if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(module) { @@ -449,11 +451,11 @@ fn transform_module( /// Auxiliary function to generate the storage constructor for a given field, using /// the Storage definition as a reference. Supports nesting. fn generate_storage_field_constructor( - (type_ident, unresolved_type): (Ident, UnresolvedType), + (type_ident, unresolved_type): &(Ident, UnresolvedType), slot: Expression, ) -> Result { - let typ = unresolved_type.typ; - match &typ { + let typ = &unresolved_type.typ; + match typ { UnresolvedTypeData::Named(path, generics) => { let mut new_path = path.clone().to_owned(); new_path.segments.push(ident("new")); @@ -466,7 +468,7 @@ fn generate_storage_field_constructor( lambda( vec![ ( - Pattern::Identifier(ident("context")), + pattern("context"), make_type(UnresolvedTypeData::Named( chained_path!("aztec", "context", "Context"), vec![], @@ -478,7 +480,7 @@ fn generate_storage_field_constructor( ), ], generate_storage_field_constructor( - (type_ident, generics.iter().cloned().last().unwrap()), + &(type_ident.clone(), generics.iter().cloned().last().unwrap()), variable("slot"), )?, ), @@ -538,7 +540,7 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte .fields .iter() .map(|field| { - generate_storage_field_constructor(field.clone(), slot_zero.clone()) + generate_storage_field_constructor(field, slot_zero.clone()) .map(|expression| (field.0.clone(), expression)) }) .flatten() @@ -553,13 +555,10 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte &vec![], &vec![( ident("context"), - UnresolvedType { - typ: UnresolvedTypeData::Named( - chained_path!("aztec", "context", "Context"), - vec![], - ), - span: Some(Span::default()), - }, + make_type(UnresolvedTypeData::Named( + chained_path!("aztec", "context", "Context"), + vec![], + )), )], &BlockExpression(vec![storage_constructor_statement]), &vec![], @@ -787,16 +786,14 @@ fn get_serialized_length( secondary_message: Some("State storage variable must be a struct".to_string()), }), }?; - let stored_in_state = match maybe_stored_in_state { - Some(stored_in_state) => Ok(stored_in_state), - None => Err(AztecMacroError::CouldNotAssignStorageSlots { + let stored_in_state = + maybe_stored_in_state.ok_or(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: Some("State storage variable must be generic".to_string()), - }), - }?; + })?; let is_note = traits.iter().any(|&trait_id| { let r#trait = interner.get_trait(trait_id); - r#trait.borrow().name.0.contents == "NoteInterface" + r#trait.name.0.contents == "NoteInterface" && !interner .lookup_all_trait_implementations(stored_in_state.clone(), trait_id) .is_empty() @@ -822,7 +819,7 @@ fn get_serialized_length( None } }) - .nth(0) + .next() .ok_or(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: Some("Stored data must implement Serialize trait".to_string()), })?; diff --git a/yarn-project/aztec-nr/aztec/src/state_vars.nr b/yarn-project/aztec-nr/aztec/src/state_vars.nr index 8e186bc2ef86..177844f75c17 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars.nr @@ -4,4 +4,4 @@ mod public_state; mod set; mod singleton; mod stable_public_state; -mod store; +mod storage; diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index 9368436bcc26..9d595081c20b 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -16,7 +16,7 @@ use crate::note::{ note_viewer_options::NoteViewerOptions, }; use crate::oracle::notes::check_nullifier_exists; -use crate::state_vars::store::Store; +use crate::state_vars::storage::Storage; // docs:start:struct struct ImmutableSingleton { @@ -25,7 +25,7 @@ struct ImmutableSingleton { } // docs:end:struct -impl Store for ImmutableSingleton {} +impl Storage for ImmutableSingleton {} impl ImmutableSingleton { // docs:start:new diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/map.nr b/yarn-project/aztec-nr/aztec/src/state_vars/map.nr index 90c6ee3a1888..7e38552e2ca4 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/map.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/map.nr @@ -4,7 +4,7 @@ use dep::protocol_types::{ hash::pedersen_hash, traits::{ToField} }; -use crate::state_vars::store::Store; +use crate::state_vars::storage::Storage; // docs:start:map struct Map { @@ -14,7 +14,7 @@ struct Map { } // docs:end:map -impl Store for Map {} +impl Storage for Map {} impl Map { // docs:start:new diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr index fa8387d377ac..081b0d59653c 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/public_state.nr @@ -3,7 +3,7 @@ use crate::oracle::storage::storage_read; use crate::oracle::storage::storage_write; use dep::std::option::Option; use dep::protocol_types::traits::{Deserialize, Serialize}; -use crate::state_vars::store::Store; +use crate::state_vars::storage::Storage; // docs:start:public_state_struct struct PublicState { @@ -12,7 +12,7 @@ struct PublicState { } // docs:end:public_state_struct -impl Store for PublicState {} +impl Storage for PublicState {} impl PublicState { // docs:start:public_state_struct_new diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr index e0f82bbea02d..6813a9fa98be 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/set.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/set.nr @@ -15,7 +15,7 @@ use crate::note::{ note_viewer_options::NoteViewerOptions, utils::compute_note_hash_for_consumption, }; -use crate::state_vars::store::Store; +use crate::state_vars::storage::Storage; // docs:start:struct struct Set { @@ -24,7 +24,7 @@ struct Set { } // docs:end:struct -impl Store for Set {} +impl Storage for Set {} impl Set { // docs:start:new diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 0c141b1e53b4..47d8aef5a9f4 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -20,7 +20,7 @@ use crate::oracle::{ nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists, }; -use crate::state_vars::store::Store; +use crate::state_vars::storage::Storage; // docs:start:struct struct Singleton { @@ -29,7 +29,7 @@ struct Singleton { } // docs:end:struct -impl Store for Singleton {} +impl Storage for Singleton {} impl Singleton { // docs:start:new diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr b/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr index 8482890a54ff..af4925f47ffc 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/stable_public_state.nr @@ -5,14 +5,14 @@ use crate::oracle::{ use crate::history::public_value_inclusion::prove_public_value_inclusion; use dep::std::option::Option; use dep::protocol_types::traits::{Deserialize, Serialize}; -use crate::state_vars::store::Store; +use crate::state_vars::storage::Storage; struct StablePublicState{ context: Context, storage_slot: Field, } -impl Store for StablePublicState {} +impl Storage for StablePublicState {} impl StablePublicState { pub fn new( diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/store.nr b/yarn-project/aztec-nr/aztec/src/state_vars/storage.nr similarity index 74% rename from yarn-project/aztec-nr/aztec/src/state_vars/store.nr rename to yarn-project/aztec-nr/aztec/src/state_vars/storage.nr index 966c55911294..5f28b55f9f7f 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/store.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/storage.nr @@ -1,7 +1,7 @@ use crate::context::{Context}; use dep::protocol_types::traits::{Deserialize, Serialize}; -trait Store where T: Serialize + Deserialize { +trait Storage where T: Serialize + Deserialize { fn get_storage_slot(self) -> Field { self.storage_slot } diff --git a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr index ff78e2c8f365..6b4502e83bc0 100644 --- a/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/yarn-project/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -14,7 +14,6 @@ contract Benchmarking { protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, - type_serialization::FIELD_SERIALIZED_LEN }, context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, From b29f90b737dc169ef3fcc86b62eb767fda388557 Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 2 Feb 2024 09:22:00 +0100 Subject: [PATCH 51/56] more pr comments --- noir/aztec_macros/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 2be9cb603773..b7c83cafbe75 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -182,6 +182,11 @@ fn member_access(lhs: &str, rhs: &str) -> Expression { }))) } +fn return_type(path: Path) -> FunctionReturnType { + let ty = make_type(UnresolvedTypeData::Named(path, vec![])); + FunctionReturnType::Ty(ty) +} + fn lambda(parameters: Vec<(Pattern, UnresolvedType)>, body: Expression) -> Expression { expression(ExpressionKind::Lambda(Box::new(Lambda { parameters, @@ -562,10 +567,7 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte )], &BlockExpression(vec![storage_constructor_statement]), &vec![], - &FunctionReturnType::Ty(UnresolvedType { - typ: UnresolvedTypeData::Named(chained_path!("Self"), vec![]), - span: Some(Span::default()), - }), + &return_type(chained_path!("Self")), )); let storage_impl = TypeImpl { @@ -1346,9 +1348,7 @@ fn make_castable_return_type(expression: Expression) -> Statement { /// } fn create_return_type(ty: &str) -> FunctionReturnType { let return_path = chained_path!("aztec", "abi", ty); - - let ty = make_type(UnresolvedTypeData::Named(return_path, vec![])); - FunctionReturnType::Ty(ty) + return_type(return_path) } /// Create Context Finish From 48fbfaf4baaa1efc110982ddecbe0291df77d906 Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 2 Feb 2024 11:14:09 +0100 Subject: [PATCH 52/56] clippy --- noir/aztec_macros/src/lib.rs | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index b7c83cafbe75..014f6b206403 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -88,7 +88,7 @@ impl From for MacroError { span, }, AztecMacroError::CouldNotAssignStorageSlots { secondary_message } => MacroError { - primary_message: format!("Could not assign storage slots, please provide a custom storage implementation"), + primary_message: "Could not assign storage slots, please provide a custom storage implementation".to_string(), secondary_message, span: None, }, @@ -391,8 +391,7 @@ fn transform_module( let crate_graph = &context.crate_graph[crate_id]; if storage_defined && !storage_implemented { - generate_storage_implementation(module) - .map_err(|err| (err.into(), crate_graph.root_file_id))?; + generate_storage_implementation(module).map_err(|err| (err, crate_graph.root_file_id))?; } if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(module) { @@ -485,7 +484,7 @@ fn generate_storage_field_constructor( ), ], generate_storage_field_constructor( - &(type_ident.clone(), generics.iter().cloned().last().unwrap()), + &(type_ident.clone(), generics.iter().last().unwrap().clone()), variable("slot"), )?, ), @@ -494,12 +493,10 @@ fn generate_storage_field_constructor( _ => Ok(call(variable_path(new_path), vec![variable("context"), slot])), } } - _ => { - return Err(AztecMacroError::UnsupportedStorageType { - typ: typ.clone(), - span: Some(type_ident.span()), - }) - } + _ => Err(AztecMacroError::UnsupportedStorageType { + typ: typ.clone(), + span: Some(type_ident.span()), + }), } } @@ -544,11 +541,10 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte let field_constructors = definition .fields .iter() - .map(|field| { + .flat_map(|field| { generate_storage_field_constructor(field, slot_zero.clone()) .map(|expression| (field.0.clone(), expression)) }) - .flatten() .collect(); let storage_constructor_statement = make_statement(StatementKind::Expression(expression( @@ -558,7 +554,7 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte let init = NoirFunction::normal(FunctionDefinition::normal( &ident("init"), &vec![], - &vec![( + &[( ident("context"), make_type(UnresolvedTypeData::Named( chained_path!("aztec", "context", "Context"), @@ -566,7 +562,7 @@ fn generate_storage_implementation(module: &mut SortedModule) -> Result<(), Azte )), )], &BlockExpression(vec![storage_constructor_statement]), - &vec![], + &[], &return_type(chained_path!("Self")), )); @@ -668,7 +664,7 @@ fn collect_crate_structs(crate_id: &CrateId, context: &HirContext) -> Vec Vec { let crates = context.crates(); crates - .flat_map(|crate_id| context.def_map(&crate_id).and_then(|def_map| Some(def_map.modules()))) + .flat_map(|crate_id| context.def_map(&crate_id).map(|def_map| def_map.modules())) .flatten() .flat_map(|(_, module)| { module.type_definitions().filter_map(|typ| { @@ -776,7 +772,7 @@ fn transform_events( /// Obtains the serialized length of a type that implements the Serialize trait. fn get_serialized_length( - traits: &Vec, + traits: &[TraitId], typ: &Type, interner: &NodeInterner, ) -> Result { @@ -816,7 +812,7 @@ fn get_serialized_length( interner .lookup_all_trait_implementations(stored_in_state.clone(), trait_id) .into_iter() - .nth(0) + .next() } else { None } @@ -835,7 +831,7 @@ fn get_serialized_length( let trait_impl = trait_impl_shared.borrow(); match trait_impl.trait_generics.get(0).unwrap() { - Type::Constant(value) => Ok(value.clone()), + Type::Constant(value) => Ok(*value), _ => Err(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: None }), } } @@ -846,7 +842,7 @@ fn assign_storage_slots( crate_id: &CrateId, context: &mut HirContext, ) -> Result<(), (AztecMacroError, FileId)> { - let traits: Vec<_> = collect_traits(context).iter().cloned().collect(); + let traits: Vec<_> = collect_traits(context); for struct_id in collect_crate_structs(crate_id, context) { let interner: &mut NodeInterner = context.def_interner.borrow_mut(); let r#struct = interner.get_struct(struct_id); @@ -940,7 +936,7 @@ fn assign_storage_slots( } let type_serialized_len = get_serialized_length(&traits, field_type, interner) - .map_err(|err| (err.into(), file_id))?; + .map_err(|err| (err, file_id))?; interner.update_expression(new_call_expression.arguments[1], |expr| { *expr = HirExpression::Literal(HirLiteral::Integer( FieldElement::from(u128::from(storage_slot)), From b1f2ea1702a51b8608aab3e504c5481ad1f77a3a Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 2 Feb 2024 11:36:59 +0100 Subject: [PATCH 53/56] more pr comments --- noir/aztec_macros/src/lib.rs | 10 +++++----- noir/compiler/noirc_frontend/src/node_interner.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 014f6b206403..9101e26506d7 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -802,7 +802,7 @@ fn get_serialized_length( return Ok(1); } - let trait_impl_kind = traits + let serialized_trait_impl_kind = traits .iter() .filter_map(|&trait_id| { let r#trait = interner.get_trait(trait_id); @@ -822,15 +822,15 @@ fn get_serialized_length( secondary_message: Some("Stored data must implement Serialize trait".to_string()), })?; - let trait_impl_id = match trait_impl_kind { + let serialized_trait_impl_id = match serialized_trait_impl_kind { TraitImplKind::Normal(trait_impl_id) => Ok(trait_impl_id), _ => Err(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: None }), }?; - let trait_impl_shared = interner.get_trait_implementation(trait_impl_id); - let trait_impl = trait_impl_shared.borrow(); + let serialized_trait_impl_shared = interner.get_trait_implementation(*serialized_trait_impl_id); + let serialized_trait_impl = serialized_trait_impl_shared.borrow(); - match trait_impl.trait_generics.get(0).unwrap() { + match serialized_trait_impl.trait_generics.get(0).unwrap() { Type::Constant(value) => Ok(*value), _ => Err(AztecMacroError::CouldNotAssignStorageSlots { secondary_message: None }), } diff --git a/noir/compiler/noirc_frontend/src/node_interner.rs b/noir/compiler/noirc_frontend/src/node_interner.rs index b3f302dce126..76b5cbfd22b5 100644 --- a/noir/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/compiler/noirc_frontend/src/node_interner.rs @@ -1049,7 +1049,7 @@ impl NodeInterner { &self, object_type: Type, trait_id: TraitId, - ) -> Vec { + ) -> Vec<&TraitImplKind> { let trait_impl = self.trait_implementation_map.get(&trait_id); trait_impl @@ -1059,7 +1059,7 @@ impl NodeInterner { .filter_map(|(typ, impl_kind)| match &typ { Type::Forall(_, typ) => { if typ.deref() == &object_type { - Some(impl_kind.clone()) + Some(impl_kind) } else { None } From 114e11802ae620b18b54b2e2b9bd53f943bdbd21 Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 2 Feb 2024 13:05:43 +0100 Subject: [PATCH 54/56] remove clang after install --- .github/workflows/protocol-circuits-gate-diff.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/protocol-circuits-gate-diff.yml b/.github/workflows/protocol-circuits-gate-diff.yml index 94ca8959b4f7..e1e8b96b4727 100644 --- a/.github/workflows/protocol-circuits-gate-diff.yml +++ b/.github/workflows/protocol-circuits-gate-diff.yml @@ -34,6 +34,7 @@ jobs: sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/include/* /usr/local/include/ sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/lib/* /usr/local/lib/ sudo cp -r clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/share/* /usr/local/share/ + rm -rf clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04 - uses: actions/cache@v3 with: From 6b23d17f9d5623830c7652c571764b3c5e94737d Mon Sep 17 00:00:00 2001 From: sirasistant Date: Fri, 2 Feb 2024 12:30:56 +0000 Subject: [PATCH 55/56] chore: use reference to reduce cloning --- noir/aztec_macros/src/lib.rs | 6 ++---- noir/compiler/noirc_frontend/src/node_interner.rs | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 9101e26506d7..006664884554 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -792,9 +792,7 @@ fn get_serialized_length( let is_note = traits.iter().any(|&trait_id| { let r#trait = interner.get_trait(trait_id); r#trait.name.0.contents == "NoteInterface" - && !interner - .lookup_all_trait_implementations(stored_in_state.clone(), trait_id) - .is_empty() + && !interner.lookup_all_trait_implementations(stored_in_state, trait_id).is_empty() }); // Maps and (private) Notes always occupy a single slot. Someone could store a Note in PublicState for whatever reason though. @@ -810,7 +808,7 @@ fn get_serialized_length( && r#trait.borrow().generics.len() == 1 { interner - .lookup_all_trait_implementations(stored_in_state.clone(), trait_id) + .lookup_all_trait_implementations(stored_in_state, trait_id) .into_iter() .next() } else { diff --git a/noir/compiler/noirc_frontend/src/node_interner.rs b/noir/compiler/noirc_frontend/src/node_interner.rs index 76b5cbfd22b5..11ef12ef83ee 100644 --- a/noir/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/compiler/noirc_frontend/src/node_interner.rs @@ -1047,7 +1047,7 @@ impl NodeInterner { /// applying any type bindings. Useful to look for a specific trait in a type that is used in a macro. pub fn lookup_all_trait_implementations( &self, - object_type: Type, + object_type: &Type, trait_id: TraitId, ) -> Vec<&TraitImplKind> { let trait_impl = self.trait_implementation_map.get(&trait_id); @@ -1058,7 +1058,7 @@ impl NodeInterner { .iter() .filter_map(|(typ, impl_kind)| match &typ { Type::Forall(_, typ) => { - if typ.deref() == &object_type { + if typ.deref() == object_type { Some(impl_kind) } else { None From 61b365020a19967f35d677034d75fe119f2ef043 Mon Sep 17 00:00:00 2001 From: thunkar Date: Fri, 2 Feb 2024 14:07:23 +0100 Subject: [PATCH 56/56] updated boxes --- boxes/token/src/contracts/src/main.nr | 61 +-------- boxes/token/src/contracts/src/types.nr | 1 - .../src/contracts/src/types/balance_set.nr | 113 ---------------- .../src/contracts/src/types/balances_map.nr | 125 +++++++++++++++--- .../src/contracts/src/types/token_note.nr | 42 ++++-- .../contracts/src/types/transparent_note.nr | 14 +- boxes/yarn.lock | 2 +- 7 files changed, 153 insertions(+), 205 deletions(-) delete mode 100644 boxes/token/src/contracts/src/types/balance_set.nr diff --git a/boxes/token/src/contracts/src/main.nr b/boxes/token/src/contracts/src/main.nr index 65ce0ce07718..075bd4d0f132 100644 --- a/boxes/token/src/contracts/src/main.nr +++ b/boxes/token/src/contracts/src/main.nr @@ -55,7 +55,7 @@ contract Token { minters: Map>, // docs:end:storage_minters // docs:start:storage_balances - balances: BalancesMap, + balances: BalancesMap, // docs:end:storage_balances total_supply: PublicState, // docs:start:storage_pending_shields @@ -65,53 +65,6 @@ contract Token { } // docs:end:storage_struct - // docs:start:storage_init - impl Storage { - fn init(context: Context) -> Self { - Storage { - // docs:start:storage_admin_init - admin: PublicState::new( - context, - 1, - ), - // docs:end:storage_admin_init - // docs:start:storage_minters_init - minters: Map::new( - context, - 2, - |context, slot| { - PublicState::new( - context, - slot, - ) - }, - ), - // docs:end:storage_minters_init - // docs:start:storage_balances_init - balances: BalancesMap::new(context, 3), - // docs:end:storage_balances_init - total_supply: PublicState::new( - context, - 4, - ), - // docs:start:storage_pending_shields_init - pending_shields: Set::new(context, 5), - // docs:end:storage_pending_shields_init - public_balances: Map::new( - context, - 6, - |context, slot| { - PublicState::new( - context, - slot, - ) - }, - ), - } - } - } - // docs:end:storage_init - // docs:start:constructor #[aztec(private)] fn constructor(admin: AztecAddress) { @@ -245,7 +198,7 @@ contract Token { pending_shields.remove(note); // Add the token note to user's balances set - storage.balances.at(to).add(SafeU120::new(amount)); + storage.balances.add(to, SafeU120::new(amount)); } // docs:end:redeem_shield @@ -258,7 +211,7 @@ contract Token { assert(nonce == 0, "invalid nonce"); } - storage.balances.at(from).sub(SafeU120::new(amount)); + storage.balances.sub(from, SafeU120::new(amount)); let selector = FunctionSelector::from_signature("_increase_public_balance((Field),Field)"); let _void = context.call_public_function(context.this_address(), selector, [to.to_field(), amount]); @@ -277,9 +230,9 @@ contract Token { // docs:end:assert_current_call_valid_authwit let amount = SafeU120::new(amount); - storage.balances.at(from).sub(amount); + storage.balances.sub(from, amount); // docs:start:increase_private_balance - storage.balances.at(to).add(amount); + storage.balances.add(to, amount); // docs:end:increase_private_balance } // docs:end:transfer @@ -293,7 +246,7 @@ contract Token { assert(nonce == 0, "invalid nonce"); } - storage.balances.at(from).sub(SafeU120::new(amount)); + storage.balances.sub(from, SafeU120::new(amount)); let selector = FunctionSelector::from_signature("_reduce_total_supply(Field)"); let _void = context.call_public_function(context.this_address(), selector, [amount]); @@ -350,7 +303,7 @@ contract Token { // docs:start:balance_of_private unconstrained fn balance_of_private(owner: AztecAddress) -> pub u120 { - storage.balances.at(owner).balance_of().value + storage.balances.balance_of(owner).value } // docs:end:balance_of_private diff --git a/boxes/token/src/contracts/src/types.nr b/boxes/token/src/contracts/src/types.nr index d3b3b1c9e773..62a1bb2a363e 100644 --- a/boxes/token/src/contracts/src/types.nr +++ b/boxes/token/src/contracts/src/types.nr @@ -1,4 +1,3 @@ mod transparent_note; -mod balance_set; mod balances_map; mod token_note; diff --git a/boxes/token/src/contracts/src/types/balance_set.nr b/boxes/token/src/contracts/src/types/balance_set.nr deleted file mode 100644 index 184fd5fe9259..000000000000 --- a/boxes/token/src/contracts/src/types/balance_set.nr +++ /dev/null @@ -1,113 +0,0 @@ -use dep::std::option::Option; -use dep::safe_math::SafeU120; -use dep::aztec::{ - context::Context, - state_vars::set::Set, -}; -use dep::aztec::protocol_types::{ - constants::MAX_READ_REQUESTS_PER_CALL, - address::AztecAddress, -}; -use dep::aztec::note::{ - note_getter::view_notes, - note_getter_options::{NoteGetterOptions, SortOrder}, - note_viewer_options::NoteViewerOptions -}; - -use crate::types::token_note::TokenNote; - -// A set implementing standard manipulation of balances. -// Does not require spending key, but only knowledge. -// Spending key requirement should be enforced by the contract using this. -struct BalanceSet { - owner: AztecAddress, - set: Set -} - -impl BalanceSet { - pub fn new(set: Set, owner: AztecAddress) -> Self { - Self { - owner, - set, - } - } - - unconstrained pub fn balance_of(self: Self) -> SafeU120 { - self.balance_of_with_offset(0) - } - - unconstrained pub fn balance_of_with_offset(self: Self, offset: u32) -> SafeU120 { - // Same as SafeU120::new(0), but fewer constraints because no check. - let mut balance = SafeU120::min(); - // docs:start:view_notes - let options = NoteViewerOptions::new().set_offset(offset); - let opt_notes = self.set.view_notes(options); - // docs:end:view_notes - let len = opt_notes.len(); - for i in 0..len { - if opt_notes[i].is_some() { - balance = balance.add(opt_notes[i].unwrap_unchecked().amount); - } - } - if (opt_notes[len - 1].is_some()) { - balance = balance.add(self.balance_of_with_offset(offset + opt_notes.len() as u32)); - } - - balance - } - - pub fn add(self: Self, addend: SafeU120) { - let mut addend_note = TokenNote::new(addend, self.owner); - - // docs:start:insert - self.set.insert(&mut addend_note, true); - // docs:end:insert - } - - pub fn sub(self: Self, subtrahend: SafeU120) { - // docs:start:get_notes - let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend); - let maybe_notes = self.set.get_notes(options); - // docs:end:get_notes - - let mut minuend: SafeU120 = SafeU120::min(); - for i in 0..maybe_notes.len() { - if maybe_notes[i].is_some() { - let note = maybe_notes[i].unwrap_unchecked(); - - // Removes the note from the owner's set of notes. - // This will call the the `compute_nullifer` function of the `token_note` - // which require knowledge of the secret key (currently the users encryption key). - // The contract logic must ensure that the spending key is used as well. - // docs:start:remove - self.set.remove(note); - // docs:end:remove - - minuend = minuend.add(note.amount); - } - } - - // This is to provide a nicer error msg, - // without it minuend-subtrahend would still catch it, but more generic error then. - // without the == true, it includes 'minuend.ge(subtrahend)' as part of the error. - assert(minuend.ge(subtrahend) == true, "Balance too low"); - - self.add(minuend.sub(subtrahend)); - } -} - -pub fn filter_notes_min_sum( - notes: [Option; MAX_READ_REQUESTS_PER_CALL], - min_sum: SafeU120 -) -> [Option; MAX_READ_REQUESTS_PER_CALL] { - let mut selected = [Option::none(); MAX_READ_REQUESTS_PER_CALL]; - let mut sum = SafeU120::min(); - for i in 0..notes.len() { - if notes[i].is_some() & sum.lt(min_sum) { - let note = notes[i].unwrap_unchecked(); - selected[i] = Option::some(note); - sum = sum.add(note.amount); - } - } - selected -} diff --git a/boxes/token/src/contracts/src/types/balances_map.nr b/boxes/token/src/contracts/src/types/balances_map.nr index e8cb09f62a31..2f5835248a04 100644 --- a/boxes/token/src/contracts/src/types/balances_map.nr +++ b/boxes/token/src/contracts/src/types/balances_map.nr @@ -1,34 +1,119 @@ -use dep::aztec::context::{PrivateContext, PublicContext, Context}; use dep::std::option::Option; -use crate::types::balance_set::BalanceSet; -use dep::aztec::hash::pedersen_hash; -use dep::aztec::protocol_types::address::AztecAddress; - -use crate::types::token_note::TokenNote; -use dep::aztec::state_vars::{map::Map, set::Set}; +use dep::safe_math::SafeU120; +use dep::aztec::{ + context::{PrivateContext, PublicContext, Context}, + hash::pedersen_hash, + protocol_types::{ + address::AztecAddress, + constants::MAX_READ_REQUESTS_PER_CALL, + traits::{Serialize, Deserialize} + }, + state_vars::{ + set::Set, + map::Map + }, + note::{ + note_getter::view_notes, + note_getter_options::{NoteGetterOptions, SortOrder}, + note_viewer_options::NoteViewerOptions, + note_header::NoteHeader, + note_interface::NoteInterface, + } +}; +use crate::types::token_note::{TokenNote, OwnedNote}; -struct BalancesMap { - store: Map>, +struct BalancesMap { + map: Map> } -impl BalancesMap { +impl BalancesMap { pub fn new( context: Context, storage_slot: Field, ) -> Self { - let store = Map::new(context, storage_slot, |context, storage_slot| { - Set { - context, - storage_slot, - } - }); + assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { - store, + map: Map::new(context, storage_slot, |context, slot| Set::new(context, slot)) + } + } + + unconstrained pub fn balance_of(self: Self, owner: AztecAddress) -> SafeU120 where T: Deserialize + Serialize + NoteInterface + OwnedNote { + self.balance_of_with_offset(owner, 0) + } + + unconstrained pub fn balance_of_with_offset(self: Self, owner: AztecAddress, offset: u32) -> SafeU120 where T: Deserialize + Serialize + NoteInterface + OwnedNote { + // Same as SafeU120::new(0), but fewer constraints because no check. + let mut balance = SafeU120::min(); + // docs:start:view_notes + let options = NoteViewerOptions::new().set_offset(offset); + let opt_notes = self.map.at(owner).view_notes(options); + // docs:end:view_notes + let len = opt_notes.len(); + for i in 0..len { + if opt_notes[i].is_some() { + balance = balance.add(opt_notes[i].unwrap_unchecked().get_amount()); + } + } + if (opt_notes[len - 1].is_some()) { + balance = balance.add(self.balance_of_with_offset(owner, offset + opt_notes.len() as u32)); + } + + balance + } + + pub fn add(self: Self, owner: AztecAddress, addend: SafeU120) where T: Deserialize + Serialize + NoteInterface + OwnedNote { + let mut addend_note = T::new(addend, owner); + + // docs:start:insert + self.map.at(owner).insert(&mut addend_note, true); + // docs:end:insert + } + + pub fn sub(self: Self, owner: AztecAddress, subtrahend: SafeU120) where T: Deserialize + Serialize + NoteInterface + OwnedNote{ + // docs:start:get_notes + let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend); + let maybe_notes = self.map.at(owner).get_notes(options); + // docs:end:get_notes + + let mut minuend: SafeU120 = SafeU120::min(); + for i in 0..maybe_notes.len() { + if maybe_notes[i].is_some() { + let note = maybe_notes[i].unwrap_unchecked(); + + // Removes the note from the owner's set of notes. + // This will call the the `compute_nullifer` function of the `token_note` + // which require knowledge of the secret key (currently the users encryption key). + // The contract logic must ensure that the spending key is used as well. + // docs:start:remove + self.map.at(owner).remove(note); + // docs:end:remove + + minuend = minuend.add(note.get_amount()); + } } + + // This is to provide a nicer error msg, + // without it minuend-subtrahend would still catch it, but more generic error then. + // without the == true, it includes 'minuend.ge(subtrahend)' as part of the error. + assert(minuend.ge(subtrahend) == true, "Balance too low"); + + self.add(owner, minuend.sub(subtrahend)); } - pub fn at(self, owner: AztecAddress) -> BalanceSet { - let set = self.store.at(owner); - BalanceSet::new(set, owner) +} + +pub fn filter_notes_min_sum( + notes: [Option; MAX_READ_REQUESTS_PER_CALL], + min_sum: SafeU120 +) -> [Option; MAX_READ_REQUESTS_PER_CALL] where T: Deserialize + Serialize + NoteInterface + OwnedNote { + let mut selected = [Option::none(); MAX_READ_REQUESTS_PER_CALL]; + let mut sum = SafeU120::min(); + for i in 0..notes.len() { + if notes[i].is_some() & sum.lt(min_sum) { + let note = notes[i].unwrap_unchecked(); + selected[i] = Option::some(note); + sum = sum.add(note.get_amount()); + } } + selected } diff --git a/boxes/token/src/contracts/src/types/token_note.nr b/boxes/token/src/contracts/src/types/token_note.nr index a0283d4a95a1..214f942cec8a 100644 --- a/boxes/token/src/contracts/src/types/token_note.nr +++ b/boxes/token/src/contracts/src/types/token_note.nr @@ -1,10 +1,10 @@ -use dep::aztec::{ - protocol_types::{ - address::AztecAddress, - constants::{ - MAX_READ_REQUESTS_PER_CALL - }, +use dep::aztec::protocol_types::{ + address::AztecAddress, + constants::{ + MAX_READ_REQUESTS_PER_CALL }, +}; +use dep::aztec::{ note::{ note_header::NoteHeader, note_interface::NoteInterface, @@ -14,7 +14,10 @@ use dep::aztec::{ state_vars::set::Set, log::emit_encrypted_log, hash::pedersen_hash, - protocol_types::traits::{Serialize, Deserialize}, + protocol_types::traits::{ + Serialize, + Deserialize + }, }; use dep::aztec::oracle::{ rand::rand, @@ -24,6 +27,12 @@ use dep::aztec::oracle::{ use dep::safe_math::SafeU120; use dep::std::option::Option; +trait OwnedNote { + fn new(amount: SafeU120, owner: AztecAddress) -> Self; + fn get_amount(self) -> SafeU120; + fn get_owner(self) -> AztecAddress; +} + global TOKEN_NOTE_LEN: Field = 3; // 3 plus a header. struct TokenNote { @@ -58,7 +67,7 @@ impl Deserialize for TokenNote { } impl NoteInterface for TokenNote { - fn compute_note_content_hash(self) -> Field { + fn compute_note_content_hash(self) -> Field { // TODO(#1205) Should use a non-zero generator index. pedersen_hash(self.serialize(), 0) } @@ -91,8 +100,8 @@ impl NoteInterface for TokenNote { self.header = header; } - fn get_header(self) -> NoteHeader { - self.header + fn get_header(note: TokenNote) -> NoteHeader { + note.header } // Broadcasts the note as an encrypted log on L1. @@ -111,8 +120,8 @@ impl NoteInterface for TokenNote { } } -impl TokenNote { - pub fn new(amount: SafeU120, owner: AztecAddress) -> Self { +impl OwnedNote for TokenNote { + fn new(amount: SafeU120, owner: AztecAddress) -> Self { Self { amount, owner, @@ -120,4 +129,13 @@ impl TokenNote { header: NoteHeader::empty(), } } + + fn get_amount(self) -> SafeU120 { + self.amount + } + + fn get_owner(self) -> AztecAddress { + self.owner + } + } diff --git a/boxes/token/src/contracts/src/types/transparent_note.nr b/boxes/token/src/contracts/src/types/transparent_note.nr index b8d6812330d7..4ee641794c4e 100644 --- a/boxes/token/src/contracts/src/types/transparent_note.nr +++ b/boxes/token/src/contracts/src/types/transparent_note.nr @@ -7,7 +7,7 @@ use dep::aztec::{ }, hash::{compute_secret_hash, pedersen_hash}, context::PrivateContext, - protocol_types::traits::{Serialize, Deserialize} + protocol_types::traits::{Serialize, Deserialize, Empty} }; global TRANSPARENT_NOTE_LEN: Field = 2; @@ -40,6 +40,12 @@ impl Deserialize for TransparentNote { } } +impl Empty for TransparentNote { + fn empty() -> Self { + TransparentNote::new(0, 0) + } +} + impl NoteInterface for TransparentNote { fn compute_note_content_hash(self) -> Field { @@ -57,12 +63,13 @@ impl NoteInterface for TransparentNote { pedersen_hash([self.secret, siloed_note_hash],0) } + fn set_header(&mut self, header: NoteHeader) { self.header = header; } - fn get_header(self) -> NoteHeader { - self.header + fn get_header(note: TransparentNote) -> NoteHeader { + note.header } fn broadcast(self, context: &mut PrivateContext, slot: Field) { @@ -82,7 +89,6 @@ impl TransparentNote { header: NoteHeader::empty(), } } - // new oracle call primitive // get me the secret corresponding to this hash pub fn new_from_secret(amount: Field, secret: Field) -> Self { diff --git a/boxes/yarn.lock b/boxes/yarn.lock index 0f764e1dd065..2b37f7139af4 100644 --- a/boxes/yarn.lock +++ b/boxes/yarn.lock @@ -253,9 +253,9 @@ __metadata: dependencies: "@aztec/bb.js": "portal:../../barretenberg/ts" "@aztec/foundation": "workspace:^" + "@aztec/types": "workspace:^" eslint: "npm:^8.35.0" lodash.chunk: "npm:^4.2.0" - lodash.times: "npm:^4.3.2" tslib: "npm:^2.4.0" languageName: node linkType: soft