From b3d6ae26eba2d4f7125d81325f6e2752b49b18bd Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 4 Feb 2025 12:50:40 +0000 Subject: [PATCH 1/2] Fix bb prover time --- .../avm_check_circuit1.test.ts | 114 +++++++++++++++++ .../avm_check_circuit2.test.ts | 118 ++++++++++++++++++ .../avm_check_circuit3.test.ts | 106 ++++++++++++++++ .../avm_contract_class_limits.test.ts | 84 +++++++++++++ .../avm_proving_and_verification.test.ts | 60 +++++++++ .../avm_proving_tests/avm_proving_tester.ts | 7 +- .../avm_public_fee_payment.test.ts | 73 +++++++++++ .../src/avm_proving_tests/avm_v2.test.ts | 64 ++++++++++ 8 files changed, 623 insertions(+), 3 deletions(-) create mode 100644 yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit1.test.ts create mode 100644 yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit2.test.ts create mode 100644 yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit3.test.ts create mode 100644 yarn-project/bb-prover/src/avm_proving_tests/avm_contract_class_limits.test.ts create mode 100644 yarn-project/bb-prover/src/avm_proving_tests/avm_proving_and_verification.test.ts create mode 100644 yarn-project/bb-prover/src/avm_proving_tests/avm_public_fee_payment.test.ts create mode 100644 yarn-project/bb-prover/src/avm_proving_tests/avm_v2.test.ts diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit1.test.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit1.test.ts new file mode 100644 index 000000000000..6833b8786f68 --- /dev/null +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit1.test.ts @@ -0,0 +1,114 @@ +import { + type ContractClassPublic, + type ContractInstanceWithAddress, + FunctionSelector, + MAX_L2_TO_L1_MSGS_PER_TX, + MAX_NOTE_HASHES_PER_TX, + MAX_NULLIFIERS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_LOGS_PER_TX, + PUBLIC_DISPATCH_SELECTOR, +} from '@aztec/circuits.js'; +import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { Fr } from '@aztec/foundation/fields'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; +import { getAvmTestContractBytecode } from '@aztec/simulator/public/fixtures'; + +import { AvmProvingTester } from './avm_proving_tester.js'; + +const TIMEOUT = 300_000; +const DISPATCH_FN_NAME = 'public_dispatch'; +const DISPATCH_SELECTOR = new FunctionSelector(PUBLIC_DISPATCH_SELECTOR); + +describe('AVM WitGen & Circuit – check circuit', () => { + const avmTestContractClassSeed = 0; + const avmTestContractBytecode = getAvmTestContractBytecode(DISPATCH_FN_NAME); + let avmTestContractClass: ContractClassPublic; + let avmTestContractInstance: ContractInstanceWithAddress; + let tester: AvmProvingTester; + + beforeEach(async () => { + avmTestContractClass = await makeContractClassPublic( + /*seed=*/ avmTestContractClassSeed, + /*publicDispatchFunction=*/ { bytecode: avmTestContractBytecode, selector: DISPATCH_SELECTOR }, + ); + avmTestContractInstance = await makeContractInstanceFromClassId( + avmTestContractClass.id, + /*seed=*/ avmTestContractClassSeed, + ); + tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true); + await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact); + await tester.addContractInstance(avmTestContractInstance); + }); + + it( + 'perform too many storage writes and revert', + async () => { + await tester.simProveVerifyAppLogic( + { + address: avmTestContractInstance.address, + fnName: 'n_storage_writes', + args: [new Fr(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + 1)], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'create too many note hashes and revert', + async () => { + await tester.simProveVerifyAppLogic( + { + address: avmTestContractInstance.address, + fnName: 'n_new_note_hashes', + args: [new Fr(MAX_NOTE_HASHES_PER_TX + 1)], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'create too many nullifiers and revert', + async () => { + await tester.simProveVerifyAppLogic( + { + address: avmTestContractInstance.address, + fnName: 'n_new_nullifiers', + args: [new Fr(MAX_NULLIFIERS_PER_TX + 1)], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'create too many l2tol1 messages and revert', + async () => { + await tester.simProveVerifyAppLogic( + { + address: avmTestContractInstance.address, + fnName: 'n_new_l2_to_l1_msgs', + args: [new Fr(MAX_L2_TO_L1_MSGS_PER_TX + 1)], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'create too many public logs and revert', + async () => { + await tester.simProveVerifyAppLogic( + { + address: avmTestContractInstance.address, + fnName: 'n_new_public_logs', + args: [new Fr(MAX_PUBLIC_LOGS_PER_TX + 1)], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); +}); diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit2.test.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit2.test.ts new file mode 100644 index 000000000000..7cdccc0adcb3 --- /dev/null +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit2.test.ts @@ -0,0 +1,118 @@ +import { + AztecAddress, + type ContractClassPublic, + type ContractInstanceWithAddress, + FunctionSelector, + PUBLIC_DISPATCH_SELECTOR, +} from '@aztec/circuits.js'; +import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { Fr } from '@aztec/foundation/fields'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; +import { getAvmTestContractBytecode } from '@aztec/simulator/public/fixtures'; + +import { AvmProvingTester } from './avm_proving_tester.js'; + +const TIMEOUT = 300_000; +const DISPATCH_FN_NAME = 'public_dispatch'; +const DISPATCH_SELECTOR = new FunctionSelector(PUBLIC_DISPATCH_SELECTOR); + +describe('AVM WitGen & Circuit – check circuit', () => { + const sender = AztecAddress.fromNumber(42); + const avmTestContractClassSeed = 0; + const avmTestContractBytecode = getAvmTestContractBytecode(DISPATCH_FN_NAME); + let avmTestContractClass: ContractClassPublic; + let avmTestContractInstance: ContractInstanceWithAddress; + let tester: AvmProvingTester; + + beforeEach(async () => { + avmTestContractClass = await makeContractClassPublic( + /*seed=*/ avmTestContractClassSeed, + /*publicDispatchFunction=*/ { bytecode: avmTestContractBytecode, selector: DISPATCH_SELECTOR }, + ); + avmTestContractInstance = await makeContractInstanceFromClassId( + avmTestContractClass.id, + /*seed=*/ avmTestContractClassSeed, + ); + tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true); + await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact); + await tester.addContractInstance(avmTestContractInstance); + }); + + it( + 'an exceptional halt due to a nested call to non-existent contract is propagated to top-level', + async () => { + await tester.simProveVerifyAppLogic( + { address: avmTestContractInstance.address, fnName: 'nested_call_to_nothing', args: [] }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'an exceptional halt due to a nested call to non-existent contract is recovered from in caller', + async () => { + await tester.simProveVerifyAppLogic( + { address: avmTestContractInstance.address, fnName: 'nested_call_to_nothing_recovers', args: [] }, + /*expectRevert=*/ false, + ); + }, + TIMEOUT, + ); + it.skip('top-level exceptional halts due to a non-existent contract in app-logic and teardown', async () => { + // don't insert contracts into trees, and make sure retrieval fails + const tester = await AvmProvingTester.create(/*checkCircuitOnly=*/ true, /*skipContractDeployments=*/ true); + await tester.simProveVerify( + sender, + /*setupCalls=*/ [], + /*appCalls=*/ [ + { address: avmTestContractInstance.address, fnName: 'add_args_return', args: [new Fr(1), new Fr(2)] }, + ], + /*teardownCall=*/ { + address: avmTestContractInstance.address, + fnName: 'add_args_return', + args: [new Fr(1), new Fr(2)], + }, + /*expectRevert=*/ true, + ); + }); + it( + 'enqueued calls in every phase, with enqueued calls that depend on each other', + async () => { + await tester.simProveVerify( + sender, + /*setupCalls=*/ [ + { address: avmTestContractInstance.address, fnName: 'read_assert_storage_single', args: [new Fr(0)] }, + { address: avmTestContractInstance.address, fnName: 'set_storage_single', args: [new Fr(5)] }, + ], + /*appCalls=*/ [ + { address: avmTestContractInstance.address, fnName: 'read_assert_storage_single', args: [new Fr(5)] }, + { address: avmTestContractInstance.address, fnName: 'set_storage_single', args: [new Fr(10)] }, + ], + /*teardownCall=*/ { + address: avmTestContractInstance.address, + fnName: 'read_assert_storage_single', + args: [new Fr(10)], + }, + /*expectRevert=*/ false, + ); + }, + TIMEOUT, + ); + it( + 'Should prove and verify a TX that reverts in teardown', + async () => { + await tester.simProveVerify( + sender, + /*setupCalls=*/ [], + /*appCalls=*/ [], + /*teardownCall=*/ { + address: avmTestContractInstance.address, + fnName: 'read_assert_storage_single', + args: [new Fr(10)], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); +}); diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit3.test.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit3.test.ts new file mode 100644 index 000000000000..034c8b2dce2c --- /dev/null +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit3.test.ts @@ -0,0 +1,106 @@ +import { + AztecAddress, + type ContractClassPublic, + type ContractInstanceWithAddress, + FunctionSelector, + PUBLIC_DISPATCH_SELECTOR, +} from '@aztec/circuits.js'; +import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { Fr } from '@aztec/foundation/fields'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; +import { getAvmTestContractBytecode } from '@aztec/simulator/public/fixtures'; + +import { AvmProvingTester } from './avm_proving_tester.js'; + +const TIMEOUT = 300_000; +const DISPATCH_FN_NAME = 'public_dispatch'; +const DISPATCH_SELECTOR = new FunctionSelector(PUBLIC_DISPATCH_SELECTOR); + +describe('AVM WitGen & Circuit – check circuit', () => { + const sender = AztecAddress.fromNumber(42); + const avmTestContractClassSeed = 0; + const avmTestContractBytecode = getAvmTestContractBytecode(DISPATCH_FN_NAME); + let avmTestContractClass: ContractClassPublic; + let avmTestContractInstance: ContractInstanceWithAddress; + let tester: AvmProvingTester; + + beforeEach(async () => { + avmTestContractClass = await makeContractClassPublic( + /*seed=*/ avmTestContractClassSeed, + /*publicDispatchFunction=*/ { bytecode: avmTestContractBytecode, selector: DISPATCH_SELECTOR }, + ); + avmTestContractInstance = await makeContractInstanceFromClassId( + avmTestContractClass.id, + /*seed=*/ avmTestContractClassSeed, + ); + tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true); + await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact); + await tester.addContractInstance(avmTestContractInstance); + }); + + it( + 'top-level exceptional halts in both app logic and teardown', + async () => { + await tester.simProveVerify( + sender, + /*setupCalls=*/ [], + /*appCalls=*/ [{ address: avmTestContractInstance.address, fnName: 'divide_by_zero', args: [] }], + /*teardownCall=*/ undefined, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'top-level exceptional halt in app logic, but teardown succeeds', + async () => { + await tester.simProveVerify( + sender, + /*setupCalls=*/ [], + /*appCalls=*/ [{ address: avmTestContractInstance.address, fnName: 'divide_by_zero', args: [] }], + /*teardownCall=*/ { + address: avmTestContractInstance.address, + fnName: 'add_args_return', + args: [new Fr(1), new Fr(2)], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'top-level exceptional halt in teardown, but app logic succeeds', + async () => { + await tester.simProveVerify( + sender, + /*setupCalls=*/ [], + /*appCalls=*/ [ + { address: avmTestContractInstance.address, fnName: 'add_args_return', args: [new Fr(1), new Fr(2)] }, + ], + /*teardownCall=*/ { address: avmTestContractInstance.address, fnName: 'divide_by_zero', args: [] }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'a nested exceptional halt propagate to top-level', + async () => { + await tester.simProveVerifyAppLogic( + { address: avmTestContractInstance.address, fnName: 'external_call_to_divide_by_zero', args: [] }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); + it( + 'a nested exceptional halt is recovered from in caller', + async () => { + await tester.simProveVerifyAppLogic( + { address: avmTestContractInstance.address, fnName: 'external_call_to_divide_by_zero_recovers', args: [] }, + /*expectRevert=*/ false, + ); + }, + TIMEOUT, + ); +}); diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_contract_class_limits.test.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_contract_class_limits.test.ts new file mode 100644 index 000000000000..bbba6b94cb4b --- /dev/null +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_contract_class_limits.test.ts @@ -0,0 +1,84 @@ +import { + AztecAddress, + type ContractInstanceWithAddress, + MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS, +} from '@aztec/circuits.js'; +import { makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; + +import { AvmProvingTester } from './avm_proving_tester.js'; + +const TIMEOUT = 300_000; + +describe('AVM WitGen & Circuit – check circuit - contract class limits', () => { + const deployer = AztecAddress.fromNumber(42); + let instances: ContractInstanceWithAddress[]; + let tester: AvmProvingTester; + let avmTestContractAddress: AztecAddress; + + beforeEach(async () => { + tester = await AvmProvingTester.create(/*checkCircuitOnly=*/ true); + // create enough unique contract classes to hit the limit + instances = []; + for (let i = 0; i <= MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS; i++) { + const instance = await tester.registerAndDeployContract( + /*constructorArgs=*/ [], + deployer, + /*contractArtifact=*/ AvmTestContractArtifact, + /*seed=*/ i, + ); + instances.push(instance); + } + avmTestContractAddress = instances[0].address; + }); + it.skip( + 'call the max number of unique contract classes', + async () => { + // args is initialized to MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS contract addresses with unique class IDs + const instanceAddresses = instances + .map(instance => instance.address) + .slice(0, MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS); + + // include the first contract again again at the end to ensure that we can call it even after the limit is reached + instanceAddresses.push(instanceAddresses[0]); + + // include another contract address that reuses a class ID to ensure that we can call it even after the limit is reached + const instanceSameClassAsFirstContract = await makeContractInstanceFromClassId( + instances[0].contractClassId, + /*seed=*/ 1000, + ); + instanceAddresses.push(instanceSameClassAsFirstContract.address); + // add it to the contract data source so it is found + await tester.addContractInstance(instanceSameClassAsFirstContract); + + await tester.simProveVerifyAppLogic( + { + address: avmTestContractAddress, + fnName: 'nested_call_to_add_n_times_different_addresses', + args: [instanceAddresses], + }, + /*expectRevert=*/ false, + ); + }, + TIMEOUT, + ); + it.skip( + 'attempt too many calls to unique contract class ids', + async () => { + // args is initialized to MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS+1 contract addresses with unique class IDs + // should fail because we are trying to call MAX+1 unique class IDs + const instanceAddresses = instances.map(instance => instance.address); + // push an empty one (just padding to match function calldata size of MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS+2) + instanceAddresses.push(AztecAddress.zero()); + await tester.simProveVerifyAppLogic( + { + address: avmTestContractAddress, + fnName: 'nested_call_to_add_n_times_different_addresses', + args: [instanceAddresses], + }, + /*expectRevert=*/ true, + ); + }, + TIMEOUT, + ); +}); diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_and_verification.test.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_and_verification.test.ts new file mode 100644 index 000000000000..56656363080d --- /dev/null +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_and_verification.test.ts @@ -0,0 +1,60 @@ +import { + type ContractClassPublic, + type ContractInstanceWithAddress, + FunctionSelector, + PUBLIC_DISPATCH_SELECTOR, +} from '@aztec/circuits.js'; +import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { Fr } from '@aztec/foundation/fields'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; +import { getAvmTestContractBytecode } from '@aztec/simulator/public/fixtures'; + +import { AvmProvingTester } from './avm_proving_tester.js'; + +const TIMEOUT = 300_000; +const DISPATCH_FN_NAME = 'public_dispatch'; +const DISPATCH_SELECTOR = new FunctionSelector(PUBLIC_DISPATCH_SELECTOR); + +describe('AVM WitGen & Circuit – proving and verification', () => { + const avmTestContractClassSeed = 0; + const avmTestContractBytecode = getAvmTestContractBytecode(DISPATCH_FN_NAME); + let avmTestContractClass: ContractClassPublic; + let avmTestContractInstance: ContractInstanceWithAddress; + let tester: AvmProvingTester; + + beforeEach(async () => { + avmTestContractClass = await makeContractClassPublic( + /*seed=*/ avmTestContractClassSeed, + /*publicDispatchFunction=*/ { bytecode: avmTestContractBytecode, selector: DISPATCH_SELECTOR }, + ); + avmTestContractInstance = await makeContractInstanceFromClassId( + avmTestContractClass.id, + /*seed=*/ avmTestContractClassSeed, + ); + tester = await AvmProvingTester.create(/*checkCircuitOnly*/ false); + await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact); + await tester.addContractInstance(avmTestContractInstance); + }); + + it( + 'bulk_testing v1', + async () => { + // Get a deployed contract instance to pass to the contract + // for it to use as "expected" values when testing contract instance retrieval. + const expectContractInstance = avmTestContractInstance; + const argsField = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + const args = [ + argsField, + argsU8, + /*getInstanceForAddress=*/ expectContractInstance.address.toField(), + /*expectedDeployer=*/ expectContractInstance.deployer.toField(), + /*expectedClassId=*/ expectContractInstance.contractClassId.toField(), + /*expectedInitializationHash=*/ expectContractInstance.initializationHash.toField(), + ]; + + await tester.simProveVerifyAppLogic({ address: avmTestContractInstance.address, fnName: 'bulk_testing', args }); + }, + TIMEOUT, + ); +}); diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts index dfb4457d30a4..6e4b3fb181d5 100644 --- a/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts @@ -1,7 +1,8 @@ import { type MerkleTreeWriteOperations } from '@aztec/circuit-types'; import { type AvmCircuitInputs, AztecAddress, VerificationKeyData } from '@aztec/circuits.js'; +import { openTmpStore } from '@aztec/kv-store/lmdb'; import { PublicTxSimulationTester, type TestEnqueuedCall } from '@aztec/simulator/public/fixtures'; -import { NativeWorldStateService } from '@aztec/world-state'; +import { MerkleTrees } from '@aztec/world-state'; import fs from 'node:fs/promises'; import { tmpdir } from 'node:os'; @@ -36,7 +37,7 @@ export class AvmProvingTester extends PublicTxSimulationTester { const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-')); const contractDataSource = new SimpleContractDataSource(); - const merkleTrees = await (await NativeWorldStateService.tmp()).fork(); + const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork(); return new AvmProvingTester( bbWorkingDirectory, checkCircuitOnly, @@ -121,7 +122,7 @@ export class AvmProvingTesterV2 extends PublicTxSimulationTester { const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-')); const contractDataSource = new SimpleContractDataSource(); - const merkleTrees = await (await NativeWorldStateService.tmp()).fork(); + const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork(); return new AvmProvingTesterV2(bbWorkingDirectory, contractDataSource, merkleTrees, skipContractDeployments); } diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_public_fee_payment.test.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_public_fee_payment.test.ts new file mode 100644 index 000000000000..90997ce9314b --- /dev/null +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_public_fee_payment.test.ts @@ -0,0 +1,73 @@ +import { + AztecAddress, + type ContractClassPublic, + type ContractInstanceWithAddress, + FunctionSelector, + PUBLIC_DISPATCH_SELECTOR, +} from '@aztec/circuits.js'; +import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { Fr } from '@aztec/foundation/fields'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; +import { type ProtocolContract } from '@aztec/protocol-contracts'; +import { FeeJuiceArtifact, getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice'; +import { getAvmTestContractBytecode } from '@aztec/simulator/public/fixtures'; + +import { AvmProvingTester } from './avm_proving_tester.js'; + +const TIMEOUT = 300_000; +const DISPATCH_FN_NAME = 'public_dispatch'; +const DISPATCH_SELECTOR = new FunctionSelector(PUBLIC_DISPATCH_SELECTOR); + +describe('AVM WitGen & Circuit – public fee payment', () => { + const sender = AztecAddress.fromNumber(42); + const feePayer = sender; + + const initialFeeJuiceBalance = new Fr(20000); + let feeJuice: ProtocolContract; + let feeJuiceContractClassPublic: ContractClassPublic; + + const avmTestContractClassSeed = 0; + const avmTestContractBytecode = getAvmTestContractBytecode(DISPATCH_FN_NAME); + let avmTestContractClass: ContractClassPublic; + let avmTestContractInstance: ContractInstanceWithAddress; + let tester: AvmProvingTester; + + beforeEach(async () => { + feeJuice = await getCanonicalFeeJuice(); + feeJuiceContractClassPublic = { + ...feeJuice.contractClass, + privateFunctions: [], + unconstrainedFunctions: [], + }; + avmTestContractClass = await makeContractClassPublic( + /*seed=*/ avmTestContractClassSeed, + /*publicDispatchFunction=*/ { bytecode: avmTestContractBytecode, selector: DISPATCH_SELECTOR }, + ); + avmTestContractInstance = await makeContractInstanceFromClassId( + avmTestContractClass.id, + /*seed=*/ avmTestContractClassSeed, + ); + tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true); + await tester.addContractClass(feeJuiceContractClassPublic, FeeJuiceArtifact); + await tester.addContractInstance(feeJuice.instance); + await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact); + await tester.addContractInstance(avmTestContractInstance); + await tester.setFeePayerBalance(feePayer, initialFeeJuiceBalance); + }); + it( + 'fee payment', + async () => { + await tester.simProveVerify( + sender, + /*setupCalls=*/ [], + /*appCalls=*/ [ + { address: avmTestContractInstance.address, fnName: 'add_args_return', args: [new Fr(1), new Fr(2)] }, + ], + /*teardownCall=*/ undefined, + /*expectRevert=*/ false, + feePayer, + ); + }, + TIMEOUT, + ); +}); diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_v2.test.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_v2.test.ts new file mode 100644 index 000000000000..1ba8f7658b1c --- /dev/null +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_v2.test.ts @@ -0,0 +1,64 @@ +import { + AztecAddress, + type ContractClassPublic, + type ContractInstanceWithAddress, + FunctionSelector, + PUBLIC_DISPATCH_SELECTOR, +} from '@aztec/circuits.js'; +import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { Fr } from '@aztec/foundation/fields'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; +import { getAvmTestContractBytecode } from '@aztec/simulator/public/fixtures'; + +import { AvmProvingTesterV2 } from './avm_proving_tester.js'; + +const DISPATCH_FN_NAME = 'public_dispatch'; +const DISPATCH_SELECTOR = new FunctionSelector(PUBLIC_DISPATCH_SELECTOR); + +describe('AVM v2', () => { + const sender = AztecAddress.fromNumber(42); + const avmTestContractClassSeed = 0; + const avmTestContractBytecode = getAvmTestContractBytecode(DISPATCH_FN_NAME); + let avmTestContractClass: ContractClassPublic; + let avmTestContractInstance: ContractInstanceWithAddress; + + let tester: AvmProvingTesterV2; + + beforeEach(async () => { + avmTestContractClass = await makeContractClassPublic( + /*seed=*/ avmTestContractClassSeed, + /*publicDispatchFunction=*/ { bytecode: avmTestContractBytecode, selector: DISPATCH_SELECTOR }, + ); + avmTestContractInstance = await makeContractInstanceFromClassId( + avmTestContractClass.id, + /*seed=*/ avmTestContractClassSeed, + ); + tester = await AvmProvingTesterV2.create(); + await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact); + await tester.addContractInstance(avmTestContractInstance); + }); + + it('bulk_testing v2', async () => { + // Get a deployed contract instance to pass to the contract + // for it to use as "expected" values when testing contract instance retrieval. + const expectContractInstance = avmTestContractInstance; + const argsField = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + const argsU8 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)); + const args = [ + argsField, + argsU8, + /*getInstanceForAddress=*/ expectContractInstance.address.toField(), + /*expectedDeployer=*/ expectContractInstance.deployer.toField(), + /*expectedClassId=*/ expectContractInstance.contractClassId.toField(), + /*expectedInitializationHash=*/ expectContractInstance.initializationHash.toField(), + ]; + + await tester.simProveVerifyV2( + sender, + /*setupCalls=*/ [], + /*appCalls=*/ [{ address: avmTestContractInstance.address, fnName: 'bulk_testing', args }], + /*teardownCall=*/ undefined, + /*expectRevert=*/ false, + ); + }, 180_000); +}); From 93f0026ee9dfefd25e3708cc0600b13e3d2a70f5 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 4 Feb 2025 12:51:30 +0000 Subject: [PATCH 2/2] revert part --- .../bb-prover/src/avm_proving_tests/avm_proving_tester.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts b/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts index 6e4b3fb181d5..dfb4457d30a4 100644 --- a/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts +++ b/yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts @@ -1,8 +1,7 @@ import { type MerkleTreeWriteOperations } from '@aztec/circuit-types'; import { type AvmCircuitInputs, AztecAddress, VerificationKeyData } from '@aztec/circuits.js'; -import { openTmpStore } from '@aztec/kv-store/lmdb'; import { PublicTxSimulationTester, type TestEnqueuedCall } from '@aztec/simulator/public/fixtures'; -import { MerkleTrees } from '@aztec/world-state'; +import { NativeWorldStateService } from '@aztec/world-state'; import fs from 'node:fs/promises'; import { tmpdir } from 'node:os'; @@ -37,7 +36,7 @@ export class AvmProvingTester extends PublicTxSimulationTester { const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-')); const contractDataSource = new SimpleContractDataSource(); - const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork(); + const merkleTrees = await (await NativeWorldStateService.tmp()).fork(); return new AvmProvingTester( bbWorkingDirectory, checkCircuitOnly, @@ -122,7 +121,7 @@ export class AvmProvingTesterV2 extends PublicTxSimulationTester { const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-')); const contractDataSource = new SimpleContractDataSource(); - const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork(); + const merkleTrees = await (await NativeWorldStateService.tmp()).fork(); return new AvmProvingTesterV2(bbWorkingDirectory, contractDataSource, merkleTrees, skipContractDeployments); }