From a8128a6ee47dbb8fcf1c9c7f9b3fa3636f563325 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Fri, 4 Aug 2023 12:49:01 +0000 Subject: [PATCH] test: use public views in tests --- .../src/client/unconstrained_execution.ts | 4 +- .../src/cross_chain/test_harness.ts | 10 ++--- .../src/e2e_lending_contract.test.ts | 37 ++++++++----------- .../e2e_public_cross_chain_messaging.test.ts | 5 +-- .../e2e_public_to_private_messaging.test.ts | 7 ++-- .../contracts/lending_contract/src/main.nr | 18 +++++++++ .../non_native_token_contract/src/main.nr | 7 ++++ 7 files changed, 53 insertions(+), 35 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts index 99f195bd0d82..e673ab3175e0 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.ts @@ -58,7 +58,8 @@ export class UnconstrainedFunctionExecution { getCommitment: ([commitment]) => this.context.getCommitment(this.contractAddress, commitment), storageRead: async ([slot], [numberOfElements]) => { if (aztecNode === undefined) { - throw new Error('AztecNode is undefined'); + this.log(`Aztec node is undefined, cannot read public storage`); + throw new Error(`Aztec node is undefined, cannot read public storage`); } const startStorageSlot = fromACVMField(slot); const values = []; @@ -66,6 +67,7 @@ export class UnconstrainedFunctionExecution { const storageSlot = startStorageSlot.value + BigInt(i); const value = await aztecNode.getPublicStorageAt(this.contractAddress, storageSlot); if (value === undefined) { + this.log(`Oracle storage read: slot=${storageSlot.toString()} value=undefined`); throw new Error(`Oracle storage read: slot=${storageSlot.toString()} value=undefined`); } const frValue = Fr.fromBuffer(value); diff --git a/yarn-project/end-to-end/src/cross_chain/test_harness.ts b/yarn-project/end-to-end/src/cross_chain/test_harness.ts index 130a8a240662..5538e5b464e2 100644 --- a/yarn-project/end-to-end/src/cross_chain/test_harness.ts +++ b/yarn-project/end-to-end/src/cross_chain/test_harness.ts @@ -203,12 +203,10 @@ export class CrossChainTestHarness { expect(balance).toBe(expectedBalance); } - async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint, publicBalanceSlot: bigint) { - const balance = await this.cc.l2.loadPublic( - this.l2Contract.address, - this.cc.l2.computeSlotInMap(publicBalanceSlot, owner.toField()), - ); - expect(balance.value).toBe(expectedBalance); + async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) { + this.logger(`test_harness::expectPublicBalanceOnL2`); + const balance = (await this.l2Contract.methods.publicBalanceOf(owner.toField()).view({ from: owner }))[0]; + expect(balance).toBe(expectedBalance); } async checkEntryIsNotInOutbox(withdrawAmount: bigint, callerOnL1: EthAddress = EthAddress.ZERO): Promise { 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 46d20311335b..e1284fc6725b 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 @@ -1,13 +1,12 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; -import { AztecAddress, Contract, Fr, Wallet } from '@aztec/aztec.js'; +import { AztecAddress, Fr, Wallet } from '@aztec/aztec.js'; import { CircuitsWasm } from '@aztec/circuits.js'; import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg'; import { DebugLogger } from '@aztec/foundation/log'; import { LendingContract } from '@aztec/noir-contracts/types'; import { AztecRPC, TxStatus } from '@aztec/types'; -import { CheatCodes } from './cheat_codes.js'; import { setup } from './utils.js'; describe('e2e_lending_contract', () => { @@ -17,9 +16,7 @@ describe('e2e_lending_contract', () => { let accounts: AztecAddress[]; let logger: DebugLogger; - let contract: Contract; - - let cc: CheatCodes; + let contract: LendingContract; const deployContract = async () => { logger(`Deploying L2 public contract...`); @@ -35,7 +32,7 @@ describe('e2e_lending_contract', () => { }; beforeEach(async () => { - ({ aztecNode, aztecRpcServer, wallet, accounts, logger, cheatCodes: cc } = await setup()); + ({ aztecNode, aztecRpcServer, wallet, accounts, logger } = await setup()); }, 100_000); afterEach(async () => { @@ -46,24 +43,22 @@ describe('e2e_lending_contract', () => { }); // Fetch a storage snapshot from the contract that we can use to compare between transitions. - const getStorageSnapshot = async (contract: Contract, aztecNode: AztecRPC, account: Account) => { - const loadPublicStorageInMap = async (slot: Fr | bigint, key: Fr | bigint) => { - return await cc.l2.loadPublic(contract.address, cc.l2.computeSlotInMap(slot, key)); - }; + const getStorageSnapshot = async (contract: LendingContract, aztecNode: AztecRPC, account: Account) => { + const storageValues: { [key: string]: Fr } = {}; + const accountKey = await account.key(); + const toFields = (res: any) => res[0].map((v: number | bigint | Fr) => new Fr(v)); - const storageValues: { [key: string]: any } = {}; - { - const baseSlot = cc.l2.computeSlotInMap(1n, 0n); - storageValues['interestAccumulator'] = await cc.l2.loadPublic(contract.address, baseSlot); - storageValues['last_updated_ts'] = await cc.l2.loadPublic(contract.address, baseSlot.value + 1n); - } + [storageValues['interestAccumulator'], storageValues['last_updated_ts']] = toFields( + await contract.methods.getTot(0).view({ from: account.address }), + ); - const accountKey = await account.key(); + [storageValues['private_collateral'], storageValues['private_debt']] = toFields( + await contract.methods.getPosition(accountKey).view({ from: account.address }), + ); - storageValues['private_collateral'] = await loadPublicStorageInMap(2n, accountKey); - storageValues['public_collateral'] = await loadPublicStorageInMap(2n, account.address.toField()); - storageValues['private_debt'] = await loadPublicStorageInMap(3n, accountKey); - storageValues['public_debt'] = await loadPublicStorageInMap(3n, account.address.toField()); + [storageValues['public_collateral'], storageValues['public_debt']] = toFields( + await contract.methods.getPosition(account.address.toField()).view({ from: account.address }), + ); return storageValues; }; 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 7cc8ccd2934a..de8ca25a152b 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 @@ -82,7 +82,6 @@ describe('e2e_public_cross_chain_messaging', () => { // Generate a claim secret using pedersen const l1TokenBalance = 1000000n; const bridgeAmount = 100n; - const publicBalanceSlot = 2n; const [secret, secretHash] = await crossChainTestHarness.generateClaimSecret(); @@ -98,14 +97,14 @@ describe('e2e_public_cross_chain_messaging', () => { await crossChainTestHarness.performL2Transfer(transferAmount); await crossChainTestHarness.consumeMessageOnAztecAndMintPublicly(bridgeAmount, messageKey, secret); - await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount, publicBalanceSlot); + await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount); // time to withdraw the funds again! logger('Withdrawing funds from L2'); const withdrawAmount = 9n; const entryKey = await crossChainTestHarness.checkEntryIsNotInOutbox(withdrawAmount); await withdrawFundsFromAztec(withdrawAmount); - await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount - withdrawAmount, publicBalanceSlot); + await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount - withdrawAmount); // Check balance before and after exit. expect(await underlyingERC20.read.balanceOf([ethAccount.toString()])).toBe(l1TokenBalance - bridgeAmount); diff --git a/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts index ced0650c0a1c..85188601924b 100644 --- a/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts @@ -65,7 +65,6 @@ describe('e2e_public_to_private_messaging', () => { const l1TokenBalance = 1000000n; const bridgeAmount = 100n; const shieldAmount = 50n; - const publicBalanceSlot = 2n; const [secret, secretHash] = await crossChainTestHarness.generateClaimSecret(); @@ -83,19 +82,19 @@ describe('e2e_public_to_private_messaging', () => { await crossChainTestHarness.expectBalanceOnL2(ownerAddress, initialBalance - transferAmount); await crossChainTestHarness.consumeMessageOnAztecAndMintPublicly(bridgeAmount, messageKey, secret); - await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount, publicBalanceSlot); + await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount); // Create the commitment to be spent in the private domain await crossChainTestHarness.shieldFundsOnL2(shieldAmount, secretHash); // Create the transaction spending the commitment await crossChainTestHarness.redeemShieldPrivatelyOnL2(shieldAmount, secret); - await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount - shieldAmount, publicBalanceSlot); + await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount - shieldAmount); await crossChainTestHarness.expectBalanceOnL2(ownerAddress, initialBalance + shieldAmount - transferAmount); // Unshield the tokens again, sending them to the same account, however this can be any account. await crossChainTestHarness.unshieldTokensOnL2(shieldAmount); - await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount, publicBalanceSlot); + await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount); await crossChainTestHarness.expectBalanceOnL2(ownerAddress, initialBalance - transferAmount); }, 200_000); }); diff --git a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr index 0e4f63d4e161..b45524852549 100644 --- a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr @@ -306,4 +306,22 @@ contract Lending { debt_loc.write(static_debt - amount); 1 } + + unconstrained fn getTot( + assetId: Field, + ) -> [Field; 2]{ + let storage = Storage::init(); + let asset = storage.assets.at(assetId); + let tot = asset.read(); + [tot.interest_accumulator as Field, tot.last_updated_ts as Field] + } + + unconstrained fn getPosition( + owner: Field, + ) -> [Field; 2] { + let storage = Storage::init(); + let collateral = storage.collateral.at(owner).read(); + let debt = storage.static_debt.at(owner).read(); + [collateral, debt] + } } diff --git a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr index ab590d6e41d7..b0f7e0216523 100644 --- a/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr @@ -329,4 +329,11 @@ contract NonNativeToken { let note_header = NoteHeader { contract_address, nonce, storage_slot }; note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, preimage) } + + unconstrained fn publicBalanceOf( + owner: Field, + ) -> Field { + let storage = Storage::init(); + storage.public_balances.at(owner).read() + } }