diff --git a/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr index 7c2bd5f5fb0b..821aeaf1c1c0 100644 --- a/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr @@ -299,31 +299,35 @@ pub contract PendingNoteHashes { //} #[external("private")] - fn test_recursively_create_notes(owner: AztecAddress, how_many_recursions: u64) { + fn test_recursively_create_notes(recipients: [AztecAddress; 10], how_many_recursions: u64) { let initial_offset: u64 = 0; - self.internal.create_max_notes(owner, initial_offset); + self.internal.create_max_notes(recipients, initial_offset); let max_notes = self.internal.max_notes_per_call() as u64; - self.call_self.recursively_destroy_and_create_notes(owner, how_many_recursions, max_notes); + self.call_self.recursively_destroy_and_create_notes( + recipients, + how_many_recursions, + max_notes, + ); } #[external("private")] fn recursively_destroy_and_create_notes( - owner: AztecAddress, + recipients: [AztecAddress; 10], executions_left: u64, current_offset: u64, ) { assert(executions_left > 0); - self.internal.destroy_max_notes(owner); - self.internal.create_max_notes(owner, current_offset); + self.internal.destroy_max_notes(recipients); + self.internal.create_max_notes(recipients, current_offset); let executions_left = executions_left - 1; if executions_left > 0 { let max_notes = self.internal.max_notes_per_call() as u64; self.call_self.recursively_destroy_and_create_notes( - owner, + recipients, executions_left, current_offset + max_notes, ); @@ -331,21 +335,30 @@ pub contract PendingNoteHashes { } #[internal("private")] - fn create_max_notes(owner: AztecAddress, offset: u64) { - let owner_balance = self.storage.balances.at(owner); + fn create_max_notes(recipients: [AztecAddress; 10], offset: u64) { + // Distribute notes across recipients using global offset to ensure + // no recipient receives more than 10 notes (UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN) for i in 0..self.internal.max_notes_per_call() { - let note = FieldNote { value: (offset + i as u64) as Field }; - // Skip deliver(): notes are created and nullified in the same tx (kernel squashing), - // so tagged log delivery is unnecessary. Delivering would also exceed - // UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN for the sender-recipient pair. - let _ = owner_balance.insert(note); + let global_index = offset + i as u64; + let recipient_index = (global_index % 10) as u32; + let recipient = recipients[recipient_index]; + let recipient_balance = self.storage.balances.at(recipient); + + let note = FieldNote { value: i as Field }; + recipient_balance.insert(note).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); } } #[internal("private")] - fn destroy_max_notes(owner: AztecAddress) { - let owner_balance = self.storage.balances.at(owner); - let _ = owner_balance.pop_notes(NoteGetterOptions::new()); + fn destroy_max_notes(recipients: [AztecAddress; 10]) { + // Pop notes from all recipients + for i in 0..10 { + let recipient = recipients[i]; + let recipient_balance = self.storage.balances.at(recipient); + // Note that we're relying on PXE actually returning the notes, we're not constraining that any specific + // number of notes are deleted. + let _ = recipient_balance.pop_notes(NoteGetterOptions::new()); + } } #[internal("private")] diff --git a/yarn-project/cli-wallet/src/cmds/create_account.ts b/yarn-project/cli-wallet/src/cmds/create_account.ts index 2e317c6a7799..72a854c6fe74 100644 --- a/yarn-project/cli-wallet/src/cmds/create_account.ts +++ b/yarn-project/cli-wallet/src/cmds/create_account.ts @@ -79,6 +79,8 @@ export async function createAccount( skipInstancePublication: !publicDeploy, skipInitialization, from, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [address], fee: { paymentMethod, gasSettings }, }; diff --git a/yarn-project/cli-wallet/src/utils/wallet.ts b/yarn-project/cli-wallet/src/utils/wallet.ts index 2124b79197dd..a1493d0cc13c 100644 --- a/yarn-project/cli-wallet/src/utils/wallet.ts +++ b/yarn-project/cli-wallet/src/utils/wallet.ts @@ -87,7 +87,7 @@ export class CLIWallet extends BaseWallet { increasedFee: InteractionFeeOptions, ): Promise { const cancellationTxRequest = await this.createCancellationTxExecutionRequest(from, txNonce, increasedFee); - return await this.pxe.proveTx(cancellationTxRequest, this.scopesFor(from)); + return await this.pxe.proveTx(cancellationTxRequest, this.scopesFrom(from)); } override async getAccountFromAddress(address: AztecAddress) { diff --git a/yarn-project/end-to-end/src/composed/docs_examples.test.ts b/yarn-project/end-to-end/src/composed/docs_examples.test.ts index 45611db7c898..c9e1bbd2f7a0 100644 --- a/yarn-project/end-to-end/src/composed/docs_examples.test.ts +++ b/yarn-project/end-to-end/src/composed/docs_examples.test.ts @@ -30,7 +30,11 @@ describe('docs_examples', () => { const prefundedAccount = await wallet.createSchnorrAccount(accountData.secret, accountData.salt); const newAccountManager = await wallet.createSchnorrAccount(secretKey, Fr.random(), signingPrivateKey); const newAccountDeployMethod = await newAccountManager.getDeployMethod(); - await newAccountDeployMethod.send({ from: prefundedAccount.address }); + await newAccountDeployMethod.send({ + from: prefundedAccount.address, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [newAccountManager.address], + }); const newAccountAddress = newAccountManager.address; const defaultAccountAddress = prefundedAccount.address; diff --git a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts index 7bd8d64e0fad..30b5747bcedb 100644 --- a/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_local_network_example.test.ts @@ -145,7 +145,8 @@ describe('e2e_local_network_example', () => { return await Promise.all( accountManagers.map(async x => { const deployMethod = await x.getDeployMethod(); - await deployMethod.send({ from: fundedAccount }); + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + await deployMethod.send({ from: fundedAccount, additionalScopes: [x.address] }); return x; }), ); diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index 7da34cf384a2..1b99f2b3657e 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -161,7 +161,10 @@ describe('e2e_crowdfunding_and_claim', () => { expect(balanceDNTBeforeWithdrawal).toEqual(0n); // 3) At last, we withdraw the raised funds from the crowdfunding contract to the operator's address - await crowdfundingContract.methods.withdraw(donationAmount).send({ from: operatorAddress }); + await crowdfundingContract.methods + .withdraw(donationAmount) + // Withdraw nullifies the contract's own token notes, which requires its nullifier key. + .send({ from: operatorAddress, additionalScopes: [crowdfundingContract.address] }); const { result: balanceDNTAfterWithdrawal } = await donationToken.methods .balance_of_private(operatorAddress) @@ -285,9 +288,12 @@ describe('e2e_crowdfunding_and_claim', () => { await crowdfundingContract.methods.donate(donationAmount).send({ from: donor2Address, authWitnesses: [witness] }); // The following should fail as msg_sender != operator - await expect(crowdfundingContract.methods.withdraw(donationAmount).send({ from: donor2Address })).rejects.toThrow( - 'Assertion failed: Not an operator', - ); + await expect( + crowdfundingContract.methods + .withdraw(donationAmount) + // Withdraw nullifies the contract's own token notes, which requires its nullifier key. + .send({ from: donor2Address, additionalScopes: [crowdfundingContract.address] }), + ).rejects.toThrow('Assertion failed: Not an operator'); }); it('cannot donate after a deadline', async () => { diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index c3051b449b5a..949e5eb6e15c 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -66,7 +66,10 @@ describe('e2e_escrow_contract', () => { await expectTokenBalance(wallet, token, escrowContract.address, 100n, logger); logger.info(`Withdrawing funds from token contract to ${recipient}`); - await escrowContract.methods.withdraw(token.address, 30, recipient).send({ from: owner }); + await escrowContract.methods + .withdraw(token.address, 30, recipient) + // Withdraw nullifies the contract's own token notes, which requires its nullifier key. + .send({ from: owner, additionalScopes: [escrowContract.address] }); await expectTokenBalance(wallet, token, owner, 0n, logger); await expectTokenBalance(wallet, token, recipient, 30n, logger); @@ -75,7 +78,10 @@ describe('e2e_escrow_contract', () => { it('refuses to withdraw funds as a non-owner', async () => { await expect( - escrowContract.methods.withdraw(token.address, 30, recipient).simulate({ from: recipient }), + escrowContract.methods + .withdraw(token.address, 30, recipient) + // Withdraw nullifies the contract's own token notes, which requires its nullifier key. + .simulate({ from: recipient, additionalScopes: [escrowContract.address] }), ).rejects.toThrow(); }); @@ -90,7 +96,8 @@ describe('e2e_escrow_contract', () => { await new BatchCall(wallet, [ token.methods.transfer(recipient, 10), escrowContract.methods.withdraw(token.address, 20, recipient), - ]).send({ from: owner }); + // Withdraw nullifies the contract's own token notes, which requires its nullifier key. + ]).send({ from: owner, additionalScopes: [escrowContract.address] }); await expectTokenBalance(wallet, token, recipient, 30n, logger); }); }); diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index 1323bd1ba00a..67733719ca76 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -89,7 +89,12 @@ describe('e2e_fees account_init', () => { const [bobsInitialGas] = await t.getGasBalanceFn(bobsAddress); expect(bobsInitialGas).toEqual(mintAmount); - const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, wait: { returnReceipt: true } }); + const { receipt: tx } = await bobsDeployMethod.send({ + from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [bobsAddress], + wait: { returnReceipt: true }, + }); expect(tx.transactionFee!).toBeGreaterThan(0n); await expect(t.getGasBalanceFn(bobsAddress)).resolves.toEqual([bobsInitialGas - tx.transactionFee!]); @@ -100,6 +105,8 @@ describe('e2e_fees account_init', () => { const paymentMethod = new FeeJuicePaymentMethodWithClaim(bobsAddress, claim); const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [bobsAddress], fee: { paymentMethod }, wait: { returnReceipt: true }, }); @@ -120,6 +127,8 @@ describe('e2e_fees account_init', () => { const paymentMethod = new PrivateFeePaymentMethod(bananaFPC.address, bobsAddress, wallet, gasSettings); const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [bobsAddress], fee: { paymentMethod }, wait: { returnReceipt: true }, }); @@ -149,6 +158,8 @@ describe('e2e_fees account_init', () => { const paymentMethod = new PublicFeePaymentMethod(bananaFPC.address, bobsAddress, wallet, gasSettings); const { receipt: tx } = await bobsDeployMethod.send({ from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [bobsAddress], skipInstancePublication: false, fee: { paymentMethod }, wait: { returnReceipt: true }, @@ -187,6 +198,8 @@ describe('e2e_fees account_init', () => { bobsSigningPubKey.y, ).send({ from: aliceAddress, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [bobsAddress], contractAddressSalt: bobsInstance.salt, skipClassPublication: true, skipInstancePublication: true, diff --git a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts index 16889aef501f..668ddf07f18d 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fee_juice_payments.test.ts @@ -33,8 +33,9 @@ describe('e2e_fees Fee Juice payments', () => { // Alice pays for Bob's account contract deployment. const bobsDeployMethod = await bobsAccountManager.getDeployMethod(); - await bobsDeployMethod.send({ from: aliceAddress }); bobAddress = bobsAccountManager.address; + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + await bobsDeployMethod.send({ from: aliceAddress, additionalScopes: [bobAddress] }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts index 9982087e83dd..e69a176d72e7 100644 --- a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts @@ -1,5 +1,5 @@ import { AztecAddress } from '@aztec/aztec.js/addresses'; -import { Fr } from '@aztec/aztec.js/fields'; +import { Fr, GrumpkinScalar } from '@aztec/aztec.js/fields'; import type { Logger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; import { @@ -286,8 +286,19 @@ describe('e2e_pending_note_hashes_contract', () => { const minToNeedReset = Math.min(MAX_NOTE_HASHES_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX) + 1; const deployedContract = await deployContract(); + // We use 10 different recipients to send private logs to in order to avoid exceeding + // UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN logs emitted for any single sender-recipient pair. + const recipients = ( + await Promise.all( + Array.from({ length: 10 }, () => + wallet.createSchnorrAccount(Fr.random(), Fr.random(), GrumpkinScalar.random()), + ), + ) + ).map(a => a.address); + await deployedContract.methods - .test_recursively_create_notes(owner, Math.ceil(minToNeedReset / notesPerIteration)) - .send({ from: owner }); + .test_recursively_create_notes(recipients, Math.ceil(minToNeedReset / notesPerIteration)) + // Recipients need to be in scope so their keys are accessible for note creation. + .send({ from: owner, additionalScopes: recipients }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts index daed07568294..551304e259bd 100644 --- a/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_testnet/e2e_public_testnet_transfer.test.ts @@ -62,6 +62,8 @@ describe(`deploys and transfers a private only token`, () => { await wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey); const { contract: token } = await tokenDeployment.send({ from: deployerAddress, + // The contract constructor initializes private storage vars that need the contract's own nullifier key. + additionalScopes: [tokenInstance.address], universalDeploy: true, skipInstancePublication: true, skipClassPublication: true, diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index fb9ab8d9d88f..e45a7dfffab6 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -842,6 +842,8 @@ export const deployAccounts = const deployMethod = await accountManager.getDeployMethod(); await deployMethod.send({ from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [accountManager.address], skipClassPublication: i !== 0, // Publish the contract class at most once. }); } diff --git a/yarn-project/end-to-end/src/fixtures/token_utils.ts b/yarn-project/end-to-end/src/fixtures/token_utils.ts index ede82e6966c2..a0d67993b7eb 100644 --- a/yarn-project/end-to-end/src/fixtures/token_utils.ts +++ b/yarn-project/end-to-end/src/fixtures/token_utils.ts @@ -27,8 +27,9 @@ export async function mintTokensToPrivate( minter: AztecAddress, recipient: AztecAddress, amount: bigint, + additionalScopes?: AztecAddress[], ) { - await token.methods.mint_to_private(recipient, amount).send({ from: minter }); + await token.methods.mint_to_private(recipient, amount).send({ from: minter, additionalScopes }); } export async function expectTokenBalance( diff --git a/yarn-project/end-to-end/src/shared/submit-transactions.ts b/yarn-project/end-to-end/src/shared/submit-transactions.ts index b8b6c5c1a11e..04efd68cdf7e 100644 --- a/yarn-project/end-to-end/src/shared/submit-transactions.ts +++ b/yarn-project/end-to-end/src/shared/submit-transactions.ts @@ -19,7 +19,12 @@ export const submitTxsTo = async ( times(numTxs, async () => { const accountManager = await wallet.createSchnorrAccount(Fr.random(), Fr.random(), GrumpkinScalar.random()); const deployMethod = await accountManager.getDeployMethod(); - const { txHash } = await deployMethod.send({ from: submitter, wait: NO_WAIT }); + const { txHash } = await deployMethod.send({ + from: submitter, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [accountManager.address], + wait: NO_WAIT, + }); logger.info(`Tx sent with hash ${txHash}`); const receipt: TxReceipt = await wallet.getTxReceipt(txHash); diff --git a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts index d2a0908c62a8..b0e8295928f3 100644 --- a/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts +++ b/yarn-project/end-to-end/src/spartan/setup_test_wallets.ts @@ -88,11 +88,23 @@ export async function deploySponsoredTestAccountsWithTokens( const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress()); const recipientDeployMethod = await recipientAccount.getDeployMethod(); - await recipientDeployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: { timeout: 2400 } }); + await recipientDeployMethod.send({ + from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [recipientAccount.address], + fee: { paymentMethod }, + wait: { timeout: 2400 }, + }); await Promise.all( fundedAccounts.map(async a => { const deployMethod = await a.getDeployMethod(); - await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: { timeout: 2400 } }); // increase timeout on purpose in order to account for two empty epochs + await deployMethod.send({ + from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [a.address], + fee: { paymentMethod }, + wait: { timeout: 2400 }, + }); // increase timeout on purpose in order to account for two empty epochs logger.info(`Account deployed at ${a.address}`); }), ); @@ -139,6 +151,8 @@ async function deployAccountWithDiagnostics( } const deployResult = await deployMethod.send({ from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [account.address], fee: { paymentMethod, gasSettings }, wait: NO_WAIT, }); @@ -261,7 +275,8 @@ export async function deployTestAccountsWithTokens( fundedAccounts.map(async (a, i) => { const paymentMethod = new FeeJuicePaymentMethodWithClaim(a.address, claims[i]); const deployMethod = await a.getDeployMethod(); - await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod } }); + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + await deployMethod.send({ from: AztecAddress.ZERO, additionalScopes: [a.address], fee: { paymentMethod } }); logger.info(`Account deployed at ${a.address}`); }), ); diff --git a/yarn-project/end-to-end/src/test-wallet/test_wallet.ts b/yarn-project/end-to-end/src/test-wallet/test_wallet.ts index 9407c10950fe..24dc0adb6c85 100644 --- a/yarn-project/end-to-end/src/test-wallet/test_wallet.ts +++ b/yarn-project/end-to-end/src/test-wallet/test_wallet.ts @@ -275,7 +275,7 @@ export class TestWallet extends BaseWallet { async proveTx(exec: ExecutionPayload, opts: Omit): Promise { const fee = await this.completeFeeOptions(opts.from, exec.feePayer, opts.fee?.gasSettings); const txRequest = await this.createTxExecutionRequestFromPayloadAndFee(exec, opts.from, fee); - const txProvingResult = await this.pxe.proveTx(txRequest, this.scopesFor(opts.from)); + const txProvingResult = await this.pxe.proveTx(txRequest, this.scopesFrom(opts.from, opts.additionalScopes)); return new ProvenTx( this.aztecNode, await txProvingResult.toTx(), diff --git a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts index 5d4c188afdc2..1159e0d2267e 100644 --- a/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts +++ b/yarn-project/pxe/src/contract_function_simulator/oracle/private_execution_oracle.ts @@ -530,22 +530,13 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP isStaticCall = isStaticCall || this.callContext.isStaticCall; - // When scopes are set and the target contract is a registered account (has keys in the keyStore), - // expand scopes to include it so nested private calls can sync and read the contract's own notes. - // We only expand for registered accounts because the log service needs the recipient's keys to derive - // tagging secrets, which are only available for registered accounts. - const expandedScopes = - this.scopes !== 'ALL_SCOPES' && (await this.keyStore.hasAccount(targetContractAddress)) - ? [...this.scopes, targetContractAddress] - : this.scopes; - await this.contractSyncService.ensureContractSynced( targetContractAddress, functionSelector, this.utilityExecutor, this.anchorBlockHeader, this.jobId, - expandedScopes, + this.scopes, ); const targetArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata( @@ -583,8 +574,8 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP jobId: this.jobId, totalPublicCalldataCount: this.totalPublicCalldataCount, sideEffectCounter, + scopes: this.scopes, log: this.logger, - scopes: expandedScopes, senderForTags: this.senderForTags, simulator: this.simulator!, }); diff --git a/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts b/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts index 867d97f3fcfd..8e065f0db345 100644 --- a/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts +++ b/yarn-project/wallet-sdk/src/base-wallet/base_wallet.ts @@ -94,12 +94,6 @@ export abstract class BaseWallet implements Wallet { protected log = createLogger('wallet-sdk:base_wallet'), ) {} - // When `from` is the zero address (e.g. when deploying a new account contract), we return an - // empty scope list which acts as deny-all: no notes are visible and no keys are accessible. - protected scopesFor(from: AztecAddress): AztecAddress[] { - return from.isZero() ? [] : [from]; - } - protected scopesFrom(from: AztecAddress, additionalScopes: AztecAddress[] = []): AztecAddress[] { const allScopes = from.isZero() ? additionalScopes : [from, ...additionalScopes]; const scopeSet = new Set(allScopes.map(address => address.toString())); diff --git a/yarn-project/wallets/src/testing.ts b/yarn-project/wallets/src/testing.ts index 3b2723cde5b6..64838bfec198 100644 --- a/yarn-project/wallets/src/testing.ts +++ b/yarn-project/wallets/src/testing.ts @@ -22,6 +22,8 @@ export async function deployFundedSchnorrAccounts( const deployMethod = await accountManager.getDeployMethod(); await deployMethod.send({ from: AztecAddress.ZERO, + // The account constructor initializes storage vars that need the contract's own nullifier key, so we need to add it to scopes. + additionalScopes: [accountManager.address], skipClassPublication: i !== 0, wait: waitOptions, });