From 2288e44a5b817076c9d51db5f99905deeeffc418 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Sat, 9 Sep 2023 08:26:16 -0300 Subject: [PATCH] feat(noir): Introduce context union to simplify storage declarations (#2143) Fixes #2012 --- .../src/abis/ecdsa_account_contract.json | 2 +- .../src/abis/schnorr_account_contract.json | 2 +- .../contracts/card_game_contract/src/cards.nr | 10 +-- .../contracts/card_game_contract/src/main.nr | 58 ++++++-------- .../src/contracts/child_contract/src/main.nr | 20 ++--- .../docs_example_contract/src/main.nr | 47 +++++------ .../easy_private_token_contract/src/main.nr | 22 +++--- .../ecdsa_account_contract/src/main.nr | 10 +-- .../src/contracts/escrow_contract/src/main.nr | 13 ++-- .../contracts/lending_contract/src/main.nr | 55 ++++++------- .../native_token_contract/src/main.nr | 78 ++++++++----------- .../non_native_token_contract/src/main.nr | 48 +++++------- .../pending_commitments_contract/src/main.nr | 24 +++--- .../pokeable_token_contract/src/main.nr | 24 +++--- .../contracts/price_feed_contract/src/main.nr | 21 ++--- .../src/main.nr | 32 ++++---- .../private_token_contract/src/main.nr | 22 +++--- .../public_token_contract/src/main.nr | 25 ++---- .../schnorr_account_contract/src/main.nr | 10 +-- .../src/easy_private_state.nr | 16 ++-- .../noir-libs/noir-aztec/src/context.nr | 29 +++++++ .../src/state_vars/immutable_singleton.nr | 12 +-- .../noir-aztec/src/state_vars/map.nr | 25 ++---- .../noir-aztec/src/state_vars/public_state.nr | 5 +- .../noir-aztec/src/state_vars/set.nr | 29 ++++--- .../noir-aztec/src/state_vars/singleton.nr | 7 +- .../noir-libs/value-note/src/utils.nr | 2 +- 27 files changed, 288 insertions(+), 360 deletions(-) diff --git a/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json b/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json index 8b4e12fbee2..edf8ef64388 100644 --- a/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json +++ b/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json @@ -153,7 +153,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ] diff --git a/yarn-project/aztec.js/src/abis/schnorr_account_contract.json b/yarn-project/aztec.js/src/abis/schnorr_account_contract.json index c661a036019..15268ac7d51 100644 --- a/yarn-project/aztec.js/src/abis/schnorr_account_contract.json +++ b/yarn-project/aztec.js/src/abis/schnorr_account_contract.json @@ -141,7 +141,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ] diff --git a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr index e0bb5a538b7..d5698677b46 100644 --- a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr +++ b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr @@ -1,5 +1,5 @@ use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}, log::emit_encrypted_log, note::{ @@ -119,13 +119,11 @@ fn filter_cards(notes: [Option; MAX_READ_REQUESTS_PER_CALL], desir impl Deck { fn new( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, + context: Context, storage_slot: Field, ) -> Self { let set = Set { - private_context, - public_context, + context, storage_slot, note_interface: ValueNoteMethods, }; @@ -136,7 +134,7 @@ impl Deck { fn add_cards(&mut self, cards: [Card; N], owner: Field) -> [CardNote]{ let owner_key = get_public_key(owner); - let context = self.set.private_context.unwrap(); + let context = self.set.context.private.unwrap(); let mut inserted_cards = []; for card in cards { diff --git a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr index a1d8b0ce3ca..1d53056a5d1 100644 --- a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr @@ -2,7 +2,7 @@ mod cards; mod game; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, state_vars::{ map::Map, public_state::PublicState, @@ -22,35 +22,29 @@ struct Storage { impl Storage { fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, + context: Context, ) -> Self { Storage { collections: Map::new( - private_context, - public_context, + context, 1, - |private_context, public_context, slot| { + |context, slot| { Deck::new( - private_context, - public_context, + context, slot, ) }, ), game_decks: Map::new( - private_context, - public_context, + context, 2, - |private_context, public_context, slot| { + |context, slot| { Map::new( - private_context, - public_context, + context, slot, - |private_context, public_context, slot|{ + |context, slot|{ Deck::new( - private_context, - public_context, + context, slot, ) } @@ -58,13 +52,11 @@ impl Storage { }, ), games: Map::new( - private_context, - public_context, + context, 3, - |private_context, public_context, slot| { + |context, slot| { PublicState::new( - private_context, - public_context, + context, slot, GameSerialisationMethods, ) @@ -90,7 +82,7 @@ contract CardGame { abi::{ Hasher, PrivateContextInputs, }, - context::PrivateContext, + context::{PrivateContext, Context}, note::{ note_header::NoteHeader, utils as note_utils, @@ -121,7 +113,7 @@ contract CardGame { fn buy_pack( seed: Field, // The randomness used to generate the cards. Passed in for now. ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let buyer = context.msg_sender(); let mut cards = get_pack_cards(seed, buyer); @@ -135,7 +127,7 @@ contract CardGame { cards_fields: [Field; 2], ) { let cards = cards_fields.map(|card_field| Card::from_field(card_field)); - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let player = context.msg_sender(); let mut collection = storage.collections.at(player); @@ -153,7 +145,7 @@ contract CardGame { player: Field, deck_strength: u32, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); @@ -164,7 +156,7 @@ contract CardGame { #[aztec(public)] fn start_game(game: u32) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); @@ -177,7 +169,7 @@ contract CardGame { game: u32, card: Card, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let player = context.msg_sender(); let mut game_deck = storage.game_decks.at(game as Field).at(player); @@ -189,7 +181,7 @@ contract CardGame { #[aztec(public)] internal fn on_card_played(game: u32, player: Field, card_as_field: Field) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); @@ -207,7 +199,7 @@ contract CardGame { game: u32, cards_fields: [Field; PLAYABLE_CARDS], ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let player = context.msg_sender(); let cards = cards_fields.map(|card_field| Card::from_field(card_field)); @@ -224,7 +216,7 @@ contract CardGame { #[aztec(public)] internal fn on_cards_claimed(game: u32, player: Field, cards_hash: Field) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); @@ -243,21 +235,21 @@ contract CardGame { } unconstrained fn view_collection_cards(owner: Field, offset: u32) -> [Option; MAX_NOTES_PER_PAGE] { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); let collection = storage.collections.at(owner); collection.view_cards(offset) } unconstrained fn view_game_cards(game: u32, player: Field, offset: u32) -> [Option; MAX_NOTES_PER_PAGE] { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); let game_deck = storage.game_decks.at(game as Field).at(player); game_deck.view_cards(offset) } unconstrained fn view_game(game: u32) -> Game { - Storage::init(Option::none(), Option::none()).games.at(game as Field).read() + Storage::init(Context::none()).games.at(game as Field).read() } // Computes note hash and nullifier. diff --git a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr index d661347201d..98641d7054d 100644 --- a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr @@ -4,7 +4,7 @@ contract Child { use dep::aztec::{ abi::CallContext, - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, oracle::{ logs::emit_unencrypted_log, compute_selector::compute_selector, @@ -18,14 +18,10 @@ contract Child { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { current_value: PublicState::new( - private_context, - public_context, + context, 1, FieldSerialisationMethods, ), @@ -69,7 +65,7 @@ contract Child { // Sets `current_value` to `new_value` #[aztec(public)] fn pubSetValue(new_value: Field) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); storage.current_value.write(new_value); let _hash = emit_unencrypted_log(new_value); @@ -79,7 +75,7 @@ contract Child { // Increments `current_value` by `new_value` #[aztec(public)] fn pubIncValue(new_value: Field) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let old_value = storage.current_value.read(); storage.current_value.write(old_value + new_value); let _hash = emit_unencrypted_log(new_value); @@ -90,7 +86,7 @@ contract Child { // Increments `current_value` by `new_value`. Can only be called from this contract. #[aztec(public)] fn pubIncValueInternal(new_value: Field) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); check_sender(inputs.call_context); let old_value = storage.current_value.read(); storage.current_value.write(old_value + new_value); @@ -104,14 +100,14 @@ contract Child { let pubSetValueSelector = compute_selector("pubSetValue(Field)"); let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]); - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); storage.current_value.write(20); let _hash = emit_unencrypted_log(20); } #[aztec(public)] fn setValueTwiceWithNestedLast() { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); storage.current_value.write(20); let _hash = emit_unencrypted_log(20); diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr index a47de701dcd..cd6dc5f9b29 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr @@ -6,7 +6,7 @@ mod types; contract DocsExample { use dep::std::option::Option; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, state_vars::{ immutable_singleton::ImmutableSingleton, map::Map, public_state::PublicState, set::Set, singleton::Singleton, @@ -44,33 +44,28 @@ contract DocsExample { // docs:start:state_vars-Set // docs:start:state_vars-MapSingleton impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { // highlight-next-line:state_vars-PublicState - locked: PublicState::new(private_context, public_context, 1, BoolSerialisationMethods), + locked: PublicState::new(context, 1, BoolSerialisationMethods), // highlight-next-line:state_vars-PublicStateCustomStruct queen: PublicState::new( - private_context, - public_context, + context, 2, QueenSerialisationMethods, ), // highlight-next-line:state_vars-ImmutableSingleton - game_rules: ImmutableSingleton::new(private_context, 3, RulesNoteMethods), + game_rules: ImmutableSingleton::new(context, 3, RulesNoteMethods), // highlight-next-line:state_vars-Singleton - legendary_card: Singleton::new(private_context, public_context, 4, CardNoteMethods), + legendary_card: Singleton::new(context, 4, CardNoteMethods), // highlight-next-line:state_vars-Set - cards: Set::new(private_context, public_context, 5, CardNoteMethods), + cards: Set::new(context, 5, CardNoteMethods), // highlight-next-line:state_vars-MapSingleton profiles: Map::new( - private_context, - public_context, + context, 6, - |private_context, public_context, slot| { - Singleton::new(private_context, public_context, slot, ProfileNoteMethods) + |context, slot| { + Singleton::new(context, slot, ProfileNoteMethods) }, ), } @@ -93,7 +88,7 @@ contract DocsExample { max_points: u8, legendary_card_secret: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let mut game_rules = RulesNote::new(min_points, max_points); actions::init_game_rules(storage.game_rules, &mut game_rules); @@ -106,7 +101,7 @@ contract DocsExample { #[aztec(public)] fn lock() { // highlight-next-line:storage-init - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); storage.locked.write(true); } // docs:end:storage-init @@ -114,7 +109,7 @@ contract DocsExample { // docs:start:functions-OpenFunction #[aztec(public)] fn unlock() { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); actions::unlock(storage.locked); } // docs:end:functions-OpenFunction @@ -124,7 +119,7 @@ contract DocsExample { account: Field, points: u8, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let new_queen = Queen { account, points }; @@ -136,7 +131,7 @@ contract DocsExample { // docs:start:state_vars-PublicStateWriteBeforeCall #[aztec(public)] fn replace_queen_unsafe() { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let account = context.msg_sender(); let points = actions::get_total_points(storage.cards, account, 0); @@ -155,7 +150,7 @@ contract DocsExample { // docs:start:functions-SecretFunction #[aztec(private)] fn add_common_cards(secrets: [Field; 4]) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); for i in 0..secrets.len() as u8 { let mut card = CardNote::new(0, secrets[i], 0); @@ -169,7 +164,7 @@ contract DocsExample { new_points: u8, new_secret: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let owner = inputs.call_context.msg_sender; let mut updated_card = CardNote::new(new_points, new_secret, owner); @@ -181,7 +176,7 @@ contract DocsExample { #[aztec(private)] fn become_queen() { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let legendary_card = actions::get_legendary_card(storage.legendary_card); @@ -205,7 +200,7 @@ contract DocsExample { account: Field, offset: u32, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let mut total_points = 0; let options = create_account_card_getter_options(account, offset); @@ -224,7 +219,7 @@ contract DocsExample { // docs:start:state_vars-check_return_notes #[aztec(private)] fn discard_largest_card() { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let account = context.msg_sender(); let options = create_largest_account_card_getter_options(account); @@ -238,7 +233,7 @@ contract DocsExample { // docs:start:functions-UncontrainedFunction unconstrained fn get_total_points(account: Field) -> u8 { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); actions::get_total_points(storage.cards, account, 0) } // docs:end:functions-UncontrainedFunction diff --git a/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr index 37901c0a260..a4fdd1951ac 100644 --- a/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr @@ -2,7 +2,7 @@ contract EasyPrivateToken { use dep::std::option::Option; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, note::{ note_header::NoteHeader, utils as note_utils, @@ -23,17 +23,13 @@ contract EasyPrivateToken { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { balances: Map::new( - private_context, - public_context, + context, 1, - |private_context, public_context, slot| { - EasyPrivateUint::new(private_context, public_context, slot) + |context, slot| { + EasyPrivateUint::new(context, slot) }, ), } @@ -48,7 +44,7 @@ contract EasyPrivateToken { initial_supply: u120, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let balances = storage.balances; balances.at(owner).add(initial_supply, owner); @@ -60,7 +56,7 @@ contract EasyPrivateToken { amount: u120, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let balances = storage.balances; balances.at(owner).add(amount, owner); @@ -73,7 +69,7 @@ contract EasyPrivateToken { sender: Field, recipient: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let balances = storage.balances; balances.at(sender).sub(amount, sender); @@ -84,7 +80,7 @@ contract EasyPrivateToken { unconstrained fn getBalance( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); let balances = storage.balances; // Return the sum of all notes in the set. diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr index b7739942369..1c6c2e17dc6 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr @@ -8,7 +8,7 @@ contract EcdsaAccount { use dep::aztec::{ abi::CallContext, constants_gen::GENERATOR_INDEX__SIGNATURE_PAYLOAD, - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, entrypoint::{EntrypointPayload, ENTRYPOINT_PAYLOAD_SIZE}, log::emit_encrypted_log, note::{ @@ -28,9 +28,9 @@ contract EcdsaAccount { } impl Storage { - fn init(private_context: Option<&mut PrivateContext>, _: Option<&mut PublicContext>) -> pub Self { + fn init(context: Context) -> pub Self { Storage { - public_key: ImmutableSingleton::new(private_context, 1, EcdsaPublicKeyNoteInterface), + public_key: ImmutableSingleton::new(context, 1, EcdsaPublicKeyNoteInterface), } } } @@ -42,7 +42,7 @@ contract EcdsaAccount { signature: pub [u8;64], ) { // Load public key from storage - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let public_key = storage.public_key.get_note(); // Verify payload signature using Ethereum's signing scheme @@ -69,7 +69,7 @@ contract EcdsaAccount { signing_pub_key_x: pub [u8;32], signing_pub_key_y: pub [u8;32], ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let this = context.this_address(); let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); diff --git a/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr index af93d9e74c2..81131fae5e3 100644 --- a/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr @@ -6,7 +6,7 @@ contract Escrow { use dep::std::option::Option; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, log::emit_encrypted_log, note::{ note_getter_options::NoteGetterOptions, @@ -30,12 +30,9 @@ contract Escrow { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { - owners: Set::new(private_context, public_context, 1, AddressNoteMethods), + owners: Set::new(context, 1, AddressNoteMethods), } } } @@ -47,7 +44,7 @@ contract Escrow { ) { let this = context.this_address(); - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let mut note = AddressNote::new(owner, this); storage.owners.insert(&mut note); emit_encrypted_log( @@ -68,7 +65,7 @@ contract Escrow { ) { let this = context.this_address(); let sender = context.msg_sender(); - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // We don't remove note from the owners set. If a note exists, the owner and recipient are legit. let options = NoteGetterOptions::new().select(0, sender).select(1, this).set_limit(1); diff --git a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr index dc887d2ea04..3683aafe96d 100644 --- a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr @@ -14,7 +14,7 @@ contract Lending { use dep::safe_math::SafeU120; use dep::std::option::Option; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, oracle::compute_selector::compute_selector, state_vars::{ map::Map, @@ -40,57 +40,46 @@ contract Lending { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { collateral_asset: PublicState::new( - private_context, - public_context, + context, 1, FieldSerialisationMethods, ), stable_coin: PublicState::new( - private_context, - public_context, + context, 2, FieldSerialisationMethods, ), assets: Map::new( - private_context, - public_context, + context, 3, - |private_context, public_context, slot| { + |context, slot| { PublicState::new( - private_context, - public_context, + context, slot, AssetSerialisationMethods, ) }, ), collateral: Map::new( - private_context, - public_context, + context, 4, - |private_context, public_context, slot| { + |context, slot| { PublicState::new( - private_context, - public_context, + context, slot, FieldSerialisationMethods, ) }, ), static_debt: Map::new( - private_context, - public_context, + context, 5, - |private_context, public_context, slot| { + |context, slot| { PublicState::new( - private_context, - public_context, + context, slot, FieldSerialisationMethods, ) @@ -118,7 +107,7 @@ contract Lending { collateral_asset: Field, stable_coin: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let asset_loc = storage.assets.at(0); let asset = asset_loc.read(); @@ -142,7 +131,7 @@ contract Lending { // Create a position. #[aztec(public)] fn update_accumulator() -> Asset { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let asset_loc = storage.assets.at(0); let mut asset = asset_loc.read(); @@ -202,7 +191,7 @@ contract Lending { collateral_asset: Field, ) -> Field { let _asset = Lending::at(context.this_address()).update_accumulator(context); - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let coll_asset = storage.collateral_asset.read(); assert(coll_asset == collateral_asset); @@ -245,7 +234,7 @@ contract Lending { let asset = Lending::at(context.this_address()).update_accumulator(context); let price = PriceFeed::at(asset.oracle_address).get_price(context); - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let coll_loc = storage.collateral.at(owner); let collateral: Field = coll_loc.read(); @@ -300,7 +289,7 @@ contract Lending { let asset = Lending::at(context.this_address()).update_accumulator(context); let price = PriceFeed::at(asset.oracle_address).get_price(context); - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); // Fetch collateral and static_debt, compute health of current position let collateral = storage.collateral.at(owner).read() as u120; @@ -355,7 +344,7 @@ contract Lending { stable_coin: Field, ) { let asset = Lending::at(context.this_address()).update_accumulator(context); - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); // To ensure that private is using the correct token. assert(stable_coin == storage.stable_coin.read()); @@ -371,14 +360,14 @@ contract Lending { unconstrained fn get_asset( assetId: Field, ) -> Asset { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); storage.assets.at(assetId).read() } unconstrained fn get_position( owner: Field, ) -> Position { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); let collateral = storage.collateral.at(owner).read(); let static_debt = storage.static_debt.at(owner).read(); let asset = storage.assets.at(0).read(); @@ -387,7 +376,7 @@ contract Lending { } unconstrained fn get_assets() -> [Field; 2] { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); [storage.collateral_asset.read(), storage.stable_coin.read()] } } diff --git a/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr index b7a14525a4f..0f140b06731 100644 --- a/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/native_token_contract/src/main.nr @@ -14,7 +14,7 @@ contract NativeToken { use dep::std; use dep::aztec::{ constants_gen::GENERATOR_INDEX__SIGNATURE_PAYLOAD, - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, note::{ note_header::NoteHeader, utils as note_utils, @@ -52,52 +52,42 @@ contract NativeToken { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { balances: Map::new( - private_context, - public_context, + context, 1, // Storage slot - |private_context, public_context, slot| { - Set::new(private_context, public_context, slot, ValueNoteMethods) + |context, slot| { + Set::new(context, slot, ValueNoteMethods) }, ), total_supply: PublicState::new( - private_context, - public_context, + context, 2, FieldSerialisationMethods, ), - pending_shields: Set::new(private_context, public_context, 3, TransparentNoteMethods), + pending_shields: Set::new(context, 3, TransparentNoteMethods), public_balances: Map::new( - private_context, - public_context, + context, 4, - |private_context, public_context, slot| { + |context, slot| { PublicState::new( - private_context, - public_context, + context, slot, FieldSerialisationMethods, ) }, ), public_allowances: Map::new( - private_context, - public_context, + context, 5, - |private_context, public_context, s1| { + |context, s1| { Map::new( - private_context, - public_context, + context, s1, - |private_context, public_context, s2| { + |context, s2| { PublicState::new( - private_context, - public_context, + context, s2, FieldSerialisationMethods, ) @@ -114,7 +104,7 @@ contract NativeToken { initial_supply: Field, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let balance = storage.balances.at(owner); increment(balance, initial_supply, owner); @@ -125,7 +115,7 @@ contract NativeToken { to: Field, amount: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let new_balance = storage.public_balances.at(to).read() + amount; storage.public_balances.at(to).write(new_balance); storage.total_supply.write(storage.total_supply.read() + amount); @@ -139,7 +129,7 @@ contract NativeToken { amount: Field, secret_hash: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let pending_shields = storage.pending_shields; let mut note = TransparentNote::new(amount, secret_hash); @@ -162,7 +152,7 @@ contract NativeToken { secret: Field, canceller: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let content_hash = get_mint_content_hash(amount, owner, canceller); @@ -183,7 +173,7 @@ contract NativeToken { recipient: Field, // ethereum address in the field callerOnL1: Field, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let sender_balance = storage.balances.at(sender); decrement(sender_balance, amount, sender); @@ -204,7 +194,7 @@ contract NativeToken { secret: Field, canceller: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let public_balances = storage.public_balances; let content_hash = get_mint_content_hash(amount, owner_address, canceller); @@ -228,7 +218,7 @@ contract NativeToken { recipient: Field, callerOnL1: Field, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let public_balances = storage.public_balances; let sender = context.msg_sender(); @@ -248,7 +238,7 @@ contract NativeToken { spender: Field, allowance: Field, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); storage.public_allowances.at(context.msg_sender()).at(spender).write(allowance); } @@ -257,7 +247,7 @@ contract NativeToken { to: Field, amount: Field, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); // Decrease user's balance. let sender = context.msg_sender(); @@ -281,7 +271,7 @@ contract NativeToken { to: Field, amount: Field, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); // Decrease allowance let allowance = storage.public_allowances.at(from).at(context.msg_sender()); @@ -310,7 +300,7 @@ contract NativeToken { to: Field, amount: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // Gets the set of sender's notes and picks 2 of those. let sender_balance = storage.balances.at(from); @@ -326,7 +316,7 @@ contract NativeToken { amount: Field, secretHash: Field, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let public_balances = storage.public_balances; let pending_shields = storage.pending_shields; @@ -355,7 +345,7 @@ contract NativeToken { secret: Field, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let pending_shields = storage.pending_shields; let public_note = TransparentNote::new_from_secret(amount, secret); @@ -374,7 +364,7 @@ contract NativeToken { to: Field, amount: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // If `from != sender` then we use the is_valid function to check that the message is approved. if (from != context.msg_sender()) { @@ -411,7 +401,7 @@ contract NativeToken { amount: Field, to: Field, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let to_balance = storage.public_balances.at(to); let current_balance = to_balance.read(); @@ -422,7 +412,7 @@ contract NativeToken { unconstrained fn balance_of( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); let owner_balance = storage.balances.at(owner); balance_utils::get_balance(owner_balance) @@ -441,14 +431,14 @@ contract NativeToken { } unconstrained fn total_supply() -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); storage.total_supply.read() } unconstrained fn public_balance_of( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); storage.public_balances.at(owner).read() } @@ -456,7 +446,7 @@ contract NativeToken { owner: Field, spender: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); storage.public_allowances.at(owner).at(spender).read() } } diff --git a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr index 8c585b078d3..c19f4ca5a3c 100644 --- a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr @@ -33,7 +33,7 @@ contract NonNativeToken { use crate::hash::{get_mint_content_hash, get_withdraw_content_hash}; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, note::{ note_header::NoteHeader, utils as note_utils, @@ -52,28 +52,22 @@ contract NonNativeToken { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { balances: Map::new( - private_context, - public_context, + context, 1, // Storage slot - |private_context, public_context, slot| { - Set::new(private_context, public_context, slot, ValueNoteMethods) + |context, slot| { + Set::new(context, slot, ValueNoteMethods) }, ), - pending_shields: Set::new(private_context, public_context, 2, TransparentNoteMethods), + pending_shields: Set::new(context, 2, TransparentNoteMethods), public_balances: Map::new( - private_context, - public_context, + context, 3, - |private_context, public_context, slot| { + |context, slot| { PublicState::new( - private_context, - public_context, + context, slot, FieldSerialisationMethods, ) @@ -88,7 +82,7 @@ contract NonNativeToken { initial_supply: Field, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let balance = storage.balances.at(owner); increment(balance, initial_supply, owner); @@ -106,7 +100,7 @@ contract NonNativeToken { secret: Field, canceller: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let content_hash = get_mint_content_hash(amount, owner, canceller); @@ -127,7 +121,7 @@ contract NonNativeToken { recipient: Field, // ethereum address in the field callerOnL1: Field, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let sender_balance = storage.balances.at(sender); decrement(sender_balance, amount, sender); @@ -148,7 +142,7 @@ contract NonNativeToken { secret: Field, canceller: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let public_balances = storage.public_balances; let content_hash = get_mint_content_hash(amount, owner_address, canceller); @@ -173,7 +167,7 @@ contract NonNativeToken { recipient: Field, callerOnL1: Field, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let public_balances = storage.public_balances; let sender = context.msg_sender(); @@ -201,7 +195,7 @@ contract NonNativeToken { amount: Field, recipient: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let sender = context.msg_sender(); // Gets the set of sender's notes and picks 2 of those. @@ -218,7 +212,7 @@ contract NonNativeToken { amount: Field, secretHash: Field, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let public_balances = storage.public_balances; let pending_shields = storage.pending_shields; @@ -247,7 +241,7 @@ contract NonNativeToken { secret: Field, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let pending_shields = storage.pending_shields; let public_note = TransparentNote::new_from_secret(amount, secret); @@ -265,7 +259,7 @@ contract NonNativeToken { amount: Field, recipient: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let owner = context.msg_sender(); // Remove user balance @@ -284,7 +278,7 @@ contract NonNativeToken { amount: Field, recipient: Field, ) { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let recipient_balance = storage.public_balances.at(recipient); let current_balance = recipient_balance.read(); @@ -295,7 +289,7 @@ contract NonNativeToken { unconstrained fn getBalance( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); let owner_balance = storage.balances.at(owner); balance_utils::get_balance(owner_balance) @@ -316,7 +310,7 @@ contract NonNativeToken { unconstrained fn publicBalanceOf( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); storage.public_balances.at(owner).read() } } diff --git a/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr index cd9110b7629..85525a26448 100644 --- a/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr @@ -12,7 +12,7 @@ contract PendingCommitments { }; use dep::aztec::{ constants_gen::ARGS_LENGTH, - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, log::emit_encrypted_log, note::{ note_getter::NoteGetterOptions, @@ -28,17 +28,13 @@ contract PendingCommitments { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { balances: Map::new( - private_context, - public_context, + context, 1, // Storage slot - |private_context, public_context, slot| { - Set::new(private_context, public_context, slot, ValueNoteMethods) + |context, slot| { + Set::new(context, slot, ValueNoteMethods) }, ), } @@ -59,7 +55,7 @@ contract PendingCommitments { amount: Field, owner: Field, ) -> Field { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let owner_balance = storage.balances.at(owner); let mut note = ValueNote::new(amount, owner); @@ -93,7 +89,7 @@ contract PendingCommitments { amount: Field, owner: Field, ) -> Field { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let owner_balance = storage.balances.at(owner); @@ -131,7 +127,7 @@ contract PendingCommitments { amount: Field, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let owner_balance = storage.balances.at(owner); let mut note = ValueNote::new(amount, owner); @@ -153,7 +149,7 @@ contract PendingCommitments { expected_value: Field, owner: Field, ) -> Field { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let owner_balance = storage.balances.at(owner); @@ -172,7 +168,7 @@ contract PendingCommitments { fn get_note_zero_balance( owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let owner_balance = storage.balances.at(owner); diff --git a/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/main.nr index 860350460b7..706c734d602 100644 --- a/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/main.nr @@ -9,7 +9,7 @@ contract PokeableToken { value_note::{VALUE_NOTE_LEN, ValueNoteMethods, ValueNote}, }; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, log::emit_encrypted_log, note::{ note_getter::NoteGetterOptions, @@ -28,19 +28,15 @@ contract PokeableToken { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { - sender: ImmutableSingleton::new(private_context, 1, AddressNoteMethods), - recipient: ImmutableSingleton::new(private_context, 2, AddressNoteMethods), + sender: ImmutableSingleton::new(context, 1, AddressNoteMethods), + recipient: ImmutableSingleton::new(context, 2, AddressNoteMethods), balances: Map::new( - private_context, - public_context, + context, 3, - |private_context, public_context, slot| { - Set::new(private_context, public_context, slot, ValueNoteMethods) + |context, slot| { + Set::new(context, slot, ValueNoteMethods) }, ), } @@ -54,7 +50,7 @@ contract PokeableToken { sender: Field, recipient: Field ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let mut sender_note = AddressNote::new(sender); let mut recipient_note = AddressNote::new(recipient); @@ -73,7 +69,7 @@ contract PokeableToken { sender: Field, recipient: Field ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // TODO: This check is not satisfying constraints // let mut sender_note = AddressNote::new(sender); @@ -111,7 +107,7 @@ contract PokeableToken { unconstrained fn getBalance( sender: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); // Get the set of notes owned by the user. let sender_balance = storage.balances.at(sender); diff --git a/yarn-project/noir-contracts/src/contracts/price_feed_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/price_feed_contract/src/main.nr index 78441d762f2..6adea42406b 100644 --- a/yarn-project/noir-contracts/src/contracts/price_feed_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/price_feed_contract/src/main.nr @@ -3,7 +3,7 @@ mod asset; contract PriceFeed { use dep::std::option::Option; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, state_vars::{ map::Map, public_state::PublicState, @@ -17,19 +17,14 @@ contract PriceFeed { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { assets: Map::new( - private_context, - public_context, + context, 1, - |private_context, public_context, slot| { + |context, slot| { PublicState::new( - private_context, - public_context, + context, slot, AssetSerialisationMethods, ) @@ -47,7 +42,7 @@ contract PriceFeed { asset_id: Field, price: u120, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let asset = storage.assets.at(asset_id); asset.write(Asset {price: price}); @@ -58,7 +53,7 @@ contract PriceFeed { fn get_price( asset_id: Field, ) -> Asset { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); storage.assets.at(asset_id).read() } @@ -66,7 +61,7 @@ contract PriceFeed { unconstrained fn fetch_price( assetId: Field, ) -> Asset { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); storage.assets.at(assetId).read() } } diff --git a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr index 359a46bdca9..da67fc0bb4f 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr @@ -10,7 +10,7 @@ contract PrivateTokenAirdrop { value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, }; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, state_vars::{map::Map, set::Set}, note::{ note_getter_options::NoteGetterOptions, @@ -30,20 +30,16 @@ contract PrivateTokenAirdrop { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { balances: Map::new( - private_context, - public_context, + context, 1, // Storage slot - |private_context, public_context, slot| { - Set::new(private_context, public_context, slot, ValueNoteMethods) + |context, slot| { + Set::new(context, slot, ValueNoteMethods) }, ), - claims: Set::new(private_context, public_context, 2, ClaimNoteMethods), + claims: Set::new(context, 2, ClaimNoteMethods), } } } @@ -54,7 +50,7 @@ contract PrivateTokenAirdrop { initial_supply: Field, owner: Field ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // Insert new note to a set of user notes and emit the newly created encrypted note preimage via oracle call. let owner_balance = storage.balances.at(owner); @@ -69,7 +65,7 @@ contract PrivateTokenAirdrop { amount: Field, owner: Field ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // Insert new note to a set of user notes and emit the newly created encrypted note preimage via oracle call. let owner_balance = storage.balances.at(owner); @@ -83,7 +79,7 @@ contract PrivateTokenAirdrop { amount: Field, owner: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let msg_sender = context.msg_sender(); let this_address = context.this_address(); @@ -112,7 +108,7 @@ contract PrivateTokenAirdrop { amount: Field, recipient: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let sender = context.msg_sender(); let sender_balance = storage.balances.at(sender); @@ -142,7 +138,7 @@ contract PrivateTokenAirdrop { amounts: [Field; 2], secrets: [Field; 2], ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let sender = context.msg_sender(); // Pick from the set of sender's notes to spend amount. @@ -166,7 +162,7 @@ contract PrivateTokenAirdrop { secret: Field, owner: Field ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // Remove the claim note if it exists in the set. let note = ClaimNote::new(amount, secret); @@ -187,7 +183,7 @@ contract PrivateTokenAirdrop { recipients: [Field; 3], spend_note_offset: u32, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // Gets the set of sender's notes and picks 4 of those based on the offset. // Spends the first of those 4 notes. @@ -228,7 +224,7 @@ contract PrivateTokenAirdrop { unconstrained fn getBalance( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); // Get the set of notes owned by the user. let owner_balance = storage.balances.at(owner); diff --git a/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr index f3aae3c8dcc..8395bbd1ea0 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr @@ -6,7 +6,7 @@ contract PrivateToken { value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, }; use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, note::{ note_header::NoteHeader, utils as note_utils, @@ -20,17 +20,13 @@ contract PrivateToken { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { balances: Map::new( - private_context, - public_context, + context, 1, // Storage slot - |private_context, public_context, slot| { - Set::new(private_context, public_context, slot, ValueNoteMethods) + |context, slot| { + Set::new(context, slot, ValueNoteMethods) }, ), } @@ -44,7 +40,7 @@ contract PrivateToken { initial_supply: Field, owner: Field ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // Insert new note to a set of user notes and emit the newly created encrypted note preimage via oracle call. let owner_balance = storage.balances.at(owner); if (initial_supply != 0) { @@ -60,7 +56,7 @@ contract PrivateToken { amount: Field, owner: Field ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); // Insert new note to a set of user notes and emit the newly created encrypted note preimage via oracle call. let owner_balance = storage.balances.at(owner); @@ -75,7 +71,7 @@ contract PrivateToken { amount: Field, recipient: Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let sender = context.msg_sender(); // Pick from the set of sender's notes to spend amount. @@ -93,7 +89,7 @@ contract PrivateToken { unconstrained fn getBalance( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); // Get the set of notes owned by the user. let owner_balance = storage.balances.at(owner); diff --git a/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr index e94ccf1b7e0..f32f3ec07bf 100644 --- a/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr @@ -6,7 +6,7 @@ contract PublicToken { // docs:end:unencrypted_import use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, state_vars::{ map::Map, public_state::PublicState, @@ -21,22 +21,13 @@ contract PublicToken { } impl Storage { - fn init( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, - ) -> pub Self { + fn init(context: Context) -> pub Self { Storage { balances: Map::new( - private_context, - public_context, + context, 1, - |private_context, public_context, slot| { - PublicState::new( - private_context, - public_context, - slot, - FieldSerialisationMethods, - ) + |context, slot| { + PublicState::new(context, slot, FieldSerialisationMethods) }, ), } @@ -54,7 +45,7 @@ contract PublicToken { recipient: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let recipient_balance = storage.balances.at(recipient); let new_amount = recipient_balance.read() + amount; // docs:start:unencrypted_log @@ -72,7 +63,7 @@ contract PublicToken { amount: Field, recipient: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::some(&mut context)); + let storage = Storage::init(Context::public(&mut context)); let sender = context.msg_sender(); let sender_balance = storage.balances.at(sender); @@ -101,7 +92,7 @@ contract PublicToken { unconstrained fn publicBalanceOf( owner: Field, ) -> Field { - let storage = Storage::init(Option::none(), Option::none()); + let storage = Storage::init(Context::none()); storage.balances.at(owner).read() } } diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr index 65aebff95c2..0b7e926224e 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr @@ -7,7 +7,7 @@ contract SchnorrAccount { use dep::std::option::Option; use dep::aztec::{ constants_gen::GENERATOR_INDEX__SIGNATURE_PAYLOAD, - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, entrypoint::{ENTRYPOINT_PAYLOAD_SIZE, EntrypointPayload}, log::emit_encrypted_log, note::{ @@ -25,9 +25,9 @@ contract SchnorrAccount { } impl Storage { - fn init(private_context: Option<&mut PrivateContext>, _: Option<&mut PublicContext>) -> pub Self { + fn init(context: Context) -> pub Self { Storage { - signing_public_key: ImmutableSingleton::new(private_context, 1, PublicKeyNoteMethods), + signing_public_key: ImmutableSingleton::new(context, 1, PublicKeyNoteMethods), } } } @@ -39,7 +39,7 @@ contract SchnorrAccount { signature: pub [u8;64], // schnorr signature of the payload hash ) { // Load public key from storage - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let public_key = storage.signing_public_key.get_note(); // Verify payload signature @@ -68,7 +68,7 @@ contract SchnorrAccount { signing_pub_key_x: pub Field, signing_pub_key_y: pub Field, ) { - let storage = Storage::init(Option::some(&mut context), Option::none()); + let storage = Storage::init(Context::private(&mut context)); let this = context.this_address(); let mut pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); diff --git a/yarn-project/noir-libs/easy-private-state/src/easy_private_state.nr b/yarn-project/noir-libs/easy-private-state/src/easy_private_state.nr index 0c6761ec0fb..62f6e85d6e0 100644 --- a/yarn-project/noir-libs/easy-private-state/src/easy_private_state.nr +++ b/yarn-project/noir-libs/easy-private-state/src/easy_private_state.nr @@ -1,5 +1,5 @@ use dep::aztec::{ - context::{PrivateContext, PublicContext}, + context::{PrivateContext, PublicContext, Context}, log::emit_encrypted_log, note::note_getter_options::NoteGetterOptions, oracle::get_public_key::get_public_key, @@ -13,26 +13,24 @@ use dep::value_note::{ }; struct EasyPrivateUint { - maybe_context: Option<&mut PrivateContext>, + context: Context, set: Set, storage_slot: Field, } impl EasyPrivateUint { fn new( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, + context: Context, storage_slot: Field, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); let set = Set { - private_context, - public_context, + context, storage_slot, note_interface: ValueNoteMethods, }; EasyPrivateUint { - maybe_context: private_context, + context, set, storage_slot, } @@ -48,7 +46,7 @@ impl EasyPrivateUint { // Emit the newly created encrypted note preimages via oracle calls. let owner_key = get_public_key(owner); - let context = self.maybe_context.unwrap(); + let context = self.context.private.unwrap(); emit_encrypted_log( context, (*context).this_address(), @@ -94,7 +92,7 @@ impl EasyPrivateUint { let owner_key = get_public_key(owner); - let context = self.maybe_context.unwrap(); + let context = self.context.private.unwrap(); emit_encrypted_log( context, (*context).this_address(), diff --git a/yarn-project/noir-libs/noir-aztec/src/context.nr b/yarn-project/noir-libs/noir-aztec/src/context.nr index f28b1e3fa9b..7043ec87b76 100644 --- a/yarn-project/noir-libs/noir-aztec/src/context.nr +++ b/yarn-project/noir-libs/noir-aztec/src/context.nr @@ -47,6 +47,7 @@ use crate::oracle::{ context::get_portal_address, }; +use dep::std::option::Option; // When finished, one can call .finish() to convert back to the abi struct PrivateContext { @@ -548,4 +549,32 @@ impl PublicContext { ) } +} + +struct Context { + private: Option<&mut PrivateContext>, + public: Option<&mut PublicContext>, +} + +impl Context { + fn private(context: &mut PrivateContext) -> Context { + Context { + private: Option::some(context), + public: Option::none() + } + } + + fn public(context: &mut PublicContext) -> Context { + Context { + public: Option::some(context), + private: Option::none() + } + } + + fn none() -> Context { + Context { + public: Option::none(), + private: Option::none() + } + } } \ No newline at end of file diff --git a/yarn-project/noir-libs/noir-aztec/src/state_vars/immutable_singleton.nr b/yarn-project/noir-libs/noir-aztec/src/state_vars/immutable_singleton.nr index 1d135f03137..f419e7a0c32 100644 --- a/yarn-project/noir-libs/noir-aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/noir-libs/noir-aztec/src/state_vars/immutable_singleton.nr @@ -1,5 +1,5 @@ use crate::constants_gen::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__INITIALISATION_NULLIFIER}; -use crate::context::PrivateContext; +use crate::context::{PrivateContext, Context}; use crate::note::{ lifecycle::create_note, note_getter::{get_note, view_notes}, @@ -11,14 +11,14 @@ use dep::std::hash::pedersen_with_separator; use dep::std::option::Option; struct ImmutableSingleton { - context: Option<&mut PrivateContext>, + context: Context, storage_slot: Field, note_interface: NoteInterface, } impl ImmutableSingleton { fn new( - context: Option<&mut PrivateContext>, + context: Context, storage_slot: Field, note_interface: NoteInterface, ) -> Self { @@ -38,12 +38,12 @@ impl ImmutableSingleton { fn initialise(self, note: &mut Note) { // Nullify the storage slot. let nullifier = self.compute_initialisation_nullifier(); - self.context + self.context.private .unwrap() .push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT); create_note( - self.context.unwrap(), + self.context.private.unwrap(), self.storage_slot, note, self.note_interface, @@ -59,7 +59,7 @@ impl ImmutableSingleton { fn get_note(self) -> Note { let storage_slot = self.storage_slot; - get_note(self.context.unwrap(), storage_slot, self.note_interface) + get_note(self.context.private.unwrap(), storage_slot, self.note_interface) } unconstrained fn view_note(self) -> Note { diff --git a/yarn-project/noir-libs/noir-aztec/src/state_vars/map.nr b/yarn-project/noir-libs/noir-aztec/src/state_vars/map.nr index 0adb1ea0303..10df31dd31a 100644 --- a/yarn-project/noir-libs/noir-aztec/src/state_vars/map.nr +++ b/yarn-project/noir-libs/noir-aztec/src/state_vars/map.nr @@ -1,28 +1,21 @@ -use crate::context::{PrivateContext, PublicContext}; +use crate::context::{PrivateContext, PublicContext, Context}; use dep::std::option::Option; struct Map { - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, + context: Context, storage_slot: Field, - state_var_constructor: fn(Option<&mut PrivateContext>, Option<&mut PublicContext>, Field) -> V, + state_var_constructor: fn(Context, Field) -> V, } impl Map { fn new( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, + context: Context, storage_slot: Field, - state_var_constructor: fn( - Option<&mut PrivateContext>, - Option<&mut PublicContext>, - Field, - ) -> V, + state_var_constructor: fn(Context, Field) -> V, ) -> Map { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Map { - private_context, - public_context, + context, storage_slot, state_var_constructor, } @@ -33,10 +26,6 @@ impl Map { let derived_storage_slot = dep::std::hash::pedersen([self.storage_slot, key])[0]; let state_var_constructor = self.state_var_constructor; - state_var_constructor( - self.private_context, - self.public_context, - derived_storage_slot, - ) + state_var_constructor(self.context, derived_storage_slot) } } diff --git a/yarn-project/noir-libs/noir-aztec/src/state_vars/public_state.nr b/yarn-project/noir-libs/noir-aztec/src/state_vars/public_state.nr index ee10446a7fd..5216ae906f3 100644 --- a/yarn-project/noir-libs/noir-aztec/src/state_vars/public_state.nr +++ b/yarn-project/noir-libs/noir-aztec/src/state_vars/public_state.nr @@ -1,4 +1,4 @@ -use crate::context::{PrivateContext, PublicContext}; +use crate::context::{Context}; use crate::oracle::storage::storage_read; use crate::oracle::storage::storage_write; use crate::types::type_serialisation::TypeSerialisationInterface; @@ -12,8 +12,7 @@ struct PublicState { impl PublicState { fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. - _: Option<&mut PrivateContext>, - _: Option<&mut PublicContext>, + _: Context, storage_slot: Field, serialisation_methods: TypeSerialisationInterface, ) -> Self { diff --git a/yarn-project/noir-libs/noir-aztec/src/state_vars/set.nr b/yarn-project/noir-libs/noir-aztec/src/state_vars/set.nr index 5012ab86e7e..69685deeee4 100644 --- a/yarn-project/noir-libs/noir-aztec/src/state_vars/set.nr +++ b/yarn-project/noir-libs/noir-aztec/src/state_vars/set.nr @@ -1,7 +1,7 @@ use dep::std::option::Option; use crate::abi::PublicContextInputs; use crate::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}; -use crate::context::{PrivateContext, PublicContext}; +use crate::context::{PrivateContext, PublicContext, Context}; use crate::note::{ lifecycle::{create_note, create_note_hash_from_public, destroy_note}, note_getter::{ensure_note_exists, ensure_note_hash_exists, get_notes, view_notes}, @@ -12,23 +12,20 @@ use crate::note::{ }; struct Set { - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, + context: Context, storage_slot: Field, note_interface: NoteInterface, } impl Set { fn new( - private_context: Option<&mut PrivateContext>, - public_context: Option<&mut PublicContext>, + context: Context, storage_slot: Field, note_interface: NoteInterface, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Set { - private_context, - public_context, + context, storage_slot, note_interface, } @@ -36,7 +33,7 @@ impl Set { fn insert(self, note: &mut Note) { create_note( - self.private_context.unwrap(), + self.context.private.unwrap(), self.storage_slot, note, self.note_interface, @@ -45,7 +42,7 @@ impl Set { fn insert_from_public(self, note: &mut Note) { create_note_hash_from_public( - self.public_context.unwrap(), + self.context.public.unwrap(), self.storage_slot, note, self.note_interface, @@ -57,13 +54,13 @@ impl Set { fn assert_contains_note_and_remove(self, note: Note) { let mut note_with_header = note; ensure_note_exists( - self.private_context.unwrap(), + self.context.private.unwrap(), self.storage_slot, self.note_interface, &mut note_with_header, ); destroy_note( - self.private_context.unwrap(), + self.context.private.unwrap(), self.storage_slot, note_with_header, self.note_interface, @@ -77,7 +74,7 @@ impl Set { let mut note_with_header = note; // Modifies note with the header which is necessary for the next step (remove). ensure_note_hash_exists( - self.private_context.unwrap(), + self.context.private.unwrap(), self.storage_slot, self.note_interface, &mut note_with_header, @@ -94,7 +91,7 @@ impl Set { header.nonce = 1; set_header(&mut note_with_header, header); destroy_note( - self.private_context.unwrap(), + self.context.private.unwrap(), self.storage_slot, note_with_header, self.note_interface, @@ -103,12 +100,12 @@ impl Set { fn remove(self, note: Note) { let note_hash = compute_note_hash_for_read_or_nullify(self.note_interface, note); - let read_requests = self.private_context.unwrap_unchecked().read_requests; + let read_requests = self.context.private.unwrap_unchecked().read_requests; let has_been_read = read_requests.any(|r| r == note_hash); assert(has_been_read, "Can only remove a note that has been read from the set."); destroy_note( - self.private_context.unwrap(), + self.context.private.unwrap(), self.storage_slot, note, self.note_interface, @@ -121,7 +118,7 @@ impl Set { ) -> [Option; MAX_READ_REQUESTS_PER_CALL] { let storage_slot = self.storage_slot; let opt_notes = get_notes( - self.private_context.unwrap(), + self.context.private.unwrap(), storage_slot, self.note_interface, options, diff --git a/yarn-project/noir-libs/noir-aztec/src/state_vars/singleton.nr b/yarn-project/noir-libs/noir-aztec/src/state_vars/singleton.nr index e386107f78b..e1033604995 100644 --- a/yarn-project/noir-libs/noir-aztec/src/state_vars/singleton.nr +++ b/yarn-project/noir-libs/noir-aztec/src/state_vars/singleton.nr @@ -1,5 +1,5 @@ use crate::constants_gen::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__INITIALISATION_NULLIFIER}; -use crate::context::{PrivateContext, PublicContext}; +use crate::context::{PrivateContext, PublicContext, Context}; use crate::note::{ lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes}, @@ -18,14 +18,13 @@ struct Singleton { impl Singleton { fn new( - context: Option<&mut PrivateContext>, - _: Option<&mut PublicContext>, + context: Context, storage_slot: Field, note_interface: NoteInterface, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Singleton { - context, + context: context.private, storage_slot, note_interface, } diff --git a/yarn-project/noir-libs/value-note/src/utils.nr b/yarn-project/noir-libs/value-note/src/utils.nr index f431895e956..4b7fcebd127 100644 --- a/yarn-project/noir-libs/value-note/src/utils.nr +++ b/yarn-project/noir-libs/value-note/src/utils.nr @@ -94,7 +94,7 @@ fn create_note( if note.value != 0 { // Emit the newly created encrypted note preimages via oracle calls. // docs:start:encrypted - let context = balance.private_context.unwrap(); + let context = balance.context.private.unwrap(); let application_contract_address = (*context).this_address(); let note_storage_slot = balance.storage_slot; let encryption_pub_key = get_public_key(owner);