From 2bbcc7bfde00eb8078fac51e83906287d39119a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Tue, 20 Aug 2024 19:49:10 +0200 Subject: [PATCH] feat: removing redundant key fetching (#8043) Fixes #7954 I replaced the use of `encode_and_encrypt_note` with `encode_and_encrypt_note_with_keys` in most of the places as it allowed for reusing the obtained keys. Note that there is only 1 legimate place remaining where it made sense to keep on using `encode_and_encrypt_note` and that is [here](https://github.com/AztecProtocol/aztec-packages/blob/34ae51df5d45973deb3408075a50070c781f7a48/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr#L47). All the other places are either test contracts or the token blacklist contract which is very outdated by now and hence it didn't seem to be worth it to update it. Given this I think we should nuke `encode_and_encrypt_note` to keep the API simpler and to make devs write efficient code. Does the reviewer agree? (possibly also `encode_and_encrypt_event`) Token::transfer(...) gates before were 49296 and after 38903. Diff of **10393 gates**. --- .../src/easy_private_uint.nr | 30 +++++++++++++---- .../aztec-nr/value-note/src/utils.nr | 16 +++++++--- .../app_subscription_contract/src/main.nr | 29 +++++++++-------- .../contracts/child_contract/src/main.nr | 8 ++--- .../crowdfunding_contract/src/main.nr | 8 ++--- .../ecdsa_k_account_contract/src/main.nr | 8 ++--- .../ecdsa_r_account_contract/src/main.nr | 8 ++--- .../contracts/escrow_contract/src/main.nr | 11 ++++--- .../pending_note_hashes_contract/src/main.nr | 1 - .../schnorr_account_contract/src/main.nr | 8 ++--- .../contracts/token_contract/src/main.nr | 32 ++++++++++--------- .../token_contract/src/types/balances_map.nr | 11 +++---- 12 files changed, 100 insertions(+), 70 deletions(-) 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 780dd75d46d..4f829187d07 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 @@ -1,7 +1,7 @@ use dep::aztec::{ context::PrivateContext, protocol_types::{address::AztecAddress}, note::note_getter_options::NoteGetterOptions, state_vars::PrivateSet, - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, keys::getters::get_current_public_keys }; use dep::value_note::{filter::filter_notes_min_sum, value_note::ValueNote}; @@ -24,19 +24,28 @@ impl EasyPrivateUint { impl EasyPrivateUint<&mut PrivateContext> { // Very similar to `value_note::utils::increment`. pub fn add(self, addend: u64, owner: AztecAddress, outgoing_viewer: AztecAddress) { - let owner_npk_m_hash = get_current_public_keys(self.context, owner).npk_m.hash(); + let owner_keys = get_current_public_keys(self.context, owner); + let outgoing_viewer_keys = get_current_public_keys(self.context, outgoing_viewer); // Creates new note for the owner. - let mut addend_note = ValueNote::new(addend as Field, owner_npk_m_hash); + let mut addend_note = ValueNote::new(addend as Field, owner_keys.npk_m.hash()); // Insert the new note to the owner's set of notes. // docs:start:insert - self.set.insert(&mut addend_note).emit(encode_and_encrypt_note(self.context, outgoing_viewer, owner)); + self.set.insert(&mut addend_note).emit( + encode_and_encrypt_note_with_keys( + self.context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner + ) + ); // docs:end:insert } // Very similar to `value_note::utils::decrement`. pub fn sub(self, subtrahend: u64, owner: AztecAddress, outgoing_viewer: AztecAddress) { - let owner_npk_m_hash = get_current_public_keys(self.context, owner).npk_m.hash(); + let owner_keys = get_current_public_keys(self.context, owner); + let outgoing_viewer_keys = get_current_public_keys(self.context, outgoing_viewer); // docs:start:pop_notes let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend as Field); @@ -56,7 +65,14 @@ impl EasyPrivateUint<&mut PrivateContext> { // Creates change note for the owner. let result_value = minuend - subtrahend; - let mut result_note = ValueNote::new(result_value as Field, owner_npk_m_hash); - self.set.insert(&mut result_note).emit(encode_and_encrypt_note(self.context, outgoing_viewer, owner)); + let mut result_note = ValueNote::new(result_value as Field, owner_keys.npk_m.hash()); + self.set.insert(&mut result_note).emit( + encode_and_encrypt_note_with_keys( + self.context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner + ) + ); } } diff --git a/noir-projects/aztec-nr/value-note/src/utils.nr b/noir-projects/aztec-nr/value-note/src/utils.nr index e9fa2536959..f4919981818 100644 --- a/noir-projects/aztec-nr/value-note/src/utils.nr +++ b/noir-projects/aztec-nr/value-note/src/utils.nr @@ -1,6 +1,6 @@ use dep::aztec::prelude::{AztecAddress, PrivateContext, PrivateSet, NoteGetterOptions}; use dep::aztec::note::note_getter_options::SortOrder; -use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note; +use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys; use dep::aztec::keys::getters::get_current_public_keys; use crate::{filter::filter_notes_min_sum, value_note::{ValueNote, VALUE_NOTE_LEN, VALUE_NOTE_BYTES_LEN}}; @@ -19,11 +19,19 @@ pub fn increment( recipient: AztecAddress, outgoing_viewer: AztecAddress // docs:end:increment_args ) { - let recipient_npk_m_hash = get_current_public_keys(balance.context, recipient).npk_m.hash(); + let recipient_keys = get_current_public_keys(balance.context, recipient); + let outgoing_viewer_ovpk_m = get_current_public_keys(balance.context, outgoing_viewer).ovpk_m; - let mut note = ValueNote::new(amount, recipient_npk_m_hash); + let mut note = ValueNote::new(amount, recipient_keys.npk_m.hash()); // Insert the new note to the owner's set of notes and emit the log if value is non-zero. - balance.insert(&mut note).emit(encode_and_encrypt_note(balance.context, outgoing_viewer, recipient)); + balance.insert(&mut note).emit( + encode_and_encrypt_note_with_keys( + balance.context, + outgoing_viewer_ovpk_m, + recipient_keys.ivpk_m, + recipient + ) + ); } // Find some of the `owner`'s notes whose values add up to the `amount`. 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 63d92871eef..c695fc0841f 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 @@ -9,7 +9,7 @@ contract AppSubscription { AztecAddress, FunctionSelector, PrivateContext, NoteHeader, Map, PrivateMutable, PublicMutable, SharedImmutable }, - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + encrypted_logs::encrypted_note_emission::{encode_and_encrypt_note, encode_and_encrypt_note_with_keys}, keys::getters::get_current_public_keys, protocol_types::constants::MAX_FIELD_VALUE }; use authwit::{auth_witness::get_auth_witness, auth::assert_current_call_valid_authwit}; @@ -92,12 +92,7 @@ contract AppSubscription { } #[aztec(private)] - fn subscribe( - subscriber_address: AztecAddress, - nonce: Field, - expiry_block_number: Field, - tx_count: Field - ) { + fn subscribe(subscriber: AztecAddress, nonce: Field, expiry_block_number: Field, tx_count: Field) { assert(tx_count as u64 <= SUBSCRIPTION_TXS as u64); Token::at(storage.subscription_token_address.read_private()).transfer_from( @@ -109,13 +104,21 @@ contract AppSubscription { // Assert that the given expiry_block_number < current_block_number + SUBSCRIPTION_DURATION_IN_BLOCKS. AppSubscription::at(context.this_address()).assert_block_number(expiry_block_number).enqueue_view(&mut context); - let subscriber_npk_m_hash = get_current_public_keys(&mut context, subscriber_address).npk_m.hash(); - - let mut subscription_note = SubscriptionNote::new(subscriber_npk_m_hash, expiry_block_number, tx_count); - storage.subscriptions.at(subscriber_address).initialize_or_replace(&mut subscription_note).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), subscriber_address)); + let subscriber_keys = get_current_public_keys(&mut context, subscriber); + let msg_sender_ovpk_m = get_current_public_keys(&mut context, context.msg_sender()).ovpk_m; + + let mut subscription_note = SubscriptionNote::new(subscriber_keys.npk_m.hash(), expiry_block_number, tx_count); + storage.subscriptions.at(subscriber).initialize_or_replace(&mut subscription_note).emit( + encode_and_encrypt_note_with_keys( + &mut context, + msg_sender_ovpk_m, + subscriber_keys.ivpk_m, + subscriber + ) + ); } - unconstrained fn is_initialized(subscriber_address: AztecAddress) -> pub bool { - storage.subscriptions.at(subscriber_address).is_initialized() + unconstrained fn is_initialized(subscriber: AztecAddress) -> pub bool { + storage.subscriptions.at(subscriber).is_initialized() } } 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 3a90384f3fb..05c584a767e 100644 --- a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr @@ -5,7 +5,7 @@ contract Child { use dep::aztec::{ context::gas::GasOpts, protocol_types::{abis::call_context::CallContext}, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, keys::getters::get_current_public_keys }; use dep::value_note::value_note::ValueNote; @@ -52,10 +52,10 @@ contract Child { #[aztec(private)] fn private_set_value(new_value: Field, owner: AztecAddress) -> Field { - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_keys = get_current_public_keys(&mut context, owner); - let mut note = ValueNote::new(new_value, owner_npk_m_hash); - storage.a_map_with_private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note(&mut context, owner, owner)); + let mut note = ValueNote::new(new_value, owner_keys.npk_m.hash()); + storage.a_map_with_private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note_with_keys(&mut context, owner_keys.ovpk_m, owner_keys.ivpk_m, owner)); new_value } diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr index b62a496db09..3c7f9b60389 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr @@ -5,7 +5,7 @@ contract Crowdfunding { // docs:start:all-deps use dep::aztec::{ protocol_types::address::AztecAddress, - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, keys::getters::get_current_public_keys, state_vars::{PrivateSet, PublicImmutable, SharedImmutable} }; @@ -79,11 +79,11 @@ contract Crowdfunding { // 3) Create a value note for the donor so that he can later on claim a rewards token in the Claim // contract by proving that the hash of this note exists in the note hash tree. - let donor_npk_m_hash = get_current_public_keys(&mut context, donor).npk_m.hash(); + let donor_keys = get_current_public_keys(&mut context, donor); // docs:start:valuenote_new - let mut note = ValueNote::new(amount as Field, donor_npk_m_hash); + let mut note = ValueNote::new(amount as Field, donor_keys.npk_m.hash()); // docs:end:valuenote_new - storage.donation_receipts.insert(&mut note).emit(encode_and_encrypt_note(&mut context, donor, donor)); + storage.donation_receipts.insert(&mut note).emit(encode_and_encrypt_note_with_keys(&mut context, donor_keys.ovpk_m, donor_keys.ivpk_m, donor)); } // docs:end:donate diff --git a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr index 339e20b7d98..e1a3db1ff5f 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr @@ -3,7 +3,7 @@ contract EcdsaKAccount { use dep::aztec::prelude::{AztecAddress, FunctionSelector, NoteHeader, NoteGetterOptions, PrivateContext, PrivateImmutable}; use dep::aztec::{ - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, keys::getters::get_current_public_keys }; @@ -27,13 +27,13 @@ contract EcdsaKAccount { #[aztec(initializer)] fn constructor(signing_pub_key_x: [u8; 32], signing_pub_key_y: [u8; 32]) { let this = context.this_address(); - let this_npk_m_hash = get_current_public_keys(&mut context, this).npk_m.hash(); + let this_keys = get_current_public_keys(&mut context, this); // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. - let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_npk_m_hash); - storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note(&mut context, this, this)); + let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); + storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note_with_keys(&mut context, this_keys.ovpk_m, this_keys.ivpk_m, this)); } // Note: If you globally change the entrypoint signature don't forget to update default_entrypoint.ts diff --git a/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr index 3a997e9ebc3..1b60e8733b0 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr @@ -2,7 +2,7 @@ contract EcdsaRAccount { use dep::aztec::prelude::{AztecAddress, FunctionSelector, NoteHeader, NoteGetterOptions, PrivateContext, PrivateImmutable}; use dep::aztec::{ - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, keys::getters::get_current_public_keys }; @@ -26,13 +26,13 @@ contract EcdsaRAccount { #[aztec(initializer)] fn constructor(signing_pub_key_x: [u8; 32], signing_pub_key_y: [u8; 32]) { let this = context.this_address(); - let this_npk_m_hash = get_current_public_keys(&mut context, this).npk_m.hash(); + let this_keys = get_current_public_keys(&mut context, this); // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. - let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_npk_m_hash); - storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note(&mut context, this, this)); + let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); + storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note_with_keys(&mut context, this_keys.ovpk_m, this_keys.ivpk_m, this)); } // Note: If you globally change the entrypoint signature don't forget to update default_entrypoint.ts 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 d44a0b6a9e3..d56ab328825 100644 --- a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr @@ -2,7 +2,7 @@ contract Escrow { use dep::aztec::prelude::{AztecAddress, EthAddress, FunctionSelector, NoteHeader, PrivateContext, PrivateImmutable}; use dep::aztec::{ - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys, keys::getters::get_current_public_keys }; @@ -20,11 +20,14 @@ contract Escrow { #[aztec(private)] #[aztec(initializer)] fn constructor(owner: AztecAddress) { - let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); + let owner_keys = get_current_public_keys(&mut context, owner); + let msg_sender_keys = get_current_public_keys(&mut context, context.msg_sender()); // docs:start:addressnote_new - let mut note = AddressNote::new(owner, owner_npk_m_hash); + let mut note = AddressNote::new(owner, owner_keys.npk_m.hash()); // docs:end:addressnote_new - storage.owner.initialize(&mut note).emit(encode_and_encrypt_note(&mut context, context.msg_sender(), owner)); + storage.owner.initialize(&mut note).emit( + encode_and_encrypt_note_with_keys(&mut context, msg_sender_keys.ovpk_m, owner_keys.ivpk_m, owner) + ); } // Withdraws balance. Requires that msg.sender is the owner. diff --git a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr index da8e23d4b76..1fd805f2c2d 100644 --- a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr @@ -59,7 +59,6 @@ contract PendingNoteHashes { assert(notes.len() == 0); - let header = context.get_header(); let owner_npk_m_hash = get_current_public_keys(&mut context, owner).npk_m.hash(); // Insert note 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 c6c0c4b9a31..1d8d2441476 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 @@ -6,7 +6,7 @@ contract SchnorrAccount { use dep::std; use dep::aztec::prelude::{AztecAddress, FunctionSelector, NoteHeader, PrivateContext, PrivateImmutable}; - use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note; + use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, auth_witness::get_auth_witness, auth::{compute_authwit_nullifier, compute_authwit_message_hash} @@ -28,14 +28,14 @@ contract SchnorrAccount { #[aztec(initializer)] fn constructor(signing_pub_key_x: Field, signing_pub_key_y: Field) { let this = context.this_address(); - let this_npk_m_hash = get_current_public_keys(&mut context, this).npk_m.hash(); + let this_keys = get_current_public_keys(&mut context, this); // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. // docs:start:initialize - let mut pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_npk_m_hash); - storage.signing_public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note(&mut context, this, this)); + let mut pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); + storage.signing_public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note_with_keys(&mut context, this_keys.ovpk_m, this_keys.ivpk_m, this)); // docs:end:initialize } 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 253a39a4b4e..97e0cf031b6 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -22,10 +22,7 @@ contract Token { FunctionSelector, NoteHeader, Point }, encrypted_logs::{ - encrypted_note_emission::{ - encode_and_encrypt_note, encode_and_encrypt_note_with_keys, - encode_and_encrypt_note_with_keys_unconstrained - }, + encrypted_note_emission::{encode_and_encrypt_note_with_keys, encode_and_encrypt_note_with_keys_unconstrained}, encrypted_event_emission::{encode_and_encrypt_event, encode_and_encrypt_event_with_keys_unconstrained} }, keys::getters::get_current_public_keys @@ -225,7 +222,10 @@ contract Token { #[aztec(private)] fn privately_mint_private_note(amount: Field) { let caller = context.msg_sender(); - storage.balances.add(caller, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, caller, caller)); + let caller_keys = get_current_public_keys(&mut context, caller); + storage.balances.add(caller, caller_keys.npk_m, U128::from_integer(amount)).emit( + encode_and_encrypt_note_with_keys(&mut context, caller_keys.ovpk_m, caller_keys.ivpk_m, caller) + ); Token::at(context.this_address()).assert_minter_and_mint(context.msg_sender(), amount).enqueue(&mut context); } @@ -318,7 +318,9 @@ contract Token { // Note: Using context.msg_sender() as a sender below makes this incompatible with escrows because we send // outgoing logs to that address and to send outgoing logs you need to get a hold of ovsk_m. let from = context.msg_sender(); - storage.balances.add(to, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from, to)); + let from_keys = get_current_public_keys(&mut context, from); + let to_keys = get_current_public_keys(&mut context, to); + storage.balances.add(to, to_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); } // docs:end:redeem_shield @@ -331,7 +333,8 @@ contract Token { assert(nonce == 0, "invalid nonce"); } - storage.balances.sub(from, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from, from)); + let from_keys = get_current_public_keys(&mut context, from); + storage.balances.sub(from, from_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); Token::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); } @@ -361,11 +364,11 @@ contract Token { INITIAL_TRANSFER_CALL_MAX_NOTES ); - storage.balances.add(from, change).emit( + storage.balances.add(from, from_keys.npk_m, change).emit( encode_and_encrypt_note_with_keys_unconstrained(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from) ); - storage.balances.add(to, amount).emit( + storage.balances.add(to, to_keys.npk_m, amount).emit( encode_and_encrypt_note_with_keys_unconstrained(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to) ); @@ -462,10 +465,10 @@ contract Token { let amount = U128::from_integer(amount); // docs:start:increase_private_balance // docs:start:encrypted - storage.balances.sub(from, amount).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); + storage.balances.sub(from, from_keys.npk_m, amount).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); // docs:end:encrypted // docs:end:increase_private_balance - storage.balances.add(to, amount).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); + storage.balances.add(to, to_keys.npk_m, amount).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); } // docs:end:transfer_from @@ -478,7 +481,8 @@ contract Token { assert(nonce == 0, "invalid nonce"); } - storage.balances.sub(from, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from, from)); + let from_keys = get_current_public_keys(&mut context, from); + storage.balances.sub(from, from_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note_with_keys(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); Token::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); } @@ -512,8 +516,6 @@ contract Token { assert_current_call_valid_authwit(&mut context, user); // 2. Get all the relevant keys - let header = context.get_header(); - let fee_payer_npk_m_hash = get_current_public_keys(&mut context, fee_payer).npk_m.hash(); let user_keys = get_current_public_keys(&mut context, user); let user_npk_m_hash = user_keys.npk_m.hash(); @@ -528,7 +530,7 @@ contract Token { U128::from_integer(funded_amount), INITIAL_TRANSFER_CALL_MAX_NOTES ); - storage.balances.add(user, change).emit( + storage.balances.add(user, user_keys.npk_m, change).emit( encode_and_encrypt_note_with_keys_unconstrained(&mut context, user_keys.ovpk_m, user_keys.ivpk_m, user) ); 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 0fece696437..c90678f9abd 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 @@ -1,4 +1,4 @@ -use dep::aztec::prelude::{AztecAddress, NoteGetterOptions, NoteViewerOptions, NoteHeader, NoteInterface, PrivateSet, Map}; +use dep::aztec::prelude::{AztecAddress, NoteGetterOptions, NoteViewerOptions, NoteHeader, NoteInterface, PrivateSet, Map, Point}; use dep::aztec::{ context::{PrivateContext, UnconstrainedContext}, protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, @@ -62,16 +62,14 @@ impl BalancesMap { pub fn add( self: Self, owner: AztecAddress, + owner_npk_m: Point, addend: U128 ) -> OuterNoteEmission where T: NoteInterface + OwnedNote + Eq { if addend == U128::from_integer(0) { OuterNoteEmission::new(Option::none()) } else { - let context = self.map.context; - // We fetch the nullifier public key hash from the registry / from our PXE - let owner_npk_m_hash = get_current_public_keys(context, owner).npk_m.hash(); - let mut addend_note = T::new(addend, owner_npk_m_hash); + let mut addend_note = T::new(addend, owner_npk_m.hash()); // docs:start:insert OuterNoteEmission::new(Option::some(self.map.at(owner).insert(&mut addend_note))) @@ -82,6 +80,7 @@ impl BalancesMap { pub fn sub( self: Self, owner: AztecAddress, + owner_npk_m: Point, amount: U128 ) -> OuterNoteEmission where T: NoteInterface + OwnedNote + Eq { let subtracted = self.try_sub(owner, amount, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL); @@ -89,7 +88,7 @@ impl BalancesMap { // try_sub may have substracted more or less than amount. We must ensure that we subtracted at least as much as // we needed, and then create a new note for the owner for the change (if any). assert(subtracted >= amount, "Balance too low"); - self.add(owner, subtracted - amount) + self.add(owner, owner_npk_m, subtracted - amount) } // Attempts to remove 'target_amount' from the owner's balance. try_sub returns how much was actually subtracted