From cba1be0ae6da3958aa9c38b4687fa93f1c651eca Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 25 Sep 2023 10:15:45 +0000 Subject: [PATCH 1/3] WIP --- .../end-to-end/src/e2e_2_rpc_servers.test.ts | 72 ++++++++++++++++--- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts index 856b6c354da6..0eacd49c3fc1 100644 --- a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts @@ -7,11 +7,17 @@ import { toBigInt } from '@aztec/foundation/serialize'; import { ChildContract, TokenContract } from '@aztec/noir-contracts/types'; import { AztecRPC, CompleteAddress, TxStatus } from '@aztec/types'; +import { jest } from '@jest/globals'; + import { expectsNumOfEncryptedLogsInTheLastBlockToBe, setup, setupAztecRPCServer } from './fixtures/utils.js'; const { SANDBOX_URL = '' } = process.env; +const TIMEOUT = 60_000; + describe('e2e_2_rpc_servers', () => { + jest.setTimeout(TIMEOUT); + let aztecNode: AztecNodeService | undefined; let aztecRpcServerA: AztecRPC; let aztecRpcServerB: AztecRPC; @@ -77,24 +83,28 @@ describe('e2e_2_rpc_servers', () => { expect(balance).toBe(expectedBalance); }; - const deployTokenContract = async (initialBalance: bigint, owner: AztecAddress) => { + const deployTokenContract = async (initialAdminBalance: bigint, admin: AztecAddress) => { logger(`Deploying Token contract...`); const contract = await TokenContract.deploy(walletA).send().deployed(); - expect((await contract.methods._initialize(owner).send().wait()).status).toBe(TxStatus.MINED); + expect((await contract.methods._initialize(admin).send().wait()).status).toBe(TxStatus.MINED); + + if (initialAdminBalance > 0n) { + await mintTokens(contract, admin, initialAdminBalance); + } + + logger('L2 contract deployed'); + + return contract.completeAddress; + }; + const mintTokens = async (contract: TokenContract, recipient: AztecAddress, balance: bigint) => { const secret = Fr.random(); const secretHash = await computeMessageSecretHash(secret); - expect((await contract.methods.mint_private(initialBalance, secretHash).send().wait()).status).toEqual( + expect((await contract.methods.mint_private(balance, secretHash).send().wait()).status).toEqual(TxStatus.MINED); + expect((await contract.methods.redeem_shield(recipient, balance, secret).send().wait()).status).toEqual( TxStatus.MINED, ); - expect((await contract.methods.redeem_shield(owner, initialBalance, secret).send().wait()).status).toEqual( - TxStatus.MINED, - ); - - logger('L2 contract deployed'); - - return contract.completeAddress; }; it('transfers fund from user A to B via RPC server A followed by transfer from B to A via RPC server B', async () => { @@ -191,5 +201,45 @@ describe('e2e_2_rpc_servers', () => { const storedValue = await getChildStoredValue(childCompleteAddress, aztecRpcServerB); expect(storedValue).toBe(newValueToSet); - }, 60_000); + }); + + it.only('private state is "zero" when Aztec RPC Server does not have the account private key', async () => { + const userABalance = 100n; + const userBBalance = 150n; + + const completeTokenAddress = await deployTokenContract(userABalance, userA.address); + const contractWithWalletA = await TokenContract.at(completeTokenAddress.address, walletA); + + // Add account B to wallet A + await aztecRpcServerA.registerRecipient(userB); + // Add account A to wallet B + await aztecRpcServerB.registerRecipient(userA); + + // Add token to RPC server B + await aztecRpcServerB.addContracts([ + { + abi: TokenContract.abi, + completeAddress: completeTokenAddress, + portalContract: EthAddress.ZERO, + }, + ]); + + // Mint tokens to user B + await mintTokens(contractWithWalletA, userB.address, userBBalance); + + // Ensure that both servers are synchronized + await awaitServerSynchronized(aztecRpcServerA); + await awaitServerSynchronized(aztecRpcServerB); + + // Check that user A balance is 100 on server A + await expectTokenBalance(walletA, completeTokenAddress.address, userA.address, userABalance); + // Check that user B balance is 150 on server B + await expectTokenBalance(walletB, completeTokenAddress.address, userB.address, userBBalance); + + // CHECK THAT PRIVATE BALANCES ARE 0 WHEN ACCOUNT'S PRIVATE KEYS ARE NOT REGISTERED + // Check that user A balance is 0 on server B + await expectTokenBalance(walletB, completeTokenAddress.address, userA.address, 0n); + // Check that user B balance is 0 on server A + await expectTokenBalance(walletA, completeTokenAddress.address, userB.address, 0n); + }); }); From d703c490f06f691c87ec77289af0a16f8b373269 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 25 Sep 2023 11:22:13 +0000 Subject: [PATCH 2/3] fixes --- .../src/synchronizer/synchronizer.ts | 7 +++++-- .../end-to-end/src/e2e_2_rpc_servers.test.ts | 19 ++++++++++--------- .../types/src/interfaces/aztec_rpc.ts | 1 + 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/yarn-project/aztec-rpc/src/synchronizer/synchronizer.ts b/yarn-project/aztec-rpc/src/synchronizer/synchronizer.ts index b3cc55363a38..e8e69c7b0045 100644 --- a/yarn-project/aztec-rpc/src/synchronizer/synchronizer.ts +++ b/yarn-project/aztec-rpc/src/synchronizer/synchronizer.ts @@ -247,15 +247,18 @@ export class Synchronizer { * @returns True if the account is fully synched, false otherwise. * @remarks Checks whether all the notes from all the blocks have been processed. If it is not the case, the * retrieved information from contracts might be old/stale (e.g. old token balance). + * @throws If checking a sync status of account which is not registered. */ public async isAccountStateSynchronized(account: AztecAddress) { const completeAddress = await this.db.getCompleteAddress(account); if (!completeAddress) { - return false; + throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`); } const processor = this.noteProcessors.find(x => x.publicKey.equals(completeAddress.publicKey)); if (!processor) { - return false; + throw new Error( + `Checking if account is synched is not possible for ${account} because it is only registered as a recipient.`, + ); } return await processor.isSynchronized(); } diff --git a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts index 0eacd49c3fc1..523210680ddf 100644 --- a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts @@ -72,9 +72,12 @@ describe('e2e_2_rpc_servers', () => { tokenAddress: AztecAddress, owner: AztecAddress, expectedBalance: bigint, + checkIfSynchronized = true, ) => { - // First wait until the corresponding RPC server has synchronized the account - await awaitUserSynchronized(wallet, owner); + if (checkIfSynchronized) { + // First wait until the corresponding RPC server has synchronized the account + await awaitUserSynchronized(wallet, owner); + } // Then check the balance const contractWithWallet = await TokenContract.at(tokenAddress, wallet); @@ -203,7 +206,7 @@ describe('e2e_2_rpc_servers', () => { expect(storedValue).toBe(newValueToSet); }); - it.only('private state is "zero" when Aztec RPC Server does not have the account private key', async () => { + it('private state is "zero" when Aztec RPC Server does not have the account private key', async () => { const userABalance = 100n; const userBBalance = 150n; @@ -227,19 +230,17 @@ describe('e2e_2_rpc_servers', () => { // Mint tokens to user B await mintTokens(contractWithWalletA, userB.address, userBBalance); - // Ensure that both servers are synchronized - await awaitServerSynchronized(aztecRpcServerA); - await awaitServerSynchronized(aztecRpcServerB); - // Check that user A balance is 100 on server A await expectTokenBalance(walletA, completeTokenAddress.address, userA.address, userABalance); // Check that user B balance is 150 on server B await expectTokenBalance(walletB, completeTokenAddress.address, userB.address, userBBalance); // CHECK THAT PRIVATE BALANCES ARE 0 WHEN ACCOUNT'S PRIVATE KEYS ARE NOT REGISTERED + // Note: Not checking if the account is synchronized because it is not registered as an account (it would throw). + const checkIfSynchronized = false; // Check that user A balance is 0 on server B - await expectTokenBalance(walletB, completeTokenAddress.address, userA.address, 0n); + await expectTokenBalance(walletB, completeTokenAddress.address, userA.address, 0n, checkIfSynchronized); // Check that user B balance is 0 on server A - await expectTokenBalance(walletA, completeTokenAddress.address, userB.address, 0n); + await expectTokenBalance(walletA, completeTokenAddress.address, userB.address, 0n, checkIfSynchronized); }); }); diff --git a/yarn-project/types/src/interfaces/aztec_rpc.ts b/yarn-project/types/src/interfaces/aztec_rpc.ts index d362e4fc7289..2c487329facf 100644 --- a/yarn-project/types/src/interfaces/aztec_rpc.ts +++ b/yarn-project/types/src/interfaces/aztec_rpc.ts @@ -241,6 +241,7 @@ export interface AztecRPC { * @deprecated Use `getSyncStatus` instead. * @remarks Checks whether all the notes from all the blocks have been processed. If it is not the case, the * retrieved information from contracts might be old/stale (e.g. old token balance). + * @throws If checking a sync status of account which is not registered. */ isAccountStateSynchronized(account: AztecAddress): Promise; From 9ffb3a5c08ed15391d5f941f7b8a03044b95a5b0 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 25 Sep 2023 14:13:59 +0000 Subject: [PATCH 3/3] improved comment --- yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts index 523210680ddf..91c4e736dbc7 100644 --- a/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_rpc_servers.test.ts @@ -123,7 +123,7 @@ describe('e2e_2_rpc_servers', () => { // Add account A to wallet B await aztecRpcServerB.registerRecipient(userA); - // Add token to RPC server B + // Add token to RPC server B (RPC server A already has it because it was deployed through it) await aztecRpcServerB.addContracts([ { abi: TokenContract.abi, @@ -218,7 +218,7 @@ describe('e2e_2_rpc_servers', () => { // Add account A to wallet B await aztecRpcServerB.registerRecipient(userA); - // Add token to RPC server B + // Add token to RPC server B (RPC server A already has it because it was deployed through it) await aztecRpcServerB.addContracts([ { abi: TokenContract.abi,