From 4b9c532116cec50463b06b47d0014cad08ef326d Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 23 Feb 2024 14:52:27 +0000 Subject: [PATCH 01/32] refactor: renamings of state var wrappers --- .../references/storage/public_state.md | 20 ++++++------- .../resources/common_patterns/main.md | 2 +- .../sandbox/references/cheat_codes.md | 8 ++--- .../writing_private_voting_contract.md | 2 +- docs/docs/misc/migration_notes.md | 10 +++---- noir-projects/aztec-nr/authwit/src/account.nr | 6 ++-- .../aztec/src/context/private_context.nr | 4 +++ .../aztec/src/context/public_context.nr | 4 +++ .../aztec-nr/aztec/src/state_vars.nr | 2 +- .../{public_state.nr => public_mutable.nr} | 29 ++++++++++--------- .../src/state_vars/stable_public_state.nr | 2 ++ .../benchmarking_contract/src/main.nr | 4 +-- .../contracts/card_game_contract/src/main.nr | 4 +-- .../contracts/child_contract/src/main.nr | 4 +-- .../delegated_on_contract/src/main.nr | 4 +-- .../contracts/delegator_contract/src/main.nr | 4 +-- .../docs_example_contract/src/main.nr | 12 ++++---- .../easy_private_voting_contract/src/main.nr | 8 ++--- .../contracts/gas_token_contract/src/main.nr | 4 +-- .../inclusion_proofs_contract/src/main.nr | 6 ++-- .../contracts/lending_contract/src/main.nr | 12 ++++---- .../contracts/price_feed_contract/src/main.nr | 4 +-- .../contracts/slow_tree_contract/src/main.nr | 2 +- .../stateful_test_contract/src/main.nr | 4 +-- .../token_blacklist_contract/src/main.nr | 10 +++---- .../token_bridge_contract/src/main.nr | 4 +-- .../contracts/token_contract/src/main.nr | 10 +++---- .../contracts/uniswap_contract/src/main.nr | 6 ++-- noir/aztec_macros/src/lib.rs | 4 +-- .../regression_4124/src/main.nr | 8 ++--- .../nargo_fmt/tests/expected/contract.nr | 6 ++-- .../tooling/nargo_fmt/tests/input/contract.nr | 24 ++++++++------- .../fixtures/Benchmarking.test.json | 2 +- 33 files changed, 126 insertions(+), 109 deletions(-) rename noir-projects/aztec-nr/aztec/src/state_vars/{public_state.nr => public_mutable.nr} (59%) diff --git a/docs/docs/developers/contracts/references/storage/public_state.md b/docs/docs/developers/contracts/references/storage/public_state.md index d96866b4fd8..193d6026262 100644 --- a/docs/docs/developers/contracts/references/storage/public_state.md +++ b/docs/docs/developers/contracts/references/storage/public_state.md @@ -8,14 +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`. The type _must_ implement Serialize and Deserialize traits, as specified here: +The `PublicMutable` struct is generic over the variable type `T`. The type _must_ implement Serialize and Deserialize traits, as specified here: #include_code serialize /noir-projects/noir-protocol-circuits/src/crates/types/src/traits.nr rust #include_code deserialize /noir-projects/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. -You can find the details of `PublicState` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr). +You can find the details of `PublicMutable` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/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/noir-projects/noir-contracts/contracts/lending_contract)'s use of an [`Asset`](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr). @@ -23,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`](../../writing_contracts/functions/context.md), 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/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr). +When declaring the storage for `T` as a persistent public storage variable, we use the `PublicMutable::new()` constructor. As seen below, this takes the `storage_slot` and the `serialization_methods` as arguments along with the [`Context`](../../writing_contracts/functions/context.md), 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/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr). #### Single value example @@ -61,7 +61,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. +On the `PublicMutable` structs we have a `read` method to read the value at the location in storage. #### Reading from our `admin` example @@ -77,7 +77,7 @@ As we saw in the Map earlier, a very similar operation can be done to perform a ### `write` -We have a `write` method on the `PublicState` struct that takes the value to write as an input and saves this in storage. It uses the serialization method to serialize the value which inserts (possibly multiple) values into storage. +We have a `write` method on the `PublicMutable` struct that takes the value to write as an input and saves this in storage. It uses the serialization method to serialize the value which inserts (possibly multiple) values into storage. #### Writing to our `admin` example @@ -91,19 +91,19 @@ We have a `write` method on the `PublicState` struct that takes the value to wri ## Stable Public State -`StablePublicState` is a special type of `PublicState` that can be read from both public and private! +`StablePublicState` is a special type of `PublicMutable` that can be read from both public and private! Since private execution is based on historical data, the user can pick ANY of its prior values to read from. This is why it `MUST` not be updated after the contract is deployed. The variable should be initialized at the constructor and then never changed. This makes the stable public variables useful for stuff that you would usually have in `immutable` values in solidity. For example this can be the name of a token or its number of decimals. -Just like the `PublicState` it is generic over the variable type `T`. The type `MUST` implement Serialize and Deserialize traits. +Just like the `PublicMutable` it is generic over the variable type `T`. The type `MUST` implement Serialize and Deserialize traits. You can find the details of `StablePublicState` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr). ### `new` -Is done exactly like the `PublicState` struct, but with the `StablePublicState` struct. +Is done exactly like the `PublicMutable` struct, but with the `StablePublicState` struct. #include_code storage-stable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust @@ -121,11 +121,11 @@ Currently this is not constrained as we are in the middle of changing deployment ### `read_public` -Reading the value is like `PublicState`, simply with `read_public` instead of `read`. +Reading the value is like `PublicMutable`, simply with `read_public` instead of `read`. #include_code read_decimals_public /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust ### `read_private` -Reading the value is like `PublicState`, simply with `read_private` instead of `read`. This part can only be executed in private. +Reading the value is like `PublicMutable`, simply with `read_private` instead of `read`. This part can only be executed in private. #include_code read_decimals_private /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust diff --git a/docs/docs/developers/contracts/resources/common_patterns/main.md b/docs/docs/developers/contracts/resources/common_patterns/main.md index 51b733e2ef0..4f80d9aaa78 100644 --- a/docs/docs/developers/contracts/resources/common_patterns/main.md +++ b/docs/docs/developers/contracts/resources/common_patterns/main.md @@ -54,7 +54,7 @@ You can't read public storage in private domain. But nevertheless reading public ```rust struct Storage { - token: PublicState, + token: PublicMutable, } contract Bridge { diff --git a/docs/docs/developers/sandbox/references/cheat_codes.md b/docs/docs/developers/sandbox/references/cheat_codes.md index d9c04dddfd9..2f206adcae0 100644 --- a/docs/docs/developers/sandbox/references/cheat_codes.md +++ b/docs/docs/developers/sandbox/references/cheat_codes.md @@ -462,13 +462,13 @@ The baseSlot is specified in the Aztec.nr contract. ```rust struct Storage { - balances: Map>, + balances: Map>, } impl Storage { fn init() -> Self { Storage { - balances: Map::new(1, |slot| PublicState::new(slot)), + balances: Map::new(1, |slot| PublicMutable::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(context: Context) -> Self { Storage { - balances: Map::new(context, 1, |context, slot| PublicState::new(context, slot)), + balances: Map::new(context, 1, |context, slot| PublicMutable::new(context, slot)), } } } diff --git a/docs/docs/developers/tutorials/writing_private_voting_contract.md b/docs/docs/developers/tutorials/writing_private_voting_contract.md index 46766c3da23..eee17de69da 100644 --- a/docs/docs/developers/tutorials/writing_private_voting_contract.md +++ b/docs/docs/developers/tutorials/writing_private_voting_contract.md @@ -73,7 +73,7 @@ We are using various utils within the Aztec library: - `context` - exposes things such as the contract address, msg_sender, etc - `context.request_nullifier_secret_key` - get your secret key to help us create a randomized nullifier - `FunctionSelector::from_signature` - compute a function selector from signature so we can call functions from other functions -- `state_vars::{ map::Map, public_state::PublicState, }` - we will use a Map to store the votes (key = voteId, value = number of votes), and PublicState to hold our public values that we mentioned earlier +- `state_vars::{ map::Map, public_state::PublicMutable, }` - we will use a Map to store the votes (key = voteId, value = number of votes), and PublicMutable to hold our public values that we mentioned earlier - `types::type_serialization::{..}` - various serialization methods for defining how to use these types - `types::address::{AztecAddress},` - our admin will be held as an address - `constants::EMPTY_NULLIFIED_COMMITMENT,` - this will come in useful when creating our nullifier diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 4c1d9253bb7..9ad36241a3e 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -190,7 +190,7 @@ Storage definition and initialization has been simplified. Previously: ```rust struct Storage { - leader: PublicState, + leader: PublicMutable, legendary_card: Singleton, profiles: Map>, test: Set, @@ -200,7 +200,7 @@ struct Storage { impl Storage { fn init(context: Context) -> Self { Storage { - leader: PublicState::new( + leader: PublicMutable::new( context, 1, LeaderSerializationMethods, @@ -224,7 +224,7 @@ Now: ```rust struct Storage { - leader: PublicState, + leader: PublicMutable, legendary_card: Singleton, profiles: Map>, test: Set, @@ -462,7 +462,7 @@ It is still possible to manually implement the storage initialization (for custo impl Storage { fn init(context: Context) -> Self { Storage { - leader: PublicState::new( + leader: PublicMutable::new( context, 1 ), @@ -554,7 +554,7 @@ Before: ```rust struct Storage { - balances: Map> + balances: Map> } let user_balance = balances.at(owner.to_field()) diff --git a/noir-projects/aztec-nr/authwit/src/account.nr b/noir-projects/aztec-nr/authwit/src/account.nr index 5d82902efc4..4fe33d8785b 100644 --- a/noir-projects/aztec-nr/authwit/src/account.nr +++ b/noir-projects/aztec-nr/authwit/src/account.nr @@ -1,5 +1,5 @@ use dep::aztec::context::{PrivateContext, PublicContext, Context}; -use dep::aztec::state_vars::{map::Map, public_state::PublicState}; +use dep::aztec::state_vars::{map::Map, public_mutable::PublicMutable}; use crate::entrypoint::{app::AppPayload, fee::FeePayload}; use crate::auth::IS_VALID_SELECTOR; @@ -7,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 { @@ -23,7 +23,7 @@ impl AccountActions { context, approved_action_storage_slot, |context, slot| { - PublicState::new(context, slot) + PublicMutable::new(context, slot) } ) } diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index f504a8b392e..f94e95d5c3c 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -95,6 +95,10 @@ impl PrivateContext { } } + pub fn assert_deployment() { + // TODO(#4738): Implement this + } + pub fn msg_sender(self) -> AztecAddress { self.inputs.call_context.msg_sender } diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index 9b82f578464..d009d94a043 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -70,6 +70,10 @@ impl PublicContext { } } + pub fn assert_deployment() { + // TODO(#4738): Implement this + } + pub fn msg_sender(self) -> AztecAddress { self.inputs.call_context.msg_sender } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars.nr b/noir-projects/aztec-nr/aztec/src/state_vars.nr index 177844f75c1..5f0276334d5 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars.nr @@ -1,6 +1,6 @@ mod immutable_singleton; mod map; -mod public_state; +mod public_mutable; mod set; mod singleton; mod stable_public_state; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr similarity index 59% rename from noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr rename to noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr index 883a2f7a3df..4d5649232d3 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr @@ -5,40 +5,43 @@ use dep::std::option::Option; use dep::protocol_types::traits::{Deserialize, Serialize}; use crate::state_vars::storage::Storage; -// docs:start:public_state_struct -struct PublicState { +// docs:start:public_mutable_struct +struct PublicMutable { context: Context, storage_slot: Field, } -// docs:end:public_state_struct +// docs:end:public_mutable_struct -impl Storage for PublicState {} +impl Storage for PublicMutable {} -impl PublicState { - // docs:start:public_state_struct_new +impl PublicMutable { + // docs:start:public_mutable_struct_new pub fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. context: Context, storage_slot: Field ) -> Self { + assert( + context.private.is_none(), "Initializing public mutable is only supported in public functions" + ); assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); - PublicState { context, storage_slot } + PublicMutable { context, storage_slot } } - // docs:end:public_state_struct_new + // docs:end:public_mutable_struct_new - // docs:start:public_state_struct_read + // docs:start:public_mutable_struct_read pub fn read(self) -> T where T: Deserialize { - assert(self.context.private.is_none(), "Public state writes only supported in public functions"); + assert(self.context.private.is_none(), "Public state reads only supported in public functions"); let fields = storage_read(self.storage_slot); T::deserialize(fields) } - // docs:end:public_state_struct_read + // docs:end:public_mutable_struct_read - // docs:start:public_state_struct_write + // docs:start:public_mutable_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); storage_write(self.storage_slot, fields); } - // docs:end:public_state_struct_write + // docs:end:public_mutable_struct_write } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr b/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr index 9612fb30a5d..1354a6fafc5 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr @@ -29,6 +29,8 @@ impl StablePublicState { // This is currently impractical, as public functions are never marked `is_contract_deployment` // in the `call_context`, only private functions will have this flag set. let fields = T::serialize(value); + // TODO(benesjan): check here that the value is not already set + // storage_write(self.storage_slot, 0xdead); storage_write(self.storage_slot, fields); } diff --git a/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr index 86215deb334..a835868cf16 100644 --- a/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -11,12 +11,12 @@ contract Benchmarking { protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, 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} + log::emit_unencrypted_log, state_vars::{map::Map, public_mutable::PublicMutable, set::Set} }; struct Storage { notes: Map>, - balances: Map>, + balances: Map>, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr index 8af2576846a..ccf2bc469d0 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr @@ -3,7 +3,7 @@ mod game; contract CardGame { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress, constants::MAX_NOTES_PER_PAGE}; - use dep::aztec::{context::Context, hash::pedersen_hash, state_vars::{map::Map, public_state::PublicState}}; + use dep::aztec::{context::Context, hash::pedersen_hash, state_vars::{map::Map, public_mutable::PublicMutable}}; use dep::std::option::Option; use dep::value_note::{balance_utils, value_note::{ValueNote, VALUE_NOTE_LEN}}; @@ -16,7 +16,7 @@ contract CardGame { struct Storage { collections: Map, game_decks: Map>, - games: Map>, + games: Map>, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr index 8542bea1b84..9dfbd588e22 100644 --- a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr @@ -4,14 +4,14 @@ contract Child { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, - state_vars::{public_state::PublicState, set::Set}, + state_vars::{public_mutable::PublicMutable, set::Set}, protocol_types::{abis::{function_selector::FunctionSelector, call_context::CallContext}, address::AztecAddress}, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader, utils as note_utils} }; use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN}; struct Storage { - current_value: PublicState, + current_value: PublicMutable, a_private_value: Set, } diff --git a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr index c1678eb1814..083df69456e 100644 --- a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr @@ -4,7 +4,7 @@ contract DelegatedOn { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, - state_vars::{public_state::PublicState, set::Set}, + state_vars::{public_mutable::PublicMutable, set::Set}, protocol_types::{abis::{function_selector::FunctionSelector, call_context::CallContext}, address::AztecAddress}, note::{ note_getter_options::NoteGetterOptions, note_viewer_options::NoteViewerOptions, @@ -14,7 +14,7 @@ contract DelegatedOn { use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN}; struct Storage { - current_value: PublicState, + current_value: PublicMutable, a_private_value: Set, } diff --git a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr index 64a6bfe8b14..403f1f6be5d 100644 --- a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr @@ -3,14 +3,14 @@ contract Delegator { use dep::std::option::Option; use dep::aztec::{ - log::emit_unencrypted_log, state_vars::{public_state::PublicState, set::Set}, + log::emit_unencrypted_log, state_vars::{public_mutable::PublicMutable, set::Set}, protocol_types::{abis::{function_selector::FunctionSelector}, address::AztecAddress}, note::{note_viewer_options::NoteViewerOptions, utils as note_utils, note_header::NoteHeader} }; use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN}; struct Storage { - current_value: PublicState, + current_value: PublicMutable, a_private_value: Set, } diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 7c555eea3b5..b6a01ceafec 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -25,7 +25,7 @@ contract DocsExample { utils as note_utils, }, context::{PrivateContext, PublicContext, Context}, - state_vars::{map::Map, public_state::PublicState,singleton::Singleton, immutable_singleton::ImmutableSingleton, set::Set, stable_public_state::StablePublicState}, + state_vars::{map::Map, public_mutable::PublicMutable,singleton::Singleton, immutable_singleton::ImmutableSingleton, set::Set, stable_public_state::StablePublicState}, }; // how to import methods from other files/folders within your workspace use crate::options::create_account_card_getter_options; @@ -35,9 +35,9 @@ contract DocsExample { }; struct Storage { - // Shows how to create a custom struct in PublicState + // Shows how to create a custom struct in PublicMutable // docs:start:storage-leader-declaration - leader: PublicState, + leader: PublicMutable, // docs:end:storage-leader-declaration // docs:start:storage-singleton-declaration legendary_card: Singleton, @@ -56,7 +56,7 @@ contract DocsExample { stable_value: StablePublicState, // docs:end:storage-stable-declaration // docs:start:storage-minters-declaration - minters: Map>, + minters: Map>, // docs:end:storage-minters-declaration } @@ -64,7 +64,7 @@ contract DocsExample { fn init(context: Context) -> Self { Storage { // docs:start:storage-leader-init - leader: PublicState::new( + leader: PublicMutable::new( context, 1 ), @@ -94,7 +94,7 @@ contract DocsExample { context, 8, |context, slot| { - PublicState::new(context, slot) + PublicMutable::new(context, slot) }, ), // docs:end:storage-minters-init diff --git a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index f53586132a0..cb812487329 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -2,14 +2,14 @@ contract EasyPrivateVoting { // docs:start:imports use dep::aztec::{ protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, - context::{PrivateContext, Context}, state_vars::{map::Map, public_state::PublicState} + context::{PrivateContext, Context}, state_vars::{map::Map, public_mutable::PublicMutable} }; // 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: PublicMutable, // admin can end vote + tally: Map>, // we will store candidate as key and number of votes as value + voteEnded: PublicMutable, // voteEnded is boolean } // docs:end:storage_struct diff --git a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr index e34a44272fa..e29fb27805e 100644 --- a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr @@ -2,14 +2,14 @@ mod lib; contract GasToken { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}}; - use dep::aztec::{hash::{compute_secret_hash}, state_vars::{public_state::PublicState, map::Map}}; + use dep::aztec::{hash::{compute_secret_hash}, state_vars::{public_mutable::PublicMutable, map::Map}}; use dep::safe_math::SafeU120; use crate::lib::{calculate_fee, get_bridge_gas_msg_hash}; struct Storage { - balances: Map>, + balances: Map>, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index e737a47313c..82c29851733 100644 --- a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -5,7 +5,7 @@ contract InclusionProofs { grumpkin_point::GrumpkinPoint, contract_class_id::ContractClassId }; use dep::aztec::{ - state_vars::{map::Map, set::Set, public_state::PublicState}, context::Context, + state_vars::{map::Map, set::Set, public_mutable::PublicMutable}, context::Context, note::{ note_getter_options::NoteGetterOptions, note_getter_options::NoteStatus, note_header::NoteHeader, utils as note_utils @@ -32,8 +32,8 @@ contract InclusionProofs { // docs:end:value_note_imports struct Storage { private_values: Map>, - public_value: PublicState, - public_unused_value: PublicState, + public_value: PublicMutable, + public_unused_value: PublicMutable, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr index 40c16ecf6f6..fd4be20d959 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr @@ -21,7 +21,7 @@ contract Lending { context::{PrivateContext, PublicContext, Context}, state_vars::{ map::Map, - public_state::PublicState, + public_mutable::PublicMutable, } }; use crate::asset::Asset; @@ -31,11 +31,11 @@ contract Lending { // 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: PublicMutable, + stable_coin: PublicMutable, + assets: Map>, + collateral: Map>, + static_debt: Map>, // abusing keys very heavily } struct Position { diff --git a/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr b/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr index a86fcc73bfd..9edee7589a6 100644 --- a/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr @@ -6,7 +6,7 @@ contract PriceFeed { context::{PrivateContext, PublicContext, Context}, state_vars::{ map::Map, - public_state::PublicState, + public_mutable::PublicMutable, }, }; use dep::aztec::protocol_types::address::AztecAddress; @@ -14,7 +14,7 @@ contract PriceFeed { // Storage structure, containing all storage, and specifying what slots they use. struct Storage { - assets: Map>, + assets: Map>, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr index 5ae8795d957..9104fd9ece1 100644 --- a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr @@ -12,7 +12,7 @@ contract SlowTree { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, note::{note_header::NoteHeader, utils as note_utils}, - state_vars::{map::Map, public_state::PublicState, set::Set}, + state_vars::{map::Map, public_mutable::PublicMutable, set::Set}, protocol_types::type_serialization::FIELD_SERIALIZED_LEN }; use dep::slow_updates_tree::{SlowMap, Leaf, SlowUpdateProof, compute_merkle_root, deserialize_slow_update_proof}; diff --git a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr index b276253718f..f559fbe5e6a 100644 --- a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -6,12 +6,12 @@ contract StatefulTest { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, note::{note_header::NoteHeader, utils as note_utils}, - state_vars::{map::Map, public_state::PublicState, set::Set} + state_vars::{map::Map, public_mutable::PublicMutable, set::Set} }; struct Storage { notes: Map>, - public_values: Map>, + public_values: Map>, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr index 92cb8dbab85..497a1049404 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -29,7 +29,7 @@ contract TokenBlacklist { }, context::{PrivateContext, PublicContext, Context}, hash::{compute_secret_hash}, - state_vars::{map::Map, public_state::PublicState, set::Set, immutable_singleton::ImmutableSingleton}, + state_vars::{map::Map, public_mutable::PublicMutable, set::Set, immutable_singleton::ImmutableSingleton}, }; use dep::field_note::field_note::FieldNote; @@ -52,13 +52,13 @@ contract TokenBlacklist { // docs:end:interface struct Storage { - admin: PublicState, + admin: PublicMutable, balances: BalancesMap, - total_supply: PublicState, + total_supply: PublicMutable, pending_shields: Set, - public_balances: Map>, + public_balances: Map>, slow_update: ImmutableSingleton, - public_slow_update: PublicState, + public_slow_update: PublicMutable, } // docs:start:constructor diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index a542c1846fa..15369905c5e 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -9,7 +9,7 @@ mod token_interface; contract TokenBridge { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}}; - use dep::aztec::{context::{Context}, hash::{compute_secret_hash}, state_vars::{public_state::PublicState}}; + use dep::aztec::{context::{Context}, hash::{compute_secret_hash}, state_vars::{public_mutable::PublicMutable}}; use dep::token_portal_content_hash_lib::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash}; @@ -19,7 +19,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: PublicMutable, } // Constructs the contract. diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index 6f0dfcbe9e2..91d37b2c694 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -23,7 +23,7 @@ contract Token { utils as note_utils, }, hash::{compute_secret_hash}, - state_vars::{map::Map, public_state::PublicState, stable_public_state::StablePublicState, set::Set}, + state_vars::{map::Map, public_mutable::PublicMutable, stable_public_state::StablePublicState, set::Set}, protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress @@ -49,19 +49,19 @@ contract Token { // docs:start:storage_struct struct Storage { // docs:start:storage_admin - admin: PublicState, + admin: PublicMutable, // 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: PublicMutable, // docs:start:storage_pending_shields pending_shields: Set, // docs:end:storage_pending_shields - public_balances: Map>, + public_balances: Map>, symbol: StablePublicState, name: StablePublicState, // docs:start:storage_decimals diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index 311c0e349e8..60ce3c62536 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -7,7 +7,7 @@ mod util; // Uses the token bridge contract, which tells which input token we need to talk to and handles the exit funds to L1 contract Uniswap { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}}; - use dep::aztec::{oracle::{context::get_portal_address}, state_vars::{map::Map, public_state::PublicState}}; + use dep::aztec::{oracle::{context::get_portal_address}, state_vars::{map::Map, public_mutable::PublicMutable}}; use dep::authwit::auth::{IS_VALID_SELECTOR, assert_current_call_valid_authwit_public, compute_authwit_message_hash}; @@ -16,10 +16,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: PublicMutable, } #[aztec(private)] diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 8f70d5b5e86..91efd74ddaa 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -840,8 +840,8 @@ fn get_serialized_length( && !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. - if struct_name == "Map" || (is_note && struct_name != "PublicState") { + // Maps and (private) Notes always occupy a single slot. Someone could store a Note in PublicMutable for whatever reason though. + if struct_name == "Map" || (is_note && struct_name != "PublicMutable") { return Ok(1); } diff --git a/noir/test_programs/execution_success/regression_4124/src/main.nr b/noir/test_programs/execution_success/regression_4124/src/main.nr index b47bf28d461..49ff68ee6ad 100644 --- a/noir/test_programs/execution_success/regression_4124/src/main.nr +++ b/noir/test_programs/execution_success/regression_4124/src/main.nr @@ -14,14 +14,14 @@ pub fn storage_read() -> [Field; N] { dep::std::unsafe::zeroed() } -struct PublicState { +struct PublicMutable { storage_slot: Field, } -impl PublicState { +impl PublicMutable { pub fn new(storage_slot: Field) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); - PublicState { storage_slot } + PublicMutable { storage_slot } } pub fn read(_self: Self) -> T where T: MyDeserialize { @@ -32,7 +32,7 @@ impl PublicState { } fn main(value: Field) { - let ps: PublicState = PublicState::new(27); + let ps: PublicMutable = PublicMutable::new(27); // error here assert(ps.read() == value); diff --git a/noir/tooling/nargo_fmt/tests/expected/contract.nr b/noir/tooling/nargo_fmt/tests/expected/contract.nr index 226667619f5..94c9317d1a1 100644 --- a/noir/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/tooling/nargo_fmt/tests/expected/contract.nr @@ -10,14 +10,14 @@ contract Benchmarking { use dep::aztec::{ 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}, + log::emit_unencrypted_log, state_vars::{map::Map, public_mutable::PublicMutable, set::Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, types::address::{AztecAddress} }; struct Storage { notes: Map>, - balances: Map>, + balances: Map>, } impl Storage { @@ -31,7 +31,7 @@ contract Benchmarking { balances: Map::new( context, 2, - |context, slot| { PublicState::new(context, slot, FieldSerializationMethods) } + |context, slot| { PublicMutable::new(context, slot, FieldSerializationMethods) } ) } } diff --git a/noir/tooling/nargo_fmt/tests/input/contract.nr b/noir/tooling/nargo_fmt/tests/input/contract.nr index f863a9dc955..94c9317d1a1 100644 --- a/noir/tooling/nargo_fmt/tests/input/contract.nr +++ b/noir/tooling/nargo_fmt/tests/input/contract.nr @@ -5,30 +5,34 @@ contract Benchmarking { use dep::aztec::protocol_types::abis::function_selector::FunctionSelector; - use dep::value_note::{ - utils::{increment, decrement}, - value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, - }; + use dep::value_note::{utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}}; use dep::aztec::{ 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}, + log::emit_unencrypted_log, state_vars::{map::Map, public_mutable::PublicMutable, set::Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - types::address::{AztecAddress}, + types::address::{AztecAddress} }; struct Storage { notes: Map>, - balances: Map>, + balances: Map>, } impl Storage { fn init(context: Context) -> pub 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, ValueNoteMethods) } + ), + balances: Map::new( + context, + 2, + |context, slot| { PublicMutable::new(context, slot, FieldSerializationMethods) } + ) } } } diff --git a/yarn-project/circuits.js/fixtures/Benchmarking.test.json b/yarn-project/circuits.js/fixtures/Benchmarking.test.json index 6bd40d7241c..8e964fa5566 100644 --- a/yarn-project/circuits.js/fixtures/Benchmarking.test.json +++ b/yarn-project/circuits.js/fixtures/Benchmarking.test.json @@ -3404,7 +3404,7 @@ "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/state_vars/map.nr" }, "50": { - "source": "use crate::context::{Context};\nuse crate::oracle::storage::storage_read;\nuse crate::oracle::storage::storage_write;\nuse crate::types::type_serialization::TypeSerializationInterface;\nuse dep::std::option::Option;\n\n// docs:start:public_state_struct\nstruct PublicState {\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n}\n// docs:end:public_state_struct\n\nimpl PublicState {\n // docs:start:public_state_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicState {\n context,\n storage_slot,\n serialization_methods,\n }\n }\n // docs:end:public_state_struct_new\n\n // docs:start:public_state_struct_read\n pub fn read(self) -> T {\n assert(self.context.private.is_none(), \"Public state reads only supported in public functions\");\n storage_read(self.storage_slot, self.serialization_methods.deserialize)\n }\n // docs:end:public_state_struct_read\n\n // docs:start:public_state_struct_write\n pub fn write(self, value: T) {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n let serialize = self.serialization_methods.serialize;\n let fields = serialize(value);\n storage_write(self.storage_slot, fields);\n }\n // docs:end:public_state_struct_write\n}\n", + "source": "use crate::context::{Context};\nuse crate::oracle::storage::storage_read;\nuse crate::oracle::storage::storage_write;\nuse crate::types::type_serialization::TypeSerializationInterface;\nuse dep::std::option::Option;\n\n// docs:start:public_mutable_struct\nstruct PublicState {\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n}\n// docs:end:public_mutable_struct\n\nimpl PublicState {\n // docs:start:public_mutable_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicState {\n context,\n storage_slot,\n serialization_methods,\n }\n }\n // docs:end:public_mutable_struct_new\n\n // docs:start:public_mutable_struct_read\n pub fn read(self) -> T {\n assert(self.context.private.is_none(), \"Public state reads only supported in public functions\");\n storage_read(self.storage_slot, self.serialization_methods.deserialize)\n }\n // docs:end:public_mutable_struct_read\n\n // docs:start:public_mutable_struct_write\n pub fn write(self, value: T) {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n let serialize = self.serialization_methods.serialize;\n let fields = serialize(value);\n storage_write(self.storage_slot, fields);\n }\n // docs:end:public_mutable_struct_write\n}\n", "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/state_vars/public_state.nr" }, "56": { From 5c8c1398caa8d0c955fdfc1394c97024edebeb68 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 23 Feb 2024 15:05:05 +0000 Subject: [PATCH 02/32] SharedImmutable --- .../contracts/references/storage/public_state.md | 6 +++--- .../aztec-nr/aztec/src/context/private_context.nr | 2 +- .../aztec-nr/aztec/src/context/public_context.nr | 2 +- noir-projects/aztec-nr/aztec/src/state_vars.nr | 2 +- .../{stable_public_state.nr => shared_immutable.nr} | 11 +++++++---- .../contracts/docs_example_contract/src/main.nr | 6 +++--- .../contracts/token_contract/src/main.nr | 8 ++++---- 7 files changed, 20 insertions(+), 17 deletions(-) rename noir-projects/aztec-nr/aztec/src/state_vars/{stable_public_state.nr => shared_immutable.nr} (89%) diff --git a/docs/docs/developers/contracts/references/storage/public_state.md b/docs/docs/developers/contracts/references/storage/public_state.md index 193d6026262..6282bdf3d04 100644 --- a/docs/docs/developers/contracts/references/storage/public_state.md +++ b/docs/docs/developers/contracts/references/storage/public_state.md @@ -91,7 +91,7 @@ We have a `write` method on the `PublicMutable` struct that takes the value to w ## Stable Public State -`StablePublicState` is a special type of `PublicMutable` that can be read from both public and private! +`SharedImmutable` is a special type of `PublicMutable` that can be read from both public and private! Since private execution is based on historical data, the user can pick ANY of its prior values to read from. This is why it `MUST` not be updated after the contract is deployed. The variable should be initialized at the constructor and then never changed. @@ -99,11 +99,11 @@ This makes the stable public variables useful for stuff that you would usually h Just like the `PublicMutable` it is generic over the variable type `T`. The type `MUST` implement Serialize and Deserialize traits. -You can find the details of `StablePublicState` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr). +You can find the details of `SharedImmutable` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr). ### `new` -Is done exactly like the `PublicMutable` struct, but with the `StablePublicState` struct. +Is done exactly like the `PublicMutable` struct, but with the `SharedImmutable` struct. #include_code storage-stable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index f94e95d5c3c..614953cadd9 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -95,7 +95,7 @@ impl PrivateContext { } } - pub fn assert_deployment() { + pub fn assert_deployment(self) { // TODO(#4738): Implement this } diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index d009d94a043..ede0da672e6 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -70,7 +70,7 @@ impl PublicContext { } } - pub fn assert_deployment() { + pub fn assert_deployment(self) { // TODO(#4738): Implement this } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars.nr b/noir-projects/aztec-nr/aztec/src/state_vars.nr index 5f0276334d5..ad8a3f6fad7 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars.nr @@ -3,5 +3,5 @@ mod map; mod public_mutable; mod set; mod singleton; -mod stable_public_state; +mod shared_immutable; mod storage; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr similarity index 89% rename from noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr rename to noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 1354a6fafc5..45705e5e142 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/stable_public_state.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -5,14 +5,14 @@ use dep::std::option::Option; use dep::protocol_types::traits::{Deserialize, Serialize}; use crate::state_vars::storage::Storage; -struct StablePublicState{ +struct SharedImmutable{ context: Context, storage_slot: Field, } -impl Storage for StablePublicState {} +impl Storage for SharedImmutable {} -impl StablePublicState { +impl SharedImmutable { pub fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. context: Context, @@ -24,7 +24,10 @@ impl StablePublicState { // Intended to be only called once. pub fn initialize(self, value: T) where T: Serialize { - assert(self.context.private.is_none(), "Public state wrties only supported in public functions"); + assert( + self.context.private.is_none(), "SharedImmutable can only be initialized from public functions" + ); + self.context.public.unwrap_unchecked().assert_deployment(); // TODO: Must throw if the storage slot is not empty -> cannot allow overwriting // This is currently impractical, as public functions are never marked `is_contract_deployment` // in the `call_context`, only private functions will have this flag set. diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index b6a01ceafec..e15b18efd2e 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -25,7 +25,7 @@ contract DocsExample { utils as note_utils, }, context::{PrivateContext, PublicContext, Context}, - state_vars::{map::Map, public_mutable::PublicMutable,singleton::Singleton, immutable_singleton::ImmutableSingleton, set::Set, stable_public_state::StablePublicState}, + state_vars::{map::Map, public_mutable::PublicMutable,singleton::Singleton, immutable_singleton::ImmutableSingleton, set::Set, shared_immutable::SharedImmutable}, }; // how to import methods from other files/folders within your workspace use crate::options::create_account_card_getter_options; @@ -53,7 +53,7 @@ contract DocsExample { imm_singleton: ImmutableSingleton, // docs:end:storage-immutable-singleton-declaration // docs:start:storage-stable-declaration - stable_value: StablePublicState, + stable_value: SharedImmutable, // docs:end:storage-stable-declaration // docs:start:storage-minters-declaration minters: Map>, @@ -87,7 +87,7 @@ contract DocsExample { // docs:end:storage-set-init imm_singleton: ImmutableSingleton::new(context, 6), // docs:start:storage-stable-init - stable_value: StablePublicState::new(context, 7), + stable_value: SharedImmutable::new(context, 7), // docs:end:storage-stable-init // docs:start:storage-minters-init minters: Map::new( diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index 91d37b2c694..1af6cd1a9ff 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -23,7 +23,7 @@ contract Token { utils as note_utils, }, hash::{compute_secret_hash}, - state_vars::{map::Map, public_mutable::PublicMutable, stable_public_state::StablePublicState, set::Set}, + state_vars::{map::Map, public_mutable::PublicMutable, shared_immutable::SharedImmutable, set::Set}, protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress @@ -62,10 +62,10 @@ contract Token { pending_shields: Set, // docs:end:storage_pending_shields public_balances: Map>, - symbol: StablePublicState, - name: StablePublicState, + symbol: SharedImmutable, + name: SharedImmutable, // docs:start:storage_decimals - decimals: StablePublicState, + decimals: SharedImmutable, // docs:end:storage_decimals } // docs:end:storage_struct From a79338b423bd4413118e0600631f3583d16f26c3 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 23 Feb 2024 16:20:24 +0000 Subject: [PATCH 03/32] fix --- noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr | 3 --- 1 file changed, 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr index 4d5649232d3..cc41e42dc5a 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr @@ -21,9 +21,6 @@ impl PublicMutable { context: Context, storage_slot: Field ) -> Self { - assert( - context.private.is_none(), "Initializing public mutable is only supported in public functions" - ); assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); PublicMutable { context, storage_slot } } From 4cbd515dd621f6f07a1a85d9051b17ae9861d1c0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 23 Feb 2024 16:24:07 +0000 Subject: [PATCH 04/32] private immutable --- .../references/storage/private_state.md | 30 +++++++++---------- docs/docs/misc/migration_notes.md | 8 ++--- .../aztec-nr/aztec/src/state_vars.nr | 2 +- ...able_singleton.nr => private_immutable.nr} | 8 ++--- .../docs_example_contract/src/main.nr | 8 ++--- .../ecdsa_account_contract/src/main.nr | 4 +-- .../schnorr_account_contract/src/main.nr | 4 +-- .../contracts/test_contract/src/main.nr | 4 +-- .../token_blacklist_contract/src/main.nr | 4 +-- .../end-to-end/src/e2e_state_vars.test.ts | 4 +-- 10 files changed, 38 insertions(+), 38 deletions(-) rename noir-projects/aztec-nr/aztec/src/state_vars/{immutable_singleton.nr => private_immutable.nr} (92%) diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index 61d3046a67c..0283b17f5ec 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -17,7 +17,7 @@ Aztec private state follows a [utxo](https://en.wikipedia.org/wiki/Unspent_trans To greatly simplify the experience of writing private state, Aztec.nr provides three different types of private state variable: - [Singleton](#singletonnotetype) -- [ImmutableSingleton](#immutablesingletonnotetype) +- [PrivateImmutable](#privateimmutablenotetype) - [Set](#setnotetype) These three structs abstract-away many of Aztec's protocol complexities, by providing intuitive methods to modify notes in the utxo tree in a privacy-preserving way. @@ -42,15 +42,15 @@ A note should implement the following traits: The interplay between a private state variable and its notes can be confusing. Here's a summary to aid intuition: -A private state variable (of type `Singleton`, `ImmutableSingleton` or `Set`) may be declared in storage. +A private state variable (of type `Singleton`, `PrivateImmutable` or `Set`) may be declared in storage. Every note contains a header, which contains the contract address and storage slot of the state variable to which it is associated. A note is associated with a private state variable if the storage slot of the private state variable matches the storage slot contained in the note's header. The header provides information that helps the user interpret the note's data. -Management of the header is abstracted-away from developers who use the `ImmutableSingleton`, `Singleton` and `Set` types. +Management of the header is abstracted-away from developers who use the `PrivateImmutable`, `Singleton` and `Set` types. A private state variable points to one or many notes (depending on the type). The note(s) are all valid private state if the note(s) haven't yet been nullified. -An `ImmutableSingleton` will point to _one_ note over the lifetime of the contract. This note is a struct of information that is persisted forever. +An `PrivateImmutable` will point to _one_ note over the lifetime of the contract. This note is a struct of information that is persisted forever. A `Singleton` may point to _one_ note at a time. But since it's not "immutable", the note that it points to may be [replaced](#replace) by functions of the contract. The current value of a `Singleton` is interpreted as the one note which has not-yet been nullified. The act of replacing a Singleton's note is how a `Singleton` state may be modified by functions. @@ -94,7 +94,7 @@ Beware that because this nullifier is created only from the storage slot without For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the singleton is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. ::: -Unlike public states, which have a default initial value of `0` (or many zeros, in the case of a struct, array or map), a private state (of type `Singleton`, `ImmutableSingleton` or `Set`) does not have a default initial value. The `initialize` method (or `insert`, in the case of a `Set`) must be called. +Unlike public states, which have a default initial value of `0` (or many zeros, in the case of a struct, array or map), a private state (of type `Singleton`, `PrivateImmutable` or `Set`) does not have a default initial value. The `initialize` method (or `insert`, in the case of a `Set`) must be called. :::info Extend on what happens if you try to use non-initialized state. @@ -132,9 +132,9 @@ This also makes read operations indistinguishable from write operations and allo Functionally similar to [`get_note`](#get_note), but executed in unconstrained functions and can be used by the wallet to fetch notes for use by front-ends etc. -## `ImmutableSingleton` +## `PrivateImmutable` -`ImmutableSingleton` represents a unique private state variable that, as the name suggests, is immutable. Once initialized, its value cannot be altered. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/immutable_singleton.nr). +`PrivateImmutable` represents a unique private state variable that, as the name suggests, is immutable. Once initialized, its value cannot be altered. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr). ### `new` @@ -144,7 +144,7 @@ As part of the initialization of the `Storage` struct, the `Singleton` is create ### `initialize` -When this function is invoked, it creates a nullifier for the storage slot, ensuring that the ImmutableSingleton cannot be initialized again. +When this function is invoked, it creates a nullifier for the storage slot, ensuring that the PrivateImmutable cannot be initialized again. :::danger Privacy-Leak Beware that because this nullifier is created only from the storage slot without randomness it leaks privacy. This means that it is possible for an external observer to determine when the note is nullified. @@ -152,27 +152,27 @@ Beware that because this nullifier is created only from the storage slot without For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the singleton is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. ::: -Set the value of an ImmutableSingleton by calling the `initialize` method: +Set the value of an PrivateImmutable by calling the `initialize` method: #include_code initialize-immutable-singleton /noir-projects/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. +Once initialized, an PrivateImmutable's value remains unchangeable. This method can only be called once. ### `is_initialized` -An unconstrained method to check if the ImmutableSingleton has been initialized. Takes an optional owner and returns a boolean. You can find the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/immutable_singleton.nr). +An unconstrained method to check if the PrivateImmutable has been initialized. Takes an optional owner and returns a boolean. You can find the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr). ### `get_note` -Similar to the `Singleton`, we can use the `get_note` method to read the value of an ImmutableSingleton. +Similar to the `Singleton`, we can use the `get_note` method to read the value of an PrivateImmutable. -Use this method to retrieve the value of an initialized ImmutableSingleton. +Use this method to retrieve the value of an initialized PrivateImmutable. #include_code get_note-immutable-singleton /noir-projects/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. +Unlike a `Singleton`, the `get_note` function for an PrivateImmutable doesn't nullify the current note in the background. This means that multiple accounts can concurrently call this function to read the value. -This function will throw if the `ImmutableSingleton` hasn't been initialized. +This function will throw if the `PrivateImmutable` hasn't been initialized. ### `view_note` diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 9ad36241a3e..a7e2bd7e2a0 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -194,7 +194,7 @@ struct Storage { legendary_card: Singleton, profiles: Map>, test: Set, - imm_singleton: ImmutableSingleton, + imm_singleton: PrivateImmutable, } impl Storage { @@ -214,7 +214,7 @@ impl Storage { }, ), test: Set::new(context, 4, CardNoteMethods), - imm_singleton: ImmutableSingleton::new(context, 4, CardNoteMethods), + imm_singleton: PrivateImmutable::new(context, 4, CardNoteMethods), } } } @@ -228,7 +228,7 @@ struct Storage { legendary_card: Singleton, profiles: Map>, test: Set, - imm_singleton: ImmutableSingleton, + imm_singleton: PrivateImmutable, } ``` @@ -475,7 +475,7 @@ impl Storage { }, ), test: Set::new(context, 4), - imm_singleton: ImmutableSingleton::new(context, 4), + imm_singleton: PrivateImmutable::new(context, 4), } } } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars.nr b/noir-projects/aztec-nr/aztec/src/state_vars.nr index ad8a3f6fad7..d4588dc5fe5 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars.nr @@ -1,4 +1,4 @@ -mod immutable_singleton; +mod private_immutable; mod map; mod public_mutable; mod set; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr similarity index 92% rename from noir-projects/aztec-nr/aztec/src/state_vars/immutable_singleton.nr rename to noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr index fed2d66a589..0803486551c 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr @@ -10,15 +10,15 @@ use crate::oracle::notes::check_nullifier_exists; use crate::state_vars::storage::Storage; // docs:start:struct -struct ImmutableSingleton { +struct PrivateImmutable { context: Option<&mut PrivateContext>, storage_slot: Field, } // docs:end:struct -impl Storage for ImmutableSingleton {} +impl Storage for PrivateImmutable {} -impl ImmutableSingleton { +impl PrivateImmutable { // docs:start:new pub fn new(context: Context, storage_slot: Field) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); @@ -30,7 +30,7 @@ impl ImmutableSingleton { // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address. // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable. // Under such circumstances, such application developers might wish to _not_ use this state variable type. - // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. + // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. // e.g. the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address. pub fn compute_initialization_nullifier(self) -> Field { pedersen_hash( diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index e15b18efd2e..86c8b4be431 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -25,7 +25,7 @@ contract DocsExample { utils as note_utils, }, context::{PrivateContext, PublicContext, Context}, - state_vars::{map::Map, public_mutable::PublicMutable,singleton::Singleton, immutable_singleton::ImmutableSingleton, set::Set, shared_immutable::SharedImmutable}, + state_vars::{map::Map, public_mutable::PublicMutable,singleton::Singleton, private_immutable::PrivateImmutable, set::Set, shared_immutable::SharedImmutable}, }; // how to import methods from other files/folders within your workspace use crate::options::create_account_card_getter_options; @@ -50,7 +50,7 @@ contract DocsExample { set: Set, // docs:end:storage-set-declaration // docs:start:storage-immutable-singleton-declaration - imm_singleton: ImmutableSingleton, + imm_singleton: PrivateImmutable, // docs:end:storage-immutable-singleton-declaration // docs:start:storage-stable-declaration stable_value: SharedImmutable, @@ -85,7 +85,7 @@ contract DocsExample { // docs:start:storage-set-init set: Set::new(context, 5), // docs:end:storage-set-init - imm_singleton: ImmutableSingleton::new(context, 6), + imm_singleton: PrivateImmutable::new(context, 6), // docs:start:storage-stable-init stable_value: SharedImmutable::new(context, 7), // docs:end:storage-stable-init @@ -126,7 +126,7 @@ contract DocsExample { // docs:start:initialize-immutable-singleton #[aztec(private)] - fn initialize_immutable_singleton(randomness: Field, points: u8) { + fn initialize_private_immutable(randomness: Field, points: u8) { let mut new_card = CardNote::new(points, randomness, context.msg_sender()); storage.imm_singleton.initialize(&mut new_card, true); } diff --git a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index d53117493fb..5993e2aa299 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -9,7 +9,7 @@ contract EcdsaAccount { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, note::{note_header::NoteHeader, utils as note_utils}, oracle::get_public_key::get_public_key, - state_vars::immutable_singleton::ImmutableSingleton + state_vars::private_immutable::PrivateImmutable }; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, @@ -19,7 +19,7 @@ contract EcdsaAccount { use crate::ecdsa_public_key_note::EcdsaPublicKeyNote; struct Storage { - public_key: ImmutableSingleton, + public_key: PrivateImmutable, } global ACCOUNT_ACTIONS_STORAGE_SLOT = 2; diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr index 1539c038b4a..ba1b9c8b19a 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -10,7 +10,7 @@ contract SchnorrAccount { use dep::aztec::{ context::{PrivateContext, Context}, note::{note_header::NoteHeader, utils as note_utils}, - oracle::get_public_key::get_public_key, state_vars::immutable_singleton::ImmutableSingleton + oracle::get_public_key::get_public_key, state_vars::private_immutable::PrivateImmutable }; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, @@ -21,7 +21,7 @@ contract SchnorrAccount { struct Storage { // docs:start:storage - signing_public_key: ImmutableSingleton, + signing_public_key: PrivateImmutable, // docs:end:storage } diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 681f93b7dd1..7b8ec3714cf 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -19,7 +19,7 @@ contract Test { note_viewer_options::NoteViewerOptions }, oracle::{get_public_key::get_public_key as get_public_key_oracle, context::get_portal_address, rand::rand}, - state_vars::immutable_singleton::ImmutableSingleton, log::emit_unencrypted_log_from_private + state_vars::private_immutable::PrivateImmutable, log::emit_unencrypted_log_from_private }; use dep::token_portal_content_hash_lib::{get_mint_private_content_hash, get_mint_public_content_hash}; use dep::field_note::field_note::FieldNote; @@ -31,7 +31,7 @@ contract Test { } struct Storage { - example_constant: ImmutableSingleton, + example_constant: PrivateImmutable, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr index 497a1049404..5f05aa8951b 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -29,7 +29,7 @@ contract TokenBlacklist { }, context::{PrivateContext, PublicContext, Context}, hash::{compute_secret_hash}, - state_vars::{map::Map, public_mutable::PublicMutable, set::Set, immutable_singleton::ImmutableSingleton}, + state_vars::{map::Map, public_mutable::PublicMutable, set::Set, private_immutable::PrivateImmutable}, }; use dep::field_note::field_note::FieldNote; @@ -57,7 +57,7 @@ contract TokenBlacklist { total_supply: PublicMutable, pending_shields: Set, public_balances: Map>, - slow_update: ImmutableSingleton, + slow_update: PrivateImmutable, public_slow_update: PublicMutable, } 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 ef720e7ca05..52c920e19eb 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 @@ -132,7 +132,7 @@ describe('e2e_state_vars', () => { it('initialize singleton', async () => { expect(await contract.methods.is_imm_initialized().view()).toEqual(false); - const receipt = await contract.methods.initialize_immutable_singleton(RANDOMNESS, POINTS).send().wait(); + const receipt = await contract.methods.initialize_private_immutable(RANDOMNESS, POINTS).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); @@ -145,7 +145,7 @@ describe('e2e_state_vars', () => { it('fail to reinitialize', async () => { expect(await contract.methods.is_imm_initialized().view()).toEqual(true); await expect( - contract.methods.initialize_immutable_singleton(RANDOMNESS, POINTS).send().wait(), + contract.methods.initialize_private_immutable(RANDOMNESS, POINTS).send().wait(), ).rejects.toThrowError(); expect(await contract.methods.is_imm_initialized().view()).toEqual(true); }); From bebe5059e6d67187da92c3e8ce0fe59750ee15d8 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 23 Feb 2024 16:37:34 +0000 Subject: [PATCH 05/32] singleton --- boxes/react/src/contracts/src/main.nr | 13 ++---- boxes/vanilla-js/src/contracts/src/main.nr | 13 ++---- .../references/storage/private_state.md | 44 +++++++++---------- .../learn/concepts/storage/storage_slots.md | 2 +- .../docs/learn/concepts/storage/trees/main.md | 4 +- docs/docs/misc/migration_notes.md | 8 ++-- .../aztec-nr/aztec/src/state_vars.nr | 2 +- .../{singleton.nr => private_mutable.nr} | 8 ++-- .../docs_example_contract/src/main.nr | 24 +++++----- .../1327_concrete_in_generic/src/main.nr | 30 ++++++------- .../end-to-end/src/e2e_state_vars.test.ts | 32 +++++++------- 11 files changed, 85 insertions(+), 95 deletions(-) rename noir-projects/aztec-nr/aztec/src/state_vars/{singleton.nr => private_mutable.nr} (94%) diff --git a/boxes/react/src/contracts/src/main.nr b/boxes/react/src/contracts/src/main.nr index 5389aeb170f..dff28095651 100644 --- a/boxes/react/src/contracts/src/main.nr +++ b/boxes/react/src/contracts/src/main.nr @@ -1,20 +1,15 @@ contract BoxReact { use dep::aztec::{ - protocol_types::address::AztecAddress, - state_vars::{singleton::Singleton, map::Map}, - note::{ - utils as note_utils, - note_interface::NoteInterface, - note_header::NoteHeader, - }, + protocol_types::address::AztecAddress, state_vars::{private_mutable::PrivateMutable, map::Map}, + note::{utils as note_utils, note_interface::NoteInterface, note_header::NoteHeader} }; use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN}; struct Storage { - numbers: Map>, + numbers: Map>, } - + #[aztec(private)] fn constructor(number: Field, owner: AztecAddress) { let numbers = storage.numbers; diff --git a/boxes/vanilla-js/src/contracts/src/main.nr b/boxes/vanilla-js/src/contracts/src/main.nr index 4a1f5daeedc..89805e11827 100644 --- a/boxes/vanilla-js/src/contracts/src/main.nr +++ b/boxes/vanilla-js/src/contracts/src/main.nr @@ -1,20 +1,15 @@ contract Vanilla { use dep::aztec::{ - protocol_types::address::AztecAddress, - state_vars::{singleton::Singleton, map::Map}, - note::{ - utils as note_utils, - note_interface::NoteInterface, - note_header::NoteHeader, - }, + protocol_types::address::AztecAddress, state_vars::{private_mutable::PrivateMutable, map::Map}, + note::{utils as note_utils, note_interface::NoteInterface, note_header::NoteHeader} }; use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN}; struct Storage { - numbers: Map>, + numbers: Map>, } - + #[aztec(private)] fn constructor(number: Field, owner: AztecAddress) { let numbers = storage.numbers; diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index 0283b17f5ec..16414a5d187 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -16,7 +16,7 @@ Aztec private state follows a [utxo](https://en.wikipedia.org/wiki/Unspent_trans To greatly simplify the experience of writing private state, Aztec.nr provides three different types of private state variable: -- [Singleton](#singletonnotetype) +- [PrivateMutable](#singletonnotetype) - [PrivateImmutable](#privateimmutablenotetype) - [Set](#setnotetype) @@ -42,19 +42,19 @@ A note should implement the following traits: The interplay between a private state variable and its notes can be confusing. Here's a summary to aid intuition: -A private state variable (of type `Singleton`, `PrivateImmutable` or `Set`) may be declared in storage. +A private state variable (of type `PrivateMutable`, `PrivateImmutable` or `Set`) may be declared in storage. Every note contains a header, which contains the contract address and storage slot of the state variable to which it is associated. A note is associated with a private state variable if the storage slot of the private state variable matches the storage slot contained in the note's header. The header provides information that helps the user interpret the note's data. -Management of the header is abstracted-away from developers who use the `PrivateImmutable`, `Singleton` and `Set` types. +Management of the header is abstracted-away from developers who use the `PrivateImmutable`, `PrivateMutable` and `Set` types. A private state variable points to one or many notes (depending on the type). The note(s) are all valid private state if the note(s) haven't yet been nullified. An `PrivateImmutable` will point to _one_ note over the lifetime of the contract. This note is a struct of information that is persisted forever. -A `Singleton` may point to _one_ note at a time. But since it's not "immutable", the note that it points to may be [replaced](#replace) by functions of the contract. The current value of a `Singleton` is interpreted as the one note which has not-yet been nullified. The act of replacing a Singleton's note is how a `Singleton` state may be modified by functions. +A `PrivateMutable` may point to _one_ note at a time. But since it's not "immutable", the note that it points to may be [replaced](#replace) by functions of the contract. The current value of a `PrivateMutable` is interpreted as the one note which has not-yet been nullified. The act of replacing a PrivateMutable's note is how a `PrivateMutable` state may be modified by functions. -`Singleton` is a useful type when declaring a private state variable which may only ever be modified by those who are privy to the current value of that state. +`PrivateMutable` is a useful type when declaring a private state variable which may only ever be modified by those who are privy to the current value of that state. A `Set` may point to _multiple_ notes at a time. The "current value" of a private state variable of type `Set` is some accumulation of all not-yet nullified notes which belong to the `Set`. @@ -66,27 +66,27 @@ Think of a ZCash balance (or even a Bitcoin balance). The "current value" of a u Interestingly, if a developer requires a private state to be modifiable by users who _aren't_ privy to the value of that state, a `Set` is a very useful type. The `insert` method allows new notes to be added to the `Set` without knowing any of the other notes in the set! (Like posting an envelope into a post box, you don't know what else is in there!). -## `Singleton` +## `PrivateMutable` -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. +PrivateMutable is a private state variable that is unique in a way. When a PrivateMutable 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 and a storage slot. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/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: +An example of singleton usage in the account contracts is keeping track of public keys. The `PrivateMutable` is added to the `Storage` struct as follows: #include_code storage-singleton-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `new` -As part of the initialization of the `Storage` struct, the `Singleton` is created as follows at the specified storage slot. +As part of the initialization of the `Storage` struct, the `PrivateMutable` is created as follows at the specified storage slot. #include_code start_vars_singleton /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `initialize` -As mentioned, the Singleton is initialized to create the first note and value. +As mentioned, the PrivateMutable is initialized to create the first note and value. -When this function is called, a nullifier of the storage slot is created, preventing this Singleton from being initialized again. +When this function is called, a nullifier of the storage slot is created, preventing this PrivateMutable from being initialized again. :::danger Privacy-Leak Beware that because this nullifier is created only from the storage slot without randomness it leaks privacy. This means that it is possible for an external observer to determine when the note is nullified. @@ -94,7 +94,7 @@ Beware that because this nullifier is created only from the storage slot without For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the singleton is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. ::: -Unlike public states, which have a default initial value of `0` (or many zeros, in the case of a struct, array or map), a private state (of type `Singleton`, `PrivateImmutable` or `Set`) does not have a default initial value. The `initialize` method (or `insert`, in the case of a `Set`) must be called. +Unlike public states, which have a default initial value of `0` (or many zeros, in the case of a struct, array or map), a private state (of type `PrivateMutable`, `PrivateImmutable` or `Set`) does not have a default initial value. The `initialize` method (or `insert`, in the case of a `Set`) must be called. :::info Extend on what happens if you try to use non-initialized state. @@ -102,29 +102,29 @@ Extend on what happens if you try to use non-initialized state. ### `is_initialized` -An unconstrained method to check whether the Singleton has been initialized or not. It takes an optional owner and returns a boolean. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr). +An unconstrained method to check whether the PrivateMutable has been initialized or not. It takes an optional owner and returns a boolean. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr). #include_code singleton_is_initialized /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `replace` -To update the value of a `Singleton`, we can use the `replace` method. The method takes a new note as input, and replaces the current note with the new one. It emits a nullifier for the old value, and inserts the new note into the data tree. +To update the value of a `PrivateMutable`, we can use the `replace` method. The method takes a new note as input, and replaces the current note with the new one. It emits a nullifier for the old value, and inserts the new note into the data tree. An example of this is seen in a example card game, where we create a new note (a `CardNote`) containing some new data, and replace the current note with it: -#include_code state_vars-SingletonReplace /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code state_vars-PrivateMutableReplace /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust -If two people are trying to modify the Singleton at the same time, only one will succeed as we don't allow duplicate nullifiers! Developers should put in place appropriate access controls to avoid race conditions (unless a race is intended!). +If two people are trying to modify the PrivateMutable at the same time, only one will succeed as we don't allow duplicate nullifiers! Developers should put in place appropriate access controls to avoid race conditions (unless a race is intended!). ### `get_note` -This function allows us to get the note of a Singleton, essentially reading the value. +This function allows us to get the note of a PrivateMutable, essentially reading the value. -#include_code state_vars-SingletonGet /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code state_vars-PrivateMutableGet /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust #### Nullifying Note reads -To ensure that a user's private execution always uses the latest value of a Singleton, the `get_note` function will nullify the note that it is reading. This means that if two people are trying to use this function with the same note, only one will succeed (no duplicate nullifiers allowed). +To ensure that a user's private execution always uses the latest value of a PrivateMutable, the `get_note` function will nullify the note that it is reading. This means that if two people are trying to use this function with the same note, only one will succeed (no duplicate nullifiers allowed). This also makes read operations indistinguishable from write operations and allows the sequencer to verifying correct execution without learning anything about the value of the note. @@ -138,7 +138,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. +As part of the initialization of the `Storage` struct, the `PrivateMutable` is created as follows, here at storage slot 1. #include_code storage-immutable-singleton-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust @@ -164,13 +164,13 @@ An unconstrained method to check if the PrivateImmutable has been initialized. T ### `get_note` -Similar to the `Singleton`, we can use the `get_note` method to read the value of an PrivateImmutable. +Similar to the `PrivateMutable`, we can use the `get_note` method to read the value of an PrivateImmutable. Use this method to retrieve the value of an initialized PrivateImmutable. #include_code get_note-immutable-singleton /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust -Unlike a `Singleton`, the `get_note` function for an PrivateImmutable doesn't nullify the current note in the background. This means that multiple accounts can concurrently call this function to read the value. +Unlike a `PrivateMutable`, the `get_note` function for an PrivateImmutable doesn't nullify the current note in the background. This means that multiple accounts can concurrently call this function to read the value. This function will throw if the `PrivateImmutable` hasn't been initialized. diff --git a/docs/docs/learn/concepts/storage/storage_slots.md b/docs/docs/learn/concepts/storage/storage_slots.md index 9afb68ae05d..0f0d9c905e2 100644 --- a/docs/docs/learn/concepts/storage/storage_slots.md +++ b/docs/docs/learn/concepts/storage/storage_slots.md @@ -44,7 +44,7 @@ note_hash = H(logical_storage_slot, note_content_hash); This siloing (there will be more) is done in the application circuit, since it is not necessary for security of the network (but only the application). :::info -The private variable wrappers `Set` and `Singleton` in Aztec.nr include the `logical_storage_slot` in the commitments they compute, to make it easier for developers to write contracts without having to think about how to correctly handle storage slots. +The private variable wrappers `Set` and `PrivateMutable` in Aztec.nr include the `logical_storage_slot` in the commitments they compute, to make it easier for developers to write contracts without having to think about how to correctly handle storage slots. ::: When reading the values for these notes, the application circuit can then constrain the values to only read notes with a specific logical storage slot. diff --git a/docs/docs/learn/concepts/storage/trees/main.md b/docs/docs/learn/concepts/storage/trees/main.md index 672e3b0aac0..7bf22b4853e 100644 --- a/docs/docs/learn/concepts/storage/trees/main.md +++ b/docs/docs/learn/concepts/storage/trees/main.md @@ -142,9 +142,9 @@ A note cannot actually be "deleted" from the Note Hash Tree because it is an app > Note: this nullifier derivation example is an oversimplification for the purposes of illustration. -#### Initializing Singleton Notes +#### Initializing PrivateMutable Notes -'Singleton Note' is a term we've been using to mean: "A single Note which contains the whole of a private state's current value, and must be deleted and replaced with another single Note, if one ever wishes to edit that state". It's in contrast to a Note which only contains a small fragment of a private state's current value. A token balance represented by multiple notes is an example of private state that uses many notes. +'PrivateMutable Note' is a term we've been using to mean: "A single Note which contains the whole of a private state's current value, and must be deleted and replaced with another single Note, if one ever wishes to edit that state". It's in contrast to a Note which only contains a small fragment of a private state's current value. A token balance represented by multiple notes is an example of private state that uses many notes. Such notes require an 'Initialization Nullifier'; a nullifier which, when emitted, signals the initialization of this state variable (i.e. the very first time the state variable has been written to). diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index a7e2bd7e2a0..fe4c9a3d31f 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -205,12 +205,12 @@ impl Storage { 1, LeaderSerializationMethods, ), - legendary_card: Singleton::new(context, 2, CardNoteMethods), + legendary_card: PrivateMutable::new(context, 2, CardNoteMethods), profiles: Map::new( context, 3, |context, slot| { - Singleton::new(context, slot, CardNoteMethods) + PrivateMutable::new(context, slot, CardNoteMethods) }, ), test: Set::new(context, 4, CardNoteMethods), @@ -466,12 +466,12 @@ impl Storage { context, 1 ), - legendary_card: Singleton::new(context, 2), + legendary_card: PrivateMutable::new(context, 2), profiles: Map::new( context, 3, |context, slot| { - Singleton::new(context, slot) + PrivateMutable::new(context, slot) }, ), test: Set::new(context, 4), diff --git a/noir-projects/aztec-nr/aztec/src/state_vars.nr b/noir-projects/aztec-nr/aztec/src/state_vars.nr index d4588dc5fe5..99e3bfdddc2 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars.nr @@ -2,6 +2,6 @@ mod private_immutable; mod map; mod public_mutable; mod set; -mod singleton; +mod private_mutable; mod shared_immutable; mod storage; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr similarity index 94% rename from noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr rename to noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr index 137a0767d4e..5bbec736ddd 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr @@ -11,15 +11,15 @@ use crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullif use crate::state_vars::storage::Storage; // docs:start:struct -struct Singleton { +struct PrivateMutable { context: Option<&mut PrivateContext>, storage_slot: Field } // docs:end:struct -impl Storage for Singleton {} +impl Storage for PrivateMutable {} -impl Singleton { +impl PrivateMutable { // docs:start:new pub fn new(context: Context, storage_slot: Field) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); @@ -31,7 +31,7 @@ impl Singleton { // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address. // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable. // Under such circumstances, such application developers might wish to _not_ use this state variable type. - // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. + // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address. // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage. diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 86c8b4be431..8488680c540 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -25,7 +25,7 @@ contract DocsExample { utils as note_utils, }, context::{PrivateContext, PublicContext, Context}, - state_vars::{map::Map, public_mutable::PublicMutable,singleton::Singleton, private_immutable::PrivateImmutable, set::Set, shared_immutable::SharedImmutable}, + state_vars::{map::Map, public_mutable::PublicMutable,private_mutable::PrivateMutable, private_immutable::PrivateImmutable, set::Set, shared_immutable::SharedImmutable}, }; // how to import methods from other files/folders within your workspace use crate::options::create_account_card_getter_options; @@ -40,11 +40,11 @@ contract DocsExample { leader: PublicMutable, // docs:end:storage-leader-declaration // docs:start:storage-singleton-declaration - legendary_card: Singleton, + legendary_card: PrivateMutable, // docs:end:storage-singleton-declaration // just used for docs example to show how to create a singleton map. // docs:start:storage-map-singleton-declaration - profiles: Map>, + profiles: Map>, // docs:end:storage-map-singleton-declaration // docs:start:storage-set-declaration set: Set, @@ -70,18 +70,18 @@ contract DocsExample { ), // docs:end:storage-leader-init // docs:start:start_vars_singleton - legendary_card: Singleton::new(context, 3), + legendary_card: PrivateMutable::new(context, 3), // docs:end:start_vars_singleton // just used for docs example (not for game play): - // docs:start:state_vars-MapSingleton + // docs:start:state_vars-MapPrivateMutable profiles: Map::new( context, 4, |context, slot| { - Singleton::new(context, slot) + PrivateMutable::new(context, slot) }, ), - // docs:end:state_vars-MapSingleton + // docs:end:state_vars-MapPrivateMutable // docs:start:storage-set-init set: Set::new(context, 5), // docs:end:storage-set-init @@ -180,16 +180,16 @@ contract DocsExample { // Ensure `points` > current value // Also serves as a e2e test that you can `get_note()` and then `replace()` - // docs:start:state_vars-SingletonGet + // docs:start:state_vars-PrivateMutableGet let card = storage.legendary_card.get_note(false); - // docs:end:state_vars-SingletonGet + // docs:end:state_vars-PrivateMutableGet let points = card.points + 1; let mut new_card = CardNote::new(points, card.randomness, context.msg_sender()); - // docs:start:state_vars-SingletonReplace + // docs:start:state_vars-PrivateMutableReplace storage.legendary_card.replace(&mut new_card, true); - // docs:end:state_vars-SingletonReplace + // docs:end:state_vars-PrivateMutableReplace context.call_public_function( context.this_address(), @@ -228,7 +228,7 @@ contract DocsExample { storage.imm_singleton.view_note() } - unconstrained fn is_imm_initialized() -> pub bool { + unconstrained fn is_priv_imm_initialized() -> pub bool { storage.imm_singleton.is_initialized() } diff --git a/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr b/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr index e1d601b13c9..9542bf6463b 100644 --- a/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr +++ b/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr @@ -10,15 +10,15 @@ struct B { } impl B { - fn new(new_concrete_t_c_constructor: fn () -> T_C) -> B { - B { new_concrete_t_c_constructor } - } + fn new(new_concrete_t_c_constructor: fn() -> T_C) -> B { + B { new_concrete_t_c_constructor } + } - fn get_t_c(self) -> T_C { - let new_concrete_t_c_constructor = self.new_concrete_t_c_constructor; - new_concrete_t_c_constructor() - } + fn get_t_c(self) -> T_C { + let new_concrete_t_c_constructor = self.new_concrete_t_c_constructor; + new_concrete_t_c_constructor() } +} // --- // Set struct C { @@ -26,15 +26,15 @@ struct C { } impl C { - fn new (t_d_interface: MethodInterface) -> Self { - C { t_d_interface } - } + fn new(t_d_interface: MethodInterface) -> Self { + C { t_d_interface } + } - fn call_method_of_t_d(self, t_d: T_D) -> Field { - let some_method_on_t_d = self.t_d_interface.some_method_on_t_d; - some_method_on_t_d(t_d) - } + fn call_method_of_t_d(self, t_d: T_D) -> Field { + let some_method_on_t_d = self.t_d_interface.some_method_on_t_d; + some_method_on_t_d(t_d) } +} // --- struct MethodInterface { some_method_on_t_d: fn(T_D)->Field, @@ -55,7 +55,7 @@ fn get_d_method_interface() -> MethodInterface { // --- fn main(input: Field) -> pub Field { let b: B> = B::new(new_concrete_c_over_d); - let c: C = b.get_t_c(); // Singleton + let c: C = b.get_t_c(); // PrivateMutable let d: D = D { d: input }; // Note let output = c.call_method_of_t_d(d); 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 52c920e19eb..de4c4a40bd2 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 @@ -37,13 +37,13 @@ describe('e2e_state_vars', () => { }, 200_000); }); - describe('Singleton', () => { - it('fail to read uninitialized singleton', async () => { + describe('PrivateMutable', () => { + it('fail to read uninitialized PrivateMutable', async () => { expect(await contract.methods.is_legendary_initialized().view()).toEqual(false); await expect(contract.methods.get_legendary_card().view()).rejects.toThrowError(); }); - it('initialize singleton', async () => { + it('initialize PrivateMutable', async () => { expect(await contract.methods.is_legendary_initialized().view()).toEqual(false); const receipt = await contract.methods.initialize_private(RANDOMNESS, POINTS).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); @@ -61,7 +61,7 @@ describe('e2e_state_vars', () => { expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); }); - it('read initialized singleton', async () => { + it('read initialized PrivateMutable', async () => { expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); const { points, randomness } = await contract.methods.get_legendary_card().view(); expect(points).toEqual(POINTS); @@ -91,7 +91,7 @@ describe('e2e_state_vars', () => { expect(noteBefore.header.nonce).not.toEqual(noteAfter.header.nonce); }); - it('replace singleton with other values', async () => { + it('replace PrivateMutable with other values', async () => { expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); const receipt = await contract.methods .update_legendary_card(RANDOMNESS + 2n, POINTS + 1n) @@ -108,7 +108,7 @@ describe('e2e_state_vars', () => { expect(randomness).toEqual(RANDOMNESS + 2n); }); - it('replace singleton dependent on prior value', async () => { + it('replace PrivateMutable dependent on prior value', async () => { expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); const noteBefore = await contract.methods.get_legendary_card().view(); const receipt = await contract.methods.increase_legendary_points().send().wait(); @@ -124,14 +124,14 @@ describe('e2e_state_vars', () => { }); }); - describe('Immutable Singleton', () => { - it('fail to read uninitialized singleton', async () => { - expect(await contract.methods.is_imm_initialized().view()).toEqual(false); + describe('PrivateImmutable', () => { + it('fail to read uninitialized PrivateImmutable', async () => { + expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(false); await expect(contract.methods.view_imm_card().view()).rejects.toThrowError(); }); - it('initialize singleton', async () => { - expect(await contract.methods.is_imm_initialized().view()).toEqual(false); + it('initialize PrivateImmutable', async () => { + expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(false); const receipt = await contract.methods.initialize_private_immutable(RANDOMNESS, POINTS).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); @@ -139,19 +139,19 @@ describe('e2e_state_vars', () => { expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the initializer expect(tx?.newNullifiers.length).toEqual(2); - expect(await contract.methods.is_imm_initialized().view()).toEqual(true); + expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); }); it('fail to reinitialize', async () => { - expect(await contract.methods.is_imm_initialized().view()).toEqual(true); + expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); await expect( contract.methods.initialize_private_immutable(RANDOMNESS, POINTS).send().wait(), ).rejects.toThrowError(); - expect(await contract.methods.is_imm_initialized().view()).toEqual(true); + expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); }); - it('read initialized singleton', async () => { - expect(await contract.methods.is_imm_initialized().view()).toEqual(true); + it('read initialized PrivateImmutable', async () => { + expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); const { points, randomness } = await contract.methods.view_imm_card().view(); expect(points).toEqual(POINTS); expect(randomness).toEqual(RANDOMNESS); From 0f30d9905a41d1ab8b4440a9dc6362551c78f4a6 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 09:03:28 +0000 Subject: [PATCH 06/32] WIP --- boxes/react/src/contracts/src/main.nr | 2 +- boxes/vanilla-js/src/contracts/src/main.nr | 2 +- .../references/storage/private_state.md | 12 ++-- .../references/storage/public_state.md | 4 +- .../aztec-nr/aztec/src/state_vars.nr | 12 +++- .../app_subscription_contract/src/main.nr | 16 ++--- .../benchmarking_contract/src/main.nr | 2 +- .../docs_example_contract/src/main.nr | 70 +++++++++---------- .../contracts/fpc_contract/src/main.nr | 6 +- .../schnorr_account_contract/src/main.nr | 2 +- .../contracts/slow_tree_contract/src/main.nr | 3 +- .../stateful_test_contract/src/main.nr | 3 +- .../nargo_fmt/tests/expected/contract.nr | 2 +- .../tooling/nargo_fmt/tests/input/contract.nr | 2 +- .../end-to-end/src/e2e_state_vars.test.ts | 12 ++-- 15 files changed, 77 insertions(+), 73 deletions(-) diff --git a/boxes/react/src/contracts/src/main.nr b/boxes/react/src/contracts/src/main.nr index dff28095651..e57aac08ab1 100644 --- a/boxes/react/src/contracts/src/main.nr +++ b/boxes/react/src/contracts/src/main.nr @@ -1,6 +1,6 @@ contract BoxReact { use dep::aztec::{ - protocol_types::address::AztecAddress, state_vars::{private_mutable::PrivateMutable, map::Map}, + protocol_types::address::AztecAddress, state_vars::{PrivateMutable, Map}, note::{utils as note_utils, note_interface::NoteInterface, note_header::NoteHeader} }; diff --git a/boxes/vanilla-js/src/contracts/src/main.nr b/boxes/vanilla-js/src/contracts/src/main.nr index 89805e11827..bb374393d5d 100644 --- a/boxes/vanilla-js/src/contracts/src/main.nr +++ b/boxes/vanilla-js/src/contracts/src/main.nr @@ -1,6 +1,6 @@ contract Vanilla { use dep::aztec::{ - protocol_types::address::AztecAddress, state_vars::{private_mutable::PrivateMutable, map::Map}, + protocol_types::address::AztecAddress, state_vars::{PrivateMutable, Map}, note::{utils as note_utils, note_interface::NoteInterface, note_header::NoteHeader} }; diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index 16414a5d187..c6f1193ca80 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -74,13 +74,13 @@ Like for public state, we define the struct to have context and a storage slot. An example of singleton usage in the account contracts is keeping track of public keys. The `PrivateMutable` is added to the `Storage` struct as follows: -#include_code storage-singleton-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code storage-private-mutable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `new` As part of the initialization of the `Storage` struct, the `PrivateMutable` is created as follows at the specified storage slot. -#include_code start_vars_singleton /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code start_vars_private_mutable /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `initialize` @@ -104,7 +104,7 @@ Extend on what happens if you try to use non-initialized state. An unconstrained method to check whether the PrivateMutable has been initialized or not. It takes an optional owner and returns a boolean. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr). -#include_code singleton_is_initialized /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code private_mutable_is_initialized /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `replace` @@ -140,7 +140,7 @@ Functionally similar to [`get_note`](#get_note), but executed in unconstrained f As part of the initialization of the `Storage` struct, the `PrivateMutable` is created as follows, here at storage slot 1. -#include_code storage-immutable-singleton-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code storage-private-immutable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `initialize` @@ -154,7 +154,7 @@ For example, if the storage slot depends on the an address then it is possible t Set the value of an PrivateImmutable by calling the `initialize` method: -#include_code initialize-immutable-singleton /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code initialize-private-mutable /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust Once initialized, an PrivateImmutable's value remains unchangeable. This method can only be called once. @@ -168,7 +168,7 @@ Similar to the `PrivateMutable`, we can use the `get_note` method to read the va Use this method to retrieve the value of an initialized PrivateImmutable. -#include_code get_note-immutable-singleton /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code get_note-private-immutable /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust Unlike a `PrivateMutable`, the `get_note` function for an PrivateImmutable doesn't nullify the current note in the background. This means that multiple accounts can concurrently call this function to read the value. diff --git a/docs/docs/developers/contracts/references/storage/public_state.md b/docs/docs/developers/contracts/references/storage/public_state.md index 6282bdf3d04..7989070b6b1 100644 --- a/docs/docs/developers/contracts/references/storage/public_state.md +++ b/docs/docs/developers/contracts/references/storage/public_state.md @@ -105,9 +105,9 @@ You can find the details of `SharedImmutable` in the implementation [here](https Is done exactly like the `PublicMutable` struct, but with the `SharedImmutable` struct. -#include_code storage-stable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code storage-shared-immutable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust -#include_code storage-stable-init /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust +#include_code storage-shared-immutable /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `initialize` diff --git a/noir-projects/aztec-nr/aztec/src/state_vars.nr b/noir-projects/aztec-nr/aztec/src/state_vars.nr index 99e3bfdddc2..c718a748923 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars.nr @@ -1,7 +1,15 @@ -mod private_immutable; mod map; +mod private_immutable; +mod private_mutable; mod public_mutable; mod set; -mod private_mutable; mod shared_immutable; mod storage; + +use crate::state_vars::map::Map; +use crate::state_vars::private_immutable::PrivateImmutable; +use crate::state_vars::private_mutable::PrivateMutable; +use crate::state_vars::public_mutable::PublicMutable; +use crate::state_vars::set::Set; +use crate::state_vars::shared_immutable::SharedImmutable; +use crate::state_vars::storage::Storage; diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index 1e53fbfe4da..5dec0565858 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -11,20 +11,20 @@ contract AppSubscriptionContract { use dep::aztec::{ context::{PrivateContext, Context}, note::{note_header::NoteHeader, utils as note_utils}, oracle::get_public_key::get_public_key, - state_vars::{map::Map, singleton::Singleton, public_state::PublicState, stable_public_state::StablePublicState} + state_vars::{Map, PrivateMutable, PublicMutable, SharedImmutable} }; use dep::authwit::{account::AccountActions, auth_witness::get_auth_witness, auth::assert_current_call_valid_authwit}; use crate::subscription_note::{SubscriptionNote, SUBSCRIPTION_NOTE_LEN}; struct Storage { - // todo change this to immutable singletons because it's only needed in private - target_address: StablePublicState, - subscription_token_address: StablePublicState, - subscription_recipient_address: StablePublicState, - subscription_price: StablePublicState, - subscriptions: Map>, - gas_token_address: StablePublicState, + // todo change this to PrivateImmutable because it's only needed in private + target_address: SharedImmutable, + subscription_token_address: SharedImmutable, + subscription_recipient_address: SharedImmutable, + subscription_price: SharedImmutable, + subscriptions: Map>, + gas_token_address: SharedImmutable, } global SUBSCRIPTION_DURATION_IN_BLOCKS = 5; diff --git a/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr index a835868cf16..40fac05f00e 100644 --- a/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -11,7 +11,7 @@ contract Benchmarking { protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - log::emit_unencrypted_log, state_vars::{map::Map, public_mutable::PublicMutable, set::Set} + log::emit_unencrypted_log, state_vars::{Map, PublicMutable, Set} }; struct Storage { diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 8488680c540..d348dcb055c 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -1,11 +1,11 @@ mod options; mod types; -// Following is a very simple game to show case use of singleton in as minimalistic way as possible -// It also serves as an e2e test that you can read and then replace the singleton in the same call +// Following is a very simple game to show case use of PrivateMutable in as minimalistic way as possible +// It also serves as an e2e test that you can read and then replace the PrivateMutable in the same call // (tests ordering in the circuit) -// you have a card (singleton). Anyone can create a bigger card. Whoever is bigger will be the leader. +// you have a card (PrivateMutable). Anyone can create a bigger card. Whoever is bigger will be the leader. // it also has dummy methods and other examples used for documentation e.g. // how to create custom notes, a custom struct for public state, a custom note that may be unencrypted // also has `options.nr` which shows various ways of using `NoteGetterOptions` to query notes @@ -25,7 +25,7 @@ contract DocsExample { utils as note_utils, }, context::{PrivateContext, PublicContext, Context}, - state_vars::{map::Map, public_mutable::PublicMutable,private_mutable::PrivateMutable, private_immutable::PrivateImmutable, set::Set, shared_immutable::SharedImmutable}, + state_vars::{Map, PublicMutable, PrivateMutable, PrivateImmutable, Set, SharedImmutable}, }; // how to import methods from other files/folders within your workspace use crate::options::create_account_card_getter_options; @@ -39,22 +39,20 @@ contract DocsExample { // docs:start:storage-leader-declaration leader: PublicMutable, // docs:end:storage-leader-declaration - // docs:start:storage-singleton-declaration + // docs:start:storage-private-mutable-declaration legendary_card: PrivateMutable, - // docs:end:storage-singleton-declaration - // just used for docs example to show how to create a singleton map. - // docs:start:storage-map-singleton-declaration + // docs:end:storage-private-mutable-declaration + // just used for docs example to show how to create a private mutable map. profiles: Map>, - // docs:end:storage-map-singleton-declaration // docs:start:storage-set-declaration set: Set, // docs:end:storage-set-declaration - // docs:start:storage-immutable-singleton-declaration - imm_singleton: PrivateImmutable, - // docs:end:storage-immutable-singleton-declaration - // docs:start:storage-stable-declaration - stable_value: SharedImmutable, - // docs:end:storage-stable-declaration + // docs:start:storage-private-immutable-declaration + private_immutable: PrivateImmutable, + // docs:end:storage-private-immutable-declaration + // docs:start:storage-shared-immutable-declaration + shared_immutable: SharedImmutable, + // docs:end:storage-shared-immutable-declaration // docs:start:storage-minters-declaration minters: Map>, // docs:end:storage-minters-declaration @@ -69,9 +67,9 @@ contract DocsExample { 1 ), // docs:end:storage-leader-init - // docs:start:start_vars_singleton + // docs:start:start_vars_private_mutable legendary_card: PrivateMutable::new(context, 3), - // docs:end:start_vars_singleton + // docs:end:start_vars_private_mutable // just used for docs example (not for game play): // docs:start:state_vars-MapPrivateMutable profiles: Map::new( @@ -85,10 +83,10 @@ contract DocsExample { // docs:start:storage-set-init set: Set::new(context, 5), // docs:end:storage-set-init - imm_singleton: PrivateImmutable::new(context, 6), - // docs:start:storage-stable-init - stable_value: SharedImmutable::new(context, 7), - // docs:end:storage-stable-init + private_immutable: PrivateImmutable::new(context, 6), + // docs:start:storage-shared-immutable + shared_immutable: SharedImmutable::new(context, 7), + // docs:end:storage-shared-immutable // docs:start:storage-minters-init minters: Map::new( context, @@ -106,31 +104,31 @@ contract DocsExample { fn constructor() {} #[aztec(public)] - fn initialize_stable(points: u8) { + fn initialize_shared_immutable(points: u8) { let mut new_leader = Leader { account: context.msg_sender(), points }; - storage.stable_value.initialize(new_leader); + storage.shared_immutable.initialize(new_leader); } #[aztec(private)] - fn match_stable(account: AztecAddress, points: u8) { + fn match_shared_immutable(account: AztecAddress, points: u8) { let expected = Leader { account, points }; - let read = storage.stable_value.read_private(); + let read = storage.shared_immutable.read_private(); assert(read.account == expected.account, "Invalid account"); assert(read.points == expected.points, "Invalid points"); } unconstrained fn get_stable() -> pub Leader { - storage.stable_value.read_public() + storage.shared_immutable.read_public() } - // docs:start:initialize-immutable-singleton + // docs:start:initialize-private-mutable #[aztec(private)] fn initialize_private_immutable(randomness: Field, points: u8) { let mut new_card = CardNote::new(points, randomness, context.msg_sender()); - storage.imm_singleton.initialize(&mut new_card, true); + storage.private_immutable.initialize(&mut new_card, true); } - // docs:end:initialize-immutable-singleton + // docs:end:initialize-private-mutable #[aztec(private)] // msg_sender() is 0 at deploy time. So created another function @@ -212,24 +210,24 @@ contract DocsExample { storage.legendary_card.view_note() } - // docs:start:singleton_is_initialized + // docs:start:private_mutable_is_initialized unconstrained fn is_legendary_initialized() -> pub bool { storage.legendary_card.is_initialized() } - // docs:end:singleton_is_initialized + // docs:end:private_mutable_is_initialized - // docs:start:get_note-immutable-singleton + // docs:start:get_note-private-immutable unconstrained fn get_imm_card() -> pub CardNote { - storage.imm_singleton.get_note() + storage.private_immutable.get_note() } - // docs:end:get_note-immutable-singleton + // docs:end:get_note-private-immutable unconstrained fn view_imm_card() -> pub CardNote { - storage.imm_singleton.view_note() + storage.private_immutable.view_note() } unconstrained fn is_priv_imm_initialized() -> pub bool { - storage.imm_singleton.is_initialized() + storage.private_immutable.is_initialized() } /// Macro equivalence section diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr index 2ae62fa96f3..c181caa1807 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr @@ -2,14 +2,14 @@ mod interfaces; contract FPC { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}; - use dep::aztec::state_vars::stable_public_state::StablePublicState; + use dep::aztec::state_vars::SharedImmutable; use dep::safe_math::SafeU120; use crate::interfaces::Token; struct Storage { - other_asset: StablePublicState, - fee_asset: StablePublicState, + other_asset: SharedImmutable, + fee_asset: SharedImmutable, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr index ba1b9c8b19a..6e4eec425c9 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -10,7 +10,7 @@ contract SchnorrAccount { use dep::aztec::{ context::{PrivateContext, Context}, note::{note_header::NoteHeader, utils as note_utils}, - oracle::get_public_key::get_public_key, state_vars::private_immutable::PrivateImmutable + oracle::get_public_key::get_public_key, state_vars::PrivateImmutable }; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, diff --git a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr index 9104fd9ece1..7cc8b88be59 100644 --- a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr @@ -11,8 +11,7 @@ contract SlowTree { use dep::value_note::{balance_utils, utils::{increment, decrement}, value_note::ValueNote}; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, - note::{note_header::NoteHeader, utils as note_utils}, - state_vars::{map::Map, public_mutable::PublicMutable, set::Set}, + note::{note_header::NoteHeader, utils as note_utils}, state_vars::{Map, PublicMutable, Set}, protocol_types::type_serialization::FIELD_SERIALIZED_LEN }; use dep::slow_updates_tree::{SlowMap, Leaf, SlowUpdateProof, compute_merkle_root, deserialize_slow_update_proof}; diff --git a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr index f559fbe5e6a..2d7714897c0 100644 --- a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -5,8 +5,7 @@ contract StatefulTest { use dep::value_note::{balance_utils, utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote}}; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, - note::{note_header::NoteHeader, utils as note_utils}, - state_vars::{map::Map, public_mutable::PublicMutable, set::Set} + note::{note_header::NoteHeader, utils as note_utils}, state_vars::{Map, PublicMutable, Set} }; struct Storage { diff --git a/noir/tooling/nargo_fmt/tests/expected/contract.nr b/noir/tooling/nargo_fmt/tests/expected/contract.nr index 94c9317d1a1..365a6f8bfb3 100644 --- a/noir/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/tooling/nargo_fmt/tests/expected/contract.nr @@ -10,7 +10,7 @@ contract Benchmarking { use dep::aztec::{ context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - log::emit_unencrypted_log, state_vars::{map::Map, public_mutable::PublicMutable, set::Set}, + log::emit_unencrypted_log, state_vars::{Map, PublicMutable, Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, types::address::{AztecAddress} }; diff --git a/noir/tooling/nargo_fmt/tests/input/contract.nr b/noir/tooling/nargo_fmt/tests/input/contract.nr index 94c9317d1a1..365a6f8bfb3 100644 --- a/noir/tooling/nargo_fmt/tests/input/contract.nr +++ b/noir/tooling/nargo_fmt/tests/input/contract.nr @@ -10,7 +10,7 @@ contract Benchmarking { use dep::aztec::{ context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - log::emit_unencrypted_log, state_vars::{map::Map, public_mutable::PublicMutable, set::Set}, + log::emit_unencrypted_log, state_vars::{Map, PublicMutable, Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, types::address::{AztecAddress} }; 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 de4c4a40bd2..cad944a121a 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 @@ -19,20 +19,20 @@ describe('e2e_state_vars', () => { afterAll(() => teardown()); - describe('Stable Public State', () => { - it('private read of uninitialized stable', async () => { + describe('SharedImmutable', () => { + it('private read of uninitialized SharedImmutable', async () => { const s = await contract.methods.get_stable().view(); - const receipt2 = await contract.methods.match_stable(s.account, s.points).send().wait(); + const receipt2 = await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); expect(receipt2.status).toEqual(TxStatus.MINED); }); - it('private read of initialized stable', async () => { - const receipt = await contract.methods.initialize_stable(1).send().wait(); + it('private read of initialized SharedImmutable', async () => { + const receipt = await contract.methods.initialize_shared_immutable(1).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); const s = await contract.methods.get_stable().view(); - const receipt2 = await contract.methods.match_stable(s.account, s.points).send().wait(); + const receipt2 = await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); expect(receipt2.status).toEqual(TxStatus.MINED); }, 200_000); }); From 26308ec2ffc69498981d3b7e36b461a03eb73897 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 09:05:15 +0000 Subject: [PATCH 07/32] WIP --- .../contracts/docs_example_contract/src/main.nr | 2 +- yarn-project/end-to-end/src/e2e_state_vars.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index d348dcb055c..dd48f26fe51 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -118,7 +118,7 @@ contract DocsExample { assert(read.points == expected.points, "Invalid points"); } - unconstrained fn get_stable() -> pub Leader { + unconstrained fn get_shared_immutable() -> pub Leader { storage.shared_immutable.read_public() } 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 cad944a121a..b33f5f04560 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 @@ -21,7 +21,7 @@ describe('e2e_state_vars', () => { describe('SharedImmutable', () => { it('private read of uninitialized SharedImmutable', async () => { - const s = await contract.methods.get_stable().view(); + const s = await contract.methods.get_shared_immutable().view(); const receipt2 = await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); expect(receipt2.status).toEqual(TxStatus.MINED); @@ -30,7 +30,7 @@ describe('e2e_state_vars', () => { it('private read of initialized SharedImmutable', async () => { const receipt = await contract.methods.initialize_shared_immutable(1).send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); - const s = await contract.methods.get_stable().view(); + const s = await contract.methods.get_shared_immutable().view(); const receipt2 = await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); expect(receipt2.status).toEqual(TxStatus.MINED); From cfc97fc099bf76b000f18d684fcbb31d7ce6f974 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 09:47:12 +0000 Subject: [PATCH 08/32] Enforcing 1 time initialization --- .../aztec/src/state_vars/public_mutable.nr | 4 ++-- .../aztec/src/state_vars/shared_immutable.nr | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr index cc41e42dc5a..5c474846357 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr @@ -28,7 +28,7 @@ impl PublicMutable { // docs:start:public_mutable_struct_read pub fn read(self) -> T where T: Deserialize { - assert(self.context.private.is_none(), "Public state reads only supported in public functions"); + assert(self.context.private.is_none(), "PublicMutable reads only supported in public functions"); let fields = storage_read(self.storage_slot); T::deserialize(fields) } @@ -36,7 +36,7 @@ impl PublicMutable { // docs:start:public_mutable_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"); + assert(self.context.private.is_none(), "PublicMutable writes only supported in public functions"); let fields = T::serialize(value); storage_write(self.storage_slot, fields); } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 45705e5e142..341c83681c1 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -18,7 +18,9 @@ impl SharedImmutable { context: Context, storage_slot: Field ) -> Self { - assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); + assert( + (storage_slot != 0) & (storage_slot != 1), "Storage slots 0 and 1 not allowed. Storage slots must start from 2." + ); Self { context, storage_slot } } @@ -28,13 +30,17 @@ impl SharedImmutable { self.context.private.is_none(), "SharedImmutable can only be initialized from public functions" ); self.context.public.unwrap_unchecked().assert_deployment(); - // TODO: Must throw if the storage slot is not empty -> cannot allow overwriting - // This is currently impractical, as public functions are never marked `is_contract_deployment` - // in the `call_context`, only private functions will have this flag set. - let fields = T::serialize(value); - // TODO(benesjan): check here that the value is not already set - // storage_write(self.storage_slot, 0xdead); - storage_write(self.storage_slot, fields); + + // We check that the struct is not yet initialized by checking if the placeholder slot is 0 + let placeholder_storage_slot = self.storage_slot - 1; + let fields_read: [Field; 1] = storage_read(placeholder_storage_slot); + assert(fields_read[0] != 0, "SharedImmutable already initialized"); + + // We populate the placeholder slot with a non-zero value to indicate that the struct is initialized + storage_write(placeholder_storage_slot, [0xdead]); + + let fields_write = T::serialize(value); + storage_write(self.storage_slot, fields_write); } pub fn read_public(self) -> T where T: Deserialize { From 336414f082756dace22afe2c606de58964655034 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 10:12:42 +0000 Subject: [PATCH 09/32] using re-exports --- .../noir-contracts/contracts/child_contract/src/main.nr | 2 +- .../noir-contracts/contracts/delegated_on_contract/src/main.nr | 2 +- .../noir-contracts/contracts/delegator_contract/src/main.nr | 2 +- .../contracts/inclusion_proofs_contract/src/main.nr | 2 +- .../noir-contracts/contracts/token_contract/src/main.nr | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr index 9dfbd588e22..623d5b6463e 100644 --- a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr @@ -4,7 +4,7 @@ contract Child { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, - state_vars::{public_mutable::PublicMutable, set::Set}, + state_vars::{PublicMutable, Set}, protocol_types::{abis::{function_selector::FunctionSelector, call_context::CallContext}, address::AztecAddress}, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader, utils as note_utils} }; diff --git a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr index 083df69456e..c1a7c4e0cdb 100644 --- a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr @@ -4,7 +4,7 @@ contract DelegatedOn { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, - state_vars::{public_mutable::PublicMutable, set::Set}, + state_vars::{PublicMutable, Set}, protocol_types::{abis::{function_selector::FunctionSelector, call_context::CallContext}, address::AztecAddress}, note::{ note_getter_options::NoteGetterOptions, note_viewer_options::NoteViewerOptions, diff --git a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr index 403f1f6be5d..407d551d197 100644 --- a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr @@ -3,7 +3,7 @@ contract Delegator { use dep::std::option::Option; use dep::aztec::{ - log::emit_unencrypted_log, state_vars::{public_mutable::PublicMutable, set::Set}, + log::emit_unencrypted_log, state_vars::{PublicMutable, Set}, protocol_types::{abis::{function_selector::FunctionSelector}, address::AztecAddress}, note::{note_viewer_options::NoteViewerOptions, utils as note_utils, note_header::NoteHeader} }; diff --git a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index 82c29851733..33bf68dd8ec 100644 --- a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -5,7 +5,7 @@ contract InclusionProofs { grumpkin_point::GrumpkinPoint, contract_class_id::ContractClassId }; use dep::aztec::{ - state_vars::{map::Map, set::Set, public_mutable::PublicMutable}, context::Context, + state_vars::{Map, Set, PublicMutable}, context::Context, note::{ note_getter_options::NoteGetterOptions, note_getter_options::NoteStatus, note_header::NoteHeader, utils as note_utils diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index 1af6cd1a9ff..b7e5da9b3f1 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -23,7 +23,7 @@ contract Token { utils as note_utils, }, hash::{compute_secret_hash}, - state_vars::{map::Map, public_mutable::PublicMutable, shared_immutable::SharedImmutable, set::Set}, + state_vars::{Map, PublicMutable, SharedImmutable, Set}, protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress From dc7cd837a4c6a632645ddbafbae6cfcc7faf6424 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 10:25:35 +0000 Subject: [PATCH 10/32] SharedImmutable fix --- .../aztec/src/state_vars/shared_immutable.nr | 23 ++++++++++--------- .../src/crates/types/src/constants.nr | 1 + yarn-project/circuits.js/src/constants.gen.ts | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 341c83681c1..29242863c9b 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -1,9 +1,9 @@ -use crate::context::{Context}; -use crate::oracle::{storage::{storage_read, storage_write}}; -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::storage::Storage; +use crate::{ + context::{Context}, hash::pedersen_hash, + history::public_value_inclusion::prove_public_value_inclusion, + oracle::{storage::{storage_read, storage_write}}, state_vars::storage::Storage +}; +use dep::protocol_types::{constants::GENERATOR_INDEX__IMMUTABLE_INITIALIZE_PLACEHOLDER, traits::{Deserialize, Serialize}}; struct SharedImmutable{ context: Context, @@ -18,9 +18,7 @@ impl SharedImmutable { context: Context, storage_slot: Field ) -> Self { - assert( - (storage_slot != 0) & (storage_slot != 1), "Storage slots 0 and 1 not allowed. Storage slots must start from 2." - ); + assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { context, storage_slot } } @@ -32,9 +30,12 @@ impl SharedImmutable { self.context.public.unwrap_unchecked().assert_deployment(); // We check that the struct is not yet initialized by checking if the placeholder slot is 0 - let placeholder_storage_slot = self.storage_slot - 1; + let placeholder_storage_slot = pedersen_hash( + [self.storage_slot], + GENERATOR_INDEX__IMMUTABLE_INITIALIZE_PLACEHOLDER + ); let fields_read: [Field; 1] = storage_read(placeholder_storage_slot); - assert(fields_read[0] != 0, "SharedImmutable already initialized"); + assert(fields_read[0] == 0, "SharedImmutable already initialized"); // We populate the placeholder slot with a non-zero value to indicate that the struct is initialized storage_write(placeholder_storage_slot, [0xdead]); diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index be81885d059..99b7f006833 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -230,3 +230,4 @@ global GENERATOR_INDEX__VK = 41; global GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42; global GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43; global GENERATOR_INDEX__FUNCTION_ARGS = 44; +global GENERATOR_INDEX__IMMUTABLE_INITIALIZE_PLACEHOLDER = 45; diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 47bbff17361..bfb3ef3f462 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -144,4 +144,5 @@ export enum GeneratorIndex { PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42, PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43, FUNCTION_ARGS = 44, + IMMUTABLE_INITIALIZE_PLACEHOLDER = 45, } From 6f23109c1d5e47de4d8045a643e846f223601808 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 10:56:20 +0000 Subject: [PATCH 11/32] double initialization test --- yarn-project/end-to-end/src/e2e_state_vars.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) 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 b33f5f04560..6365d289bc4 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 @@ -35,6 +35,14 @@ describe('e2e_state_vars', () => { const receipt2 = await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); expect(receipt2.status).toEqual(TxStatus.MINED); }, 200_000); + + it('initializing SharedImmutable the second time should fail', async () => { + // Jest executes the tests sequentially and the first call to initialize_shared_immutable was executed + // in the previous test, so the call bellow should fail. + await expect(contract.methods.initialize_shared_immutable(1).send().wait()).rejects.toThrowError( + "Assertion failed: SharedImmutable already initialized 'fields_read[0] == 0'", + ); + }, 100_000); }); describe('PrivateMutable', () => { From c09bc54180406edecd32f389fe1b39f96f409ce2 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 11:12:56 +0000 Subject: [PATCH 12/32] migration notes --- docs/docs/misc/migration_notes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index fe4c9a3d31f..8b959a6981c 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -14,6 +14,20 @@ Historically developers have been required to include a `compute_note_hash_and_n It is possible to provide a user-defined implementation, in which case auto-generation will be skipped (though there are no known use cases for this). +### Updated naming of state variable wrappers +We have decided to change the naming of our state variable wrappers because the naming was not clear. +The changes are as follows: +2. `Singleton` -> `PrivateMutable` +1. `ImmutableSingleton` -> `PrivateImmutable` +3. `StablePublicState` -> `SharedImmutable` +4. `SlowUpdates` -> `SharedMutable` +4. `PublicState` -> `PublicMutable` + +This is the meaning of "private", "public" and "shared": +Private: read (R) and write (W) from private, not accessible from public +Public: not accessible from private, R/W from public +Shared: R from private, R/W from public + ## 0.24.0 ### Introduce Note Type IDs From 218a2340495d072c3206f01f2de9d508775a9d8b Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 11:25:12 +0000 Subject: [PATCH 13/32] linking issues --- docs/docs/misc/migration_notes.md | 9 +++++---- noir-projects/aztec-nr/slow-updates-tree/src/slow_map.nr | 1 + .../contracts/slow_tree_contract/src/main.nr | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 8b959a6981c..565d33d4722 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -17,17 +17,18 @@ It is possible to provide a user-defined implementation, in which case auto-gene ### Updated naming of state variable wrappers We have decided to change the naming of our state variable wrappers because the naming was not clear. The changes are as follows: -2. `Singleton` -> `PrivateMutable` -1. `ImmutableSingleton` -> `PrivateImmutable` +1. `Singleton` -> `PrivateMutable` +2. `ImmutableSingleton` -> `PrivateImmutable` 3. `StablePublicState` -> `SharedImmutable` -4. `SlowUpdates` -> `SharedMutable` -4. `PublicState` -> `PublicMutable` +5. `PublicState` -> `PublicMutable` This is the meaning of "private", "public" and "shared": Private: read (R) and write (W) from private, not accessible from public Public: not accessible from private, R/W from public Shared: R from private, R/W from public +Note: `SlowUpdates` will be renamed to `SharedMutable` once the implementation is ready. + ## 0.24.0 ### Introduce Note Type IDs diff --git a/noir-projects/aztec-nr/slow-updates-tree/src/slow_map.nr b/noir-projects/aztec-nr/slow-updates-tree/src/slow_map.nr index aee68bcb36e..bbfa414e523 100644 --- a/noir-projects/aztec-nr/slow-updates-tree/src/slow_map.nr +++ b/noir-projects/aztec-nr/slow-updates-tree/src/slow_map.nr @@ -17,6 +17,7 @@ fn compute_next_change(time: Field) -> Field { ((time as u120 / EPOCH_LENGTH + 1) * EPOCH_LENGTH) as Field } +// TODO(#4760): Rename slow updates to shared mutable and ideally move the impl to state-vars in aztec-nr. // The simple slow map which stores a sparse tree struct SlowMap { context: Context, diff --git a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr index 7cc8b88be59..ecc2e6bb4de 100644 --- a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr @@ -5,6 +5,7 @@ mod types; // More documentation need to be outlined for this properly, but there is some in // https://github.com/AztecProtocol/aztec-packages/issues/1291 // This is made as a separate contract for one thing mainly. Making it simpler to use. +// TODO(#4760): Rename slow updates to shared mutable and ideally move the impl to state-vars in aztec-nr. contract SlowTree { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}; use dep::std::option::Option; From 1cf4c81c3695510b95cf7ba227a93a447181ddd9 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 11:42:45 +0000 Subject: [PATCH 14/32] fixes + diff cleanup --- .../contracts/references/storage/private_state.md | 6 +++--- .../developers/contracts/references/storage/public_state.md | 4 ++-- docs/docs/learn/concepts/storage/trees/main.md | 4 ++-- .../aztec-nr/aztec/src/state_vars/private_mutable.nr | 2 +- .../noir-contracts/contracts/card_game_contract/src/main.nr | 2 +- .../contracts/docs_example_contract/src/main.nr | 2 +- .../contracts/token_blacklist_contract/src/main.nr | 2 +- .../noir-contracts/contracts/token_contract/src/main.nr | 4 ++-- .../noir-contracts/contracts/uniswap_contract/src/main.nr | 2 +- yarn-project/circuits.js/fixtures/Benchmarking.test.json | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index c6f1193ca80..44d4375020a 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -70,9 +70,9 @@ Interestingly, if a developer requires a private state to be modifiable by users PrivateMutable is a private state variable that is unique in a way. When a PrivateMutable 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 and a storage slot. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/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/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr). -An example of singleton usage in the account contracts is keeping track of public keys. The `PrivateMutable` is added to the `Storage` struct as follows: +An example of `PrivateMutable` usage in the account contracts is keeping track of public keys. The `PrivateMutable` is added to the `Storage` struct as follows: #include_code storage-private-mutable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust @@ -102,7 +102,7 @@ Extend on what happens if you try to use non-initialized state. ### `is_initialized` -An unconstrained method to check whether the PrivateMutable has been initialized or not. It takes an optional owner and returns a boolean. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr). +An unconstrained method to check whether the PrivateMutable has been initialized or not. It takes an optional owner and returns a boolean. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr). #include_code private_mutable_is_initialized /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust diff --git a/docs/docs/developers/contracts/references/storage/public_state.md b/docs/docs/developers/contracts/references/storage/public_state.md index 7989070b6b1..e8330a4ab44 100644 --- a/docs/docs/developers/contracts/references/storage/public_state.md +++ b/docs/docs/developers/contracts/references/storage/public_state.md @@ -15,7 +15,7 @@ The `PublicMutable` struct is generic over the variable type `T`. The type _must 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. -You can find the details of `PublicMutable` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr). +You can find the details of `PublicMutable` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr). :::info An example using a larger struct can be found in the [lending example](https://github.com/AztecProtocol/aztec-packages/tree/master/noir-projects/noir-contracts/contracts/lending_contract)'s use of an [`Asset`](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr). @@ -23,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 `PublicMutable::new()` constructor. As seen below, this takes the `storage_slot` and the `serialization_methods` as arguments along with the [`Context`](../../writing_contracts/functions/context.md), 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/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr). +When declaring the storage for `T` as a persistent public storage variable, we use the `PublicMutable::new()` constructor. As seen below, this takes the `storage_slot` and the `serialization_methods` as arguments along with the [`Context`](../../writing_contracts/functions/context.md), 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/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr). #### Single value example diff --git a/docs/docs/learn/concepts/storage/trees/main.md b/docs/docs/learn/concepts/storage/trees/main.md index 7bf22b4853e..826aa7364a2 100644 --- a/docs/docs/learn/concepts/storage/trees/main.md +++ b/docs/docs/learn/concepts/storage/trees/main.md @@ -142,9 +142,9 @@ A note cannot actually be "deleted" from the Note Hash Tree because it is an app > Note: this nullifier derivation example is an oversimplification for the purposes of illustration. -#### Initializing PrivateMutable Notes +#### Initializing Notes wrapped by PrivateMutable -'PrivateMutable Note' is a term we've been using to mean: "A single Note which contains the whole of a private state's current value, and must be deleted and replaced with another single Note, if one ever wishes to edit that state". It's in contrast to a Note which only contains a small fragment of a private state's current value. A token balance represented by multiple notes is an example of private state that uses many notes. +Notes wrapped 'PrivateMutable' have the following meaning: "A single Note which contains the whole of a private state's current value, and must be deleted and replaced with another single Note, if one ever wishes to edit that state". It's in contrast to a Note which only contains a small fragment of a private state's current value. A token balance represented by multiple notes is an example of private state that uses many notes. Such notes require an 'Initialization Nullifier'; a nullifier which, when emitted, signals the initialization of this state variable (i.e. the very first time the state variable has been written to). diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr index 5bbec736ddd..14dd9609c05 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr @@ -31,7 +31,7 @@ impl PrivateMutable { // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address. // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable. // Under such circumstances, such application developers might wish to _not_ use this state variable type. - // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. + // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address. // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage. diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr index ccf2bc469d0..930215d7802 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr @@ -3,7 +3,7 @@ mod game; contract CardGame { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress, constants::MAX_NOTES_PER_PAGE}; - use dep::aztec::{context::Context, hash::pedersen_hash, state_vars::{map::Map, public_mutable::PublicMutable}}; + use dep::aztec::{context::Context, hash::pedersen_hash, state_vars::{Map, PublicMutable}}; use dep::std::option::Option; use dep::value_note::{balance_utils, value_note::{ValueNote, VALUE_NOTE_LEN}}; diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index dd48f26fe51..34a0b3ad701 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -54,7 +54,7 @@ contract DocsExample { shared_immutable: SharedImmutable, // docs:end:storage-shared-immutable-declaration // docs:start:storage-minters-declaration - minters: Map>, + minters: Map>, // docs:end:storage-minters-declaration } diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr index 5f05aa8951b..7836995713a 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -54,7 +54,7 @@ contract TokenBlacklist { struct Storage { admin: PublicMutable, balances: BalancesMap, - total_supply: PublicMutable, + total_supply: PublicMutable, pending_shields: Set, public_balances: Map>, slow_update: PrivateImmutable, diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index b7e5da9b3f1..b3e4d8ba5f5 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -52,12 +52,12 @@ contract Token { admin: PublicMutable, // 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: PublicMutable, + total_supply: PublicMutable, // docs:start:storage_pending_shields pending_shields: Set, // docs:end:storage_pending_shields diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index 60ce3c62536..f92dddff2f2 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -7,7 +7,7 @@ mod util; // Uses the token bridge contract, which tells which input token we need to talk to and handles the exit funds to L1 contract Uniswap { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}}; - use dep::aztec::{oracle::{context::get_portal_address}, state_vars::{map::Map, public_mutable::PublicMutable}}; + use dep::aztec::{oracle::{context::get_portal_address}, state_vars::{Map, PublicMutable}}; use dep::authwit::auth::{IS_VALID_SELECTOR, assert_current_call_valid_authwit_public, compute_authwit_message_hash}; diff --git a/yarn-project/circuits.js/fixtures/Benchmarking.test.json b/yarn-project/circuits.js/fixtures/Benchmarking.test.json index 8e964fa5566..4ee8cebbe8b 100644 --- a/yarn-project/circuits.js/fixtures/Benchmarking.test.json +++ b/yarn-project/circuits.js/fixtures/Benchmarking.test.json @@ -3405,7 +3405,7 @@ }, "50": { "source": "use crate::context::{Context};\nuse crate::oracle::storage::storage_read;\nuse crate::oracle::storage::storage_write;\nuse crate::types::type_serialization::TypeSerializationInterface;\nuse dep::std::option::Option;\n\n// docs:start:public_mutable_struct\nstruct PublicState {\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n}\n// docs:end:public_mutable_struct\n\nimpl PublicState {\n // docs:start:public_mutable_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicState {\n context,\n storage_slot,\n serialization_methods,\n }\n }\n // docs:end:public_mutable_struct_new\n\n // docs:start:public_mutable_struct_read\n pub fn read(self) -> T {\n assert(self.context.private.is_none(), \"Public state reads only supported in public functions\");\n storage_read(self.storage_slot, self.serialization_methods.deserialize)\n }\n // docs:end:public_mutable_struct_read\n\n // docs:start:public_mutable_struct_write\n pub fn write(self, value: T) {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n let serialize = self.serialization_methods.serialize;\n let fields = serialize(value);\n storage_write(self.storage_slot, fields);\n }\n // docs:end:public_mutable_struct_write\n}\n", - "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/state_vars/public_state.nr" + "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/state_vars/public_mutable.nr" }, "56": { "source": "#[oracle(storageRead)]\nfn storage_read_oracle(_storage_slot: Field, _number_of_elements: Field) -> [Field; N] {}\n\nunconstrained fn storage_read_oracle_wrapper(_storage_slot: Field) -> [Field; N] {\n storage_read_oracle(_storage_slot, N)\n}\n\npub fn storage_read(storage_slot: Field, deserialize: fn([Field; N]) -> T) -> T {\n let fields = storage_read_oracle_wrapper(storage_slot);\n deserialize(fields)\n}\n\n#[oracle(storageWrite)]\nfn storage_write_oracle(_storage_slot: Field, _values: [Field; N]) -> [Field; N] {}\n\n// TODO: Remove return value.\nunconstrained pub fn storage_write(storage_slot: Field, fields: [Field; N]) {\n let _hash = storage_write_oracle(storage_slot, fields);\n}\n", From 03f0759bd2b02f327abd3873070df8836dd43956 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 12:57:02 +0000 Subject: [PATCH 15/32] docs fix --- .../developers/contracts/references/storage/public_state.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/developers/contracts/references/storage/public_state.md b/docs/docs/developers/contracts/references/storage/public_state.md index e8330a4ab44..2fe6111d38e 100644 --- a/docs/docs/developers/contracts/references/storage/public_state.md +++ b/docs/docs/developers/contracts/references/storage/public_state.md @@ -89,13 +89,13 @@ We have a `write` method on the `PublicMutable` struct that takes the value to w --- -## Stable Public State +## Shared Immutable -`SharedImmutable` is a special type of `PublicMutable` that can be read from both public and private! +`SharedImmutable` is a special type that can be read from both public and private! Since private execution is based on historical data, the user can pick ANY of its prior values to read from. This is why it `MUST` not be updated after the contract is deployed. The variable should be initialized at the constructor and then never changed. -This makes the stable public variables useful for stuff that you would usually have in `immutable` values in solidity. For example this can be the name of a token or its number of decimals. +This makes the immutable public variables useful for stuff that you would usually have in `immutable` values in solidity. For example this can be the name of a token or its number of decimals. Just like the `PublicMutable` it is generic over the variable type `T`. The type `MUST` implement Serialize and Deserialize traits. From 6e6f5b5d62fdffd996faec0e45bd08cab247f9e0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 13:12:49 +0000 Subject: [PATCH 16/32] Set -> PrivateSet --- .../contracts/references/storage/main.md | 6 +++--- .../contracts/references/storage/private_state.md | 14 +++++++------- .../developers/tutorials/writing_token_contract.md | 6 +++--- docs/docs/learn/concepts/storage/storage_slots.md | 2 +- noir-projects/aztec-nr/authwit/src/account.nr | 2 +- noir-projects/aztec-nr/aztec/src/state_vars.nr | 4 ++-- .../src/state_vars/{set.nr => private_set.nr} | 12 ++++++------ .../easy-private-state/src/easy_private_uint.nr | 6 +++--- .../aztec-nr/value-note/src/balance_utils.nr | 6 +++--- noir-projects/aztec-nr/value-note/src/utils.nr | 10 +++++----- .../contracts/benchmarking_contract/src/main.nr | 4 ++-- .../contracts/card_game_contract/src/cards.nr | 6 +++--- .../contracts/child_contract/src/main.nr | 4 ++-- .../contracts/counter_contract/src/main.nr | 2 +- .../contracts/delegated_on_contract/src/main.nr | 4 ++-- .../contracts/delegator_contract/src/main.nr | 4 ++-- .../contracts/docs_example_contract/src/main.nr | 6 +++--- .../easy_private_token_contract/src/main.nr | 2 +- .../easy_private_voting_contract/src/main.nr | 2 +- .../contracts/ecdsa_account_contract/src/main.nr | 2 +- .../contracts/escrow_contract/src/main.nr | 4 ++-- .../contracts/gas_token_contract/src/main.nr | 2 +- .../inclusion_proofs_contract/src/main.nr | 4 ++-- .../contracts/lending_contract/src/main.nr | 4 ++-- .../pending_commitments_contract/src/main.nr | 4 ++-- .../contracts/price_feed_contract/src/main.nr | 4 ++-- .../contracts/slow_tree_contract/src/main.nr | 3 ++- .../contracts/stateful_test_contract/src/main.nr | 5 +++-- .../contracts/test_contract/src/main.nr | 2 +- .../contracts/token_blacklist_contract/src/main.nr | 4 ++-- .../src/types/balances_map.nr | 12 +++++++++--- .../src/types/token_note.nr | 2 +- .../contracts/token_bridge_contract/src/main.nr | 2 +- .../contracts/token_contract/src/main.nr | 4 ++-- .../token_contract/src/types/balances_map.nr | 12 +++++++++--- .../token_contract/src/types/token_note.nr | 2 +- .../1327_concrete_in_generic/src/main.nr | 2 +- noir/tooling/nargo_fmt/tests/expected/contract.nr | 6 +++--- noir/tooling/nargo_fmt/tests/input/contract.nr | 6 +++--- 39 files changed, 101 insertions(+), 87 deletions(-) rename noir-projects/aztec-nr/aztec/src/state_vars/{set.nr => private_set.nr} (89%) diff --git a/docs/docs/developers/contracts/references/storage/main.md b/docs/docs/developers/contracts/references/storage/main.md index f8260d0313f..b59350ee35f 100644 --- a/docs/docs/developers/contracts/references/storage/main.md +++ b/docs/docs/developers/contracts/references/storage/main.md @@ -233,9 +233,9 @@ Reading through the storage variables: - `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. +- `balances` is a mapping of private balances. Private balances are stored in a `PrivateSet` 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. -- `pending_shields` is a `Set` of `TransparentNote`s stored in private state. What is stored publicly is a set of commitments to `TransparentNote`s. +- `pending_shields` is a `PrivateSet` of `TransparentNote`s stored in private state. What is stored publicly is a set of commitments to `TransparentNote`s. - `public_balances` is a mapping field elements in public state and represents the publicly viewable balances of accounts. You can read more about it [here](../storage/main.md). @@ -288,7 +288,7 @@ The function returns 1 to indicate successful execution. This public function allows an account approved in the public `minters` mapping to create new private tokens that can be claimed by anyone that has the pre-image to the `secret_hash`. -First, public storage is initialized. Then it checks that the `msg_sender` is an approved minter. Then a new `TransparentNote` is created with the specified `amount` and `secret_hash`. You can read the details of the `TransparentNote` in the `types.nr` file [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/token_contract/src/types.nr#L61). The `amount` is added to the existing public `total_supply` and the storage value is updated. Then the new `TransparentNote` is added to the `pending_shields` using the `insert_from_public` function, which is accessible on the `Set` type. Then it's ready to be claimed by anyone with the `secret_hash` pre-image using the `redeem_shield` function. It returns `1` to indicate successful execution. +First, public storage is initialized. Then it checks that the `msg_sender` is an approved minter. Then a new `TransparentNote` is created with the specified `amount` and `secret_hash`. You can read the details of the `TransparentNote` in the `types.nr` file [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/token_contract/src/types.nr#L61). The `amount` is added to the existing public `total_supply` and the storage value is updated. Then the new `TransparentNote` is added to the `pending_shields` using the `insert_from_public` function, which is accessible on the `PrivateSet` type. Then it's ready to be claimed by anyone with the `secret_hash` pre-image using the `redeem_shield` function. It returns `1` to indicate successful execution. #include_code mint_private /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index 44d4375020a..d413886b0b3 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -42,11 +42,11 @@ A note should implement the following traits: The interplay between a private state variable and its notes can be confusing. Here's a summary to aid intuition: -A private state variable (of type `PrivateMutable`, `PrivateImmutable` or `Set`) may be declared in storage. +A private state variable (of type `PrivateMutable`, `PrivateImmutable` or `PrivateSet`) may be declared in storage. Every note contains a header, which contains the contract address and storage slot of the state variable to which it is associated. A note is associated with a private state variable if the storage slot of the private state variable matches the storage slot contained in the note's header. The header provides information that helps the user interpret the note's data. -Management of the header is abstracted-away from developers who use the `PrivateImmutable`, `PrivateMutable` and `Set` types. +Management of the header is abstracted-away from developers who use the `PrivateImmutable`, `PrivateMutable` and `PrivateSet` types. A private state variable points to one or many notes (depending on the type). The note(s) are all valid private state if the note(s) haven't yet been nullified. @@ -56,15 +56,15 @@ A `PrivateMutable` may point to _one_ note at a time. But since it's not "immuta `PrivateMutable` is a useful type when declaring a private state variable which may only ever be modified by those who are privy to the current value of that state. -A `Set` may point to _multiple_ notes at a time. The "current value" of a private state variable of type `Set` is some accumulation of all not-yet nullified notes which belong to the `Set`. +A `PrivateSet` may point to _multiple_ notes at a time. The "current value" of a private state variable of type `PrivateSet` is some accumulation of all not-yet nullified notes which belong to the `PrivateSet`. :::note -The term "some accumulation" is intentionally vague. The interpretation of the "current value" of a `Set` must be expressed by the smart contract developer. A common use case for a `Set` is to represent the sum of a collection of values (in which case 'accumulation' is 'summation'). +The term "some accumulation" is intentionally vague. The interpretation of the "current value" of a `PrivateSet` must be expressed by the smart contract developer. A common use case for a `PrivateSet` is to represent the sum of a collection of values (in which case 'accumulation' is 'summation'). -Think of a ZCash balance (or even a Bitcoin balance). The "current value" of a user's ZCash balance is the sum of all unspent (not-yet nullified) notes belonging to that user. To modify the "current value" of a `Set` state variable, is to [`insert`](#insert) new notes into the `Set`, or [`remove`](#remove) notes from that set. +Think of a ZCash balance (or even a Bitcoin balance). The "current value" of a user's ZCash balance is the sum of all unspent (not-yet nullified) notes belonging to that user. To modify the "current value" of a `PrivateSet` state variable, is to [`insert`](#insert) new notes into the `PrivateSet`, or [`remove`](#remove) notes from that set. ::: -Interestingly, if a developer requires a private state to be modifiable by users who _aren't_ privy to the value of that state, a `Set` is a very useful type. The `insert` method allows new notes to be added to the `Set` without knowing any of the other notes in the set! (Like posting an envelope into a post box, you don't know what else is in there!). +Interestingly, if a developer requires a private state to be modifiable by users who _aren't_ privy to the value of that state, a `PrivateSet` is a very useful type. The `insert` method allows new notes to be added to the `PrivateSet` without knowing any of the other notes in the set! (Like posting an envelope into a post box, you don't know what else is in there!). ## `PrivateMutable` @@ -94,7 +94,7 @@ Beware that because this nullifier is created only from the storage slot without For example, if the storage slot depends on the an address then it is possible to link the nullifier to the address. If the singleton is part of a `map` with an `AztecAddress` as the key then the nullifier will be linked to the address. ::: -Unlike public states, which have a default initial value of `0` (or many zeros, in the case of a struct, array or map), a private state (of type `PrivateMutable`, `PrivateImmutable` or `Set`) does not have a default initial value. The `initialize` method (or `insert`, in the case of a `Set`) must be called. +Unlike public states, which have a default initial value of `0` (or many zeros, in the case of a struct, array or map), a private state (of type `PrivateMutable`, `PrivateImmutable` or `PrivateSet`) does not have a default initial value. The `initialize` method (or `insert`, in the case of a `PrivateSet`) must be called. :::info Extend on what happens if you try to use non-initialized state. diff --git a/docs/docs/developers/tutorials/writing_token_contract.md b/docs/docs/developers/tutorials/writing_token_contract.md index 7a0960f0f2d..1d6f4098b3d 100644 --- a/docs/docs/developers/tutorials/writing_token_contract.md +++ b/docs/docs/developers/tutorials/writing_token_contract.md @@ -233,9 +233,9 @@ Reading through the storage variables: - `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. +- `balances` is a mapping of private balances. Private balances are stored in a `PrivateSet` 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. -- `pending_shields` is a `Set` of `TransparentNote`s stored in private state. What is stored publicly is a set of commitments to `TransparentNote`s. +- `pending_shields` is a `PrivateSet` of `TransparentNote`s stored in private state. What is stored publicly is a set of commitments to `TransparentNote`s. - `public_balances` is a mapping field elements in public state and represents the publicly viewable balances of accounts. You can read more about it [here](../contracts/writing_contracts/storage/main.md). @@ -288,7 +288,7 @@ The function returns 1 to indicate successful execution. This public function allows an account approved in the public `minters` mapping to create new private tokens that can be claimed by anyone that has the pre-image to the `secret_hash`. -First, public storage is initialized. Then it checks that the `msg_sender` is an approved minter. Then a new `TransparentNote` is created with the specified `amount` and `secret_hash`. You can read the details of the `TransparentNote` in the `types.nr` file [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/token_contract/src/types.nr#L61). The `amount` is added to the existing public `total_supply` and the storage value is updated. Then the new `TransparentNote` is added to the `pending_shields` using the `insert_from_public` function, which is accessible on the `Set` type. Then it's ready to be claimed by anyone with the `secret_hash` pre-image using the `redeem_shield` function. It returns `1` to indicate successful execution. +First, public storage is initialized. Then it checks that the `msg_sender` is an approved minter. Then a new `TransparentNote` is created with the specified `amount` and `secret_hash`. You can read the details of the `TransparentNote` in the `types.nr` file [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/token_contract/src/types.nr#L61). The `amount` is added to the existing public `total_supply` and the storage value is updated. Then the new `TransparentNote` is added to the `pending_shields` using the `insert_from_public` function, which is accessible on the `PrivateSet` type. Then it's ready to be claimed by anyone with the `secret_hash` pre-image using the `redeem_shield` function. It returns `1` to indicate successful execution. #include_code mint_private /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust diff --git a/docs/docs/learn/concepts/storage/storage_slots.md b/docs/docs/learn/concepts/storage/storage_slots.md index 0f0d9c905e2..a18afb9577b 100644 --- a/docs/docs/learn/concepts/storage/storage_slots.md +++ b/docs/docs/learn/concepts/storage/storage_slots.md @@ -44,7 +44,7 @@ note_hash = H(logical_storage_slot, note_content_hash); This siloing (there will be more) is done in the application circuit, since it is not necessary for security of the network (but only the application). :::info -The private variable wrappers `Set` and `PrivateMutable` in Aztec.nr include the `logical_storage_slot` in the commitments they compute, to make it easier for developers to write contracts without having to think about how to correctly handle storage slots. +The private variable wrappers `PrivateSet` and `PrivateMutable` in Aztec.nr include the `logical_storage_slot` in the commitments they compute, to make it easier for developers to write contracts without having to think about how to correctly handle storage slots. ::: When reading the values for these notes, the application circuit can then constrain the values to only read notes with a specific logical storage slot. diff --git a/noir-projects/aztec-nr/authwit/src/account.nr b/noir-projects/aztec-nr/authwit/src/account.nr index 4fe33d8785b..20816c6ae61 100644 --- a/noir-projects/aztec-nr/authwit/src/account.nr +++ b/noir-projects/aztec-nr/authwit/src/account.nr @@ -1,5 +1,5 @@ use dep::aztec::context::{PrivateContext, PublicContext, Context}; -use dep::aztec::state_vars::{map::Map, public_mutable::PublicMutable}; +use dep::aztec::state_vars::{Map, PublicMutable}; use crate::entrypoint::{app::AppPayload, fee::FeePayload}; use crate::auth::IS_VALID_SELECTOR; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars.nr b/noir-projects/aztec-nr/aztec/src/state_vars.nr index c718a748923..4201723eb07 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars.nr @@ -2,7 +2,7 @@ mod map; mod private_immutable; mod private_mutable; mod public_mutable; -mod set; +mod private_set; mod shared_immutable; mod storage; @@ -10,6 +10,6 @@ use crate::state_vars::map::Map; use crate::state_vars::private_immutable::PrivateImmutable; use crate::state_vars::private_mutable::PrivateMutable; use crate::state_vars::public_mutable::PublicMutable; -use crate::state_vars::set::Set; +use crate::state_vars::private_set::PrivateSet; use crate::state_vars::shared_immutable::SharedImmutable; use crate::state_vars::storage::Storage; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/set.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr similarity index 89% rename from noir-projects/aztec-nr/aztec/src/state_vars/set.nr rename to noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr index 2a56fb1f8da..03d676f291f 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/set.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr @@ -13,19 +13,19 @@ use crate::note::{ use crate::state_vars::storage::Storage; // docs:start:struct -struct Set { +struct PrivateSet { context: Context, storage_slot: Field, } // docs:end:struct -impl Storage for Set {} +impl Storage for PrivateSet {} -impl Set { +impl PrivateSet { // docs:start:new pub fn new(context: Context, storage_slot: Field) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); - Set { context, storage_slot } + PrivateSet { context, storage_slot } } // docs:end:new // docs:start:insert @@ -48,14 +48,14 @@ impl Set { // DEPRECATED fn assert_contains_and_remove(_self: Self, _note: &mut Note, _nonce: Field) { assert( - false, "`assert_contains_and_remove` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note." + false, "`assert_contains_and_remove` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use PrivateSet.get_notes() and PrivateSet.remove() in your contract to verify and remove a note." ); } // DEPRECATED fn assert_contains_and_remove_publicly_created(_self: Self, _note: &mut Note) { assert( - false, "`assert_contains_and_remove_publicly_created` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note." + false, "`assert_contains_and_remove_publicly_created` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use PrivateSet.get_notes() and PrivateSet.remove() in your contract to verify and remove a note." ); } diff --git a/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr b/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr index 06664d9ccb7..e9f5c34dcd7 100644 --- a/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr +++ b/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr @@ -2,7 +2,7 @@ use dep::aztec::{ protocol_types::address::AztecAddress, context::Context, note::note_getter_options::NoteGetterOptions, - state_vars::set::Set, + state_vars::PrivateSet, }; use dep::value_note::{ filter::filter_notes_min_sum, @@ -11,7 +11,7 @@ use dep::value_note::{ struct EasyPrivateUint { context: Context, - set: Set, + set: PrivateSet, storage_slot: Field, } @@ -22,7 +22,7 @@ impl EasyPrivateUint { storage_slot: Field, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); - let set = Set { + let set = PrivateSet { context, storage_slot }; diff --git a/noir-projects/aztec-nr/value-note/src/balance_utils.nr b/noir-projects/aztec-nr/value-note/src/balance_utils.nr index 6372d718902..74cba0e9679 100644 --- a/noir-projects/aztec-nr/value-note/src/balance_utils.nr +++ b/noir-projects/aztec-nr/value-note/src/balance_utils.nr @@ -1,12 +1,12 @@ use dep::aztec::note::{note_getter::view_notes, note_viewer_options::NoteViewerOptions}; -use dep::aztec::state_vars::set::Set; +use dep::aztec::state_vars::PrivateSet; use crate::value_note::ValueNote; -unconstrained pub fn get_balance(set: Set) -> Field { +unconstrained pub fn get_balance(set: PrivateSet) -> 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: PrivateSet, offset: u32) -> Field { let mut balance = 0; // docs:start:view_notes let options = NoteViewerOptions::new().set_offset(offset); diff --git a/noir-projects/aztec-nr/value-note/src/utils.nr b/noir-projects/aztec-nr/value-note/src/utils.nr index d7ef7c948dc..af4eacb7680 100644 --- a/noir-projects/aztec-nr/value-note/src/utils.nr +++ b/noir-projects/aztec-nr/value-note/src/utils.nr @@ -2,7 +2,7 @@ use dep::std::option::Option; use dep::aztec::context::PrivateContext; use dep::aztec::note::note_getter_options::{NoteGetterOptions, SortOrder}; use dep::aztec::oracle::get_public_key::get_public_key; -use dep::aztec::state_vars::set::Set; +use dep::aztec::state_vars::PrivateSet; use crate::{ filter::filter_notes_min_sum, value_note::{ValueNote, VALUE_NOTE_LEN}, @@ -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: PrivateSet, 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, recipient: AztecAddress // 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: PrivateSet, amount: Field, owner: AztecAddress) { let sum = decrement_by_at_most(balance, amount, owner); assert(sum == amount, "Balance too low"); } @@ -40,7 +40,7 @@ pub fn decrement(balance: Set, amount: Field, owner: AztecAddress) { // 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: PrivateSet, max_amount: Field, owner: AztecAddress) -> Field { let options = create_note_getter_options_for_decreasing_balance(max_amount); let opt_notes = balance.get_notes(options); @@ -64,7 +64,7 @@ pub fn decrement_by_at_most(balance: Set, max_amount: Field, owner: A // 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: PrivateSet, 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/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr index 40fac05f00e..4044cdd6920 100644 --- a/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -11,11 +11,11 @@ contract Benchmarking { protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - log::emit_unencrypted_log, state_vars::{Map, PublicMutable, Set} + log::emit_unencrypted_log, state_vars::{Map, PublicMutable, PrivateSet} }; struct Storage { - notes: Map>, + notes: Map>, balances: Map>, } diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr index 6b3e694768b..7d5b997daa4 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr @@ -12,7 +12,7 @@ use dep::aztec::{ note_viewer_options::NoteViewerOptions, note_getter::view_notes, }, - state_vars::set::Set, + state_vars::PrivateSet, }; use dep::std; use dep::std::{ @@ -88,7 +88,7 @@ impl CardNote { } struct Deck { - set: Set, + set: PrivateSet, } pub fn filter_cards( @@ -122,7 +122,7 @@ impl Deck { context: Context, storage_slot: Field, ) -> Self { - let set = Set { + let set = PrivateSet { context, storage_slot, }; diff --git a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr index 623d5b6463e..315c4c7ec34 100644 --- a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr @@ -4,7 +4,7 @@ contract Child { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, - state_vars::{PublicMutable, Set}, + state_vars::{PublicMutable, PrivateSet}, protocol_types::{abis::{function_selector::FunctionSelector, call_context::CallContext}, address::AztecAddress}, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader, utils as note_utils} }; @@ -12,7 +12,7 @@ contract Child { struct Storage { current_value: PublicMutable, - a_private_value: Set, + a_private_value: PrivateSet, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr b/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr index 6cfad8ed21c..b6db63a8cc7 100644 --- a/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr @@ -7,7 +7,7 @@ contract Counter { note_header::NoteHeader, utils as note_utils, }, - state_vars::map::Map, + state_vars::Map, }; use dep::value_note::{ balance_utils, diff --git a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr index c1a7c4e0cdb..928760f048f 100644 --- a/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegated_on_contract/src/main.nr @@ -4,7 +4,7 @@ contract DelegatedOn { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, log::emit_unencrypted_log, - state_vars::{PublicMutable, Set}, + state_vars::{PublicMutable, PrivateSet}, protocol_types::{abis::{function_selector::FunctionSelector, call_context::CallContext}, address::AztecAddress}, note::{ note_getter_options::NoteGetterOptions, note_viewer_options::NoteViewerOptions, @@ -15,7 +15,7 @@ contract DelegatedOn { struct Storage { current_value: PublicMutable, - a_private_value: Set, + a_private_value: PrivateSet, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr index 407d551d197..d93629e4fea 100644 --- a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr @@ -3,7 +3,7 @@ contract Delegator { use dep::std::option::Option; use dep::aztec::{ - log::emit_unencrypted_log, state_vars::{PublicMutable, Set}, + log::emit_unencrypted_log, state_vars::{PublicMutable, PrivateSet}, protocol_types::{abis::{function_selector::FunctionSelector}, address::AztecAddress}, note::{note_viewer_options::NoteViewerOptions, utils as note_utils, note_header::NoteHeader} }; @@ -11,7 +11,7 @@ contract Delegator { struct Storage { current_value: PublicMutable, - a_private_value: Set, + a_private_value: PrivateSet, } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 34a0b3ad701..9e246f32e80 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -25,7 +25,7 @@ contract DocsExample { utils as note_utils, }, context::{PrivateContext, PublicContext, Context}, - state_vars::{Map, PublicMutable, PrivateMutable, PrivateImmutable, Set, SharedImmutable}, + state_vars::{Map, PublicMutable, PrivateMutable, PrivateImmutable, PrivateSet, SharedImmutable}, }; // how to import methods from other files/folders within your workspace use crate::options::create_account_card_getter_options; @@ -45,7 +45,7 @@ contract DocsExample { // just used for docs example to show how to create a private mutable map. profiles: Map>, // docs:start:storage-set-declaration - set: Set, + set: PrivateSet, // docs:end:storage-set-declaration // docs:start:storage-private-immutable-declaration private_immutable: PrivateImmutable, @@ -81,7 +81,7 @@ contract DocsExample { ), // docs:end:state_vars-MapPrivateMutable // docs:start:storage-set-init - set: Set::new(context, 5), + set: PrivateSet::new(context, 5), // docs:end:storage-set-init private_immutable: PrivateImmutable::new(context, 6), // docs:start:storage-shared-immutable diff --git a/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr index ed5091f485a..0d44ff2b3b3 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr @@ -6,7 +6,7 @@ contract EasyPrivateToken { note_header::NoteHeader, utils as note_utils, }, - state_vars::map::Map, + state_vars::Map, }; use dep::value_note::{ balance_utils, diff --git a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index cb812487329..a6a388e6459 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -2,7 +2,7 @@ contract EasyPrivateVoting { // docs:start:imports use dep::aztec::{ protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, - context::{PrivateContext, Context}, state_vars::{map::Map, public_mutable::PublicMutable} + context::{PrivateContext, Context}, state_vars::{Map, PublicMutable} }; // docs:end:imports // docs:start:storage_struct diff --git a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index 5993e2aa299..f9dac6425b8 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -9,7 +9,7 @@ contract EcdsaAccount { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, note::{note_header::NoteHeader, utils as note_utils}, oracle::get_public_key::get_public_key, - state_vars::private_immutable::PrivateImmutable + state_vars::PrivateImmutable }; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, diff --git a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr index d04a1599aea..f1fde13f770 100644 --- a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr @@ -7,13 +7,13 @@ contract Escrow { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader, utils as note_utils}, - oracle::get_public_key::get_public_key, state_vars::set::Set + oracle::get_public_key::get_public_key, state_vars::PrivateSet }; use dep::address_note::address_note::{AddressNote, ADDRESS_NOTE_LEN}; struct Storage { - owners: Set, + owners: PrivateSet, } // Creates a new instance diff --git a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr index e29fb27805e..15a3ea7f62d 100644 --- a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr @@ -2,7 +2,7 @@ mod lib; contract GasToken { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}}; - use dep::aztec::{hash::{compute_secret_hash}, state_vars::{public_mutable::PublicMutable, map::Map}}; + use dep::aztec::{hash::{compute_secret_hash}, state_vars::{PublicMutable, Map}}; use dep::safe_math::SafeU120; diff --git a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index 33bf68dd8ec..1aa7f911ad9 100644 --- a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -5,7 +5,7 @@ contract InclusionProofs { grumpkin_point::GrumpkinPoint, contract_class_id::ContractClassId }; use dep::aztec::{ - state_vars::{Map, Set, PublicMutable}, context::Context, + state_vars::{Map, PrivateSet, PublicMutable}, context::Context, note::{ note_getter_options::NoteGetterOptions, note_getter_options::NoteStatus, note_header::NoteHeader, utils as note_utils @@ -31,7 +31,7 @@ contract InclusionProofs { use dep::value_note::value_note::ValueNote; // docs:end:value_note_imports struct Storage { - private_values: Map>, + private_values: Map>, public_value: PublicMutable, public_unused_value: PublicMutable, } diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr index fd4be20d959..6f63a85e52c 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr @@ -20,8 +20,8 @@ contract Lending { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, state_vars::{ - map::Map, - public_mutable::PublicMutable, + Map, + PublicMutable, } }; use crate::asset::Asset; diff --git a/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr index 894fccf454c..fae26b23fc9 100644 --- a/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr @@ -9,12 +9,12 @@ contract PendingCommitments { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, log::emit_encrypted_log, note::{note_getter::NoteGetterOptions, note_header::NoteHeader, utils as note_utils}, - state_vars::{map::Map, set::Set} + state_vars::{Map, PrivateSet} }; use dep::aztec::protocol_types::{address::AztecAddress, abis::function_selector::FunctionSelector}; struct Storage { - balances: Map>, + balances: Map>, } // TODO(dbanks12): consolidate code into internal helper functions diff --git a/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr b/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr index 9edee7589a6..dd9a743ed3c 100644 --- a/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/price_feed_contract/src/main.nr @@ -5,8 +5,8 @@ contract PriceFeed { use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, state_vars::{ - map::Map, - public_mutable::PublicMutable, + Map, + PublicMutable, }, }; use dep::aztec::protocol_types::address::AztecAddress; diff --git a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr index ecc2e6bb4de..e930be53d75 100644 --- a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr @@ -12,7 +12,8 @@ contract SlowTree { use dep::value_note::{balance_utils, utils::{increment, decrement}, value_note::ValueNote}; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, - note::{note_header::NoteHeader, utils as note_utils}, state_vars::{Map, PublicMutable, Set}, + note::{note_header::NoteHeader, utils as note_utils}, + state_vars::{Map, PublicMutable, PrivateSet}, protocol_types::type_serialization::FIELD_SERIALIZED_LEN }; use dep::slow_updates_tree::{SlowMap, Leaf, SlowUpdateProof, compute_merkle_root, deserialize_slow_update_proof}; diff --git a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr index 2d7714897c0..62393469d9a 100644 --- a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -5,11 +5,12 @@ contract StatefulTest { use dep::value_note::{balance_utils, utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote}}; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, - note::{note_header::NoteHeader, utils as note_utils}, state_vars::{Map, PublicMutable, Set} + note::{note_header::NoteHeader, utils as note_utils}, + state_vars::{Map, PublicMutable, PrivateSet} }; struct Storage { - notes: Map>, + notes: Map>, public_values: Map>, } diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 7b8ec3714cf..90228a29b91 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -19,7 +19,7 @@ contract Test { note_viewer_options::NoteViewerOptions }, oracle::{get_public_key::get_public_key as get_public_key_oracle, context::get_portal_address, rand::rand}, - state_vars::private_immutable::PrivateImmutable, log::emit_unencrypted_log_from_private + state_vars::PrivateImmutable, log::emit_unencrypted_log_from_private }; use dep::token_portal_content_hash_lib::{get_mint_private_content_hash, get_mint_public_content_hash}; use dep::field_note::field_note::FieldNote; diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr index 7836995713a..29c8bff7c70 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -29,7 +29,7 @@ contract TokenBlacklist { }, context::{PrivateContext, PublicContext, Context}, hash::{compute_secret_hash}, - state_vars::{map::Map, public_mutable::PublicMutable, set::Set, private_immutable::PrivateImmutable}, + state_vars::{Map, PublicMutable, PrivateSet, PrivateImmutable}, }; use dep::field_note::field_note::FieldNote; @@ -55,7 +55,7 @@ contract TokenBlacklist { admin: PublicMutable, balances: BalancesMap, total_supply: PublicMutable, - pending_shields: Set, + pending_shields: PrivateSet, public_balances: Map>, slow_update: PrivateImmutable, public_slow_update: PublicMutable, diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr index cbc423cc4ff..b6ba0ef697e 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -2,7 +2,7 @@ use dep::std::option::Option; use dep::safe_math::SafeU120; use dep::aztec::{ context::Context, protocol_types::{address::AztecAddress, constants::MAX_READ_REQUESTS_PER_CALL}, - state_vars::{set::Set, map::Map}, + state_vars::{PrivateSet, Map}, note::{ note_getter::view_notes, note_getter_options::{NoteGetterOptions, SortOrder}, note_viewer_options::NoteViewerOptions, note_header::NoteHeader, note_interface::NoteInterface @@ -11,13 +11,19 @@ use dep::aztec::{ use crate::types::token_note::{TokenNote, OwnedNote}; struct BalancesMap { - map: Map> + map: Map> } impl BalancesMap { pub fn new(context: Context, storage_slot: Field) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); - Self { map: Map::new(context, storage_slot, |context, slot| Set::new(context, slot)) } + Self { + map: Map::new( + context, + storage_slot, + |context, slot| PrivateSet::new(context, slot) + ) + } } unconstrained pub fn balance_of( diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index a7e2a45f1ec..970205ffff9 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -1,7 +1,7 @@ use dep::aztec::{ protocol_types::{address::AztecAddress, constants::{MAX_READ_REQUESTS_PER_CALL}}, note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, - context::PrivateContext, state_vars::set::Set, log::emit_encrypted_log, hash::pedersen_hash + context::PrivateContext, state_vars::PrivateSet, log::emit_encrypted_log, hash::pedersen_hash }; use dep::aztec::oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key}; use dep::safe_math::SafeU120; diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index 15369905c5e..8a00972b733 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -9,7 +9,7 @@ mod token_interface; contract TokenBridge { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}}; - use dep::aztec::{context::{Context}, hash::{compute_secret_hash}, state_vars::{public_mutable::PublicMutable}}; + use dep::aztec::{context::{Context}, hash::{compute_secret_hash}, state_vars::{PublicMutable}}; use dep::token_portal_content_hash_lib::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash}; diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index b3e4d8ba5f5..6c2f351a97f 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -23,7 +23,7 @@ contract Token { utils as note_utils, }, hash::{compute_secret_hash}, - state_vars::{Map, PublicMutable, SharedImmutable, Set}, + state_vars::{Map, PublicMutable, SharedImmutable, PrivateSet}, protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress @@ -59,7 +59,7 @@ contract Token { // docs:end:storage_balances total_supply: PublicMutable, // docs:start:storage_pending_shields - pending_shields: Set, + pending_shields: PrivateSet, // docs:end:storage_pending_shields public_balances: Map>, symbol: SharedImmutable, diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr index a47fdce4f3f..7e868cdf513 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balances_map.nr @@ -3,7 +3,7 @@ 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}, - state_vars::{set::Set, map::Map}, + state_vars::{PrivateSet, Map}, note::{ note_getter::view_notes, note_getter_options::{NoteGetterOptions, SortOrder}, note_viewer_options::NoteViewerOptions, note_header::NoteHeader, note_interface::NoteInterface @@ -12,13 +12,19 @@ use dep::aztec::{ use crate::types::token_note::{TokenNote, OwnedNote}; struct BalancesMap { - map: Map> + map: Map> } impl BalancesMap { pub fn new(context: Context, storage_slot: Field) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); - Self { map: Map::new(context, storage_slot, |context, slot| Set::new(context, slot)) } + Self { + map: Map::new( + context, + storage_slot, + |context, slot| PrivateSet::new(context, slot) + ) + } } unconstrained pub fn balance_of( diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 2be2ecb3e00..0435e04b152 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -1,7 +1,7 @@ use dep::aztec::{ protocol_types::{address::AztecAddress, constants::MAX_READ_REQUESTS_PER_CALL}, note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, - context::PrivateContext, state_vars::set::Set, log::emit_encrypted_log, hash::pedersen_hash + context::PrivateContext, state_vars::PrivateSet, log::emit_encrypted_log, hash::pedersen_hash }; use dep::aztec::oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key}; use dep::safe_math::SafeU120; diff --git a/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr b/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr index 9542bf6463b..3e476107c29 100644 --- a/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr +++ b/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr @@ -20,7 +20,7 @@ impl B { } } // --- -// Set +// PrivateSet struct C { t_d_interface: MethodInterface, } diff --git a/noir/tooling/nargo_fmt/tests/expected/contract.nr b/noir/tooling/nargo_fmt/tests/expected/contract.nr index 365a6f8bfb3..a03b8774700 100644 --- a/noir/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/tooling/nargo_fmt/tests/expected/contract.nr @@ -10,13 +10,13 @@ contract Benchmarking { use dep::aztec::{ context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - log::emit_unencrypted_log, state_vars::{Map, PublicMutable, Set}, + log::emit_unencrypted_log, state_vars::{Map, PublicMutable, PrivateSet}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, types::address::{AztecAddress} }; struct Storage { - notes: Map>, + notes: Map>, balances: Map>, } @@ -26,7 +26,7 @@ contract Benchmarking { notes: Map::new( context, 1, - |context, slot| { Set::new(context, slot, ValueNoteMethods) } + |context, slot| { PrivateSet::new(context, slot, ValueNoteMethods) } ), balances: Map::new( context, diff --git a/noir/tooling/nargo_fmt/tests/input/contract.nr b/noir/tooling/nargo_fmt/tests/input/contract.nr index 365a6f8bfb3..a03b8774700 100644 --- a/noir/tooling/nargo_fmt/tests/input/contract.nr +++ b/noir/tooling/nargo_fmt/tests/input/contract.nr @@ -10,13 +10,13 @@ contract Benchmarking { use dep::aztec::{ context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - log::emit_unencrypted_log, state_vars::{Map, PublicMutable, Set}, + log::emit_unencrypted_log, state_vars::{Map, PublicMutable, PrivateSet}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, types::address::{AztecAddress} }; struct Storage { - notes: Map>, + notes: Map>, balances: Map>, } @@ -26,7 +26,7 @@ contract Benchmarking { notes: Map::new( context, 1, - |context, slot| { Set::new(context, slot, ValueNoteMethods) } + |context, slot| { PrivateSet::new(context, slot, ValueNoteMethods) } ), balances: Map::new( context, From b36f8efa9324025b11c6fe8eaa507a0a3fe8899e Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 13:17:30 +0000 Subject: [PATCH 17/32] stale docs fix --- .../docs/developers/contracts/resources/common_patterns/main.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/developers/contracts/resources/common_patterns/main.md b/docs/docs/developers/contracts/resources/common_patterns/main.md index 4f80d9aaa78..c6c31296a0e 100644 --- a/docs/docs/developers/contracts/resources/common_patterns/main.md +++ b/docs/docs/developers/contracts/resources/common_patterns/main.md @@ -54,7 +54,7 @@ You can't read public storage in private domain. But nevertheless reading public ```rust struct Storage { - token: PublicMutable, + token: PublicMutable, } contract Bridge { From 5f9dda5c978d526946afb3f5d2606dc1b4282201 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 13:18:49 +0000 Subject: [PATCH 18/32] stale docs fix 2 --- .../developers/tutorials/writing_private_voting_contract.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/developers/tutorials/writing_private_voting_contract.md b/docs/docs/developers/tutorials/writing_private_voting_contract.md index eee17de69da..cf69867fe26 100644 --- a/docs/docs/developers/tutorials/writing_private_voting_contract.md +++ b/docs/docs/developers/tutorials/writing_private_voting_contract.md @@ -73,7 +73,7 @@ We are using various utils within the Aztec library: - `context` - exposes things such as the contract address, msg_sender, etc - `context.request_nullifier_secret_key` - get your secret key to help us create a randomized nullifier - `FunctionSelector::from_signature` - compute a function selector from signature so we can call functions from other functions -- `state_vars::{ map::Map, public_state::PublicMutable, }` - we will use a Map to store the votes (key = voteId, value = number of votes), and PublicMutable to hold our public values that we mentioned earlier +- `state_vars::{Map, PublicMutable}` - we will use a Map to store the votes (key = voteId, value = number of votes), and PublicMutable to hold our public values that we mentioned earlier - `types::type_serialization::{..}` - various serialization methods for defining how to use these types - `types::address::{AztecAddress},` - our admin will be held as an address - `constants::EMPTY_NULLIFIED_COMMITMENT,` - this will come in useful when creating our nullifier From 404503925967c4b51af75e6600c048d06b3d92df Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 13:19:47 +0000 Subject: [PATCH 19/32] revert incorrect change --- docs/docs/misc/migration_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 565d33d4722..0a95e994b1d 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -205,7 +205,7 @@ Storage definition and initialization has been simplified. Previously: ```rust struct Storage { - leader: PublicMutable, + leader: PublicState, legendary_card: Singleton, profiles: Map>, test: Set, From ec9ff0d0d66785f93cf11931a0b85952b1a1f163 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 13:32:57 +0000 Subject: [PATCH 20/32] updated comment --- .../contracts/app_subscription_contract/src/main.nr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index 5dec0565858..feee4ecfecc 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -18,7 +18,9 @@ contract AppSubscriptionContract { use crate::subscription_note::{SubscriptionNote, SUBSCRIPTION_NOTE_LEN}; struct Storage { - // todo change this to PrivateImmutable because it's only needed in private + // The following is only needed in private but we use ShareImmutable here instead of PrivateImmutable because + // the value can be publicly known and SharedImmutable provides us with a better devex here because we don't + // have to bother with sharing the note between pixies of users. target_address: SharedImmutable, subscription_token_address: SharedImmutable, subscription_recipient_address: SharedImmutable, From 98658062bfb8e42c6746e5220b13588fbb88fec0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 13:33:04 +0000 Subject: [PATCH 21/32] import cleanup --- noir-projects/aztec-nr/aztec/src/state_vars/storage.nr | 1 - 1 file changed, 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr b/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr index 5f28b55f9f7..e742ab7e036 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr @@ -1,4 +1,3 @@ -use crate::context::{Context}; use dep::protocol_types::traits::{Deserialize, Serialize}; trait Storage where T: Serialize + Deserialize { From c2ccbf15f81c7e493de0876765b4220c2b3552ab Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 13:36:40 +0000 Subject: [PATCH 22/32] assert_deployment -> is_deployment --- noir-projects/aztec-nr/aztec/src/context/private_context.nr | 3 ++- noir-projects/aztec-nr/aztec/src/context/public_context.nr | 3 ++- .../aztec-nr/aztec/src/state_vars/shared_immutable.nr | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 614953cadd9..3f4185d047c 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -95,8 +95,9 @@ impl PrivateContext { } } - pub fn assert_deployment(self) { + pub fn is_deployment(self) -> bool { // TODO(#4738): Implement this + false } pub fn msg_sender(self) -> AztecAddress { diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index ede0da672e6..c75f79d902d 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -70,8 +70,9 @@ impl PublicContext { } } - pub fn assert_deployment(self) { + pub fn is_deployment(self) -> bool { // TODO(#4738): Implement this + false } pub fn msg_sender(self) -> AztecAddress { diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 29242863c9b..5427cff42ca 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -27,7 +27,10 @@ impl SharedImmutable { assert( self.context.private.is_none(), "SharedImmutable can only be initialized from public functions" ); - self.context.public.unwrap_unchecked().assert_deployment(); + // TODO(#4738): Uncomment the following assert + // assert( + // self.context.public.unwrap_unchecked().is_deployment(), "SharedImmutable can only be initialized during contract deployment" + // ); // We check that the struct is not yet initialized by checking if the placeholder slot is 0 let placeholder_storage_slot = pedersen_hash( From 9c6d668b2fc24f72f1dd135a3088fb7be9ac35a9 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 14:49:33 +0000 Subject: [PATCH 23/32] efficiently assigning initialization slot --- .../aztec/src/state_vars/shared_immutable.nr | 22 +++++++++---------- .../src/crates/types/src/constants.nr | 1 - noir/aztec_macros/src/lib.rs | 7 ++++-- yarn-project/circuits.js/src/constants.gen.ts | 1 - 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 5427cff42ca..fd122875b42 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -1,9 +1,8 @@ use crate::{ - context::{Context}, hash::pedersen_hash, - history::public_value_inclusion::prove_public_value_inclusion, + context::Context, history::public_value_inclusion::prove_public_value_inclusion, oracle::{storage::{storage_read, storage_write}}, state_vars::storage::Storage }; -use dep::protocol_types::{constants::GENERATOR_INDEX__IMMUTABLE_INITIALIZE_PLACEHOLDER, traits::{Deserialize, Serialize}}; +use dep::protocol_types::traits::{Deserialize, Serialize}; struct SharedImmutable{ context: Context, @@ -18,7 +17,9 @@ impl SharedImmutable { context: Context, storage_slot: Field ) -> Self { - assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); + assert( + (storage_slot != 0) & (storage_slot != 1), "Storage slots 0 and 1 not allowed. Storage slots must start from 2." + ); Self { context, storage_slot } } @@ -32,16 +33,13 @@ impl SharedImmutable { // self.context.public.unwrap_unchecked().is_deployment(), "SharedImmutable can only be initialized during contract deployment" // ); - // We check that the struct is not yet initialized by checking if the placeholder slot is 0 - let placeholder_storage_slot = pedersen_hash( - [self.storage_slot], - GENERATOR_INDEX__IMMUTABLE_INITIALIZE_PLACEHOLDER - ); - let fields_read: [Field; 1] = storage_read(placeholder_storage_slot); + // We check that the struct is not yet initialized by checking if the initialization slot is 0 + let initialization_slot = self.storage_slot - 1; + let fields_read: [Field; 1] = storage_read(initialization_slot); assert(fields_read[0] == 0, "SharedImmutable already initialized"); - // We populate the placeholder slot with a non-zero value to indicate that the struct is initialized - storage_write(placeholder_storage_slot, [0xdead]); + // We populate the initialization slot with a non-zero value to indicate that the struct is initialized + storage_write(initialization_slot, [0xdead]); let fields_write = T::serialize(value); storage_write(self.storage_slot, fields_write); diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index 99b7f006833..be81885d059 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -230,4 +230,3 @@ global GENERATOR_INDEX__VK = 41; global GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42; global GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43; global GENERATOR_INDEX__FUNCTION_ARGS = 44; -global GENERATOR_INDEX__IMMUTABLE_INITIALIZE_PLACEHOLDER = 45; diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 91efd74ddaa..047c34a3dc6 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -940,7 +940,8 @@ fn assign_storage_slots( )), }?; - let mut storage_slot: u64 = 1; + // We start from 2 because 0 storage slot is buggy and 1 is reserved for the initialization slot + let mut storage_slot: u64 = 2; 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(); @@ -987,7 +988,9 @@ fn assign_storage_slots( )); }); - storage_slot += type_serialized_len; + // We add 1 on the next line because some of the types use value in initialization storage slot + // (set as "type storage slot - 1") to determine whether the value in the type was already initialized. + storage_slot += type_serialized_len + 1; } } } diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index bfb3ef3f462..47bbff17361 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -144,5 +144,4 @@ export enum GeneratorIndex { PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42, PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43, FUNCTION_ARGS = 44, - IMMUTABLE_INITIALIZE_PLACEHOLDER = 45, } From f507e728a45daae2211e9eafbb88a1ebb935b193 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 15:29:43 +0000 Subject: [PATCH 24/32] simpler approach of computing initialization slot --- l1-contracts/src/core/libraries/ConstantsGen.sol | 2 +- .../aztec-nr/aztec/src/state_vars/shared_immutable.nr | 4 ++-- .../src/crates/types/src/constants.nr | 2 +- noir/aztec_macros/src/lib.rs | 7 ++----- yarn-project/circuits.js/src/constants.gen.ts | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 6f1202c6c09..d429deaa406 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -69,10 +69,10 @@ library Constants { uint256 internal constant L1_TO_L2_MSG_SUBTREE_HEIGHT = 4; uint256 internal constant L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12; uint256 internal constant FUNCTION_SELECTOR_NUM_BYTES = 4; - uint256 internal constant MAPPING_SLOT_PEDERSEN_SEPARATOR = 4; uint256 internal constant NUM_FIELDS_PER_SHA256 = 2; uint256 internal constant ARGS_HASH_CHUNK_LENGTH = 32; uint256 internal constant ARGS_HASH_CHUNK_COUNT = 32; + uint256 internal constant INITIALIZATION_SLOT_SEPARATOR = 1000; uint256 internal constant MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 1000; uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 500; uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 500; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index fd122875b42..32e0c82d68b 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -2,7 +2,7 @@ use crate::{ context::Context, history::public_value_inclusion::prove_public_value_inclusion, oracle::{storage::{storage_read, storage_write}}, state_vars::storage::Storage }; -use dep::protocol_types::traits::{Deserialize, Serialize}; +use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::{Deserialize, Serialize}}; struct SharedImmutable{ context: Context, @@ -34,7 +34,7 @@ impl SharedImmutable { // ); // We check that the struct is not yet initialized by checking if the initialization slot is 0 - let initialization_slot = self.storage_slot - 1; + let initialization_slot = INITIALIZATION_SLOT_SEPARATOR + self.storage_slot; let fields_read: [Field; 1] = storage_read(initialization_slot); assert(fields_read[0] == 0, "SharedImmutable already initialized"); diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index be81885d059..480b0f825e7 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -93,11 +93,11 @@ global L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12; // MISC CONSTANTS global FUNCTION_SELECTOR_NUM_BYTES: Field = 4; -global MAPPING_SLOT_PEDERSEN_SEPARATOR: Field = 4; // sha256 hash is stored in two fields to accommodate all 256-bits of the hash global NUM_FIELDS_PER_SHA256: Field = 2; global ARGS_HASH_CHUNK_LENGTH: u32 = 32; global ARGS_HASH_CHUNK_COUNT: u32 = 32; +global INITIALIZATION_SLOT_SEPARATOR: Field = 1000; // CONTRACT CLASS CONSTANTS // This should be around 8192 (assuming 2**15 instructions packed at 8 bytes each), diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 047c34a3dc6..91efd74ddaa 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -940,8 +940,7 @@ fn assign_storage_slots( )), }?; - // We start from 2 because 0 storage slot is buggy and 1 is reserved for the initialization slot - let mut storage_slot: u64 = 2; + 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(); @@ -988,9 +987,7 @@ fn assign_storage_slots( )); }); - // We add 1 on the next line because some of the types use value in initialization storage slot - // (set as "type storage slot - 1") to determine whether the value in the type was already initialized. - storage_slot += type_serialized_len + 1; + storage_slot += type_serialized_len; } } } diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 47bbff17361..9be3302b9b1 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -55,10 +55,10 @@ export const PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH = 35; export const L1_TO_L2_MSG_SUBTREE_HEIGHT = 4; export const L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12; export const FUNCTION_SELECTOR_NUM_BYTES = 4; -export const MAPPING_SLOT_PEDERSEN_SEPARATOR = 4; export const NUM_FIELDS_PER_SHA256 = 2; export const ARGS_HASH_CHUNK_LENGTH = 32; export const ARGS_HASH_CHUNK_COUNT = 32; +export const INITIALIZATION_SLOT_SEPARATOR = 1000; export const MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 1000; export const MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 500; export const MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 500; From 5d5f2b763413a2bc9b66ba7fbfba266f4fd2889b Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 16:11:28 +0000 Subject: [PATCH 25/32] fix --- .../aztec-nr/aztec/src/state_vars/shared_immutable.nr | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 32e0c82d68b..8720a8f58c5 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -17,9 +17,7 @@ impl SharedImmutable { context: Context, storage_slot: Field ) -> Self { - assert( - (storage_slot != 0) & (storage_slot != 1), "Storage slots 0 and 1 not allowed. Storage slots must start from 2." - ); + assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { context, storage_slot } } From b84b26341674eab6c93796c75107a996ead0f067 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 18:53:44 +0000 Subject: [PATCH 26/32] doc fix --- .../contracts/references/storage/private_state.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index d413886b0b3..c604a29f026 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -18,7 +18,7 @@ To greatly simplify the experience of writing private state, Aztec.nr provides t - [PrivateMutable](#singletonnotetype) - [PrivateImmutable](#privateimmutablenotetype) -- [Set](#setnotetype) +- [PrivateSet](#privatesetnotetype) These three structs abstract-away many of Aztec's protocol complexities, by providing intuitive methods to modify notes in the utxo tree in a privacy-preserving way. @@ -178,9 +178,9 @@ This function will throw if the `PrivateImmutable` hasn't been initialized. Functionally similar to `get_note`, but executed unconstrained and can be used by the wallet to fetch notes for use by front-ends etc. -## `Set` +## `PrivateSet` -Set is used for managing a collection of notes. All notes in a Set are of the same `NoteType`. But whether these notes all belong to one entity, or are accessible and editable by different entities, is up to the developer. The set is a collection of notes inserted into the data-tree, but notes are never removed from the tree itself, they are only nullified. +`PrivateSet` is used for managing a collection of notes. All notes in a `PrivateSet` are of the same `NoteType`. But whether these notes all belong to one entity, or are accessible and editable by different entities, is up to the developer. The set is a collection of notes inserted into the data-tree, but notes are never removed from the tree itself, they are only nullified. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/set.nr). @@ -198,7 +198,7 @@ We can initialize the set as follows: ### `insert` -Allows us to modify the storage by inserting a note into the set. +Allows us to modify the storage by inserting a note into the `PrivateSet`. A hash of the note will be generated, and inserted into the note hash tree, allowing us to later use in contract interactions. Recall that the content of the note should be shared with the owner to allow them to use it, as mentioned this can be done via an [encrypted log](../../writing_contracts/events/emit_event.md#encrypted-events), or offchain via web2, or completely offline. @@ -214,7 +214,7 @@ The usage is similar to using the `insert` method with the difference that this ### `remove` -Will remove a note from the set if it previously has been read from storage, e.g. you have fetched it through a `get_notes` call. This is useful when you want to remove a note that you have previously read from storage and do not have to read it again. +Will remove a note from the `PrivateSet` if it previously has been read from storage, e.g. you have fetched it through a `get_notes` call. This is useful when you want to remove a note that you have previously read from storage and do not have to read it again. Nullifiers are emitted when reading values to make sure that they are up to date. From f9e831c64d25af189ea8bc0b598f193a960aa02f Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 18:55:06 +0000 Subject: [PATCH 27/32] import cleanup --- .../contracts/token_blacklist_contract/src/types/token_note.nr | 2 +- .../contracts/token_contract/src/types/token_note.nr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index 970205ffff9..1c9ddb96e3b 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -1,7 +1,7 @@ use dep::aztec::{ protocol_types::{address::AztecAddress, constants::{MAX_READ_REQUESTS_PER_CALL}}, note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, - context::PrivateContext, state_vars::PrivateSet, log::emit_encrypted_log, hash::pedersen_hash + context::PrivateContext, log::emit_encrypted_log, hash::pedersen_hash }; use dep::aztec::oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key}; use dep::safe_math::SafeU120; diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 0435e04b152..0039ad02257 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -1,7 +1,7 @@ use dep::aztec::{ protocol_types::{address::AztecAddress, constants::MAX_READ_REQUESTS_PER_CALL}, note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, - context::PrivateContext, state_vars::PrivateSet, log::emit_encrypted_log, hash::pedersen_hash + context::PrivateContext, log::emit_encrypted_log, hash::pedersen_hash }; use dep::aztec::oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key}; use dep::safe_math::SafeU120; From a025a6d75249c8cb7ec479ecbf5acea0cad4eb08 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 18:59:29 +0000 Subject: [PATCH 28/32] documenting INITIALIZATION_SLOT_SEPARATOR --- .../noir-protocol-circuits/src/crates/types/src/constants.nr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index 480b0f825e7..ee8ddb87f39 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -97,6 +97,10 @@ global FUNCTION_SELECTOR_NUM_BYTES: Field = 4; global NUM_FIELDS_PER_SHA256: Field = 2; global ARGS_HASH_CHUNK_LENGTH: u32 = 32; global ARGS_HASH_CHUNK_COUNT: u32 = 32; +// The following is used in immutable state variables to compute an initialization slot whose value is used to +// determine whether a given variable has been initialized (by asserting that the value in the slot is 0). +// The initialization slot is computed by adding the constant bellow to the variable's storage slot. This constant has +// to be large enough so that it's ensured that it doesn't collide with storage slots of other variables. global INITIALIZATION_SLOT_SEPARATOR: Field = 1000; // CONTRACT CLASS CONSTANTS From 1baf757333c6c0d4a8cfb2fc336bf27049a35ca8 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 26 Feb 2024 19:06:48 +0000 Subject: [PATCH 29/32] link fix --- .../developers/contracts/references/storage/private_state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index c604a29f026..736475a8c67 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -16,7 +16,7 @@ Aztec private state follows a [utxo](https://en.wikipedia.org/wiki/Unspent_trans To greatly simplify the experience of writing private state, Aztec.nr provides three different types of private state variable: -- [PrivateMutable](#singletonnotetype) +- [PrivateMutable](#privatemutablenotetype) - [PrivateImmutable](#privateimmutablenotetype) - [PrivateSet](#privatesetnotetype) From 4f734ff32e724b847efe4b8106fcaa4b2e856524 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 27 Feb 2024 08:40:32 +0000 Subject: [PATCH 30/32] increasing INITIALIZATION_SLOT_SEPARATOR constant --- l1-contracts/src/core/libraries/ConstantsGen.sol | 1 - .../noir-protocol-circuits/src/crates/types/src/constants.nr | 2 +- yarn-project/circuits.js/src/constants.gen.ts | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index d429deaa406..1595e0cea21 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -72,7 +72,6 @@ library Constants { uint256 internal constant NUM_FIELDS_PER_SHA256 = 2; uint256 internal constant ARGS_HASH_CHUNK_LENGTH = 32; uint256 internal constant ARGS_HASH_CHUNK_COUNT = 32; - uint256 internal constant INITIALIZATION_SLOT_SEPARATOR = 1000; uint256 internal constant MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 1000; uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 500; uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 500; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index ee8ddb87f39..c5938e87500 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -101,7 +101,7 @@ global ARGS_HASH_CHUNK_COUNT: u32 = 32; // determine whether a given variable has been initialized (by asserting that the value in the slot is 0). // The initialization slot is computed by adding the constant bellow to the variable's storage slot. This constant has // to be large enough so that it's ensured that it doesn't collide with storage slots of other variables. -global INITIALIZATION_SLOT_SEPARATOR: Field = 1000; +global INITIALIZATION_SLOT_SEPARATOR: Field = 1000_000_000; // CONTRACT CLASS CONSTANTS // This should be around 8192 (assuming 2**15 instructions packed at 8 bytes each), diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 9be3302b9b1..776afeed222 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -58,7 +58,6 @@ export const FUNCTION_SELECTOR_NUM_BYTES = 4; export const NUM_FIELDS_PER_SHA256 = 2; export const ARGS_HASH_CHUNK_LENGTH = 32; export const ARGS_HASH_CHUNK_COUNT = 32; -export const INITIALIZATION_SLOT_SEPARATOR = 1000; export const MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 1000; export const MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 500; export const MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 500; From ac481d8905cd3e5453faefa4d15319cd9edbffca Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 27 Feb 2024 08:40:54 +0000 Subject: [PATCH 31/32] improved docs --- .../contracts/references/storage/private_state.md | 4 ++-- .../contracts/references/storage/public_state.md | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index 736475a8c67..ce9770ee2af 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -68,7 +68,7 @@ Interestingly, if a developer requires a private state to be modifiable by users ## `PrivateMutable` -PrivateMutable is a private state variable that is unique in a way. When a PrivateMutable 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. +PrivateMutable (formerly known as `Singleton`) is a private state variable that is unique in a way. When a PrivateMutable 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 and a storage slot. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr). @@ -134,7 +134,7 @@ Functionally similar to [`get_note`](#get_note), but executed in unconstrained f ## `PrivateImmutable` -`PrivateImmutable` represents a unique private state variable that, as the name suggests, is immutable. Once initialized, its value cannot be altered. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr). +`PrivateImmutable` (formerly known as `ImmutableSingleton`) represents a unique private state variable that, as the name suggests, is immutable. Once initialized, its value cannot be altered. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr). ### `new` diff --git a/docs/docs/developers/contracts/references/storage/public_state.md b/docs/docs/developers/contracts/references/storage/public_state.md index 2fe6111d38e..4344c0b0d10 100644 --- a/docs/docs/developers/contracts/references/storage/public_state.md +++ b/docs/docs/developers/contracts/references/storage/public_state.md @@ -8,7 +8,7 @@ For a higher level overview of the state model in Aztec, see the [state model](. ## Overview -The `PublicMutable` struct is generic over the variable type `T`. The type _must_ implement Serialize and Deserialize traits, as specified here: +The `PublicMutable` (formerly known as `PublicState`) struct is generic over the variable type `T`. The type _must_ implement Serialize and Deserialize traits, as specified here: #include_code serialize /noir-projects/noir-protocol-circuits/src/crates/types/src/traits.nr rust #include_code deserialize /noir-projects/noir-protocol-circuits/src/crates/types/src/traits.nr rust @@ -91,7 +91,7 @@ We have a `write` method on the `PublicMutable` struct that takes the value to w ## Shared Immutable -`SharedImmutable` is a special type that can be read from both public and private! +`SharedImmutable` (formerly known as `StablePublicState`) is a special type that can be read from both public and private! Since private execution is based on historical data, the user can pick ANY of its prior values to read from. This is why it `MUST` not be updated after the contract is deployed. The variable should be initialized at the constructor and then never changed. @@ -101,6 +101,10 @@ Just like the `PublicMutable` it is generic over the variable type `T`. The type You can find the details of `SharedImmutable` in the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr). +:::info +The word `Shared` in Aztec protocol means read/write from public, read only from private. +::: + ### `new` Is done exactly like the `PublicMutable` struct, but with the `SharedImmutable` struct. From 0af3f036409f8817cee023e4758a400913485d70 Mon Sep 17 00:00:00 2001 From: benesjan Date: Tue, 27 Feb 2024 08:59:00 +0000 Subject: [PATCH 32/32] updated slither --- l1-contracts/slither_output.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/l1-contracts/slither_output.md b/l1-contracts/slither_output.md index b9669bc5038..7de568caa47 100644 --- a/l1-contracts/slither_output.md +++ b/l1-contracts/slither_output.md @@ -353,15 +353,15 @@ src/core/messagebridge/Inbox.sol#L148-L153 Impact: Informational Confidence: Medium - [ ] ID-41 -Variable [Constants.LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L123) is too similar to [Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L116) +Variable [Constants.LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L122) is too similar to [Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L115) -src/core/libraries/ConstantsGen.sol#L123 +src/core/libraries/ConstantsGen.sol#L122 - [ ] ID-42 -Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L103) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L104) +Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L102) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L103) -src/core/libraries/ConstantsGen.sol#L103 +src/core/libraries/ConstantsGen.sol#L102 - [ ] ID-43