Skip to content

Commit

Permalink
chore: prep for switching AVM to checkpointed native trees - TS test …
Browse files Browse the repository at this point in the history
…cleanup and refactors (#12023)

This PR is mostly setup for switching the AVM to use checkpointed native
trees. Originally I had that in the same branch, but there were enough
of these prerequisite changes to pull them out.

## Orchestrator testing

prover-client's `TestContext` no longer mocks AVM simulation.

Context: while trying to transition the AVM to use native checkpointed
trees, I ran into issues with the orchestrator public functions tests
because the public processor will no longer update the trees for public
functions. So, I think we should stop mocking the AVM simulation for
these tests and let the AVM do its tree updates. We can then do two
types of tests:
1. A quick test that doesn't actually deploy/run any real contract
functions and instead tests the orchestrator with a mocked/garbage TX
that has 1 _revertible_ enqueued call. The AVM will fail to retrieve
it's bytecode, but the TX can still be included.
`orchestrator_public_functions.test.ts` now does this.
2. A real test that creates TXs that actually do a bunch of real token
operations via non-revertible and revertible enqueued calls.
`orchestrator_multi_public_functions.test.ts` now does this.

## AVM & PublicProcessor testing
- `PublicTxSimulationTester` lets you `createTx` separately from
`simulateTx` (useful for testing `PublicProcessor`)
- Add `PublicTxSimulator` test for avm bulk test
- Add a `PublicProcessor` test of the token contract (construct, mint,
many transfers)
- Consolidate some duplicate helper functions in `simulator/src/avm` and
`simulator/src/public`
- Simplify process of registering/deploying contracts via avm `*Tester`
classes, and optional contract address nullifier insertion
- Contract Updates test now use the tester's `register*()` function
instead of manually constructing contract classes and instances
- Remove unused function from avm test contract

## Misc
- Making contract classes for tests is now deterministic (no more random
public keys)
- Use new/proper sha256 in benchmarking test contract
  • Loading branch information
dbanks12 authored Feb 19, 2025
1 parent 8422594 commit c1cc3ed
Show file tree
Hide file tree
Showing 36 changed files with 565 additions and 470 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,6 @@ pub contract AvmTest {
context.da_gas_left()
}

#[public]
fn assert_timestamp(expected_timestamp: u64) {
let timestamp = context.timestamp();
assert(timestamp == expected_timestamp, "timestamp does not match");
}

#[public]
fn get_args_hash(_a: u8, _fields: [Field; 3]) -> Field {
context.get_args_hash()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ type = "contract"
[dependencies]
aztec = { path = "../../../aztec-nr/aztec" }
value_note = { path = "../../../aztec-nr/value-note" }
sha256 = { tag = "v0.1.2", git = "https://github.com/noir-lang/sha256" }
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ pub contract Benchmarking {
// Does a bunch of heavy compute
#[public]
fn sha256_hash_2048(data: [u8; 2048]) -> [u8; 32] {
std::hash::sha256(data)
sha256::sha256_var(data, data.len() as u64)
}
}
Original file line number Diff line number Diff line change
@@ -1,42 +1,30 @@
import { type ContractClassPublic, type ContractInstanceWithAddress, FunctionSelector } from '@aztec/circuits.js';
import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing';
import { type ContractInstanceWithAddress } from '@aztec/circuits.js';
import {
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/constants';
import { AztecAddress } from '@aztec/foundation/aztec-address';
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);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
AvmTestContractArtifact,
);
});

it(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
import {
AztecAddress,
type ContractClassPublic,
type ContractInstanceWithAddress,
FunctionSelector,
} from '@aztec/circuits.js';
import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing';
import { PUBLIC_DISPATCH_SELECTOR } from '@aztec/constants';
import { type ContractInstanceWithAddress } from '@aztec/circuits.js';
import { AztecAddress } from '@aztec/foundation/aztec-address';
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);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
AvmTestContractArtifact,
);
});

it(
Expand All @@ -58,9 +41,10 @@ describe('AVM WitGen & Circuit – check circuit', () => {
},
TIMEOUT,
);
// FIXME(dbanks12): fails with "Lookup PERM_MAIN_ALU failed."
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);
const tester = await AvmProvingTester.create(/*checkCircuitOnly=*/ true);
await tester.simProveVerify(
sender,
/*setupCalls=*/ [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
import {
AztecAddress,
type ContractClassPublic,
type ContractInstanceWithAddress,
FunctionSelector,
} from '@aztec/circuits.js';
import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing';
import { PUBLIC_DISPATCH_SELECTOR } from '@aztec/constants';
import { type ContractInstanceWithAddress } from '@aztec/circuits.js';
import { AztecAddress } from '@aztec/foundation/aztec-address';
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);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
AvmTestContractArtifact,
);
});

