diff --git a/boxes/boxes/react/src/hooks/useNumber.tsx b/boxes/boxes/react/src/hooks/useNumber.tsx index abba9b719124..46ace9652ccb 100644 --- a/boxes/boxes/react/src/hooks/useNumber.tsx +++ b/boxes/boxes/react/src/hooks/useNumber.tsx @@ -11,7 +11,7 @@ export function useNumber({ contract }: { contract: Contract }) { setWait(true); const deployerWallet = await deployerEnv.getWallet(); - const viewTxReceipt = await contract!.methods.getNumber(deployerWallet.getCompleteAddress()).view(); + const viewTxReceipt = await contract!.methods.getNumber(deployerWallet.getCompleteAddress()).simulate(); toast(`Number is: ${viewTxReceipt.value}`); setWait(false); }; diff --git a/boxes/boxes/react/tests/node.test.ts b/boxes/boxes/react/tests/node.test.ts index f0b23d6b554f..48f06bb0aafc 100644 --- a/boxes/boxes/react/tests/node.test.ts +++ b/boxes/boxes/react/tests/node.test.ts @@ -25,7 +25,7 @@ describe('BoxReact Contract Tests', () => { }, 40000); test('Can read a number', async () => { - const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress()).view(); + const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress()).simulate(); expect(numberToSet.toBigInt()).toEqual(viewTxReceipt.value); }, 40000); }); diff --git a/boxes/boxes/vanilla/src/index.ts b/boxes/boxes/vanilla/src/index.ts index e5add71062ba..ded51955e6db 100644 --- a/boxes/boxes/vanilla/src/index.ts +++ b/boxes/boxes/vanilla/src/index.ts @@ -42,6 +42,6 @@ document.querySelector('#set').addEventListener('submit', async (e: Event) => { }); document.querySelector('#get').addEventListener('click', async () => { - const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress().address).view(); + const viewTxReceipt = await contract.methods.getNumber(wallet.getCompleteAddress().address).simulate(); alert(`Number is: ${viewTxReceipt.value}`); }); diff --git a/docs/docs/developers/aztecjs/guides/call_view_function.md b/docs/docs/developers/aztecjs/guides/call_view_function.md index 0e5cbbbd2586..5028bded9971 100644 --- a/docs/docs/developers/aztecjs/guides/call_view_function.md +++ b/docs/docs/developers/aztecjs/guides/call_view_function.md @@ -1,8 +1,8 @@ --- -title: How to Call a View Function +title: How to Simulate a Function Call --- -This guide explains how to call a `view` function using [Aztec.js](../main.md). +This guide explains how to `simulate` a function call using [Aztec.js](../main.md). To do this from the CLI, go [here](../../sandbox/references/cli-commands.md#calling-an-unconstrained-view-function). @@ -26,9 +26,13 @@ Get a previously deployed contract like this: #include_code get_contract yarn-project/end-to-end/src/docs_examples.test.ts typescript -## Call view function +## Simulating function calls -Call the `view` function on the contract like this: +Call the `simulate` function on the typescript contract wrapper like this: -#include_code call_view_function yarn-project/end-to-end/src/docs_examples.test.ts typescript +#include_code simulate_function yarn-project/end-to-end/src/docs_examples.test.ts typescript +:::info Note +- If the simulated function is `unconstrained` you will get a properly typed value. +- If the simulated function is `public` or `private` it will return a Field array of size 4. +::: \ No newline at end of file diff --git a/docs/docs/developers/tutorials/testing.md b/docs/docs/developers/tutorials/testing.md index 447d80b48962..9e80aba1636f 100644 --- a/docs/docs/developers/tutorials/testing.md +++ b/docs/docs/developers/tutorials/testing.md @@ -140,7 +140,7 @@ WARN Error processing tx 06dc87c4d64462916ea58426ffcfaf20017880b353c9ec3e0f0ee5f ### State -We can check private or public state directly rather than going through view-only methods, as we did in the initial example by calling `token.methods.balance().view()`. Bear in mind that directly accessing contract storage will break any kind of encapsulation. +We can check private or public state directly rather than going through view-only methods, as we did in the initial example by calling `token.methods.balance().simulate()`. Bear in mind that directly accessing contract storage will break any kind of encapsulation. To query storage directly, you'll need to know the slot you want to access. This can be checked in the [contract's `Storage` definition](../contracts/writing_contracts/storage/main.md) directly for most data types. However, when it comes to mapping types, as in most EVM languages, we'll need to calculate the slot for a given key. To do this, we'll use the [`CheatCodes`](../sandbox/references/cheat_codes.md) utility class: diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 2d9891f07e93..be8a430cc317 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -17,6 +17,32 @@ This change was made to communicate that we do not constrain the value in circui + let random_value = unsafe_rand(); ``` +### [AztecJS] Simulate and get return values for ANY call +Historically it have been possible to "view" `unconstrained` functions to simulate them and get the return values, but not for `public` nor `private` functions. +This has lead to a lot of bad code where we have the same function implemented thrice, once in `private`, once in `public` and once in `unconstrained`. +It is not possible to call `simulate` on any call to get the return values! +However, beware that it currently always returns a Field array of size 4 for private and public. +This will change to become similar to the return values of the `unconstrained` functions with proper return types. + +```diff +- #[aztec(private)] +- fn get_shared_immutable_constrained_private() -> pub Leader { +- storage.shared_immutable.read_private() +- } +- +- unconstrained fn get_shared_immutable() -> pub Leader { +- storage.shared_immutable.read_public() +- } + ++ #[aztec(private)] ++ fn get_shared_immutable_private() -> pub Leader { ++ storage.shared_immutable.read_private() ++ } + +- const returnValues = await contract.methods.get_shared_immutable().view(); ++ const returnValues = await contract.methods.get_shared_immutable_private().simulate(); +``` + ## 0.31.0 ### [Aztec.nr] Public storage historical read API improvement @@ -935,13 +961,13 @@ To parse a `AztecAddress` to BigInt, use `.inner` Before: ```js -const tokenBigInt = await bridge.methods.token().view(); +const tokenBigInt = await bridge.methods.token().simulate(); ``` Now: ```js -const tokenBigInt = (await bridge.methods.token().view()).inner; +const tokenBigInt = (await bridge.methods.token().simulate()).inner; ``` ### [Aztec.nr] Add `protocol_types` to Nargo.toml diff --git a/docs/internal_notes/building_dapps.md b/docs/internal_notes/building_dapps.md index 4cc8792a3bde..f4b65fa93190 100644 --- a/docs/internal_notes/building_dapps.md +++ b/docs/internal_notes/building_dapps.md @@ -22,7 +22,6 @@ Explain how to write a dapp using [`aztec.js`](https://github.com/AztecProtocol/ - Instantiate a contract - Deploy a contract - How to generate a nice typescript interface for an Aztec.nr contract's functions (we have a little `.ts` program in `noir-contracts` to generate a types file at the moment... how would a user do this?) - - Call 'view' functions - Simulate functions (simulate the result, without sending to the 'network') - Execute functions (send them to the 'network') - Tx hashes and tx receipts diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 7b13ac0dc53b..691c0b1cfd6b 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -108,6 +108,42 @@ contract DocsExample { assert(read.points == expected.points, "Invalid points"); } + #[aztec(private)] + fn get_shared_immutable_constrained_private_indirect() -> pub Leader { + // This is a private function that calls another private function + // and returns the response. + // Used to test that we can retrieve values through calls and + // correctly return them in the simulation + let ret = context.call_private_function_no_args( + context.this_address(), + FunctionSelector::from_signature("get_shared_immutable_constrained_private()") + ); + Leader::deserialize([ret[0], ret[1]]) + } + + #[aztec(public)] + fn get_shared_immutable_constrained_public_indirect() -> pub Leader { + // This is a public function that calls another public function + // and returns the response. + // Used to test that we can retrieve values through calls and + // correctly return them in the simulation + let ret = context.call_public_function_no_args( + context.this_address(), + FunctionSelector::from_signature("get_shared_immutable_constrained_public()") + ); + Leader::deserialize([ret[0], ret[1]]) + } + + #[aztec(public)] + fn get_shared_immutable_constrained_public() -> pub Leader { + storage.shared_immutable.read_public() + } + + #[aztec(private)] + fn get_shared_immutable_constrained_private() -> pub Leader { + storage.shared_immutable.read_private() + } + unconstrained fn get_shared_immutable() -> pub Leader { storage.shared_immutable.read_public() } diff --git a/yarn-project/accounts/src/testing/configuration.ts b/yarn-project/accounts/src/testing/configuration.ts index f19e9383a6c5..a7e9b2c160bc 100644 --- a/yarn-project/accounts/src/testing/configuration.ts +++ b/yarn-project/accounts/src/testing/configuration.ts @@ -68,7 +68,7 @@ export async function deployInitialTestAccounts(pxe: PXE) { skipPublicDeployment: true, universalDeploy: true, }); - await deployMethod.simulate({}); + await deployMethod.prove({}); return deployMethod; }), ); diff --git a/yarn-project/accounts/src/testing/create_account.ts b/yarn-project/accounts/src/testing/create_account.ts index 17c6f8dc6bd8..9b409740b6ce 100644 --- a/yarn-project/accounts/src/testing/create_account.ts +++ b/yarn-project/accounts/src/testing/create_account.ts @@ -29,7 +29,7 @@ export async function createAccounts(pxe: PXE, numberOfAccounts = 1): Promise - d.simulate({ + d.prove({ contractAddressSalt: account.salt, skipClassRegistration: true, skipPublicDeployment: true, diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index e14012e3b29a..e9a8ce375c06 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -663,7 +663,7 @@ export class AztecNodeService implements AztecNode { new WASMSimulator(), ); const processor = await publicProcessorFactory.create(prevHeader, newGlobalVariables); - const [processedTxs, failedTxs] = await processor.process([tx]); + const [processedTxs, failedTxs, returns] = await processor.process([tx]); if (failedTxs.length) { this.log.warn(`Simulated tx ${tx.getTxHash()} fails: ${failedTxs[0].error}`); throw failedTxs[0].error; @@ -674,6 +674,7 @@ export class AztecNodeService implements AztecNode { throw reverted[0].revertReason; } this.log.info(`Simulated tx ${tx.getTxHash()} succeeds`); + return returns; } public setConfig(config: Partial): Promise { diff --git a/yarn-project/aztec.js/README.md b/yarn-project/aztec.js/README.md index 294667159a81..40f51ec3234f 100644 --- a/yarn-project/aztec.js/README.md +++ b/yarn-project/aztec.js/README.md @@ -31,12 +31,12 @@ const tx = await contract.methods.transfer(amount, recipientAddress).send().wait console.log(`Transferred ${amount} to ${recipientAddress} on block ${tx.blockNumber}`); ``` -### Call a view function +### Simulate a function ```typescript import { Contract } from '@aztec/aztec.js'; const contract = await Contract.at(contractAddress, MyContractArtifact, wallet); -const balance = await contract.methods.get_balance(wallet.getAddress()).view(); +const balance = await contract.methods.get_balance(wallet.getAddress()).simulate(); console.log(`Account balance is ${balance}`); ``` diff --git a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts index 1cc594b055a4..1125a528ec27 100644 --- a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts +++ b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts @@ -37,13 +37,13 @@ export abstract class BaseContractInteraction { public abstract create(options?: SendMethodOptions): Promise; /** - * Simulates a transaction execution request and returns a tx object ready to be sent. + * Proves a transaction execution request and returns a tx object ready to be sent. * @param options - optional arguments to be used in the creation of the transaction * @returns The resulting transaction */ - public async simulate(options: SendMethodOptions = {}): Promise { + public async prove(options: SendMethodOptions = {}): Promise { const txRequest = this.txRequest ?? (await this.create(options)); - this.tx = await this.pxe.simulateTx(txRequest, !options.skipPublicSimulation); + this.tx = await this.pxe.proveTx(txRequest, !options.skipPublicSimulation); return this.tx; } @@ -58,7 +58,7 @@ export abstract class BaseContractInteraction { */ public send(options: SendMethodOptions = {}) { const promise = (async () => { - const tx = this.tx ?? (await this.simulate(options)); + const tx = this.tx ?? (await this.prove(options)); return this.pxe.sendTx(tx); })(); diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index 449d76b99a03..ea338b82c628 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -1,7 +1,7 @@ import { type Tx, type TxExecutionRequest, type TxHash, type TxReceipt } from '@aztec/circuit-types'; import { AztecAddress, CompleteAddress, EthAddress } from '@aztec/circuits.js'; import { type L1ContractAddresses } from '@aztec/ethereum'; -import { ABIParameterVisibility, type ContractArtifact, FunctionType } from '@aztec/foundation/abi'; +import { ABIParameterVisibility, type ContractArtifact, type DecodedReturn, FunctionType } from '@aztec/foundation/abi'; import { type NodeInfo } from '@aztec/types/interfaces'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -113,10 +113,10 @@ describe('Contract Class', () => { wallet.createTxExecutionRequest.mockResolvedValue(mockTxRequest); wallet.getContractInstance.mockResolvedValue(contractInstance); wallet.sendTx.mockResolvedValue(mockTxHash); - wallet.viewTx.mockResolvedValue(mockViewResultValue); + wallet.viewTx.mockResolvedValue(mockViewResultValue as any as DecodedReturn); wallet.getTxReceipt.mockResolvedValue(mockTxReceipt); wallet.getNodeInfo.mockResolvedValue(mockNodeInfo); - wallet.simulateTx.mockResolvedValue(mockTx); + wallet.proveTx.mockResolvedValue(mockTx); wallet.getRegisteredAccounts.mockResolvedValue([account]); }); @@ -137,7 +137,7 @@ describe('Contract Class', () => { it('should call view on an unconstrained function', async () => { const fooContract = await Contract.at(contractAddress, defaultArtifact, wallet); - const result = await fooContract.methods.qux(123n).view({ + const result = await fooContract.methods.qux(123n).simulate({ from: account.address, }); expect(wallet.viewTx).toHaveBeenCalledTimes(1); @@ -149,10 +149,4 @@ describe('Contract Class', () => { const fooContract = await Contract.at(contractAddress, defaultArtifact, wallet); await expect(fooContract.methods.qux().create()).rejects.toThrow(); }); - - it('should not call view on a secret or open function', async () => { - const fooContract = await Contract.at(contractAddress, defaultArtifact, wallet); - expect(() => fooContract.methods.bar().view()).toThrow(); - expect(() => fooContract.methods.baz().view()).toThrow(); - }); }); diff --git a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts index 2fb1f6ba3a53..f04d81d25794 100644 --- a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts +++ b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts @@ -1,5 +1,5 @@ -import { type FunctionCall, type TxExecutionRequest } from '@aztec/circuit-types'; -import { type AztecAddress, FunctionData } from '@aztec/circuits.js'; +import { type FunctionCall, PackedArguments, TxExecutionRequest } from '@aztec/circuit-types'; +import { type AztecAddress, FunctionData, TxContext } from '@aztec/circuits.js'; import { type FunctionAbi, FunctionType, encodeArguments } from '@aztec/foundation/abi'; import { type Wallet } from '../account/wallet.js'; @@ -8,10 +8,11 @@ import { BaseContractInteraction, SendMethodOptions } from './base_contract_inte export { SendMethodOptions }; /** - * Represents the options for a view method in a contract function interaction. + * Represents the options for simulating a contract function interaction. * Allows specifying the address from which the view method should be called. + * Disregarded for simulation of public functions */ -export type ViewMethodOptions = { +export type SimulateMethodOptions = { /** * The sender's Aztec address. */ @@ -63,18 +64,48 @@ export class ContractFunctionInteraction extends BaseContractInteraction { } /** - * Execute a view (read-only) transaction on an unconstrained function. - * This method is used to call functions that do not modify the contract state and only return data. - * Throws an error if called on a non-unconstrained function. + * Simulate a transaction and get its return values + * Differs from prove in a few important ways: + * 1. It returns the values of the function execution + * 2. It supports `unconstrained`, `private` and `public` functions + * 3. For `private` execution it: + * 3.a SKIPS the entrypoint and starts directly at the function + * 3.b SKIPS public execution entirely + * 4. For `public` execution it: + * 4.a Removes the `txRequest` value after ended simulation + * 4.b Ignores the `from` in the options + * * @param options - An optional object containing additional configuration for the transaction. - * @returns The result of the view transaction as returned by the contract function. + * @returns The result of the transaction as returned by the contract function. */ - public view(options: ViewMethodOptions = {}) { - if (this.functionDao.functionType !== FunctionType.UNCONSTRAINED) { - throw new Error('Can only call `view` on an unconstrained function.'); + public async simulate(options: SimulateMethodOptions = {}): Promise { + if (this.functionDao.functionType == FunctionType.UNCONSTRAINED) { + return this.wallet.viewTx(this.functionDao.name, this.args, this.contractAddress, options.from); } - const { from } = options; - return this.wallet.viewTx(this.functionDao.name, this.args, this.contractAddress, from); + // TODO: If not unconstrained, we return a size 4 array of fields. + // TODO: It should instead return the correctly decoded value + // TODO: The return type here needs to be fixed! @LHerskind + + if (this.functionDao.functionType == FunctionType.SECRET) { + const nodeInfo = await this.wallet.getNodeInfo(); + const packedArgs = PackedArguments.fromArgs(encodeArguments(this.functionDao, this.args)); + + const txRequest = TxExecutionRequest.from({ + argsHash: packedArgs.hash, + origin: this.contractAddress, + functionData: FunctionData.fromAbi(this.functionDao), + txContext: TxContext.empty(nodeInfo.chainId, nodeInfo.protocolVersion), + packedArguments: [packedArgs], + authWitnesses: [], + }); + const simulatedTx = await this.pxe.simulateTx(txRequest, false, options.from ?? this.wallet.getAddress()); + return simulatedTx.privateReturnValues?.[0]; + } else { + const txRequest = await this.create(); + const simulatedTx = await this.pxe.simulateTx(txRequest, true); + this.txRequest = undefined; + return simulatedTx.publicReturnValues?.[0]; + } } } diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 44ac1f203b79..93cce037db6f 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -193,12 +193,12 @@ export class DeployMethod extends Bas } /** - * Simulate the request. + * Prove the request. * @param options - Deployment options. - * @returns The simulated tx. + * @returns The proven tx. */ - public simulate(options: DeployOptions): Promise { - return super.simulate(options); + public prove(options: DeployOptions): Promise { + return super.prove(options); } /** Return this deployment address. */ diff --git a/yarn-project/aztec.js/src/contract/index.ts b/yarn-project/aztec.js/src/contract/index.ts index b7d5c4b6742a..ef9b2e852f76 100644 --- a/yarn-project/aztec.js/src/contract/index.ts +++ b/yarn-project/aztec.js/src/contract/index.ts @@ -6,8 +6,8 @@ * * The {@link Contract} class is the main class in this module, and provides static methods for deploying * a contract or interacting with an already deployed one. The `methods` property of the contract instance - * provides access to private, public, and view methods, that can be invoked in a transaction via `send()`, - * or can be queried via `view()`. + * provides access to private, public, and simulate methods, that can be invoked in a transaction via `send()`, + * or can be queried via `simulate()`. * * ```ts * const contract = await Contract.deploy(wallet, MyContractArtifact, [...constructorArgs]).send().deployed(); @@ -17,7 +17,7 @@ * ```ts * const contract = await Contract.at(address, MyContractArtifact, wallet); * await contract.methods.mint(1000, owner).send().wait(); - * console.log(`Total supply is now ${await contract.methods.totalSupply().view()}`); + * console.log(`Total supply is now ${await contract.methods.totalSupply().simulate()}`); * ``` * * The result of calling a method in a contract instance, such as `contract.methods.mint(1000, owner)` diff --git a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts b/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts index 1aacaf16691c..3d82761b62e4 100644 --- a/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts +++ b/yarn-project/aztec.js/src/rpc_clients/pxe_client.ts @@ -8,6 +8,7 @@ import { Note, NullifierMembershipWitness, type PXE, + SimulatedTx, Tx, TxEffect, TxExecutionRequest, @@ -53,7 +54,7 @@ export const createPXEClient = (url: string, fetch = makeFetch([1, 2, 3], false) TxExecutionRequest, TxHash, }, - { Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, + { Tx, SimulatedTx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, false, 'pxe', fetch, diff --git a/yarn-project/aztec.js/src/wallet/account_wallet.ts b/yarn-project/aztec.js/src/wallet/account_wallet.ts index 9d216d3ba270..b75c81fca707 100644 --- a/yarn-project/aztec.js/src/wallet/account_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/account_wallet.ts @@ -161,7 +161,7 @@ export class AccountWallet extends BaseWallet { messageHash, ]); - const [isValidInPrivate, isValidInPublic] = await interaction.view(); + const [isValidInPrivate, isValidInPublic] = (await interaction.simulate()) as [boolean, boolean]; return { isValidInPrivate, isValidInPublic }; } diff --git a/yarn-project/aztec.js/src/wallet/base_wallet.ts b/yarn-project/aztec.js/src/wallet/base_wallet.ts index 76f9987c3a46..e5d5775eaa94 100644 --- a/yarn-project/aztec.js/src/wallet/base_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/base_wallet.ts @@ -7,6 +7,7 @@ import { type LogFilter, type NoteFilter, type PXE, + type SimulatedTx, type SyncStatus, type Tx, type TxEffect, @@ -101,8 +102,11 @@ export abstract class BaseWallet implements Wallet { getContracts(): Promise { return this.pxe.getContracts(); } - simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise { - return this.pxe.simulateTx(txRequest, simulatePublic); + proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise { + return this.pxe.proveTx(txRequest, simulatePublic); + } + simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean, msgSender: AztecAddress): Promise { + return this.pxe.simulateTx(txRequest, simulatePublic, msgSender); } sendTx(tx: Tx): Promise { return this.pxe.sendTx(tx); diff --git a/yarn-project/aztec/src/examples/token.ts b/yarn-project/aztec/src/examples/token.ts index 975692b412d9..3dfcba2666f6 100644 --- a/yarn-project/aztec/src/examples/token.ts +++ b/yarn-project/aztec/src/examples/token.ts @@ -75,7 +75,7 @@ async function main() { await tokenAlice.methods.redeem_shield(alice, ALICE_MINT_BALANCE, aliceSecret).send().wait(); logger(`${ALICE_MINT_BALANCE} tokens were successfully minted and redeemed by Alice`); - const balanceAfterMint = await tokenAlice.methods.balance_of_private(alice).view(); + const balanceAfterMint = await tokenAlice.methods.balance_of_private(alice).simulate(); logger(`Tokens successfully minted. New Alice's balance: ${balanceAfterMint}`); // We will now transfer tokens from Alice to Bob @@ -83,10 +83,10 @@ async function main() { await tokenAlice.methods.transfer(alice, bob, TRANSFER_AMOUNT, 0).send().wait(); // Check the new balances - const aliceBalance = await tokenAlice.methods.balance_of_private(alice).view(); + const aliceBalance = await tokenAlice.methods.balance_of_private(alice).simulate(); logger(`Alice's balance ${aliceBalance}`); - const bobBalance = await tokenBob.methods.balance_of_private(bob).view(); + const bobBalance = await tokenBob.methods.balance_of_private(bob).simulate(); logger(`Bob's balance ${bobBalance}`); } diff --git a/yarn-project/circuit-types/src/interfaces/aztec-node.ts b/yarn-project/circuit-types/src/interfaces/aztec-node.ts index d19c1e599588..918630b042eb 100644 --- a/yarn-project/circuit-types/src/interfaces/aztec-node.ts +++ b/yarn-project/circuit-types/src/interfaces/aztec-node.ts @@ -7,6 +7,7 @@ import { type PUBLIC_DATA_TREE_HEIGHT, } from '@aztec/circuits.js'; import { type L1ContractAddresses } from '@aztec/ethereum'; +import { type ProcessReturnValues } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type Fr } from '@aztec/foundation/fields'; import { type ContractClassPublic, type ContractInstanceWithAddress } from '@aztec/types/contracts'; @@ -282,7 +283,7 @@ export interface AztecNode { * This currently just checks that the transaction execution succeeds. * @param tx - The transaction to simulate. **/ - simulatePublicCalls(tx: Tx): Promise; + simulatePublicCalls(tx: Tx): Promise; /** * Updates the configuration of this node. diff --git a/yarn-project/circuit-types/src/interfaces/pxe.ts b/yarn-project/circuit-types/src/interfaces/pxe.ts index 7c993677ba86..ab72749fe784 100644 --- a/yarn-project/circuit-types/src/interfaces/pxe.ts +++ b/yarn-project/circuit-types/src/interfaces/pxe.ts @@ -14,7 +14,7 @@ import { type L2Block } from '../l2_block.js'; import { type GetUnencryptedLogsResponse, type LogFilter } from '../logs/index.js'; import { type ExtendedNote } from '../notes/index.js'; import { type NoteFilter } from '../notes/note_filter.js'; -import { type Tx, type TxHash, type TxReceipt } from '../tx/index.js'; +import { type SimulatedTx, type Tx, type TxHash, type TxReceipt } from '../tx/index.js'; import { type TxEffect } from '../tx_effect.js'; import { type TxExecutionRequest } from '../tx_execution_request.js'; import { type SyncStatus } from './sync-status.js'; @@ -145,11 +145,32 @@ export interface PXE { * @throws If the code for the functions executed in this transaction has not been made available via `addContracts`. * Also throws if simulatePublic is true and public simulation reverts. */ - simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise; + proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise; + + /** + * Simulates a transaction based on the provided preauthenticated execution request. + * This will run a local simulation of private execution (and optionally of public as well), assemble + * the zero-knowledge proof for the private execution, and return the transaction object along + * with simulation results (return values). + * + * + * Note that this is used with `ContractFunctionInteraction::simulateTx` to bypass certain checks. + * In that case, the transaction returned is only potentially ready to be sent to the network for execution. + * + * + * @param txRequest - An authenticated tx request ready for simulation + * @param simulatePublic - Whether to simulate the public part of the transaction. + * @param msgSender - (Optional) The message sender to use for the simulation. + * @returns A simulated transaction object that includes a transaction that is potentially ready + * to be sent to the network for execution, along with public and private return values. + * @throws If the code for the functions executed in this transaction has not been made available via `addContracts`. + * Also throws if simulatePublic is true and public simulation reverts. + */ + simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean, msgSender?: AztecAddress): Promise; /** * Sends a transaction to an Aztec node to be broadcasted to the network and mined. - * @param tx - The transaction as created via `simulateTx`. + * @param tx - The transaction as created via `proveTx`. * @returns A hash of the transaction, used to identify it. */ sendTx(tx: Tx): Promise; diff --git a/yarn-project/circuit-types/src/mocks.ts b/yarn-project/circuit-types/src/mocks.ts index cb9808eaaadd..760128c49efa 100644 --- a/yarn-project/circuit-types/src/mocks.ts +++ b/yarn-project/circuit-types/src/mocks.ts @@ -7,7 +7,7 @@ import { computeContractClassId, getContractClassFromArtifact, } from '@aztec/circuits.js'; -import { type ContractArtifact } from '@aztec/foundation/abi'; +import { type ContractArtifact, type DecodedReturn } from '@aztec/foundation/abi'; import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { randomBytes } from '@aztec/foundation/crypto'; @@ -19,7 +19,7 @@ import { EncryptedL2Log } from './logs/encrypted_l2_log.js'; import { EncryptedFunctionL2Logs, EncryptedTxL2Logs, Note, UnencryptedTxL2Logs } from './logs/index.js'; import { makePrivateKernelTailCircuitPublicInputs, makePublicCallRequest } from './mocks_to_purge.js'; import { ExtendedNote } from './notes/index.js'; -import { Tx, TxHash } from './tx/index.js'; +import { SimulatedTx, Tx, TxHash } from './tx/index.js'; /** * Testing utility to create empty logs composed from a single empty log. @@ -54,6 +54,12 @@ export const mockTx = (seed = 1, logs = true) => { return tx; }; +export const mockSimulatedTx = (seed = 1, logs = true) => { + const tx = mockTx(seed, logs); + const dec: DecodedReturn = [1n, 2n, 3n, 4n]; + return new SimulatedTx(tx, dec, dec); +}; + export const randomContractArtifact = (): ContractArtifact => ({ name: randomBytes(4).toString('hex'), functions: [], diff --git a/yarn-project/circuit-types/src/tx/index.ts b/yarn-project/circuit-types/src/tx/index.ts index f1ca9d6f8052..114cb41ab57f 100644 --- a/yarn-project/circuit-types/src/tx/index.ts +++ b/yarn-project/circuit-types/src/tx/index.ts @@ -1,4 +1,5 @@ export * from './tx.js'; +export * from './simulated_tx.js'; export * from './tx_hash.js'; export * from './tx_receipt.js'; export * from './processed_tx.js'; diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.test.ts b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts new file mode 100644 index 000000000000..29cc00194779 --- /dev/null +++ b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts @@ -0,0 +1,9 @@ +import { mockSimulatedTx } from '../mocks.js'; +import { SimulatedTx } from './simulated_tx.js'; + +describe('simulated_tx', () => { + it('convert to and from json', () => { + const simulatedTx = mockSimulatedTx(); + expect(SimulatedTx.fromJSON(simulatedTx.toJSON())).toEqual(simulatedTx); + }); +}); diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.ts b/yarn-project/circuit-types/src/tx/simulated_tx.ts new file mode 100644 index 000000000000..febf33cdfb45 --- /dev/null +++ b/yarn-project/circuit-types/src/tx/simulated_tx.ts @@ -0,0 +1,68 @@ +import { AztecAddress } from '@aztec/circuits.js'; +import { type ProcessReturnValues } from '@aztec/foundation/abi'; + +import { Tx } from './tx.js'; + +export class SimulatedTx { + constructor( + public tx: Tx, + public privateReturnValues?: ProcessReturnValues, + public publicReturnValues?: ProcessReturnValues, + ) {} + + /** + * Convert a SimulatedTx class object to a plain JSON object. + * @returns A plain object with SimulatedTx properties. + */ + public toJSON() { + const returnToJson = (data: ProcessReturnValues): string => { + const replacer = (key: string, value: any): any => { + if (typeof value === 'bigint') { + return value.toString() + 'n'; // Indicate bigint with "n" + } else if (value instanceof AztecAddress) { + return value.toString(); + } else { + return value; + } + }; + return JSON.stringify(data, replacer); + }; + + return { + tx: this.tx.toJSON(), + privateReturnValues: returnToJson(this.privateReturnValues), + publicReturnValues: returnToJson(this.publicReturnValues), + }; + } + + /** + * Convert a plain JSON object to a Tx class object. + * @param obj - A plain Tx JSON object. + * @returns A Tx class object. + */ + public static fromJSON(obj: any) { + const returnFromJson = (json: string): ProcessReturnValues => { + if (json == undefined) { + return json; + } + const reviver = (key: string, value: any): any => { + if (typeof value === 'string') { + if (value.match(/\d+n$/)) { + // Detect bigint serialization + return BigInt(value.slice(0, -1)); + } else if (value.match(/^0x[a-fA-F0-9]{64}$/)) { + return AztecAddress.fromString(value); + } + } + return value; + }; + return JSON.parse(json, reviver); + }; + + const tx = Tx.fromJSON(obj.tx); + const privateReturnValues = returnFromJson(obj.privateReturnValues); + const publicReturnValues = returnFromJson(obj.publicReturnValues); + + return new SimulatedTx(tx, privateReturnValues, publicReturnValues); + } +} diff --git a/yarn-project/end-to-end/src/benchmarks/utils.ts b/yarn-project/end-to-end/src/benchmarks/utils.ts index 0841a9725c89..4f2cc4362dae 100644 --- a/yarn-project/end-to-end/src/benchmarks/utils.ts +++ b/yarn-project/end-to-end/src/benchmarks/utils.ts @@ -88,7 +88,7 @@ export async function sendTxs( contract: BenchmarkingContract, ): Promise { const calls = times(txCount, index => makeCall(index, context, contract)); - await Promise.all(calls.map(call => call.simulate({ skipPublicSimulation: true }))); + await Promise.all(calls.map(call => call.prove({ skipPublicSimulation: true }))); const sentTxs = calls.map(call => call.send()); // Awaiting txHash waits until the aztec node has received the tx into its p2p pool diff --git a/yarn-project/end-to-end/src/docs_examples.test.ts b/yarn-project/end-to-end/src/docs_examples.test.ts index d6a754ad83df..07512e922174 100644 --- a/yarn-project/end-to-end/src/docs_examples.test.ts +++ b/yarn-project/end-to-end/src/docs_examples.test.ts @@ -43,9 +43,9 @@ describe('docs_examples', () => { const _tx = await contract.methods.mint_public(wallet.getAddress(), 1).send().wait(); // docs:end:send_transaction - // docs:start:call_view_function - const balance = await contract.methods.balance_of_public(wallet.getAddress()).view(); + // docs:start:simulate_function + const balance = await contract.methods.balance_of_public(wallet.getAddress()).simulate(); expect(balance).toEqual(1n); - // docs:end:call_view_function + // docs:end:simulate_function }, 120_000); }); diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index 409c4598db04..2091acb648a0 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -82,7 +82,7 @@ describe('e2e_2_pxes', () => { // Then check the balance const contractWithWallet = await TokenContract.at(tokenAddress, wallet); - const balance = await contractWithWallet.methods.balance_of_private(owner).view({ from: owner }); + const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner }); logger(`Account ${owner} balance: ${balance}`); expect(balance).toBe(expectedBalance); }; diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index 0d44c5603c56..fc266a36a243 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -60,7 +60,7 @@ function itShouldBehaveLikeAnAccountContract( const accountAddress = wallet.getCompleteAddress(); const invalidWallet = await walletAt(context.pxe, getAccountContract(GrumpkinScalar.random()), accountAddress); const childWithInvalidWallet = await ChildContract.at(child.address, invalidWallet); - await expect(childWithInvalidWallet.methods.value(42).simulate()).rejects.toThrow(/Cannot satisfy constraint.*/); + await expect(childWithInvalidWallet.methods.value(42).prove()).rejects.toThrow(/Cannot satisfy constraint.*/); }); }); } diff --git a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts index c4742bce15c0..a9c2df4e4118 100644 --- a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts +++ b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts @@ -27,19 +27,19 @@ describe('e2e_avm_simulator', () => { describe('Storage', () => { // FIX: Enable once the contract function works. // it('Read immutable (initialized) storage (Field)', async () => { - // expect(await avmContact.methods.view_storage_immutable().view()).toEqual(42n); + // expect(await avmContact.methods.view_storage_immutable().simulate()).toEqual(42n); // }); it('Modifies storage (Field)', async () => { await avmContact.methods.set_storage_single(20n).send().wait(); - expect(await avmContact.methods.view_storage_single().view()).toEqual(20n); + expect(await avmContact.methods.view_storage_single().simulate()).toEqual(20n); }); it('Modifies storage (Map)', async () => { const address = AztecAddress.fromBigInt(9090n); await avmContact.methods.set_storage_map(address, 100).send().wait(); await avmContact.methods.add_storage_map(address, 100).send().wait(); - expect(await avmContact.methods.view_storage_map(address).view()).toEqual(200n); + expect(await avmContact.methods.view_storage_map(address).simulate()).toEqual(200n); }); }); diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts index 8c1fe2ec1914..622fb312b721 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract.test.ts @@ -129,7 +129,7 @@ describe('e2e_blacklist_token_contract', () => { await cheatCodes.aztec.warp(time + 200); await slowUpdateTreeSimulator.commit(); - const roleLeaf = await slowTree.methods.un_read_leaf_at(asset.address, accounts[0].address).view(); + const roleLeaf = await slowTree.methods.un_read_leaf_at(asset.address, accounts[0].address).simulate(); expect(roleLeaf['next_change']).toBeGreaterThan(0n); expect(roleLeaf['before']).toEqual(0n); expect(roleLeaf['after']).toEqual(4n); @@ -162,7 +162,7 @@ describe('e2e_blacklist_token_contract', () => { const newMinter = accounts[0].address; const newRoles = 2n + 4n; - const beforeLeaf = await slowTree.methods.un_read_leaf_at(asset.address, newMinter).view(); + const beforeLeaf = await slowTree.methods.un_read_leaf_at(asset.address, newMinter).simulate(); // eslint-disable-next-line camelcase expect(beforeLeaf['next_change']).toBeGreaterThan(0n); expect(beforeLeaf['before']).toEqual(0n); @@ -176,7 +176,7 @@ describe('e2e_blacklist_token_contract', () => { await asset.methods.update_roles(newMinter, newRoles).send().wait(); await slowUpdateTreeSimulator.commit(); - const afterLeaf = await slowTree.methods.un_read_leaf_at(asset.address, newMinter).view(); + const afterLeaf = await slowTree.methods.un_read_leaf_at(asset.address, newMinter).simulate(); expect(afterLeaf['next_change']).toBeGreaterThan(beforeLeaf['next_change']); expect(afterLeaf['before']).toEqual(4n); expect(afterLeaf['after']).toEqual(newRoles); @@ -189,7 +189,7 @@ describe('e2e_blacklist_token_contract', () => { const newAdmin = accounts[1].address; const newRoles = 4n; - let v = await slowTree.methods.un_read_leaf_at(asset.address, newAdmin).view(); + let v = await slowTree.methods.un_read_leaf_at(asset.address, newAdmin).simulate(); // eslint-disable-next-line camelcase expect(v).toEqual({ next_change: 0n, before: 0n, after: 0n }); @@ -201,7 +201,7 @@ describe('e2e_blacklist_token_contract', () => { await asset.methods.update_roles(newAdmin, newRoles).send().wait(); await slowUpdateTreeSimulator.commit(); - v = await slowTree.methods.un_read_leaf_at(asset.address, newAdmin).view(); + v = await slowTree.methods.un_read_leaf_at(asset.address, newAdmin).simulate(); expect(v['next_change']).toBeGreaterThan(0n); expect(v['before']).toEqual(0n); expect(v['after']).toEqual(newRoles); @@ -216,7 +216,7 @@ describe('e2e_blacklist_token_contract', () => { const newRoles = 0n; const currentRoles = 4n; - const beforeLeaf = await slowTree.methods.un_read_leaf_at(asset.address, actor).view(); + const beforeLeaf = await slowTree.methods.un_read_leaf_at(asset.address, actor).simulate(); // eslint-disable-next-line camelcase expect(beforeLeaf['next_change']).toBeGreaterThan(0n); expect(beforeLeaf['before']).toEqual(0n); @@ -230,7 +230,7 @@ describe('e2e_blacklist_token_contract', () => { await asset.methods.update_roles(actor, newRoles).send().wait(); await slowUpdateTreeSimulator.commit(); - const afterLeaf = await slowTree.methods.un_read_leaf_at(asset.address, actor).view(); + const afterLeaf = await slowTree.methods.un_read_leaf_at(asset.address, actor).simulate(); expect(afterLeaf['next_change']).toBeGreaterThan(beforeLeaf['next_change']); expect(afterLeaf['before']).toEqual(currentRoles); expect(afterLeaf['after']).toEqual(newRoles); @@ -240,7 +240,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('Add account[3] to blacklist', async () => { - let v = await slowTree.methods.un_read_leaf_at(asset.address, accounts[3].address).view(); + let v = await slowTree.methods.un_read_leaf_at(asset.address, accounts[3].address).simulate(); // eslint-disable-next-line camelcase expect(v).toEqual({ next_change: 0n, before: 0n, after: 0n }); @@ -252,7 +252,7 @@ describe('e2e_blacklist_token_contract', () => { await asset.methods.update_roles(accounts[3].address, 1n).send().wait(); await slowUpdateTreeSimulator.commit(); - v = await slowTree.methods.un_read_leaf_at(asset.address, accounts[3].address).view(); + v = await slowTree.methods.un_read_leaf_at(asset.address, accounts[3].address).simulate(); expect(v['next_change']).toBeGreaterThan(0n); expect(v['before']).toEqual(0n); expect(v['after']).toEqual(1n); @@ -264,7 +264,7 @@ describe('e2e_blacklist_token_contract', () => { describe('failure cases', () => { it('Set admin (not admin)', async () => { const account = AztecAddress.random(); - const v = await slowTree.methods.un_read_leaf_at(asset.address, account).view(); + const v = await slowTree.methods.un_read_leaf_at(asset.address, account).simulate(); const newRoles = 4n; // eslint-disable-next-line camelcase expect(v).toEqual({ next_change: 0n, before: 0n, after: 0n }); @@ -272,14 +272,14 @@ describe('e2e_blacklist_token_contract', () => { await wallets[3].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[3].address.toBigInt(), false)), ); - await expect(asset.withWallet(wallets[3]).methods.update_roles(account, newRoles).simulate()).rejects.toThrow( + await expect(asset.withWallet(wallets[3]).methods.update_roles(account, newRoles).prove()).rejects.toThrow( "Assertion failed: caller is not admin 'caller_roles.is_admin'", ); }); it('Revoke minter not as admin', async () => { const adminAccount = accounts[0].address; - const v = await slowTree.methods.un_read_leaf_at(asset.address, adminAccount).view(); + const v = await slowTree.methods.un_read_leaf_at(asset.address, adminAccount).simulate(); const newRoles = 0n; // eslint-disable-next-line camelcase expect(v['next_change']).toBeGreaterThan(0n); @@ -289,9 +289,9 @@ describe('e2e_blacklist_token_contract', () => { await wallets[3].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[3].address.toBigInt(), false)), ); - await expect( - asset.withWallet(wallets[3]).methods.update_roles(adminAccount, newRoles).simulate(), - ).rejects.toThrow("Assertion failed: caller is not admin 'caller_roles.is_admin'"); + await expect(asset.withWallet(wallets[3]).methods.update_roles(adminAccount, newRoles).prove()).rejects.toThrow( + "Assertion failed: caller is not admin 'caller_roles.is_admin'", + ); }); }); }); @@ -303,44 +303,44 @@ describe('e2e_blacklist_token_contract', () => { await asset.methods.mint_public(accounts[0].address, amount).send().wait(); tokenSim.mintPublic(accounts[0].address, amount); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual( + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual( tokenSim.balanceOfPublic(accounts[0].address), ); - expect(await asset.methods.total_supply().view()).toEqual(tokenSim.totalSupply); + expect(await asset.methods.total_supply().simulate()).toEqual(tokenSim.totalSupply); }); describe('failure cases', () => { it('as non-minter', async () => { const amount = 10000n; await expect( - asset.withWallet(wallets[1]).methods.mint_public(accounts[0].address, amount).simulate(), + asset.withWallet(wallets[1]).methods.mint_public(accounts[0].address, amount).prove(), ).rejects.toThrow('Assertion failed: caller is not minter'); }); it('mint >u128 tokens to overflow', async () => { const amount = 2n ** 128n; // U128::max() + 1; - await expect(asset.methods.mint_public(accounts[0].address, amount).simulate()).rejects.toThrow( + await expect(asset.methods.mint_public(accounts[0].address, amount).prove()).rejects.toThrow( BITSIZE_TOO_BIG_ERROR, ); }); it('mint u128', async () => { const amount = 2n ** 128n - tokenSim.balanceOfPublic(accounts[0].address); - await expect(asset.methods.mint_public(accounts[0].address, amount).simulate()).rejects.toThrow( + await expect(asset.methods.mint_public(accounts[0].address, amount).prove()).rejects.toThrow( U128_OVERFLOW_ERROR, ); }); it('mint u128', async () => { const amount = 2n ** 128n - tokenSim.balanceOfPublic(accounts[0].address); - await expect(asset.methods.mint_public(accounts[1].address, amount).simulate()).rejects.toThrow( + await expect(asset.methods.mint_public(accounts[1].address, amount).prove()).rejects.toThrow( U128_OVERFLOW_ERROR, ); }); it('mint to blacklisted entity', async () => { await expect( - asset.withWallet(wallets[1]).methods.mint_public(accounts[3].address, 1n).simulate(), + asset.withWallet(wallets[1]).methods.mint_public(accounts[3].address, 1n).prove(), ).rejects.toThrow("Assertion failed: Blacklisted: Recipient '!to_roles.is_blacklisted'"); }); }); @@ -388,41 +388,39 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(asset.methods.redeem_shield(accounts[0].address, amount, secret).simulate()).rejects.toThrow( + await expect(asset.methods.redeem_shield(accounts[0].address, amount, secret).prove()).rejects.toThrow( `Assertion failed: Cannot return zero notes`, ); }); it('mint_private as non-minter', async () => { - await expect( - asset.withWallet(wallets[1]).methods.mint_private(amount, secretHash).simulate(), - ).rejects.toThrow('Assertion failed: caller is not minter'); + await expect(asset.withWallet(wallets[1]).methods.mint_private(amount, secretHash).prove()).rejects.toThrow( + 'Assertion failed: caller is not minter', + ); }); it('mint >u128 tokens to overflow', async () => { const amount = 2n ** 128n; // U128::max() + 1; - await expect(asset.methods.mint_private(amount, secretHash).simulate()).rejects.toThrow( - BITSIZE_TOO_BIG_ERROR, - ); + await expect(asset.methods.mint_private(amount, secretHash).prove()).rejects.toThrow(BITSIZE_TOO_BIG_ERROR); }); it('mint u128', async () => { // @todo @LHerskind this one don't make sense. It fails because of total supply overflowing. const amount = 2n ** 128n - tokenSim.balanceOfPrivate(accounts[0].address); expect(amount).toBeLessThan(2n ** 128n); - await expect(asset.methods.mint_private(amount, secretHash).simulate()).rejects.toThrow(U128_OVERFLOW_ERROR); + await expect(asset.methods.mint_private(amount, secretHash).prove()).rejects.toThrow(U128_OVERFLOW_ERROR); }); it('mint u128', async () => { const amount = 2n ** 128n - tokenSim.totalSupply; - await expect(asset.methods.mint_private(amount, secretHash).simulate()).rejects.toThrow(U128_OVERFLOW_ERROR); + await expect(asset.methods.mint_private(amount, secretHash).prove()).rejects.toThrow(U128_OVERFLOW_ERROR); }); it('mint and try to redeem at blacklist', async () => { await wallets[3].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[3].address.toBigInt(), true)), ); - await expect(asset.methods.redeem_shield(accounts[3].address, amount, secret).simulate()).rejects.toThrow( + await expect(asset.methods.redeem_shield(accounts[3].address, amount, secret).prove()).rejects.toThrow( "Assertion failed: Blacklisted: Recipient '!to_roles.is_blacklisted'", ); }); @@ -433,7 +431,7 @@ describe('e2e_blacklist_token_contract', () => { describe('Transfer', () => { describe('public', () => { it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, 0).send().wait(); @@ -442,7 +440,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('transfer to self', async () => { - const balance = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_public(accounts[0].address, accounts[0].address, amount, 0).send().wait(); @@ -451,7 +449,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const nonce = Fr.random(); @@ -479,38 +477,38 @@ describe('e2e_blacklist_token_contract', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = 0; await expect( - asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).simulate(), + asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).prove(), ).rejects.toThrow(U128_UNDERFLOW_ERROR); }); it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 - 1n; const nonce = 1; await expect( - asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).simulate(), + asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).prove(), ).rejects.toThrow('Assertion failed: invalid nonce'); }); it('transfer on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); await expect( asset .withWallet(wallets[1]) .methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce) - .simulate(), + .prove(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_public(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_public(accounts[1].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -523,15 +521,15 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait(); // Perform the transfer - await expect(action.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR); + await expect(action.prove()).rejects.toThrow(U128_UNDERFLOW_ERROR); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_public(accounts[1].address).view()).toEqual(balance1); + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_public(accounts[1].address).simulate()).toEqual(balance1); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_public(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_public(accounts[1].address).simulate(); const amount = balance0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -544,15 +542,15 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].setPublicAuthWit({ caller: accounts[0].address, action }, true).send().wait(); // Perform the transfer - await expect(action.simulate()).rejects.toThrow('Assertion failed: Message not authorized by account'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Message not authorized by account'); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_public(accounts[1].address).view()).toEqual(balance1); + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_public(accounts[1].address).simulate()).toEqual(balance1); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_public(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_public(accounts[1].address).simulate(); const amount = balance0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -564,10 +562,10 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].setPublicAuthWit({ caller: accounts[0].address, action }, true).send().wait(); // Perform the transfer - await expect(action.simulate()).rejects.toThrow('Assertion failed: Message not authorized by account'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Message not authorized by account'); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_public(accounts[1].address).view()).toEqual(balance1); + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_public(accounts[1].address).simulate()).toEqual(balance1); }); it.skip('transfer into account to overflow', () => { @@ -579,13 +577,13 @@ describe('e2e_blacklist_token_contract', () => { it('transfer from a blacklisted account', async () => { await expect( - asset.methods.transfer_public(accounts[3].address, accounts[0].address, 1n, 0n).simulate(), + asset.methods.transfer_public(accounts[3].address, accounts[0].address, 1n, 0n).prove(), ).rejects.toThrow("Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'"); }); it('transfer to a blacklisted account', async () => { await expect( - asset.methods.transfer_public(accounts[0].address, accounts[3].address, 1n, 0n).simulate(), + asset.methods.transfer_public(accounts[0].address, accounts[3].address, 1n, 0n).prove(), ).rejects.toThrow("Assertion failed: Blacklisted: Recipient '!to_roles.is_blacklisted'"); }); }); @@ -593,7 +591,7 @@ describe('e2e_blacklist_token_contract', () => { describe('private', () => { it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await wallets[0].addCapsule( @@ -607,7 +605,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('transfer to self', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await wallets[0].addCapsule( @@ -621,7 +619,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -665,7 +663,7 @@ describe('e2e_blacklist_token_contract', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); await wallets[0].addCapsule( @@ -675,12 +673,12 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); await expect( - asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 0).simulate(), + asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 0).prove(), ).rejects.toThrow('Assertion failed: Balance too low'); }); it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); await wallets[0].addCapsule( @@ -690,13 +688,13 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); await expect( - asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 1).simulate(), + asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 1).prove(), ).rejects.toThrow('Assertion failed: invalid nonce'); }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_private(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_private(accounts[1].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -718,9 +716,9 @@ describe('e2e_blacklist_token_contract', () => { ); // Perform the transfer - await expect(action.simulate()).rejects.toThrow('Assertion failed: Balance too low'); - expect(await asset.methods.balance_of_private(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_private(accounts[1].address).view()).toEqual(balance1); + await expect(action.prove()).rejects.toThrow('Assertion failed: Balance too low'); + expect(await asset.methods.balance_of_private(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_private(accounts[1].address).simulate()).toEqual(balance1); }); it.skip('transfer into account to overflow', () => { @@ -731,7 +729,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('transfer on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -753,13 +751,13 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${messageHash.toString()}`, ); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -784,10 +782,10 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${expectedMessageHash.toString()}`, ); - expect(await asset.methods.balance_of_private(accounts[0].address).view()).toEqual(balance0); + expect(await asset.methods.balance_of_private(accounts[0].address).simulate()).toEqual(balance0); }); it('transfer from a blacklisted account', async () => { @@ -797,9 +795,9 @@ describe('e2e_blacklist_token_contract', () => { await wallets[3].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[3].address.toBigInt(), true)), ); - await expect( - asset.methods.transfer(accounts[3].address, accounts[0].address, 1n, 0).simulate(), - ).rejects.toThrow("Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'"); + await expect(asset.methods.transfer(accounts[3].address, accounts[0].address, 1n, 0).prove()).rejects.toThrow( + "Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'", + ); }); it('transfer to a blacklisted account', async () => { @@ -809,9 +807,9 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect( - asset.methods.transfer(accounts[0].address, accounts[3].address, 1n, 0).simulate(), - ).rejects.toThrow("Assertion failed: Blacklisted: Recipient '!to_roles.is_blacklisted'"); + await expect(asset.methods.transfer(accounts[0].address, accounts[3].address, 1n, 0).prove()).rejects.toThrow( + "Assertion failed: Blacklisted: Recipient '!to_roles.is_blacklisted'", + ); }); }); }); @@ -826,7 +824,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('on behalf of self', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub / 2n; expect(amount).toBeGreaterThan(0n); @@ -844,7 +842,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('on behalf of other', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -875,27 +873,27 @@ describe('e2e_blacklist_token_contract', () => { describe('failure cases', () => { it('on behalf of self (more than balance)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; expect(amount).toBeGreaterThan(0n); - await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 0).simulate()).rejects.toThrow( + await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 0).prove()).rejects.toThrow( U128_UNDERFLOW_ERROR, ); }); it('on behalf of self (invalid nonce)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; expect(amount).toBeGreaterThan(0n); - await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 1).simulate()).rejects.toThrow( + await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 1).prove()).rejects.toThrow( 'Assertion failed: invalid nonce', ); }); it('on behalf of other (more than balance)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -904,11 +902,11 @@ describe('e2e_blacklist_token_contract', () => { const action = asset.withWallet(wallets[1]).methods.shield(accounts[0].address, amount, secretHash, nonce); await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait(); - await expect(action.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR); + await expect(action.prove()).rejects.toThrow(U128_UNDERFLOW_ERROR); }); it('on behalf of other (wrong designated caller)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -917,17 +915,17 @@ describe('e2e_blacklist_token_contract', () => { const action = asset.withWallet(wallets[2]).methods.shield(accounts[0].address, amount, secretHash, nonce); await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait(); - await expect(action.simulate()).rejects.toThrow('Assertion failed: Message not authorized by account'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Message not authorized by account'); }); it('on behalf of other (without approval)', async () => { - const balance = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); await expect( - asset.withWallet(wallets[1]).methods.shield(accounts[0].address, amount, secretHash, nonce).simulate(), + asset.withWallet(wallets[1]).methods.shield(accounts[0].address, amount, secretHash, nonce).prove(), ).rejects.toThrow(`Assertion failed: Message not authorized by account`); }); @@ -936,7 +934,7 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[3].address.toBigInt(), true)), ); await expect( - asset.withWallet(wallets[3]).methods.shield(accounts[3].address, 1n, secretHash, 0).simulate(), + asset.withWallet(wallets[3]).methods.shield(accounts[3].address, 1n, secretHash, 0).prove(), ).rejects.toThrow("Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'"); }); }); @@ -944,7 +942,7 @@ describe('e2e_blacklist_token_contract', () => { describe('Unshielding', () => { it('on behalf of self', async () => { - const balancePriv = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv / 2n; expect(amount).toBeGreaterThan(0n); @@ -956,7 +954,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('on behalf of other', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -989,7 +987,7 @@ describe('e2e_blacklist_token_contract', () => { describe('failure cases', () => { it('on behalf of self (more than balance)', async () => { - const balancePriv = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); @@ -1001,12 +999,12 @@ describe('e2e_blacklist_token_contract', () => { ); await expect( - asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 0).simulate(), + asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 0).prove(), ).rejects.toThrow('Assertion failed: Balance too low'); }); it('on behalf of self (invalid nonce)', async () => { - const balancePriv = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); @@ -1018,12 +1016,12 @@ describe('e2e_blacklist_token_contract', () => { ); await expect( - asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 1).simulate(), + asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 1).prove(), ).rejects.toThrow('Assertion failed: invalid nonce'); }); it('on behalf of other (more than balance)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1044,11 +1042,11 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(action.simulate()).rejects.toThrow('Assertion failed: Balance too low'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Balance too low'); }); it('on behalf of other (invalid designated caller)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1075,7 +1073,7 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${expectedMessageHash.toString()}`, ); }); @@ -1087,9 +1085,9 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[3].address.toBigInt(), true)), ); - await expect( - asset.methods.unshield(accounts[3].address, accounts[0].address, 1n, 0).simulate(), - ).rejects.toThrow("Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'"); + await expect(asset.methods.unshield(accounts[3].address, accounts[0].address, 1n, 0).prove()).rejects.toThrow( + "Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'", + ); }); it('unshield to blacklisted account', async () => { @@ -1099,9 +1097,9 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect( - asset.methods.unshield(accounts[0].address, accounts[3].address, 1n, 0).simulate(), - ).rejects.toThrow("Assertion failed: Blacklisted: Recipient '!to_roles.is_blacklisted'"); + await expect(asset.methods.unshield(accounts[0].address, accounts[3].address, 1n, 0).prove()).rejects.toThrow( + "Assertion failed: Blacklisted: Recipient '!to_roles.is_blacklisted'", + ); }); }); }); @@ -1109,7 +1107,7 @@ describe('e2e_blacklist_token_contract', () => { describe('Burn', () => { describe('public', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.burn_public(accounts[0].address, amount, 0).send().wait(); @@ -1118,7 +1116,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const nonce = Fr.random(); @@ -1138,35 +1136,35 @@ describe('e2e_blacklist_token_contract', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = 0; - await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).simulate()).rejects.toThrow( + await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).prove()).rejects.toThrow( U128_UNDERFLOW_ERROR, ); }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); const nonce = 1; - await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).simulate()).rejects.toThrow( + await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).prove()).rejects.toThrow( 'Assertion failed: invalid nonce', ); }); it('burn on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); await expect( - asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).simulate(), + asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).prove(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1175,11 +1173,11 @@ describe('e2e_blacklist_token_contract', () => { const action = asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce); await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait(); - await expect(action.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR); + await expect(action.prove()).rejects.toThrow(U128_UNDERFLOW_ERROR); }); it('burn on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1189,12 +1187,12 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].setPublicAuthWit({ caller: accounts[0].address, action }, true).send().wait(); await expect( - asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).simulate(), + asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).prove(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); }); it('burn from blacklisted account', async () => { - await expect(asset.methods.burn_public(accounts[3].address, 1n, 0).simulate()).rejects.toThrow( + await expect(asset.methods.burn_public(accounts[3].address, 1n, 0).prove()).rejects.toThrow( "Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'", ); }); @@ -1203,7 +1201,7 @@ describe('e2e_blacklist_token_contract', () => { describe('private', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await wallets[0].addCapsule( @@ -1214,7 +1212,7 @@ describe('e2e_blacklist_token_contract', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1243,31 +1241,31 @@ describe('e2e_blacklist_token_contract', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); await wallets[0].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(asset.methods.burn(accounts[0].address, amount, 0).simulate()).rejects.toThrow( + await expect(asset.methods.burn(accounts[0].address, amount, 0).prove()).rejects.toThrow( 'Assertion failed: Balance too low', ); }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); await wallets[0].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(asset.methods.burn(accounts[0].address, amount, 1).simulate()).rejects.toThrow( + await expect(asset.methods.burn(accounts[0].address, amount, 1).prove()).rejects.toThrow( 'Assertion failed: invalid nonce', ); }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1283,11 +1281,11 @@ describe('e2e_blacklist_token_contract', () => { getMembershipCapsule(await getMembershipProof(accounts[0].address.toBigInt(), true)), ); - await expect(action.simulate()).rejects.toThrow('Assertion failed: Balance too low'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Balance too low'); }); it('burn on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1304,13 +1302,13 @@ describe('e2e_blacklist_token_contract', () => { action.request(), ); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${messageHash.toString()}`, ); }); it('on behalf of other (invalid designated caller)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1330,7 +1328,7 @@ describe('e2e_blacklist_token_contract', () => { const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action }); await wallets[2].addAuthWitness(witness); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${expectedMessageHash.toString()}`, ); }); @@ -1339,7 +1337,7 @@ describe('e2e_blacklist_token_contract', () => { await wallets[0].addCapsule( getMembershipCapsule(await getMembershipProof(accounts[3].address.toBigInt(), true)), ); - await expect(asset.methods.burn(accounts[3].address, 1n, 0).simulate()).rejects.toThrow( + await expect(asset.methods.burn(accounts[3].address, 1n, 0).prove()).rejects.toThrow( "Assertion failed: Blacklisted: Sender '!from_roles.is_blacklisted'", ); }); diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index cf7208ccb1f5..bbc877c75575 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -57,7 +57,7 @@ describe('e2e_block_building', () => { skipClassRegistration: true, skipPublicDeployment: true, }); - await methods[i].simulate({}); + await methods[i].prove({}); } // Send them simultaneously to be picked up by the sequencer @@ -95,8 +95,8 @@ describe('e2e_block_building', () => { [minter.getCompleteAddress(), true], ); - await deployer.simulate({}); - await callInteraction.simulate({ + await deployer.prove({}); + await callInteraction.prove({ // we have to skip simulation of public calls simulation is done on individual transactions // and the tx deploying the contract might go in the same block as this one skipPublicSimulation: true, @@ -129,7 +129,7 @@ describe('e2e_block_building', () => { const nullifier = Fr.random(); const calls = times(2, () => contract.methods.emit_nullifier(nullifier)); for (const call of calls) { - await call.simulate(); + await call.prove(); } const [tx1, tx2] = calls.map(call => call.send()); await expectXorTx(tx1, tx2); @@ -139,7 +139,7 @@ describe('e2e_block_building', () => { const secret = Fr.random(); const calls = times(2, () => contract.methods.create_nullifier_public(140n, secret)); for (const call of calls) { - await call.simulate(); + await call.prove(); } const [tx1, tx2] = calls.map(call => call.send()); await expectXorTx(tx1, tx2); @@ -162,7 +162,7 @@ describe('e2e_block_building', () => { ]; for (const call of calls) { - await call.simulate(); + await call.prove(); } const [tx1, tx2] = calls.map(call => call.send()); await expectXorTx(tx1, tx2); diff --git a/yarn-project/end-to-end/src/e2e_card_game.test.ts b/yarn-project/end-to-end/src/e2e_card_game.test.ts index 354196882bc0..e92f0988880c 100644 --- a/yarn-project/end-to-end/src/e2e_card_game.test.ts +++ b/yarn-project/end-to-end/src/e2e_card_game.test.ts @@ -142,7 +142,7 @@ describe('e2e_card_game', () => { it('should be able to buy packs', async () => { const seed = 27n; await contract.methods.buy_pack(seed).send().wait(); - const collection = await contract.methods.view_collection_cards(firstPlayer, 0).view({ from: firstPlayer }); + const collection = await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }); const expected = getPackedCards(0, seed); expect(unwrapOptions(collection)).toMatchObject(expected); }, 30_000); @@ -157,7 +157,7 @@ describe('e2e_card_game', () => { contractAsSecondPlayer.methods.buy_pack(seed).send().wait(), ]); firstPlayerCollection = unwrapOptions( - await contract.methods.view_collection_cards(firstPlayer, 0).view({ from: firstPlayer }), + await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }), ); }, 30_000); @@ -174,11 +174,11 @@ describe('e2e_card_game', () => { .wait(), ).rejects.toThrow(`Assertion failed: Cannot return zero notes`); - const collection = await contract.methods.view_collection_cards(firstPlayer, 0).view({ from: firstPlayer }); + const collection = await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }); expect(unwrapOptions(collection)).toHaveLength(1); expect(unwrapOptions(collection)).toMatchObject([firstPlayerCollection[1]]); - expect((await contract.methods.view_game(GAME_ID).view({ from: firstPlayer })) as Game).toMatchObject({ + expect((await contract.methods.view_game(GAME_ID).simulate({ from: firstPlayer })) as Game).toMatchObject({ players: [ { address: firstPlayer, @@ -202,7 +202,7 @@ describe('e2e_card_game', () => { const secondPlayerCollection = unwrapOptions( (await contract.methods .view_collection_cards(secondPlayer, 0) - .view({ from: secondPlayer })) as NoirOption[], + .simulate({ from: secondPlayer })) as NoirOption[], ); await Promise.all([ @@ -218,7 +218,7 @@ describe('e2e_card_game', () => { await contract.methods.start_game(GAME_ID).send().wait(); - expect((await contract.methods.view_game(GAME_ID).view({ from: firstPlayer })) as Game).toMatchObject({ + expect((await contract.methods.view_game(GAME_ID).simulate({ from: firstPlayer })) as Game).toMatchObject({ players: expect.arrayContaining([ { address: firstPlayer, @@ -253,15 +253,15 @@ describe('e2e_card_game', () => { ]); firstPlayerCollection = unwrapOptions( - await contract.methods.view_collection_cards(firstPlayer, 0).view({ from: firstPlayer }), + await contract.methods.view_collection_cards(firstPlayer, 0).simulate({ from: firstPlayer }), ); secondPlayerCollection = unwrapOptions( - await contract.methods.view_collection_cards(secondPlayer, 0).view({ from: secondPlayer }), + await contract.methods.view_collection_cards(secondPlayer, 0).simulate({ from: secondPlayer }), ); thirdPlayerCOllection = unwrapOptions( - await contract.methods.view_collection_cards(thirdPlayer, 0).view({ from: thirdPlayer }), + await contract.methods.view_collection_cards(thirdPlayer, 0).simulate({ from: thirdPlayer }), ); }, 60_000); @@ -270,7 +270,7 @@ describe('e2e_card_game', () => { } async function playGame(playerDecks: { address: AztecAddress; deck: Card[] }[], id = GAME_ID) { - const initialGameState = (await contract.methods.view_game(id).view({ from: firstPlayer })) as Game; + const initialGameState = (await contract.methods.view_game(id).simulate({ from: firstPlayer })) as Game; const players = initialGameState.players.map(player => player.address); const cards = players.map( player => playerDecks.find(playerDeckEntry => playerDeckEntry.address.equals(player))!.deck, @@ -284,7 +284,7 @@ describe('e2e_card_game', () => { } } - const finalGameState = (await contract.methods.view_game(id).view({ from: firstPlayer })) as Game; + const finalGameState = (await contract.methods.view_game(id).simulate({ from: firstPlayer })) as Game; expect(finalGameState.finished).toBe(true); return finalGameState; @@ -315,7 +315,7 @@ describe('e2e_card_game', () => { await contractFor(winner).methods.claim_cards(GAME_ID, game.rounds_cards.map(cardToField)).send().wait(); const winnerCollection = unwrapOptions( - (await contract.methods.view_collection_cards(winner, 0).view({ from: winner })) as NoirOption[], + (await contract.methods.view_collection_cards(winner, 0).simulate({ from: winner })) as NoirOption[], ); const winnerGameDeck = [winnerCollection[0], winnerCollection[3]]; diff --git a/yarn-project/end-to-end/src/e2e_counter_contract.test.ts b/yarn-project/end-to-end/src/e2e_counter_contract.test.ts index 61e562eb3306..7677db89e449 100644 --- a/yarn-project/end-to-end/src/e2e_counter_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_counter_contract.test.ts @@ -32,7 +32,7 @@ describe('e2e_counter_contract', () => { describe('increments', () => { it('counts', async () => { await counterContract.methods.increment(owner).send().wait(); - expect(await counterContract.methods.get_counter(owner).view()).toBe(1n); + expect(await counterContract.methods.get_counter(owner).simulate()).toBe(1n); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts index b05638697a9d..e6f45ed8df57 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts @@ -173,7 +173,7 @@ describe('e2e_cross_chain_messaging', () => { l2Bridge .withWallet(user2Wallet) .methods.claim_private(secretHashForL2MessageConsumption, bridgeAmount, secretForL2MessageConsumption) - .simulate(), + .prove(), ).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); // send the right one - @@ -210,7 +210,7 @@ describe('e2e_cross_chain_messaging', () => { l2Bridge .withWallet(user1Wallet) .methods.exit_to_l1_private(l2Token.address, ethAccount, withdrawAmount, EthAddress.ZERO, nonce) - .simulate(), + .prove(), ).rejects.toThrow(`Unknown auth witness for message hash ${expectedBurnMessageHash.toString()}`); }, 120_000); @@ -250,7 +250,7 @@ describe('e2e_cross_chain_messaging', () => { l2Bridge .withWallet(user2Wallet) .methods.claim_public(ownerAddress, bridgeAmount, secretForL2MessageConsumption) - .simulate(), + .prove(), ).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); }, 120_000); }); 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 494a4bc1b115..1556d2b40ce8 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 @@ -231,12 +231,12 @@ describe('e2e_crowdfunding_and_claim', () => { } // Since the RWT is minted 1:1 with the DNT, the balance of the reward token should be equal to the donation amount - const balanceRWT = await rewardToken.methods.balance_of_public(donorWallets[0].getAddress()).view(); + const balanceRWT = await rewardToken.methods.balance_of_public(donorWallets[0].getAddress()).simulate(); expect(balanceRWT).toEqual(donationAmount); const balanceDNTBeforeWithdrawal = await donationToken.methods .balance_of_private(operatorWallet.getAddress()) - .view(); + .simulate(); expect(balanceDNTBeforeWithdrawal).toEqual(0n); // 4) At last, we withdraw the raised funds from the crowdfunding contract to the operator's address @@ -244,7 +244,7 @@ describe('e2e_crowdfunding_and_claim', () => { const balanceDNTAfterWithdrawal = await donationToken.methods .balance_of_private(operatorWallet.getAddress()) - .view(); + .simulate(); // Operator should have all the DNT now expect(balanceDNTAfterWithdrawal).toEqual(donationAmount); diff --git a/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts b/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts index ac44271c959f..f499b49d88d9 100644 --- a/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts +++ b/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts @@ -209,11 +209,11 @@ describe('e2e_dapp_subscription', () => { const dappPayload = new DefaultDappEntrypoint(aliceAddress, aliceWallet, subscriptionContract.address); const action = counterContract.methods.increment(bobAddress).request(); const txExReq = await dappPayload.createTxExecutionRequest([action]); - const tx = await pxe.simulateTx(txExReq, true); + const tx = await pxe.proveTx(txExReq, true); const sentTx = new SentTx(pxe, pxe.sendTx(tx)); await sentTx.wait(); - expect(await counterContract.methods.get_counter(bobAddress).view()).toBe(1n); + expect(await counterContract.methods.get_counter(bobAddress).simulate()).toBe(1n); await expectMapping( gasBalances, @@ -264,7 +264,7 @@ describe('e2e_dapp_subscription', () => { const dappEntrypoint = new DefaultDappEntrypoint(aliceAddress, aliceWallet, subscriptionContract.address); const action = counterContract.methods.increment(bobAddress).request(); const txExReq = await dappEntrypoint.createTxExecutionRequest([action]); - const tx = await pxe.simulateTx(txExReq, true); + const tx = await pxe.proveTx(txExReq, true); const sentTx = new SentTx(pxe, pxe.sendTx(tx)); return sentTx.wait(); } diff --git a/yarn-project/end-to-end/src/e2e_delegate_calls.test.ts b/yarn-project/end-to-end/src/e2e_delegate_calls.test.ts index 11a81b84f168..45fb4a22e1d1 100644 --- a/yarn-project/end-to-end/src/e2e_delegate_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_delegate_calls.test.ts @@ -34,11 +34,11 @@ describe('e2e_delegate_calls', () => { const delegatorValue = await delegatorContract.methods .view_private_value(sentValue, wallet.getCompleteAddress().address) - .view(); + .simulate(); const delegatedOnValue = await delegatedOnContract.methods .view_private_value(sentValue, wallet.getCompleteAddress().address) - .view(); + .simulate(); expect(delegatedOnValue).toEqual(0n); expect(delegatorValue).toEqual(sentValue); @@ -55,8 +55,8 @@ describe('e2e_delegate_calls', () => { .send() .wait(); - const delegatorValue = await delegatorContract.methods.view_public_value().view(); - const delegatedOnValue = await delegatedOnContract.methods.view_public_value().view(); + const delegatorValue = await delegatorContract.methods.view_public_value().simulate(); + const delegatedOnValue = await delegatedOnContract.methods.view_public_value().simulate(); expect(delegatedOnValue).toEqual(0n); expect(delegatorValue).toEqual(sentValue); @@ -71,8 +71,8 @@ describe('e2e_delegate_calls', () => { .send() .wait(); - const delegatorValue = await delegatorContract.methods.view_public_value().view(); - const delegatedOnValue = await delegatedOnContract.methods.view_public_value().view(); + const delegatorValue = await delegatorContract.methods.view_public_value().simulate(); + const delegatedOnValue = await delegatedOnContract.methods.view_public_value().simulate(); expect(delegatedOnValue).toEqual(0n); expect(delegatorValue).toEqual(sentValue); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts index 75f152ad05c1..efccbdd034c1 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts @@ -132,7 +132,7 @@ describe('e2e_deploy_contract', () => { const firstOpts = { skipPublicSimulation: true, skipClassRegistration: true, skipInstanceDeploy: true }; const secondOpts = { skipPublicSimulation: true }; - await Promise.all([goodDeploy.simulate(firstOpts), badDeploy.simulate(secondOpts)]); + await Promise.all([goodDeploy.prove(firstOpts), badDeploy.prove(secondOpts)]); const [goodTx, badTx] = [goodDeploy.send(firstOpts), badDeploy.send(secondOpts)]; const [goodTxPromiseResult, badTxReceiptResult] = await Promise.allSettled([ goodTx.wait(), @@ -192,10 +192,10 @@ describe('e2e_deploy_contract', () => { .send() .wait(); logger.info(`Checking if the constructor was run for ${contract.address}`); - expect(await contract.methods.summed_values(owner).view()).toEqual(42n); + expect(await contract.methods.summed_values(owner).simulate()).toEqual(42n); logger.info(`Calling a private function that requires initialization on ${contract.address}`); await contract.methods.create_note(owner, 10).send().wait(); - expect(await contract.methods.summed_values(owner).view()).toEqual(52n); + expect(await contract.methods.summed_values(owner).simulate()).toEqual(52n); }, 30_000, ); @@ -209,8 +209,8 @@ describe('e2e_deploy_contract', () => { ); const calls = contracts.map((c, i) => c.methods.constructor(...initArgss[i]).request()); await new BatchCall(wallet, calls).send().wait(); - expect(await contracts[0].methods.summed_values(owner).view()).toEqual(42n); - expect(await contracts[1].methods.summed_values(owner).view()).toEqual(52n); + expect(await contracts[0].methods.summed_values(owner).simulate()).toEqual(42n); + expect(await contracts[1].methods.summed_values(owner).simulate()).toEqual(52n); }, 30_000); // TODO(@spalladino): This won't work until we can read a nullifier in the same tx in which it was emitted. @@ -224,7 +224,7 @@ describe('e2e_deploy_contract', () => { ]); logger.info(`Executing constructor and private function in batch at ${contract.address}`); await batch.send().wait(); - expect(await contract.methods.summed_values(owner).view()).toEqual(52n); + expect(await contract.methods.summed_values(owner).simulate()).toEqual(52n); }); it('refuses to initialize a contract twice', async () => { @@ -256,7 +256,7 @@ describe('e2e_deploy_contract', () => { it('refuses to initialize a contract with incorrect args', async () => { const owner = await registerRandomAccount(pxe); const contract = await registerContract(wallet, StatefulTestContract, { initArgs: [owner, 42] }); - await expect(contract.methods.constructor(owner, 43).simulate()).rejects.toThrow( + await expect(contract.methods.constructor(owner, 43).prove()).rejects.toThrow( /Initialization hash does not match/, ); }); @@ -264,7 +264,7 @@ describe('e2e_deploy_contract', () => { it('refuses to initialize an instance from a different deployer', async () => { const owner = await registerRandomAccount(pxe); const contract = await registerContract(wallet, StatefulTestContract, { initArgs: [owner, 42], deployer: owner }); - await expect(contract.methods.constructor(owner, 42).simulate()).rejects.toThrow( + await expect(contract.methods.constructor(owner, 42).prove()).rejects.toThrow( /Initializer address is not the contract deployer/i, ); }); @@ -390,7 +390,7 @@ describe('e2e_deploy_contract', () => { .increment_public_value_no_init_check(whom, 10) .send({ skipPublicSimulation: true }) .wait(); - const stored = await contract.methods.get_public_value(whom).view(); + const stored = await contract.methods.get_public_value(whom).simulate(); expect(stored).toEqual(10n); }, 30_000); @@ -403,11 +403,11 @@ describe('e2e_deploy_contract', () => { expect(receipt.status).toEqual(TxStatus.REVERTED); // Meanwhile we check we didn't increment the value - expect(await contract.methods.get_public_value(whom).view()).toEqual(0n); + expect(await contract.methods.get_public_value(whom).simulate()).toEqual(0n); }, 30_000); it('refuses to initialize the instance with wrong args via a private function', async () => { - await expect(contract.methods.constructor(AztecAddress.random(), 43).simulate()).rejects.toThrow( + await expect(contract.methods.constructor(AztecAddress.random(), 43).prove()).rejects.toThrow( /initialization hash does not match/i, ); }, 30_000); @@ -419,7 +419,7 @@ describe('e2e_deploy_contract', () => { .wait(); const whom = AztecAddress.random(); await contract.methods.increment_public_value(whom, 10).send({ skipPublicSimulation: true }).wait(); - const stored = await contract.methods.get_public_value(whom).view(); + const stored = await contract.methods.get_public_value(whom).simulate(); expect(stored).toEqual(10n); }, 30_000); @@ -445,7 +445,7 @@ describe('e2e_deploy_contract', () => { .send({ skipPublicSimulation: true }) .wait({ dontThrowOnRevert: true }); expect(receipt.status).toEqual(TxStatus.REVERTED); - expect(await contract.methods.get_public_value(whom).view()).toEqual(0n); + expect(await contract.methods.get_public_value(whom).simulate()).toEqual(0n); }, 30_000); it('initializes the contract and calls a public function', async () => { @@ -455,7 +455,7 @@ describe('e2e_deploy_contract', () => { .wait(); const whom = AztecAddress.random(); await contract.methods.increment_public_value(whom, 10).send({ skipPublicSimulation: true }).wait(); - const stored = await contract.methods.get_public_value(whom).view(); + const stored = await contract.methods.get_public_value(whom).simulate(); expect(stored).toEqual(10n); }, 30_000); @@ -516,25 +516,25 @@ describe('e2e_deploy_contract', () => { const owner = accounts[0]; logger.debug(`Deploying stateful test contract`); const contract = await StatefulTestContract.deploy(wallet, owner, 42).send().deployed(); - expect(await contract.methods.summed_values(owner).view()).toEqual(42n); + expect(await contract.methods.summed_values(owner).simulate()).toEqual(42n); logger.debug(`Calling public method on stateful test contract at ${contract.address.toString()}`); await contract.methods.increment_public_value(owner, 84).send().wait(); - expect(await contract.methods.get_public_value(owner).view()).toEqual(84n); + expect(await contract.methods.get_public_value(owner).simulate()).toEqual(84n); }, 60_000); it('publicly universally deploys and initializes a contract', async () => { const owner = accounts[0]; const opts = { universalDeploy: true }; const contract = await StatefulTestContract.deploy(wallet, owner, 42).send(opts).deployed(); - expect(await contract.methods.summed_values(owner).view()).toEqual(42n); + expect(await contract.methods.summed_values(owner).simulate()).toEqual(42n); await contract.methods.increment_public_value(owner, 84).send().wait(); - expect(await contract.methods.get_public_value(owner).view()).toEqual(84n); + expect(await contract.methods.get_public_value(owner).simulate()).toEqual(84n); }, 60_000); it('publicly deploys and calls a public function from the constructor', async () => { const owner = accounts[0]; const token = await TokenContract.deploy(wallet, owner, 'TOKEN', 'TKN', 18).send().deployed(); - expect(await token.methods.is_minter(owner).view()).toEqual(true); + expect(await token.methods.is_minter(owner).simulate()).toEqual(true); }, 60_000); it('publicly deploys and initializes via a public function', async () => { @@ -543,10 +543,10 @@ describe('e2e_deploy_contract', () => { const contract = await StatefulTestContract.deployWithOpts({ wallet, method: 'public_constructor' }, owner, 42) .send() .deployed(); - expect(await contract.methods.get_public_value(owner).view()).toEqual(42n); + expect(await contract.methods.get_public_value(owner).simulate()).toEqual(42n); logger.debug(`Calling a private function to ensure the contract was properly initialized`); await contract.methods.create_note(owner, 30).send().wait(); - expect(await contract.methods.summed_values(owner).view()).toEqual(30n); + expect(await contract.methods.summed_values(owner).simulate()).toEqual(30n); }, 60_000); it('deploys a contract with a default initializer not named constructor', async () => { @@ -555,7 +555,7 @@ describe('e2e_deploy_contract', () => { const contract = await CounterContract.deploy(wallet, 10, accounts[0]).send(opts).deployed(); logger.debug(`Calling a function to ensure the contract was properly initialized`); await contract.methods.increment(accounts[0]).send().wait(); - expect(await contract.methods.get_counter(accounts[0]).view()).toEqual(11n); + expect(await contract.methods.get_counter(accounts[0]).simulate()).toEqual(11n); }); it('publicly deploys a contract with no constructor', async () => { @@ -570,7 +570,7 @@ describe('e2e_deploy_contract', () => { it('refuses to deploy a contract with no constructor and no public deployment', async () => { logger.debug(`Deploying contract with no constructor and skipping public deploy`); const opts = { skipPublicDeployment: true, skipClassRegistration: true }; - await expect(TestContract.deploy(wallet).simulate(opts)).rejects.toThrow(/no function calls needed/i); + await expect(TestContract.deploy(wallet).prove(opts)).rejects.toThrow(/no function calls needed/i); }); it.skip('publicly deploys and calls a public function in the same batched call', 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 54b2f467c828..90a6e59a747a 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 @@ -90,7 +90,7 @@ describe('e2e_escrow_contract', () => { afterEach(() => teardown(), 30_000); const expectBalance = async (who: AztecAddress, expectedBalance: bigint) => { - const balance = await token.methods.balance_of_private(who).view({ from: who }); + const balance = await token.methods.balance_of_private(who).simulate({ from: who }); logger(`Account ${who} balance: ${balance}`); expect(balance).toBe(expectedBalance); }; @@ -110,7 +110,7 @@ describe('e2e_escrow_contract', () => { it('refuses to withdraw funds as a non-owner', async () => { await expect( - escrowContract.withWallet(recipientWallet).methods.withdraw(token.address, 30, recipient).simulate(), + escrowContract.withWallet(recipientWallet).methods.withdraw(token.address, 30, recipient).prove(), ).rejects.toThrow(); }, 60_000); diff --git a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts index 3b4d88e5e6ef..21498916e4f9 100644 --- a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts @@ -261,7 +261,7 @@ describe('e2e_inclusion_proofs_contract', () => { // Or that the positive call fails when trying to prove in the older block await expect( - contract.methods.test_contract_inclusion(address, olderBlock, testDeploy, testInit).simulate(), + contract.methods.test_contract_inclusion(address, olderBlock, testDeploy, testInit).prove(), ).rejects.toThrow(/not found/); }; diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 817e894b68fd..8a5ce3cd3fd9 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -392,7 +392,7 @@ describe('e2e_lending_contract', () => { // Withdraw more than possible to test the revert. logger('Withdraw: trying to withdraw more than possible'); await expect( - lendingContract.methods.withdraw_public(lendingAccount.address, 10n ** 9n).simulate(), + lendingContract.methods.withdraw_public(lendingAccount.address, 10n ** 9n).prove(), ).rejects.toThrow(); }); }); diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index f064e08ae997..921cb5c321b5 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -88,7 +88,7 @@ describe('e2e_multiple_accounts_1_enc_key', () => { // Then check the balance const contractWithWallet = await TokenContract.at(tokenAddress, wallet); - const balance = await contractWithWallet.methods.balance_of_private(owner).view({ from: owner.address }); + const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner.address }); logger(`Account ${owner} balance: ${balance}`); expect(balance).toBe(expectedBalance); }; diff --git a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts index ae73dabb6119..919b775099fc 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts @@ -69,7 +69,7 @@ describe('e2e_nested_contract', () => { await expect( parentContract.methods .entry_point(childContract.address, (childContract.methods as any).value_internal.selector) - .simulate(), + .prove(), ).rejects.toThrow(/Assertion failed: Function value_internal can only be called internally/); }, 100_000); @@ -96,7 +96,7 @@ describe('e2e_nested_contract', () => { (childContract.methods as any).pub_inc_value_internal.selector, 42n, ) - .simulate(), + .prove(), ).rejects.toThrow(/Assertion failed: Function pub_inc_value_internal can only be called internally/); }, 100_000); diff --git a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts index 4e9df2086e5b..cc9fb6f70b7c 100644 --- a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts +++ b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts @@ -93,6 +93,6 @@ describe('e2e_non_contract_account', () => { ); await wallet.addNote(extendedNote); - expect(await contract.methods.get_constant().view()).toEqual(value); + expect(await contract.methods.get_constant().simulate()).toEqual(value); }); }); diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index 6ca1d04e782b..48320d81ac98 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -48,13 +48,13 @@ describe('e2e_note_getter', () => { await contract.methods.insert_note(5, Fr.ZERO).send().wait(); const [returnEq, returnNeq, returnLt, returnGt, returnLte, returnGte] = await Promise.all([ - contract.methods.read_note(5, Comparator.EQ).view(), - contract.methods.read_note(5, Comparator.NEQ).view(), - contract.methods.read_note(5, Comparator.LT).view(), - contract.methods.read_note(5, Comparator.GT).view(), - contract.methods.read_note(5, Comparator.LTE).view(), + contract.methods.read_note(5, Comparator.EQ).simulate(), + contract.methods.read_note(5, Comparator.NEQ).simulate(), + contract.methods.read_note(5, Comparator.LT).simulate(), + contract.methods.read_note(5, Comparator.GT).simulate(), + contract.methods.read_note(5, Comparator.LTE).simulate(), // docs:start:state_vars-NoteGetterOptionsComparatorExampleTs - contract.methods.read_note(5, Comparator.GTE).view(), + contract.methods.read_note(5, Comparator.GTE).simulate(), // docs:end:state_vars-NoteGetterOptionsComparatorExampleTs ]); @@ -166,7 +166,7 @@ describe('e2e_note_getter', () => { }); async function assertNoteIsReturned(storageSlot: number, expectedValue: number, activeOrNullified: boolean) { - const viewNotesResult = await contract.methods.call_view_notes(storageSlot, activeOrNullified).view(); + const viewNotesResult = await contract.methods.call_view_notes(storageSlot, activeOrNullified).simulate(); const getNotesResult = await callGetNotes(storageSlot, activeOrNullified); expect(viewNotesResult).toEqual(getNotesResult); @@ -174,14 +174,16 @@ describe('e2e_note_getter', () => { } async function assertNoReturnValue(storageSlot: number, activeOrNullified: boolean) { - await expect(contract.methods.call_view_notes(storageSlot, activeOrNullified).view()).rejects.toThrow('is_some'); + await expect(contract.methods.call_view_notes(storageSlot, activeOrNullified).simulate()).rejects.toThrow( + 'is_some', + ); await expect(contract.methods.call_get_notes(storageSlot, activeOrNullified).send().wait()).rejects.toThrow( `Assertion failed: Cannot return zero notes`, ); } async function callGetNotes(storageSlot: number, activeOrNullified: boolean): Promise { - // call_get_notes exposes the return value via an event since we cannot use view() with it. + // call_get_notes exposes the return value via an event since we cannot use simulate() with it. const tx = contract.methods.call_get_notes(storageSlot, activeOrNullified).send(); await tx.wait(); @@ -192,7 +194,7 @@ describe('e2e_note_getter', () => { } async function callGetNotesMany(storageSlot: number, activeOrNullified: boolean): Promise> { - // call_get_notes_many exposes the return values via event since we cannot use view() with it. + // call_get_notes_many exposes the return values via event since we cannot use simulate() with it. const tx = contract.methods.call_get_notes_many(storageSlot, activeOrNullified).send(); await tx.wait(); @@ -244,7 +246,9 @@ describe('e2e_note_getter', () => { await contract.methods.call_destroy_note(storageSlot).send().wait(); // We now fetch multiple notes, and get both the active and the nullified one. - const viewNotesManyResult = await contract.methods.call_view_notes_many(storageSlot, activeOrNullified).view(); + const viewNotesManyResult = await contract.methods + .call_view_notes_many(storageSlot, activeOrNullified) + .simulate(); const getNotesManyResult = await callGetNotesMany(storageSlot, activeOrNullified); // We can't be sure in which order the notes will be returned, so we simply sort them to test equality. Note diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index d075e0a88ca8..c373403d89b8 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -58,7 +58,7 @@ describe('e2e_ordering', () => { async method => { const expectedOrder = expectedOrders[method]; const action = parent.methods[method](child.address, pubSetValueSelector); - const tx = await action.simulate(); + const tx = await action.prove(); expect(tx.data.needsSetup).toBe(false); expect(tx.data.needsAppLogic).toBe(true); expect(tx.data.needsTeardown).toBe(false); diff --git a/yarn-project/end-to-end/src/e2e_persistence.test.ts b/yarn-project/end-to-end/src/e2e_persistence.test.ts index e74cecc589ac..a4a6d2161811 100644 --- a/yarn-project/end-to-end/src/e2e_persistence.test.ts +++ b/yarn-project/end-to-end/src/e2e_persistence.test.ts @@ -116,15 +116,17 @@ describe('Aztec persistence', () => { it('correctly restores private notes', async () => { // test for >0 instead of exact value so test isn't dependent on run order - await expect(contract.methods.balance_of_private(ownerWallet.getAddress()).view()).resolves.toBeGreaterThan(0n); + await expect(contract.methods.balance_of_private(ownerWallet.getAddress()).simulate()).resolves.toBeGreaterThan( + 0n, + ); }); it('correctly restores public storage', async () => { - await expect(contract.methods.total_supply().view()).resolves.toBeGreaterThan(0n); + await expect(contract.methods.total_supply().simulate()).resolves.toBeGreaterThan(0n); }); it('tracks new notes for the owner', async () => { - const balance = await contract.methods.balance_of_private(ownerWallet.getAddress()).view(); + const balance = await contract.methods.balance_of_private(ownerWallet.getAddress()).simulate(); const secret = Fr.random(); const mintTxReceipt = await contract.methods.mint_private(1000n, computeMessageSecretHash(secret)).send().wait(); @@ -138,7 +140,7 @@ describe('Aztec persistence', () => { await contract.methods.redeem_shield(ownerWallet.getAddress(), 1000n, secret).send().wait(); - await expect(contract.methods.balance_of_private(ownerWallet.getAddress()).view()).resolves.toEqual( + await expect(contract.methods.balance_of_private(ownerWallet.getAddress()).simulate()).resolves.toEqual( balance + 1000n, ); }); @@ -146,13 +148,13 @@ describe('Aztec persistence', () => { it('allows spending of private notes', async () => { const otherWallet = await getUnsafeSchnorrAccount(context.pxe, Fq.random(), Fr.ZERO).waitSetup(); - const initialOwnerBalance = await contract.methods.balance_of_private(ownerWallet.getAddress()).view(); + const initialOwnerBalance = await contract.methods.balance_of_private(ownerWallet.getAddress()).simulate(); await contract.methods.transfer(ownerWallet.getAddress(), otherWallet.getAddress(), 500n, Fr.ZERO).send().wait(); const [ownerBalance, targetBalance] = await Promise.all([ - contract.methods.balance_of_private(ownerWallet.getAddress()).view(), - contract.methods.balance_of_private(otherWallet.getAddress()).view(), + contract.methods.balance_of_private(ownerWallet.getAddress()).simulate(), + contract.methods.balance_of_private(otherWallet.getAddress()).simulate(), ]); expect(ownerBalance).toEqual(initialOwnerBalance - 500n); @@ -205,7 +207,7 @@ describe('Aztec persistence', () => { const wallet = await getUnsafeSchnorrAccount(context.pxe, Fq.random(), Fr.ZERO).waitSetup(); const contract = await TokenContract.at(contractAddress, wallet); - await expect(contract.methods.balance_of_private(ownerAddress.address).view()).resolves.toEqual(0n); + await expect(contract.methods.balance_of_private(ownerAddress.address).simulate()).resolves.toEqual(0n); }); it('has access to public storage', async () => { @@ -217,7 +219,7 @@ describe('Aztec persistence', () => { const wallet = await getUnsafeSchnorrAccount(context.pxe, Fq.random(), Fr.ZERO).waitSetup(); const contract = await TokenContract.at(contractAddress, wallet); - await expect(contract.methods.total_supply().view()).resolves.toBeGreaterThan(0n); + await expect(contract.methods.total_supply().simulate()).resolves.toBeGreaterThan(0n); }); it('pxe restores notes after registering the owner', async () => { @@ -234,7 +236,7 @@ describe('Aztec persistence', () => { await waitForAccountSynch(context.pxe, ownerAddress, { interval: 1, timeout: 10 }); // check that notes total more than 0 so that this test isn't dependent on run order - await expect(contract.methods.balance_of_private(ownerAddress.address).view()).resolves.toBeGreaterThan(0n); + await expect(contract.methods.balance_of_private(ownerAddress.address).simulate()).resolves.toBeGreaterThan(0n); }); }); @@ -296,7 +298,9 @@ describe('Aztec persistence', () => { }); it("restores owner's public balance", async () => { - await expect(contract.methods.balance_of_public(ownerAddress.address).view()).resolves.toEqual(revealedAmount); + await expect(contract.methods.balance_of_public(ownerAddress.address).simulate()).resolves.toEqual( + revealedAmount, + ); }); it('allows consuming transparent note created on another PXE', async () => { @@ -309,10 +313,10 @@ describe('Aztec persistence', () => { mintTxHash, ); - const balanceBeforeRedeem = await contract.methods.balance_of_private(ownerWallet.getAddress()).view(); + const balanceBeforeRedeem = await contract.methods.balance_of_private(ownerWallet.getAddress()).simulate(); await contract.methods.redeem_shield(ownerWallet.getAddress(), mintAmount, secret).send().wait(); - const balanceAfterRedeem = await contract.methods.balance_of_private(ownerWallet.getAddress()).view(); + const balanceAfterRedeem = await contract.methods.balance_of_private(ownerWallet.getAddress()).simulate(); expect(balanceAfterRedeem).toEqual(balanceBeforeRedeem + mintAmount); }); diff --git a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts index e030088e40b5..4602383f09aa 100644 --- a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts @@ -33,7 +33,7 @@ describe('e2e_voting_contract', () => { it('votes', async () => { const candidate = new Fr(1); await votingContract.methods.cast_vote(candidate).send().wait(); - expect(await votingContract.methods.get_vote(candidate).view()).toBe(1n); + expect(await votingContract.methods.get_vote(candidate).simulate()).toBe(1n); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts index 10864f56c67f..58a8872db781 100644 --- a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts @@ -165,7 +165,7 @@ describe('e2e_public_cross_chain_messaging', () => { // user2 tries to consume this message and minting to itself -> should fail since the message is intended to be consumed only by owner. await expect( - l2Bridge.withWallet(user2Wallet).methods.claim_public(user2Wallet.getAddress(), bridgeAmount, secret).simulate(), + l2Bridge.withWallet(user2Wallet).methods.claim_public(user2Wallet.getAddress(), bridgeAmount, secret).prove(), ).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); // user2 consumes owner's L1-> L2 message on bridge contract and mints public tokens on L2 @@ -187,7 +187,7 @@ describe('e2e_public_cross_chain_messaging', () => { l2Bridge .withWallet(user1Wallet) .methods.exit_to_l1_public(ethAccount, withdrawAmount, EthAddress.ZERO, nonce) - .simulate(), + .prove(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); }, 60_000); @@ -215,7 +215,7 @@ describe('e2e_public_cross_chain_messaging', () => { ); await expect( - l2Bridge.withWallet(user2Wallet).methods.claim_private(secretHash, bridgeAmount, secret).simulate(), + l2Bridge.withWallet(user2Wallet).methods.claim_private(secretHash, bridgeAmount, secret).prove(), ).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); }, 60_000); diff --git a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts index 24b602ea7bcc..389a8f2b58e5 100644 --- a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts +++ b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts @@ -101,10 +101,10 @@ describe('e2e_sandbox_example', () => { // Since we already have a token link, we can simply create a new instance of the contract linked to Bob's wallet const tokenContractBob = tokenContractAlice.withWallet(bobWallet); - let aliceBalance = await tokenContractAlice.methods.balance_of_private(alice).view(); + let aliceBalance = await tokenContractAlice.methods.balance_of_private(alice).simulate(); logger(`Alice's balance ${aliceBalance}`); - let bobBalance = await tokenContractBob.methods.balance_of_private(bob).view(); + let bobBalance = await tokenContractBob.methods.balance_of_private(bob).simulate(); logger(`Bob's balance ${bobBalance}`); // docs:end:Balance @@ -121,10 +121,10 @@ describe('e2e_sandbox_example', () => { await tokenContractAlice.methods.transfer(alice, bob, transferQuantity, 0).send().wait(); // Check the new balances - aliceBalance = await tokenContractAlice.methods.balance_of_private(alice).view(); + aliceBalance = await tokenContractAlice.methods.balance_of_private(alice).simulate(); logger(`Alice's balance ${aliceBalance}`); - bobBalance = await tokenContractBob.methods.balance_of_private(bob).view(); + bobBalance = await tokenContractBob.methods.balance_of_private(bob).simulate(); logger(`Bob's balance ${bobBalance}`); // docs:end:Transfer @@ -162,10 +162,10 @@ describe('e2e_sandbox_example', () => { await tokenContractBob.methods.redeem_shield(bob, mintQuantity, bobSecret).send().wait(); // Check the new balances - aliceBalance = await tokenContractAlice.methods.balance_of_private(alice).view(); + aliceBalance = await tokenContractAlice.methods.balance_of_private(alice).simulate(); logger(`Alice's balance ${aliceBalance}`); - bobBalance = await tokenContractBob.methods.balance_of_private(bob).view(); + bobBalance = await tokenContractBob.methods.balance_of_private(bob).simulate(); logger(`Bob's balance ${bobBalance}`); // docs:end:Mint diff --git a/yarn-project/end-to-end/src/e2e_slow_tree.test.ts b/yarn-project/end-to-end/src/e2e_slow_tree.test.ts index b776ed3d3e3f..187535f00b9f 100644 --- a/yarn-project/end-to-end/src/e2e_slow_tree.test.ts +++ b/yarn-project/end-to-end/src/e2e_slow_tree.test.ts @@ -73,8 +73,8 @@ describe('e2e_slow_tree', () => { _root: { before: bigint; after: bigint; next_change: bigint }, _leaf: { before: bigint; after: bigint; next_change: bigint }, ) => { - const root = await contract.methods.un_read_root(owner).view(); - const leaf = await contract.methods.un_read_leaf_at(owner, key).view(); + const root = await contract.methods.un_read_root(owner).simulate(); + const leaf = await contract.methods.un_read_leaf_at(owner, key).simulate(); expect(root).toEqual(_root); expect(leaf).toEqual(_leaf); }; @@ -128,7 +128,7 @@ describe('e2e_slow_tree', () => { `Tries to "read" tree[${zeroProof.index}] from the tree, but is rejected as value is not ${zeroProof.value}`, ); await wallet.addCapsule(getMembershipCapsule({ ...zeroProof, value: new Fr(0) })); - await expect(contract.methods.read_at(key).simulate()).rejects.toThrow( + await expect(contract.methods.read_at(key).prove()).rejects.toThrow( /Assertion failed: Root does not match expected/, ); diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 5e3f441ff2b0..56783ceee2ee 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -1,9 +1,15 @@ import { type Wallet } from '@aztec/aztec.js'; import { DocsExampleContract } from '@aztec/noir-contracts.js'; +import { jest } from '@jest/globals'; + import { setup } from './fixtures/utils.js'; +const TIMEOUT = 100_000; + describe('e2e_state_vars', () => { + jest.setTimeout(TIMEOUT); + let wallet: Wallet; let teardown: () => Promise; @@ -15,24 +21,56 @@ describe('e2e_state_vars', () => { beforeAll(async () => { ({ teardown, wallet } = await setup()); contract = await DocsExampleContract.deploy(wallet).send().deployed(); - }, 25_000); + }, 30_000); afterAll(() => teardown()); describe('SharedImmutable', () => { it('private read of uninitialized SharedImmutable', async () => { - const s = await contract.methods.get_shared_immutable().view(); + const s = await contract.methods.get_shared_immutable().simulate(); // Send the transaction and wait for it to be mined (wait function throws if the tx is not mined) await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); }); - it('private read of initialized SharedImmutable', async () => { + it('private read of SharedImmutable', async () => { + // Initializes the shared immutable and then reads the value using an unconstrained function + // checking the return values with: + // 1. A constrained private function that reads it directly + // 2. A constrained private function that calls another private function that reads. + await contract.methods.initialize_shared_immutable(1).send().wait(); - const s = await contract.methods.get_shared_immutable().view(); - await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); - }, 200_000); + const a = await contract.methods.get_shared_immutable_constrained_private().simulate(); + const b = await contract.methods.get_shared_immutable_constrained_private_indirect().simulate(); + const c = await contract.methods.get_shared_immutable().simulate(); + + expect((a as any)[0]).toEqual((c as any)['account'].toBigInt()); + expect((a as any)[1]).toEqual((c as any)['points']); + expect((b as any)[0]).toEqual((c as any)['account'].toBigInt()); + expect((b as any)[1]).toEqual((c as any)['points']); + + expect(a).toEqual(b); + await contract.methods.match_shared_immutable(c.account, c.points).send().wait(); + }); + + it('public read of SharedImmutable', async () => { + // Reads the value using an unconstrained function checking the return values with: + // 1. A constrained public function that reads it directly + // 2. A constrained public function that calls another public function that reads. + + const a = await contract.methods.get_shared_immutable_constrained_public().simulate(); + const b = await contract.methods.get_shared_immutable_constrained_public_indirect().simulate(); + const c = await contract.methods.get_shared_immutable().simulate(); + + expect((a as any)[0]).toEqual((c as any)['account'].toBigInt()); + expect((a as any)[1]).toEqual((c as any)['points']); + expect((b as any)[0]).toEqual((c as any)['account'].toBigInt()); + expect((b as any)[1]).toEqual((c as any)['points']); + + expect(a).toEqual(b); + await contract.methods.match_shared_immutable(c.account, c.points).send().wait(); + }); it('initializing SharedImmutable the second time should fail', async () => { // Jest executes the tests sequentially and the first call to initialize_shared_immutable was executed @@ -48,7 +86,7 @@ describe('e2e_state_vars', () => { const numPoints = 1n; await contract.methods.initialize_public_immutable(numPoints).send().wait(); - const p = await contract.methods.get_public_immutable().view(); + const p = await contract.methods.get_public_immutable().simulate(); expect(p.account).toEqual(wallet.getCompleteAddress().address); expect(p.points).toEqual(numPoints); @@ -65,36 +103,36 @@ describe('e2e_state_vars', () => { describe('PrivateMutable', () => { it('fail to read uninitialized PrivateMutable', async () => { - expect(await contract.methods.is_legendary_initialized().view()).toEqual(false); - await expect(contract.methods.get_legendary_card().view()).rejects.toThrow(); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(false); + await expect(contract.methods.get_legendary_card().simulate()).rejects.toThrow(); }); it('initialize PrivateMutable', async () => { - expect(await contract.methods.is_legendary_initialized().view()).toEqual(false); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(false); // Send the transaction and wait for it to be mined (wait function throws if the tx is not mined) const { debugInfo } = await contract.methods.initialize_private(RANDOMNESS, POINTS).send().wait({ debug: true }); // 1 for the tx, another for the initializer expect(debugInfo!.nullifiers.length).toEqual(2); - expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(true); }); it('fail to reinitialize', async () => { - expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(true); await expect(contract.methods.initialize_private(RANDOMNESS, POINTS).send().wait()).rejects.toThrow(); - expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(true); }); it('read initialized PrivateMutable', async () => { - expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); - const { points, randomness } = await contract.methods.get_legendary_card().view(); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(true); + const { points, randomness } = await contract.methods.get_legendary_card().simulate(); expect(points).toEqual(POINTS); expect(randomness).toEqual(RANDOMNESS); }); it('replace with same value', async () => { - expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); - const noteBefore = await contract.methods.get_legendary_card().view(); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(true); + const noteBefore = await contract.methods.get_legendary_card().simulate(); const { debugInfo } = await contract.methods .update_legendary_card(RANDOMNESS, POINTS) .send() @@ -104,7 +142,7 @@ describe('e2e_state_vars', () => { // 1 for the tx, another for the nullifier of the previous note expect(debugInfo!.nullifiers.length).toEqual(2); - const noteAfter = await contract.methods.get_legendary_card().view(); + const noteAfter = await contract.methods.get_legendary_card().simulate(); expect(noteBefore.owner).toEqual(noteAfter.owner); expect(noteBefore.points).toEqual(noteAfter.points); @@ -117,7 +155,7 @@ describe('e2e_state_vars', () => { }); it('replace PrivateMutable with other values', async () => { - expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(true); const { debugInfo } = await contract.methods .update_legendary_card(RANDOMNESS + 2n, POINTS + 1n) .send() @@ -127,21 +165,21 @@ describe('e2e_state_vars', () => { // 1 for the tx, another for the nullifier of the previous note expect(debugInfo!.nullifiers.length).toEqual(2); - const { points, randomness } = await contract.methods.get_legendary_card().view(); + const { points, randomness } = await contract.methods.get_legendary_card().simulate(); expect(points).toEqual(POINTS + 1n); expect(randomness).toEqual(RANDOMNESS + 2n); }); it('replace PrivateMutable dependent on prior value', async () => { - expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); - const noteBefore = await contract.methods.get_legendary_card().view(); + expect(await contract.methods.is_legendary_initialized().simulate()).toEqual(true); + const noteBefore = await contract.methods.get_legendary_card().simulate(); const { debugInfo } = await contract.methods.increase_legendary_points().send().wait({ debug: true }); expect(debugInfo!.noteHashes.length).toEqual(1); // 1 for the tx, another for the nullifier of the previous note expect(debugInfo!.nullifiers.length).toEqual(2); - const { points, randomness } = await contract.methods.get_legendary_card().view(); + const { points, randomness } = await contract.methods.get_legendary_card().simulate(); expect(points).toEqual(noteBefore.points + 1n); expect(randomness).toEqual(noteBefore.randomness); }); @@ -149,12 +187,12 @@ describe('e2e_state_vars', () => { describe('PrivateImmutable', () => { it('fail to read uninitialized PrivateImmutable', async () => { - expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(false); - await expect(contract.methods.view_imm_card().view()).rejects.toThrow(); + expect(await contract.methods.is_priv_imm_initialized().simulate()).toEqual(false); + await expect(contract.methods.view_imm_card().simulate()).rejects.toThrow(); }); it('initialize PrivateImmutable', async () => { - expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(false); + expect(await contract.methods.is_priv_imm_initialized().simulate()).toEqual(false); const { debugInfo } = await contract.methods .initialize_private_immutable(RANDOMNESS, POINTS) .send() @@ -163,18 +201,18 @@ describe('e2e_state_vars', () => { expect(debugInfo!.noteHashes.length).toEqual(1); // 1 for the tx, another for the initializer expect(debugInfo!.nullifiers.length).toEqual(2); - expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); + expect(await contract.methods.is_priv_imm_initialized().simulate()).toEqual(true); }); it('fail to reinitialize', async () => { - expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); + expect(await contract.methods.is_priv_imm_initialized().simulate()).toEqual(true); await expect(contract.methods.initialize_private_immutable(RANDOMNESS, POINTS).send().wait()).rejects.toThrow(); - expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); + expect(await contract.methods.is_priv_imm_initialized().simulate()).toEqual(true); }); it('read initialized PrivateImmutable', async () => { - expect(await contract.methods.is_priv_imm_initialized().view()).toEqual(true); - const { points, randomness } = await contract.methods.view_imm_card().view(); + expect(await contract.methods.is_priv_imm_initialized().simulate()).toEqual(true); + const { points, randomness } = await contract.methods.view_imm_card().simulate(); expect(points).toEqual(POINTS); expect(randomness).toEqual(RANDOMNESS); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_token_contract.test.ts index 91f534a68eb4..2c985d5e1f58 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract.test.ts @@ -82,7 +82,7 @@ describe('e2e_token_contract', () => { accounts.map(a => a.address), ); - expect(await asset.methods.admin().view()).toBe(accounts[0].address.toBigInt()); + expect(await asset.methods.admin().simulate()).toBe(accounts[0].address.toBigInt()); badAccount = await DocsExampleContract.deploy(wallets[0]).send().deployed(); }, 100_000); @@ -108,32 +108,32 @@ describe('e2e_token_contract', () => { "Failed to solve brillig function, reason: explicit trap hit in brillig 'name.is_eq(_what)'", ], ])('name - %s', async (_type, method, errorMessage) => { - const t = toString(await asset.methods.un_get_name().view()); + const t = toString(await asset.methods.un_get_name().simulate()); expect(t).toBe(TOKEN_NAME); await reader.methods[method](asset.address, TOKEN_NAME).send().wait(); - await expect(reader.methods[method](asset.address, 'WRONG_NAME').simulate()).rejects.toThrow(errorMessage); + await expect(reader.methods[method](asset.address, 'WRONG_NAME').prove()).rejects.toThrow(errorMessage); }); }); describe('symbol', () => { it('private', async () => { - const t = toString(await asset.methods.un_get_symbol().view()); + const t = toString(await asset.methods.un_get_symbol().simulate()); expect(t).toBe(TOKEN_SYMBOL); await reader.methods.check_symbol_private(asset.address, TOKEN_SYMBOL).send().wait(); - await expect(reader.methods.check_symbol_private(asset.address, 'WRONG_SYMBOL').simulate()).rejects.toThrow( + await expect(reader.methods.check_symbol_private(asset.address, 'WRONG_SYMBOL').prove()).rejects.toThrow( "Cannot satisfy constraint 'symbol.is_eq(_what)'", ); }); it('public', async () => { - const t = toString(await asset.methods.un_get_symbol().view()); + const t = toString(await asset.methods.un_get_symbol().simulate()); expect(t).toBe(TOKEN_SYMBOL); await reader.methods.check_symbol_public(asset.address, TOKEN_SYMBOL).send().wait(); - await expect(reader.methods.check_symbol_public(asset.address, 'WRONG_SYMBOL').simulate()).rejects.toThrow( + await expect(reader.methods.check_symbol_public(asset.address, 'WRONG_SYMBOL').prove()).rejects.toThrow( "Failed to solve brillig function, reason: explicit trap hit in brillig 'symbol.is_eq(_what)'", ); }); @@ -141,23 +141,23 @@ describe('e2e_token_contract', () => { describe('decimals', () => { it('private', async () => { - const t = await asset.methods.un_get_decimals().view(); + const t = await asset.methods.un_get_decimals().simulate(); expect(t).toBe(TOKEN_DECIMALS); await reader.methods.check_decimals_private(asset.address, TOKEN_DECIMALS).send().wait(); - await expect(reader.methods.check_decimals_private(asset.address, 99).simulate()).rejects.toThrow( + await expect(reader.methods.check_decimals_private(asset.address, 99).prove()).rejects.toThrow( "Cannot satisfy constraint 'ret[0] as u8 == what'", ); }); it('public', async () => { - const t = await asset.methods.un_get_decimals().view(); + const t = await asset.methods.un_get_decimals().simulate(); expect(t).toBe(TOKEN_DECIMALS); await reader.methods.check_decimals_public(asset.address, TOKEN_DECIMALS).send().wait(); - await expect(reader.methods.check_decimals_public(asset.address, 99).simulate()).rejects.toThrow( + await expect(reader.methods.check_decimals_public(asset.address, 99).prove()).rejects.toThrow( "Failed to solve brillig function, reason: explicit trap hit in brillig 'ret[0] as u8 == what'", ); }); @@ -167,27 +167,27 @@ describe('e2e_token_contract', () => { describe('Access controlled functions', () => { it('Set admin', async () => { await asset.methods.set_admin(accounts[1].address).send().wait(); - expect(await asset.methods.admin().view()).toBe(accounts[1].address.toBigInt()); + expect(await asset.methods.admin().simulate()).toBe(accounts[1].address.toBigInt()); }); it('Add minter as admin', async () => { await asset.withWallet(wallets[1]).methods.set_minter(accounts[1].address, true).send().wait(); - expect(await asset.methods.is_minter(accounts[1].address).view()).toBe(true); + expect(await asset.methods.is_minter(accounts[1].address).simulate()).toBe(true); }); it('Revoke minter as admin', async () => { await asset.withWallet(wallets[1]).methods.set_minter(accounts[1].address, false).send().wait(); - expect(await asset.methods.is_minter(accounts[1].address).view()).toBe(false); + expect(await asset.methods.is_minter(accounts[1].address).simulate()).toBe(false); }); describe('failure cases', () => { it('Set admin (not admin)', async () => { - await expect(asset.methods.set_admin(accounts[0].address).simulate()).rejects.toThrow( + await expect(asset.methods.set_admin(accounts[0].address).prove()).rejects.toThrow( 'Assertion failed: caller is not admin', ); }); it('Revoke minter not as admin', async () => { - await expect(asset.methods.set_minter(accounts[0].address, false).simulate()).rejects.toThrow( + await expect(asset.methods.set_minter(accounts[0].address, false).prove()).rejects.toThrow( 'Assertion failed: caller is not admin', ); }); @@ -201,37 +201,37 @@ describe('e2e_token_contract', () => { await asset.methods.mint_public(accounts[0].address, amount).send().wait(); tokenSim.mintPublic(accounts[0].address, amount); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual( + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual( tokenSim.balanceOfPublic(accounts[0].address), ); - expect(await asset.methods.total_supply().view()).toEqual(tokenSim.totalSupply); + expect(await asset.methods.total_supply().simulate()).toEqual(tokenSim.totalSupply); }); describe('failure cases', () => { it('as non-minter', async () => { const amount = 10000n; await expect( - asset.withWallet(wallets[1]).methods.mint_public(accounts[0].address, amount).simulate(), + asset.withWallet(wallets[1]).methods.mint_public(accounts[0].address, amount).prove(), ).rejects.toThrow('Assertion failed: caller is not minter'); }); it('mint >u128 tokens to overflow', async () => { const amount = 2n ** 128n; // U128::max() + 1; - await expect(asset.methods.mint_public(accounts[0].address, amount).simulate()).rejects.toThrow( + await expect(asset.methods.mint_public(accounts[0].address, amount).prove()).rejects.toThrow( BITSIZE_TOO_BIG_ERROR, ); }); it('mint u128', async () => { const amount = 2n ** 128n - tokenSim.balanceOfPublic(accounts[0].address); - await expect(asset.methods.mint_public(accounts[0].address, amount).simulate()).rejects.toThrow( + await expect(asset.methods.mint_public(accounts[0].address, amount).prove()).rejects.toThrow( U128_OVERFLOW_ERROR, ); }); it('mint u128', async () => { const amount = 2n ** 128n - tokenSim.balanceOfPublic(accounts[0].address); - await expect(asset.methods.mint_public(accounts[1].address, amount).simulate()).rejects.toThrow( + await expect(asset.methods.mint_public(accounts[1].address, amount).prove()).rejects.toThrow( U128_OVERFLOW_ERROR, ); }); @@ -274,33 +274,31 @@ describe('e2e_token_contract', () => { await expect(addPendingShieldNoteToPXE(0, amount, secretHash, txHash)).rejects.toThrow( 'The note has been destroyed.', ); - await expect(asset.methods.redeem_shield(accounts[0].address, amount, secret).simulate()).rejects.toThrow( + await expect(asset.methods.redeem_shield(accounts[0].address, amount, secret).prove()).rejects.toThrow( `Assertion failed: Cannot return zero notes`, ); }); it('mint_private as non-minter', async () => { - await expect( - asset.withWallet(wallets[1]).methods.mint_private(amount, secretHash).simulate(), - ).rejects.toThrow('Assertion failed: caller is not minter'); + await expect(asset.withWallet(wallets[1]).methods.mint_private(amount, secretHash).prove()).rejects.toThrow( + 'Assertion failed: caller is not minter', + ); }); it('mint >u128 tokens to overflow', async () => { const amount = 2n ** 128n; // U128::max() + 1; - await expect(asset.methods.mint_private(amount, secretHash).simulate()).rejects.toThrow( - BITSIZE_TOO_BIG_ERROR, - ); + await expect(asset.methods.mint_private(amount, secretHash).prove()).rejects.toThrow(BITSIZE_TOO_BIG_ERROR); }); it('mint u128', async () => { const amount = 2n ** 128n - tokenSim.balanceOfPrivate(accounts[0].address); expect(amount).toBeLessThan(2n ** 128n); - await expect(asset.methods.mint_private(amount, secretHash).simulate()).rejects.toThrow(U128_OVERFLOW_ERROR); + await expect(asset.methods.mint_private(amount, secretHash).prove()).rejects.toThrow(U128_OVERFLOW_ERROR); }); it('mint u128', async () => { const amount = 2n ** 128n - tokenSim.totalSupply; - await expect(asset.methods.mint_private(amount, secretHash).simulate()).rejects.toThrow(U128_OVERFLOW_ERROR); + await expect(asset.methods.mint_private(amount, secretHash).prove()).rejects.toThrow(U128_OVERFLOW_ERROR); }); }); }); @@ -309,7 +307,7 @@ describe('e2e_token_contract', () => { describe('Transfer', () => { describe('public', () => { it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, 0).send().wait(); @@ -318,7 +316,7 @@ describe('e2e_token_contract', () => { }); it('transfer to self', async () => { - const balance = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer_public(accounts[0].address, accounts[0].address, amount, 0).send().wait(); @@ -327,7 +325,7 @@ describe('e2e_token_contract', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const nonce = Fr.random(); @@ -355,38 +353,38 @@ describe('e2e_token_contract', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = 0; await expect( - asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).simulate(), + asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).prove(), ).rejects.toThrow(U128_UNDERFLOW_ERROR); }); it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 - 1n; const nonce = 1; await expect( - asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).simulate(), + asset.methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce).prove(), ).rejects.toThrow('Assertion failed: invalid nonce'); }); it('transfer on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); await expect( asset .withWallet(wallets[1]) .methods.transfer_public(accounts[0].address, accounts[1].address, amount, nonce) - .simulate(), + .prove(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_public(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_public(accounts[1].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -413,15 +411,15 @@ describe('e2e_token_contract', () => { }); // Perform the transfer - await expect(action.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR); + await expect(action.prove()).rejects.toThrow(U128_UNDERFLOW_ERROR); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_public(accounts[1].address).view()).toEqual(balance1); + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_public(accounts[1].address).simulate()).toEqual(balance1); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_public(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_public(accounts[1].address).simulate(); const amount = balance0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -434,15 +432,15 @@ describe('e2e_token_contract', () => { await wallets[0].setPublicAuthWit({ caller: accounts[0].address, action }, true).send().wait(); // Perform the transfer - await expect(action.simulate()).rejects.toThrow('Assertion failed: Message not authorized by account'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Message not authorized by account'); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_public(accounts[1].address).view()).toEqual(balance1); + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_public(accounts[1].address).simulate()).toEqual(balance1); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_public(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_public(accounts[1].address).simulate(); const amount = balance0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -454,14 +452,14 @@ describe('e2e_token_contract', () => { await wallets[0].setPublicAuthWit({ caller: accounts[0].address, action }, true).send().wait(); // Perform the transfer - await expect(action.simulate()).rejects.toThrow('Assertion failed: Message not authorized by account'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Message not authorized by account'); - expect(await asset.methods.balance_of_public(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_public(accounts[1].address).view()).toEqual(balance1); + expect(await asset.methods.balance_of_public(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_public(accounts[1].address).simulate()).toEqual(balance1); }); it('transfer on behalf of other, cancelled authwit', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const nonce = Fr.random(); @@ -483,7 +481,7 @@ describe('e2e_token_contract', () => { }); it('transfer on behalf of other, cancelled authwit, flow 2', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const nonce = Fr.random(); @@ -505,7 +503,7 @@ describe('e2e_token_contract', () => { }); it('transfer on behalf of other, cancelled authwit, flow 3', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const nonce = Fr.random(); @@ -556,7 +554,7 @@ describe('e2e_token_contract', () => { describe('private', () => { it('transfer less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 0).send().wait(); @@ -564,7 +562,7 @@ describe('e2e_token_contract', () => { }); it('transfer to self', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.transfer(accounts[0].address, accounts[0].address, amount, 0).send().wait(); @@ -572,7 +570,7 @@ describe('e2e_token_contract', () => { }); it('transfer on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -607,26 +605,26 @@ describe('e2e_token_contract', () => { describe('failure cases', () => { it('transfer more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); await expect( - asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 0).simulate(), + asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 0).prove(), ).rejects.toThrow('Assertion failed: Balance too low'); }); it('transfer on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); await expect( - asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 1).simulate(), + asset.methods.transfer(accounts[0].address, accounts[1].address, amount, 1).prove(), ).rejects.toThrow('Assertion failed: invalid nonce'); }); it('transfer more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); - const balance1 = await asset.methods.balance_of_private(accounts[1].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); + const balance1 = await asset.methods.balance_of_private(accounts[1].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -643,9 +641,9 @@ describe('e2e_token_contract', () => { await wallets[1].addAuthWitness(witness); // Perform the transfer - await expect(action.simulate()).rejects.toThrow('Assertion failed: Balance too low'); - expect(await asset.methods.balance_of_private(accounts[0].address).view()).toEqual(balance0); - expect(await asset.methods.balance_of_private(accounts[1].address).view()).toEqual(balance1); + await expect(action.prove()).rejects.toThrow('Assertion failed: Balance too low'); + expect(await asset.methods.balance_of_private(accounts[0].address).simulate()).toEqual(balance0); + expect(await asset.methods.balance_of_private(accounts[1].address).simulate()).toEqual(balance1); }); it.skip('transfer into account to overflow', () => { @@ -656,7 +654,7 @@ describe('e2e_token_contract', () => { }); it('transfer on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -672,13 +670,13 @@ describe('e2e_token_contract', () => { action.request(), ); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${messageHash.toString()}`, ); }); it('transfer on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -697,14 +695,14 @@ describe('e2e_token_contract', () => { const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action }); await wallets[2].addAuthWitness(witness); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${expectedMessageHash.toString()}`, ); - expect(await asset.methods.balance_of_private(accounts[0].address).view()).toEqual(balance0); + expect(await asset.methods.balance_of_private(accounts[0].address).simulate()).toEqual(balance0); }); it('transfer on behalf of other, cancelled authwit', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -728,7 +726,7 @@ describe('e2e_token_contract', () => { }); it('transfer on behalf of other, cancelled authwit, flow 2', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -776,7 +774,7 @@ describe('e2e_token_contract', () => { }); it('on behalf of self', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub / 2n; expect(amount).toBeGreaterThan(0n); @@ -793,7 +791,7 @@ describe('e2e_token_contract', () => { }); it('on behalf of other', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -823,27 +821,27 @@ describe('e2e_token_contract', () => { describe('failure cases', () => { it('on behalf of self (more than balance)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; expect(amount).toBeGreaterThan(0n); - await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 0).simulate()).rejects.toThrow( + await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 0).prove()).rejects.toThrow( U128_UNDERFLOW_ERROR, ); }); it('on behalf of self (invalid nonce)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; expect(amount).toBeGreaterThan(0n); - await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 1).simulate()).rejects.toThrow( + await expect(asset.methods.shield(accounts[0].address, amount, secretHash, 1).prove()).rejects.toThrow( 'Assertion failed: invalid nonce', ); }); it('on behalf of other (more than balance)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -852,11 +850,11 @@ describe('e2e_token_contract', () => { const action = asset.withWallet(wallets[1]).methods.shield(accounts[0].address, amount, secretHash, nonce); await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait(); - await expect(action.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR); + await expect(action.prove()).rejects.toThrow(U128_UNDERFLOW_ERROR); }); it('on behalf of other (wrong designated caller)', async () => { - const balancePub = await asset.methods.balance_of_public(accounts[0].address).view(); + const balancePub = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balancePub + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -865,17 +863,17 @@ describe('e2e_token_contract', () => { const action = asset.withWallet(wallets[2]).methods.shield(accounts[0].address, amount, secretHash, nonce); await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait(); - await expect(action.simulate()).rejects.toThrow('Assertion failed: Message not authorized by account'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Message not authorized by account'); }); it('on behalf of other (without approval)', async () => { - const balance = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); await expect( - asset.withWallet(wallets[1]).methods.shield(accounts[0].address, amount, secretHash, nonce).simulate(), + asset.withWallet(wallets[1]).methods.shield(accounts[0].address, amount, secretHash, nonce).prove(), ).rejects.toThrow(`Assertion failed: Message not authorized by account`); }); }); @@ -883,7 +881,7 @@ describe('e2e_token_contract', () => { describe('Unshielding', () => { it('on behalf of self', async () => { - const balancePriv = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv / 2n; expect(amount).toBeGreaterThan(0n); @@ -893,7 +891,7 @@ describe('e2e_token_contract', () => { }); it('on behalf of other', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -921,27 +919,27 @@ describe('e2e_token_contract', () => { describe('failure cases', () => { it('on behalf of self (more than balance)', async () => { - const balancePriv = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); await expect( - asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 0).simulate(), + asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 0).prove(), ).rejects.toThrow('Assertion failed: Balance too low'); }); it('on behalf of self (invalid nonce)', async () => { - const balancePriv = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv + 1n; expect(amount).toBeGreaterThan(0n); await expect( - asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 1).simulate(), + asset.methods.unshield(accounts[0].address, accounts[0].address, amount, 1).prove(), ).rejects.toThrow('Assertion failed: invalid nonce'); }); it('on behalf of other (more than balance)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -956,11 +954,11 @@ describe('e2e_token_contract', () => { const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action }); await wallets[1].addAuthWitness(witness); - await expect(action.simulate()).rejects.toThrow('Assertion failed: Balance too low'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Balance too low'); }); it('on behalf of other (invalid designated caller)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -981,7 +979,7 @@ describe('e2e_token_contract', () => { const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action }); await wallets[2].addAuthWitness(witness); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${expectedMessageHash.toString()}`, ); }); @@ -991,7 +989,7 @@ describe('e2e_token_contract', () => { describe('Burn', () => { describe('public', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.burn_public(accounts[0].address, amount, 0).send().wait(); @@ -1000,7 +998,7 @@ describe('e2e_token_contract', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); const nonce = Fr.random(); @@ -1020,35 +1018,35 @@ describe('e2e_token_contract', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = 0; - await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).simulate()).rejects.toThrow( + await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).prove()).rejects.toThrow( U128_UNDERFLOW_ERROR, ); }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); const nonce = 1; - await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).simulate()).rejects.toThrow( + await expect(asset.methods.burn_public(accounts[0].address, amount, nonce).prove()).rejects.toThrow( 'Assertion failed: invalid nonce', ); }); it('burn on behalf of other without "approval"', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); await expect( - asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).simulate(), + asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).prove(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1057,11 +1055,11 @@ describe('e2e_token_contract', () => { const action = asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce); await wallets[0].setPublicAuthWit({ caller: accounts[1].address, action }, true).send().wait(); - await expect(action.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR); + await expect(action.prove()).rejects.toThrow(U128_UNDERFLOW_ERROR); }); it('burn on behalf of other, wrong designated caller', async () => { - const balance0 = await asset.methods.balance_of_public(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_public(accounts[0].address).simulate(); const amount = balance0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1071,7 +1069,7 @@ describe('e2e_token_contract', () => { await wallets[0].setPublicAuthWit({ caller: accounts[0].address, action }, true).send().wait(); await expect( - asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).simulate(), + asset.withWallet(wallets[1]).methods.burn_public(accounts[0].address, amount, nonce).prove(), ).rejects.toThrow('Assertion failed: Message not authorized by account'); }); }); @@ -1079,7 +1077,7 @@ describe('e2e_token_contract', () => { describe('private', () => { it('burn less than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; expect(amount).toBeGreaterThan(0n); await asset.methods.burn(accounts[0].address, amount, 0).send().wait(); @@ -1087,7 +1085,7 @@ describe('e2e_token_contract', () => { }); it('burn on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1110,25 +1108,25 @@ describe('e2e_token_contract', () => { describe('failure cases', () => { it('burn more than balance', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 + 1n; expect(amount).toBeGreaterThan(0n); - await expect(asset.methods.burn(accounts[0].address, amount, 0).simulate()).rejects.toThrow( + await expect(asset.methods.burn(accounts[0].address, amount, 0).prove()).rejects.toThrow( 'Assertion failed: Balance too low', ); }); it('burn on behalf of self with non-zero nonce', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 - 1n; expect(amount).toBeGreaterThan(0n); - await expect(asset.methods.burn(accounts[0].address, amount, 1).simulate()).rejects.toThrow( + await expect(asset.methods.burn(accounts[0].address, amount, 1).prove()).rejects.toThrow( 'Assertion failed: invalid nonce', ); }); it('burn more than balance on behalf of other', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 + 1n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1141,11 +1139,11 @@ describe('e2e_token_contract', () => { const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action }); await wallets[1].addAuthWitness(witness); - await expect(action.simulate()).rejects.toThrow('Assertion failed: Balance too low'); + await expect(action.prove()).rejects.toThrow('Assertion failed: Balance too low'); }); it('burn on behalf of other without approval', async () => { - const balance0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balance0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balance0 / 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1159,13 +1157,13 @@ describe('e2e_token_contract', () => { action.request(), ); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${messageHash.toString()}`, ); }); it('on behalf of other (invalid designated caller)', async () => { - const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).view(); + const balancePriv0 = await asset.methods.balance_of_private(accounts[0].address).simulate(); const amount = balancePriv0 + 2n; const nonce = Fr.random(); expect(amount).toBeGreaterThan(0n); @@ -1182,7 +1180,7 @@ describe('e2e_token_contract', () => { const witness = await wallets[0].createAuthWit({ caller: accounts[1].address, action }); await wallets[2].addAuthWitness(witness); - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( `Unknown auth witness for message hash ${expectedMessageHash.toString()}`, ); }); diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 8210145c2238..fe6a4b23bc7b 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -514,7 +514,7 @@ export function getBalancesFn( logger: any, ): (...addresses: AztecAddress[]) => Promise { const balances = async (...addresses: AztecAddress[]) => { - const b = await Promise.all(addresses.map(address => method(address).view())); + const b = await Promise.all(addresses.map(address => method(address).simulate())); const debugString = `${symbol} balances: ${addresses.map((address, i) => `${address}: ${b[i]}`).join(', ')}`; logger(debugString); return b; diff --git a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts index 16074a7e3069..4e3ee9f7a7ca 100644 --- a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts +++ b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts @@ -43,7 +43,7 @@ describe('guides/dapp/testing', () => { it('increases recipient funds on mint', async () => { const recipientAddress = recipient.getAddress(); - expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(0n); + expect(await token.methods.balance_of_private(recipientAddress).simulate()).toEqual(0n); const mintAmount = 20n; const secret = Fr.random(); @@ -65,7 +65,7 @@ describe('guides/dapp/testing', () => { await pxe.addNote(extendedNote); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); - expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); + expect(await token.methods.balance_of_private(recipientAddress).simulate()).toEqual(20n); }, 30_000); }); // docs:end:sandbox-example @@ -87,7 +87,7 @@ describe('guides/dapp/testing', () => { }, 30_000); it('increases recipient funds on mint', async () => { - expect(await token.methods.balance_of_private(recipient.getAddress()).view()).toEqual(0n); + expect(await token.methods.balance_of_private(recipient.getAddress()).simulate()).toEqual(0n); const recipientAddress = recipient.getAddress(); const mintAmount = 20n; const secret = Fr.random(); @@ -109,7 +109,7 @@ describe('guides/dapp/testing', () => { await pxe.addNote(extendedNote); await token.methods.redeem_shield(recipientAddress, mintAmount, secret).send().wait(); - expect(await token.methods.balance_of_private(recipientAddress).view()).toEqual(20n); + expect(await token.methods.balance_of_private(recipientAddress).simulate()).toEqual(20n); }, 30_000); }); @@ -220,7 +220,7 @@ describe('guides/dapp/testing', () => { it('asserts a local transaction simulation fails by calling simulate', async () => { // docs:start:local-tx-fails const call = token.methods.transfer(owner.getAddress(), recipient.getAddress(), 200n, 0); - await expect(call.simulate()).rejects.toThrow(/Balance too low/); + await expect(call.prove()).rejects.toThrow(/Balance too low/); // docs:end:local-tx-fails }, 30_000); @@ -236,8 +236,8 @@ describe('guides/dapp/testing', () => { const call1 = token.methods.transfer(owner.getAddress(), recipient.getAddress(), 80n, 0); const call2 = token.methods.transfer(owner.getAddress(), recipient.getAddress(), 50n, 0); - await call1.simulate(); - await call2.simulate(); + await call1.prove(); + await call2.prove(); await call1.send().wait(); await expect(call2.send().wait()).rejects.toThrow(/dropped/); @@ -247,7 +247,7 @@ describe('guides/dapp/testing', () => { it('asserts a simulation for a public function call fails', async () => { // docs:start:local-pub-fails const call = token.methods.transfer_public(owner.getAddress(), recipient.getAddress(), 1000n, 0); - await expect(call.simulate()).rejects.toThrow(U128_UNDERFLOW_ERROR); + await expect(call.prove()).rejects.toThrow(U128_UNDERFLOW_ERROR); // docs:end:local-pub-fails }, 30_000); diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index 8309946d1f5b..185455ce4cd8 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -82,7 +82,7 @@ describe('guides/writing_an_account_contract', () => { await token.methods.redeem_shield({ address }, mintAmount, secret).send().wait(); - const balance = await token.methods.balance_of_private({ address }).view(); + const balance = await token.methods.balance_of_private({ address }).simulate(); logger(`Balance of wallet is now ${balance}`); // docs:end:account-contract-works expect(balance).toEqual(50n); @@ -95,7 +95,7 @@ describe('guides/writing_an_account_contract', () => { const tokenWithWrongWallet = token.withWallet(wrongWallet); try { - await tokenWithWrongWallet.methods.mint_private(200, secretHash).simulate(); + await tokenWithWrongWallet.methods.mint_private(200, secretHash).prove(); } catch (err) { logger(`Failed to send tx: ${err}`); } diff --git a/yarn-project/end-to-end/src/sample-dapp/index.mjs b/yarn-project/end-to-end/src/sample-dapp/index.mjs index 73bf03685de5..861c6f2cc03e 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.mjs @@ -20,7 +20,7 @@ async function showPrivateBalances(pxe) { for (const account of accounts) { // highlight-next-line:showPrivateBalances - const balance = await token.methods.balance_of_private(account.address).view(); + const balance = await token.methods.balance_of_private(account.address).simulate(); console.log(`Balance of ${account.address}: ${balance}`); } // docs:end:showPrivateBalances @@ -79,7 +79,7 @@ async function showPublicBalances(pxe) { for (const account of accounts) { // highlight-next-line:showPublicBalances - const balance = await token.methods.balance_of_public(account.address).view(); + const balance = await token.methods.balance_of_public(account.address).simulate(); console.log(`Balance of ${account.address}: ${balance}`); } // docs:end:showPublicBalances diff --git a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs index 9d22d07e7bc5..837c5386c974 100644 --- a/yarn-project/end-to-end/src/sample-dapp/index.test.mjs +++ b/yarn-project/end-to-end/src/sample-dapp/index.test.mjs @@ -49,9 +49,9 @@ describe('token', () => { // docs:start:test it('increases recipient funds on transfer', async () => { - expect(await token.methods.balance_of_private(recipient.getAddress()).view()).toEqual(0n); + expect(await token.methods.balance_of_private(recipient.getAddress()).simulate()).toEqual(0n); await token.methods.transfer(owner.getAddress(), recipient.getAddress(), 20n, 0).send().wait(); - expect(await token.methods.balance_of_private(recipient.getAddress()).view()).toEqual(20n); + expect(await token.methods.balance_of_private(recipient.getAddress()).simulate()).toEqual(20n); }, 30_000); // docs:end:test }); diff --git a/yarn-project/end-to-end/src/shared/browser.ts b/yarn-project/end-to-end/src/shared/browser.ts index 81d4725cf103..c9cc3d2098ed 100644 --- a/yarn-project/end-to-end/src/shared/browser.ts +++ b/yarn-project/end-to-end/src/shared/browser.ts @@ -168,7 +168,7 @@ export const browserTestSuite = ( const [wallet] = await getDeployedTestAccountsWallets(pxe); const owner = wallet.getCompleteAddress().address; const contract = await Contract.at(AztecAddress.fromString(contractAddress), TokenContractArtifact, wallet); - const balance = await contract.methods.balance_of_private(owner).view({ from: owner }); + const balance = await contract.methods.balance_of_private(owner).simulate({ from: owner }); return balance; }, pxeURL, @@ -199,7 +199,7 @@ export const browserTestSuite = ( .send() .wait(); console.log(`Transferred ${transferAmount} tokens to new Account`); - return await contract.methods.balance_of_private(receiverAddress).view({ from: receiverAddress }); + return await contract.methods.balance_of_private(receiverAddress).simulate({ from: receiverAddress }); }, pxeURL, (await getTokenAddress()).toString(), diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 603560339c81..78bfdb7ee735 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -105,17 +105,17 @@ export async function deployAndInitializeTokenAndBridgeContracts( .send({ portalContract: tokenPortalAddress }) .deployed(); - if ((await token.methods.admin().view()) !== owner.toBigInt()) { + if ((await token.methods.admin().simulate()) !== owner.toBigInt()) { throw new Error(`Token admin is not ${owner}`); } - if (!(await bridge.methods.token().view()).equals(token.address)) { + if (!(await bridge.methods.token().simulate()).equals(token.address)) { throw new Error(`Bridge token is not ${token.address}`); } // make the bridge a minter on the token: await token.methods.set_minter(bridge.address, true).send().wait(); - if ((await token.methods.is_minter(bridge.address).view()) === 1n) { + if ((await token.methods.is_minter(bridge.address).simulate()) === 1n) { throw new Error(`Bridge is not a minter`); } @@ -344,7 +344,7 @@ export class CrossChainTestHarness { } async getL2PrivateBalanceOf(owner: AztecAddress) { - return await this.l2Token.methods.balance_of_private(owner).view({ from: owner }); + return await this.l2Token.methods.balance_of_private(owner).simulate({ from: owner }); } async expectPrivateBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) { @@ -354,7 +354,7 @@ export class CrossChainTestHarness { } async getL2PublicBalanceOf(owner: AztecAddress) { - return await this.l2Token.methods.balance_of_public(owner).view(); + return await this.l2Token.methods.balance_of_public(owner).simulate(); } async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) { diff --git a/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts b/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts index 9e7bb4d740e4..6118be50591a 100644 --- a/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts @@ -208,7 +208,7 @@ class GasBridgingTestHarness implements IGasBridgingTestHarness { } async getL2PublicBalanceOf(owner: AztecAddress) { - return await this.l2Token.methods.balance_of_public(owner).view(); + return await this.l2Token.methods.balance_of_public(owner).simulate(); } async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) { diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index a5cd9744075e..3b01120511e3 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -209,7 +209,7 @@ export const uniswapL1L2TestSuite = ( // before swap - check nonce_for_burn_approval stored on uniswap // (which is used by uniswap to approve the bridge to burn funds on its behalf to exit to L1) - const nonceForBurnApprovalBeforeSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().view(); + const nonceForBurnApprovalBeforeSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().simulate(); // 3. Owner gives uniswap approval to unshield funds to self on its behalf logger('Approving uniswap to unshield funds to self on my behalf'); @@ -291,7 +291,7 @@ export const uniswapL1L2TestSuite = ( // ensure that uniswap contract didn't eat the funds. await wethCrossChainHarness.expectPublicBalanceOnL2(uniswapL2Contract.address, 0n); // check burn approval nonce incremented: - const nonceForBurnApprovalAfterSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().view(); + const nonceForBurnApprovalAfterSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().simulate(); expect(nonceForBurnApprovalAfterSwap).toBe(nonceForBurnApprovalBeforeSwap + 1n); // 5. Consume L2 to L1 message by calling uniswapPortal.swap_private() @@ -432,7 +432,7 @@ export const uniswapL1L2TestSuite = ( // before swap - check nonce_for_burn_approval stored on uniswap // (which is used by uniswap to approve the bridge to burn funds on its behalf to exit to L1) - const nonceForBurnApprovalBeforeSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().view(); + const nonceForBurnApprovalBeforeSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().simulate(); // 4. Swap on L1 - sends L2 to L1 message to withdraw WETH to L1 and another message to swap assets. const [secretForDepositingSwappedDai, secretHashForDepositingSwappedDai] = @@ -510,7 +510,7 @@ export const uniswapL1L2TestSuite = ( await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge); // check burn approval nonce incremented: - const nonceForBurnApprovalAfterSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().view(); + const nonceForBurnApprovalAfterSwap = await uniswapL2Contract.methods.nonce_for_burn_approval().simulate(); expect(nonceForBurnApprovalAfterSwap).toBe(nonceForBurnApprovalBeforeSwap + 1n); // 5. Perform the swap on L1 with the `uniswapPortal.swap_private()` (consuming L2 to L1 messages) @@ -632,7 +632,7 @@ export const uniswapL1L2TestSuite = ( Fr.random(), ownerEthAddress, ) - .simulate(), + .prove(), ).rejects.toThrow(`Unknown auth witness for message hash ${expectedMessageHash.toString()}`); }); @@ -672,7 +672,7 @@ export const uniswapL1L2TestSuite = ( Fr.random(), ownerEthAddress, ) - .simulate(), + .prove(), ).rejects.toThrow('Assertion failed: input_asset address is not the same as seen in the bridge contract'); }); @@ -749,7 +749,7 @@ export const uniswapL1L2TestSuite = ( await ownerWallet.setPublicAuthWit(swapMessageHash, true).send().wait(); // Swap! - await expect(action.simulate()).rejects.toThrow( + await expect(action.prove()).rejects.toThrow( "Assertion failed: Message not authorized by account 'is_valid == true'", ); }); @@ -783,7 +783,7 @@ export const uniswapL1L2TestSuite = ( ownerEthAddress, Fr.ZERO, ) - .simulate(), + .prove(), ).rejects.toThrow(`Assertion failed: Message not authorized by account 'is_valid == true'`); }); diff --git a/yarn-project/end-to-end/src/simulators/lending_simulator.ts b/yarn-project/end-to-end/src/simulators/lending_simulator.ts index 2d5c2f344a01..95805f004211 100644 --- a/yarn-project/end-to-end/src/simulators/lending_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/lending_simulator.ts @@ -165,7 +165,7 @@ export class LendingSimulator { expect(this.borrowed).toEqual(this.stableCoin.totalSupply - this.mintedOutside); - const asset = await this.lendingContract.methods.get_asset(0).view(); + const asset = await this.lendingContract.methods.get_asset(0).simulate(); const interestAccumulator = asset['interest_accumulator']; const interestAccumulatorBigint = BigInt(interestAccumulator.lo + interestAccumulator.hi * 2n ** 64n); @@ -173,7 +173,7 @@ export class LendingSimulator { expect(asset['last_updated_ts']).toEqual(BigInt(this.time)); for (const key of [this.account.address, this.account.key()]) { - const privatePos = await this.lendingContract.methods.get_position(key).view(); + const privatePos = await this.lendingContract.methods.get_position(key).simulate(); expect(new Fr(privatePos['collateral'])).toEqual(this.collateral[key.toString()] ?? Fr.ZERO); expect(new Fr(privatePos['static_debt'])).toEqual(this.staticDebt[key.toString()] ?? Fr.ZERO); expect(privatePos['debt']).toEqual( diff --git a/yarn-project/end-to-end/src/simulators/token_simulator.ts b/yarn-project/end-to-end/src/simulators/token_simulator.ts index 9a5a1938165a..eacb27e201db 100644 --- a/yarn-project/end-to-end/src/simulators/token_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/token_simulator.ts @@ -81,12 +81,14 @@ export class TokenSimulator { } public async check() { - expect(await this.token.methods.total_supply().view()).toEqual(this.totalSupply); + expect(await this.token.methods.total_supply().simulate()).toEqual(this.totalSupply); // Check that all our public matches for (const address of this.accounts) { - expect(await this.token.methods.balance_of_public({ address }).view()).toEqual(this.balanceOfPublic(address)); - expect(await this.token.methods.balance_of_private({ address }).view()).toEqual(this.balanceOfPrivate(address)); + expect(await this.token.methods.balance_of_public({ address }).simulate()).toEqual(this.balanceOfPublic(address)); + expect(await this.token.methods.balance_of_private({ address }).simulate()).toEqual( + this.balanceOfPrivate(address), + ); } } } diff --git a/yarn-project/foundation/src/abi/decoder.ts b/yarn-project/foundation/src/abi/decoder.ts index a65f52925ea3..69bab60b6c57 100644 --- a/yarn-project/foundation/src/abi/decoder.ts +++ b/yarn-project/foundation/src/abi/decoder.ts @@ -7,6 +7,7 @@ import { isAztecAddressStruct } from './utils.js'; * The type of our decoded ABI. */ export type DecodedReturn = bigint | boolean | AztecAddress | DecodedReturn[] | { [key: string]: DecodedReturn }; +export type ProcessReturnValues = (DecodedReturn | undefined)[] | undefined; /** * Decodes return values from a function call. diff --git a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts index 955d4ae80d71..68ae86533bed 100644 --- a/yarn-project/pxe/src/pxe_http/pxe_http_server.ts +++ b/yarn-project/pxe/src/pxe_http/pxe_http_server.ts @@ -9,6 +9,7 @@ import { Note, NullifierMembershipWitness, type PXE, + SimulatedTx, Tx, TxEffect, TxExecutionRequest, @@ -49,7 +50,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer { TxEffect, LogId, }, - { Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, + { SimulatedTx, Tx, TxReceipt, EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness }, ['start', 'stop'], ); } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 338d0c6cedc1..c08323ce9e61 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -11,6 +11,7 @@ import { MerkleTreeId, type NoteFilter, type PXE, + SimulatedTx, SimulationError, Tx, type TxEffect, @@ -71,7 +72,7 @@ export class PXEService implements PXE { private simulator: AcirSimulator; private log: DebugLogger; private nodeVersion: string; - // serialize synchronizer and calls to simulateTx. + // serialize synchronizer and calls to proveTx. // ensures that state is not changed while simulating private jobQueue = new SerialQueue(); @@ -388,26 +389,43 @@ export class PXEService implements PXE { return await this.node.getBlock(blockNumber); } - public async simulateTx(txRequest: TxExecutionRequest, simulatePublic: boolean) { + public async proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean) { + return (await this.simulateTx(txRequest, simulatePublic)).tx; + } + + public async simulateTx( + txRequest: TxExecutionRequest, + simulatePublic: boolean, + msgSender: AztecAddress | undefined = undefined, + ) { if (!txRequest.functionData.isPrivate) { throw new Error(`Public entrypoints are not allowed`); } - - // all simulations must be serialized w.r.t. the synchronizer return await this.jobQueue.put(async () => { const timer = new Timer(); - const tx = await this.#simulateAndProve(txRequest); - this.log(`Processed private part of ${tx.getTxHash()}`, { - eventName: 'tx-pxe-processing', - duration: timer.ms(), - ...tx.getStats(), - } satisfies TxPXEProcessingStats); + const simulatedTx = await this.#simulateAndProve(txRequest, msgSender); + // We log only if the msgSender is undefined, as simulating with a different msgSender + // is unlikely to be a real transaction, and likely to be only used to read data. + // Meaning that it will not necessarily have produced a nullifier (and thus have no TxHash) + // If we log, the `getTxHash` function will throw. + + if (!msgSender) { + this.log(`Processed private part of ${simulatedTx.tx.getTxHash()}`, { + eventName: 'tx-pxe-processing', + duration: timer.ms(), + ...simulatedTx.tx.getStats(), + } satisfies TxPXEProcessingStats); + } + if (simulatePublic) { - await this.#simulatePublicCalls(tx); + // Only one transaction, so we can take index 0. + simulatedTx.publicReturnValues = (await this.#simulatePublicCalls(simulatedTx.tx))[0]; } - this.log.info(`Executed local simulation for ${tx.getTxHash()}`); - return tx; + if (!msgSender) { + this.log.info(`Executed local simulation for ${simulatedTx.tx.getTxHash()}`); + } + return simulatedTx; }); } @@ -524,14 +542,14 @@ export class PXEService implements PXE { }; } - async #simulate(txRequest: TxExecutionRequest): Promise { + async #simulate(txRequest: TxExecutionRequest, msgSender?: AztecAddress): Promise { // TODO - Pause syncing while simulating. const { contractAddress, functionArtifact, portalContract } = await this.#getSimulationParameters(txRequest); this.log('Executing simulator...'); try { - const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, portalContract); + const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, portalContract, msgSender); this.log('Simulation completed!'); return result; } catch (err) { @@ -575,7 +593,7 @@ export class PXEService implements PXE { */ async #simulatePublicCalls(tx: Tx) { try { - await this.node.simulatePublicCalls(tx); + return await this.node.simulatePublicCalls(tx); } catch (err) { // Try to fill in the noir call stack since the PXE may have access to the debug metadata if (err instanceof SimulationError) { @@ -599,20 +617,21 @@ export class PXEService implements PXE { /** * Simulate a transaction, generate a kernel proof, and create a private transaction object. - * The function takes in a transaction request and an ECDSA signature. It simulates the transaction, - * then generates a kernel proof using the simulation result. Finally, it creates a private + * The function takes in a transaction request, simulates it, and then generates a kernel proof + * using the simulation result. Finally, it creates a private * transaction object with the generated proof and public inputs. If a new contract address is provided, * the function will also include the new contract's public functions in the transaction object. * * @param txExecutionRequest - The transaction request to be simulated and proved. * @param signature - The ECDSA signature for the transaction request. - * @returns A private transaction object containing the proof, public inputs, and encrypted logs. + * @param msgSender - (Optional) The message sender to use for the simulation. + * @returns An object tract contains: + * A private transaction object containing the proof, public inputs, and encrypted logs. + * The return values of the private execution */ - async #simulateAndProve(txExecutionRequest: TxExecutionRequest) { - // TODO - Pause syncing while simulating. - + async #simulateAndProve(txExecutionRequest: TxExecutionRequest, msgSender?: AztecAddress) { // Get values that allow us to reconstruct the block hash - const executionResult = await this.#simulate(txExecutionRequest); + const executionResult = await this.#simulate(txExecutionRequest, msgSender); const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node); const kernelProver = new KernelProver(kernelOracle); @@ -630,7 +649,8 @@ export class PXEService implements PXE { // TODO(#757): Enforce proper ordering of enqueued public calls await this.patchPublicCallStackOrdering(publicInputs, enqueuedPublicFunctions); - return new Tx(publicInputs, proof, encryptedLogs, unencryptedLogs, enqueuedPublicFunctions); + const tx = new Tx(publicInputs, proof, encryptedLogs, unencryptedLogs, enqueuedPublicFunctions); + return new SimulatedTx(tx, [executionResult.returnValues]); } /** diff --git a/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts b/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts index 7eb329c42e31..314995a4fd5a 100644 --- a/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts +++ b/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts @@ -135,12 +135,12 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise) => authWitnesses: [], }); - await expect(async () => await pxe.simulateTx(txExecutionRequest, false)).rejects.toThrow( + await expect(async () => await pxe.proveTx(txExecutionRequest, false)).rejects.toThrow( 'Public entrypoints are not allowed', ); }); - // Note: Not testing a successful run of `simulateTx`, `sendTx`, `getTxReceipt` and `viewTx` here as it requires + // Note: Not testing a successful run of `proveTx`, `sendTx`, `getTxReceipt` and `viewTx` here as it requires // a larger setup and it's sufficiently tested in the e2e tests. it('throws when getting public storage for non-existent contract', async () => { diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index edb65cc32ee1..c26f2a2e2a2a 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -42,6 +42,13 @@ import { makeEmptyProof, } from '@aztec/circuits.js'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; +import { + type ABIType, + type DecodedReturn, + type FunctionArtifact, + type ProcessReturnValues, + decodeReturnValues, +} from '@aztec/foundation/abi'; import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { type Tuple } from '@aztec/foundation/serialize'; @@ -110,6 +117,7 @@ export abstract class AbstractPhaseManager { * revert reason, if any */ revertReason: SimulationError | undefined; + returnValues: ProcessReturnValues; }>; public static extractEnqueuedPublicCallsByPhase( @@ -180,14 +188,22 @@ export abstract class AbstractPhaseManager { tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs, previousPublicKernelProof: Proof, - ): Promise<[PublicKernelCircuitPublicInputs, Proof, UnencryptedFunctionL2Logs[], SimulationError | undefined]> { + ): Promise< + [ + PublicKernelCircuitPublicInputs, + Proof, + UnencryptedFunctionL2Logs[], + SimulationError | undefined, + ProcessReturnValues, + ] + > { let kernelOutput = previousPublicKernelOutput; let kernelProof = previousPublicKernelProof; const enqueuedCalls = this.extractEnqueuedPublicCalls(tx); if (!enqueuedCalls || !enqueuedCalls.length) { - return [kernelOutput, kernelProof, [], undefined]; + return [kernelOutput, kernelProof, [], undefined, undefined]; } const newUnencryptedFunctionLogs: UnencryptedFunctionL2Logs[] = []; @@ -196,9 +212,13 @@ export abstract class AbstractPhaseManager { // separate public callstacks to be proven by separate public kernel sequences // and submitted separately to the base rollup? + const returns = []; + for (const enqueuedCall of enqueuedCalls) { const executionStack: (PublicExecution | PublicExecutionResult)[] = [enqueuedCall]; + let currentReturn: DecodedReturn | undefined = undefined; + // Keep track of which result is for the top/enqueued call let enqueuedExecutionResult: PublicExecutionResult | undefined; @@ -252,22 +272,34 @@ export abstract class AbstractPhaseManager { result.revertReason }`, ); - return [kernelOutput, kernelProof, [], result.revertReason]; + return [kernelOutput, kernelProof, [], result.revertReason, undefined]; } if (!enqueuedExecutionResult) { enqueuedExecutionResult = result; + + // Padding as the AVM is not always returning the expected return size (4) + // which is expected by the kernel. + const paddedReturn = padArrayEnd(result.returnValues, Fr.ZERO, RETURN_VALUES_LENGTH); + + // TODO(#5450) Need to use the proper return values here + const returnTypes: ABIType[] = [{ kind: 'array', length: 4, type: { kind: 'field' } }]; + const mockArtifact = { returnTypes } as any as FunctionArtifact; + + currentReturn = decodeReturnValues(mockArtifact, paddedReturn); } } // HACK(#1622): Manually patches the ordering of public state actions // TODO(#757): Enforce proper ordering of public state actions patchPublicStorageActionOrdering(kernelOutput, enqueuedExecutionResult!, this.phase); + + returns.push(currentReturn); } // TODO(#3675): This should be done in a public kernel circuit removeRedundantPublicDataWrites(kernelOutput); - return [kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined]; + return [kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns]; } protected async runKernelCircuit( diff --git a/yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts index e09fe0051faf..007910a0572a 100644 --- a/yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts @@ -40,7 +40,7 @@ export class AppLogicPhaseManager extends AbstractPhaseManager { // TODO(@spalladino): Should we allow emitting contracts in the fee preparation phase? this.log(`Processing tx ${tx.getTxHash()}`); await this.publicContractsDB.addNewContracts(tx); - const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs, revertReason] = + const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs, revertReason, returnValues] = await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousPublicKernelProof).catch( // if we throw for any reason other than simulation, we need to rollback and drop the TX async err => { @@ -57,6 +57,6 @@ export class AppLogicPhaseManager extends AbstractPhaseManager { await this.publicStateDB.checkpoint(); } - return { publicKernelOutput, publicKernelProof, revertReason }; + return { publicKernelOutput, publicKernelProof, revertReason, returnValues }; } } diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts index 592fe9019a53..cd589b0e70d8 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -814,7 +814,7 @@ class PublicExecutionResultBuilder { nullifierReadRequests: [], nullifierNonExistentReadRequests: [], contractStorageUpdateRequests: this._contractStorageUpdateRequests, - returnValues: this._returnValues, + returnValues: padArrayEnd(this._returnValues, Fr.ZERO, 4), // TODO(#5450) Need to use the proper return values here newNoteHashes: [], newNullifiers: [], newL2ToL1Messages: [], diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.ts index 064d0c45b4df..14c15d70b9bd 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.ts @@ -11,6 +11,7 @@ import { } from '@aztec/circuit-types'; import { type TxSequencerProcessingStats } from '@aztec/circuit-types/stats'; import { type GlobalVariables, type Header } from '@aztec/circuits.js'; +import { type ProcessReturnValues } from '@aztec/foundation/abi'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { PublicExecutor, type PublicStateDB, type SimulationProvider } from '@aztec/simulator'; @@ -20,7 +21,7 @@ import { type MerkleTreeOperations } from '@aztec/world-state'; import { type PublicKernelCircuitSimulator } from '../simulator/index.js'; import { ContractsDataSourcePublicDB, WorldStateDB, WorldStatePublicDB } from '../simulator/public_executor.js'; import { RealPublicKernelCircuitSimulator } from '../simulator/public_kernel.js'; -import { type AbstractPhaseManager } from './abstract_phase_manager.js'; +import { type AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js'; import { PhaseManagerFactory } from './phase_manager_factory.js'; /** @@ -84,13 +85,15 @@ export class PublicProcessor { * @param txs - Txs to process. * @returns The list of processed txs with their circuit simulation outputs. */ - public async process(txs: Tx[]): Promise<[ProcessedTx[], FailedTx[]]> { + public async process(txs: Tx[]): Promise<[ProcessedTx[], FailedTx[], ProcessReturnValues[]]> { // The processor modifies the tx objects in place, so we need to clone them. txs = txs.map(tx => Tx.clone(tx)); const result: ProcessedTx[] = []; const failed: FailedTx[] = []; + const returns: ProcessReturnValues[] = []; for (const tx of txs) { + let returnValues: ProcessReturnValues = undefined; let phase: AbstractPhaseManager | undefined = PhaseManagerFactory.phaseFromTx( tx, this.db, @@ -108,6 +111,9 @@ export class PublicProcessor { try { while (phase) { const output = await phase.handle(tx, publicKernelPublicInput, proof); + if (phase.phase === PublicKernelPhase.APP_LOGIC) { + returnValues = output.returnValues; + } publicKernelPublicInput = output.publicKernelOutput; proof = output.publicKernelProof; revertReason ??= output.revertReason; @@ -128,6 +134,7 @@ export class PublicProcessor { validateProcessedTx(processedTransaction); result.push(processedTransaction); + returns.push(returnValues); this.log(`Processed public part of ${tx.data.endNonRevertibleData.newNullifiers[0].value}`, { eventName: 'tx-sequencer-processing', @@ -146,10 +153,11 @@ export class PublicProcessor { tx, error: err instanceof Error ? err : new Error(errorMessage), }); + returns.push([]); } } - return [result, failed]; + return [result, failed, returns]; } /** diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 49d0b0748249..f4b77c110b77 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -71,7 +71,7 @@ describe('sequencer', () => { }); publicProcessor = mock({ - process: async txs => [await Promise.all(txs.map(tx => makeProcessedTx(tx))), []], + process: async txs => [await Promise.all(txs.map(tx => makeProcessedTx(tx))), [], []], makeEmptyProcessedTx: () => makeEmptyProcessedTx(Header.empty(), chainId, version), }); diff --git a/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.ts index c491843436c3..43e434d9b02f 100644 --- a/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.ts @@ -45,6 +45,6 @@ export class SetupPhaseManager extends AbstractPhaseManager { ); tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs); await this.publicStateDB.checkpoint(); - return { publicKernelOutput, publicKernelProof, revertReason }; + return { publicKernelOutput, publicKernelProof, revertReason, returnValues: undefined }; } } diff --git a/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts index 684931c30a72..ff1ca8c7de40 100644 --- a/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts @@ -42,6 +42,6 @@ export class TailPhaseManager extends AbstractPhaseManager { // commit the state updates from this transaction await this.publicStateDB.commit(); - return { publicKernelOutput, publicKernelProof, revertReason: undefined }; + return { publicKernelOutput, publicKernelProof, revertReason: undefined, returnValues: undefined }; } } diff --git a/yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts index 62cd6bfdf3b0..825d2de24100 100644 --- a/yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts @@ -45,6 +45,6 @@ export class TeardownPhaseManager extends AbstractPhaseManager { ); tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs); await this.publicStateDB.checkpoint(); - return { publicKernelOutput, publicKernelProof, revertReason }; + return { publicKernelOutput, publicKernelProof, revertReason, returnValues: undefined }; } } diff --git a/yarn-project/simulator/README.md b/yarn-project/simulator/README.md index 41b8fe31baf6..ec524980fc84 100644 --- a/yarn-project/simulator/README.md +++ b/yarn-project/simulator/README.md @@ -28,13 +28,15 @@ They are run with the assistance of an oracle that provides any value read from Public functions can call other public function, but no private functions. -### Unconstrained (view) Functions +### Unconstrained Functions -Unconstrained functions are used to extract useful data for users, such as the user balance. They are not proved, and are simulated client-side. +Unconstrained functions are useful to extract useful data for users that could produce very large execution traces - such as the summed balance of all a users notes +They are not proved, and are simulated client-side. They are run with the assistance of a DB oracle that provides any private data requested by the function. -At the moment, unconstrained functions cannot call any other function. It would be possible to allow them to call other unconstrained functions. +At the moment, unconstrained functions cannot call any other function. +It would be possible to allow them to call other unconstrained functions. ## Usage diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index e79629abfd19..379bb25504e2 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -1011,7 +1011,7 @@ describe('Private Execution test suite', () => { oracle.getCompleteAddress.mockResolvedValue(completeAddress); const result = await runSimulator({ artifact, args }); - expect(result.returnValues).toEqual([pubKey.x.value, pubKey.y.value]); + expect(result.returnValues).toEqual([pubKey.x.value, pubKey.y.value, 0n, 0n]); }); }); @@ -1040,7 +1040,7 @@ describe('Private Execution test suite', () => { // Overwrite the oracle return value oracle.getPortalContractAddress.mockResolvedValue(portalContractAddress); const result = await runSimulator({ artifact, args }); - expect(result.returnValues).toEqual(portalContractAddress.toField().value); + expect(result.returnValues).toEqual([portalContractAddress.toField().value, 0n, 0n, 0n]); }); it('this_address should return the current context address', async () => { @@ -1052,7 +1052,7 @@ describe('Private Execution test suite', () => { // Overwrite the oracle return value const result = await runSimulator({ artifact, args: [], contractAddress }); - expect(result.returnValues).toEqual(contractAddress.toField().value); + expect(result.returnValues).toEqual([contractAddress.toField().value, 0n, 0n, 0n]); }); it("this_portal_address should return the current context's portal address", async () => { @@ -1064,7 +1064,7 @@ describe('Private Execution test suite', () => { // Overwrite the oracle return value const result = await runSimulator({ artifact, args: [], portalContractAddress }); - expect(result.returnValues).toEqual(portalContractAddress.toField().value); + expect(result.returnValues).toEqual([portalContractAddress.toField().value, 0n, 0n, 0n]); }); }); diff --git a/yarn-project/simulator/src/client/private_execution.ts b/yarn-project/simulator/src/client/private_execution.ts index de31eae0da15..2eb822b4b7a8 100644 --- a/yarn-project/simulator/src/client/private_execution.ts +++ b/yarn-project/simulator/src/client/private_execution.ts @@ -1,5 +1,5 @@ import { type FunctionData, PrivateCallStackItem, PrivateCircuitPublicInputs } from '@aztec/circuits.js'; -import { type FunctionArtifactWithDebugMetadata, decodeReturnValues } from '@aztec/foundation/abi'; +import { type ABIType, type FunctionArtifactWithDebugMetadata, decodeReturnValues } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -52,7 +52,13 @@ export async function executePrivateFunction( publicInputs.unencryptedLogPreimagesLength = new Fr(unencryptedLogs.getSerializedLength()); const callStackItem = new PrivateCallStackItem(contractAddress, functionData, publicInputs); - const returnValues = decodeReturnValues(artifact, publicInputs.returnValues); + + // Mocking the return type to be an array of 4 fields + // TODO: @LHerskind must be updated as we are progressing with the macros to get the information + const returnTypes: ABIType[] = [{ kind: 'array', length: 4, type: { kind: 'field' } }]; + const mockArtifact = { ...artifact, returnTypes }; + const returnValues = decodeReturnValues(mockArtifact, publicInputs.returnValues); + const noteHashReadRequestPartialWitnesses = context.getNoteHashReadRequestPartialWitnesses( publicInputs.noteHashReadRequests, );