it(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('AVM WitGen & Circuit – check circuit - contract class limits', () =>
/*constructorArgs=*/ [],
deployer,
/*contractArtifact=*/ AvmTestContractArtifact,
/*skipNullifierInsertion=*/ false,
/*seed=*/ i,
);
instances.push(instance);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,29 @@
import {
AztecAddress,
type ContractClassPublic,
type ContractInstanceWithAddress,
FunctionSelector,
} from '@aztec/circuits.js';
import { type ContractInstanceWithAddress } from '@aztec/circuits.js';
import { deriveStorageSlotInMap } from '@aztec/circuits.js/hash';
import {
ScheduledDelayChange,
ScheduledValueChange,
computeSharedMutableHashSlot,
} from '@aztec/circuits.js/shared-mutable';
import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing';
import { PUBLIC_DISPATCH_SELECTOR, UPDATED_CLASS_IDS_SLOT, UPDATES_SCHEDULED_VALUE_CHANGE_LEN } from '@aztec/constants';
import { UPDATED_CLASS_IDS_SLOT, UPDATES_SCHEDULED_VALUE_CHANGE_LEN } from '@aztec/constants';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { poseidon2Hash } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest';
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
import { DEFAULT_BLOCK_NUMBER, getAvmTestContractBytecode } from '@aztec/simulator/public/fixtures';
import { DEFAULT_BLOCK_NUMBER } 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 - contract updates', () => {
const sender = AztecAddress.fromNumber(42);

const avmTestContractClassSeed = 0;
const avmTestContractBytecode = getAvmTestContractBytecode(DISPATCH_FN_NAME);
let avmTestContractClass: ContractClassPublic;
let avmTestContractInstance: ContractInstanceWithAddress;

beforeEach(async () => {
avmTestContractClass = await makeContractClassPublic(
/*seed=*/ avmTestContractClassSeed,
/*publicDispatchFunction=*/ { bytecode: avmTestContractBytecode, selector: DISPATCH_SELECTOR },
);
});
beforeEach(async () => {});

const writeContractUpdate = async (
tester: AvmProvingTester,
Expand Down Expand Up @@ -69,16 +55,17 @@ describe('AVM WitGen & Circuit - contract updates', () => {
async () => {
// Contract was not originally the avmTestContract
const originalClassId = new Fr(27);
avmTestContractInstance = await makeContractInstanceFromClassId(
originalClassId,
const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);

avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
sender,
/*contractArtifact=*/ AvmTestContractArtifact,
/*skipNullifierInsertion=*/ false,
/*seed=*/ avmTestContractClassSeed,
{
currentClassId: avmTestContractClass.id,
},
/*originalContractClassId=*/ originalClassId, // upgraded from
);
const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact);
await tester.addContractInstance(avmTestContractInstance);

await writeContractUpdate(
tester,
avmTestContractInstance.address,
Expand All @@ -105,16 +92,17 @@ describe('AVM WitGen & Circuit - contract updates', () => {
async () => {
// Contract was not originally the avmTestContract
const originalClassId = new Fr(27);
avmTestContractInstance = await makeContractInstanceFromClassId(
originalClassId,

const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
sender,
/*contractArtifact=*/ AvmTestContractArtifact,
/*skipNullifierInsertion=*/ false,
/*seed=*/ avmTestContractClassSeed,
{
currentClassId: avmTestContractClass.id,
},
/*originalContractClassId=*/ originalClassId, // upgraded from
);
const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact);
await tester.addContractInstance(avmTestContractInstance);

await writeContractUpdate(
tester,
avmTestContractInstance.address,
Expand Down Expand Up @@ -143,13 +131,16 @@ describe('AVM WitGen & Circuit - contract updates', () => {
async () => {
// Contract was not originally the avmTestContract
const newClassId = new Fr(27);
avmTestContractInstance = await makeContractInstanceFromClassId(
avmTestContractClass.id,

const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
sender,
/*contractArtifact=*/ AvmTestContractArtifact,
/*skipNullifierInsertion=*/ false,
/*seed=*/ avmTestContractClassSeed,
);
const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact);
await tester.addContractInstance(avmTestContractInstance);

await writeContractUpdate(
tester,
avmTestContractInstance.address,
Expand All @@ -176,13 +167,16 @@ describe('AVM WitGen & Circuit - contract updates', () => {
async () => {
// Contract was not originally the avmTestContract
const newClassId = new Fr(27);
avmTestContractInstance = await makeContractInstanceFromClassId(
avmTestContractClass.id,

const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
sender,
/*contractArtifact=*/ AvmTestContractArtifact,
/*skipNullifierInsertion=*/ false,
/*seed=*/ avmTestContractClassSeed,
);
const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
await tester.addContractClass(avmTestContractClass, AvmTestContractArtifact);
await tester.addContractInstance(avmTestContractInstance);

await writeContractUpdate(
tester,
avmTestContractInstance.address,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AztecAddress, type ContractInstanceWithAddress } from '@aztec/circuits.js';
import { type ContractInstanceWithAddress } from '@aztec/circuits.js';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
import { AMMContractArtifact } from '@aztec/noir-contracts.js/AMM';
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
Expand Down Expand Up @@ -72,6 +73,7 @@ describe('AVM Witgen & Circuit apps tests: AMM', () => {
constructorArgs,
/*deployer=*/ admin,
TokenContractArtifact,
/*skipNullifierInsertion=*/ false,
seed,
);

Expand All @@ -93,7 +95,13 @@ describe('AVM Witgen & Circuit apps tests: AMM', () => {

const deployAMM = async (seed = 0) => {
const constructorArgs = [token0, token1, liquidityToken];
const amm = await tester.registerAndDeployContract(constructorArgs, /*deployer=*/ admin, AMMContractArtifact, seed);
const amm = await tester.registerAndDeployContract(
constructorArgs,
/*deployer=*/ admin,
AMMContractArtifact,
/*skipNullifierInsertion=*/ false,
seed,
);

await tester.simProveVerify(
/*sender=*/ admin,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AztecAddress, type ContractInstanceWithAddress } from '@aztec/circuits.js';
import { type ContractInstanceWithAddress } from '@aztec/circuits.js';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
import { type PublicTxResult } from '@aztec/simulator/server';
Expand Down
Loading

0 comments on commit c1cc3ed

Please sign in to comment.