Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
0ca12e2
feat: benchmark avm simulator token test
Mar 24, 2025
77a152e
deps
Mar 24, 2025
953dc8b
blah
Mar 24, 2025
6439d18
bench
Mar 24, 2025
f3f3ea9
cleanup and more tests
Mar 24, 2025
7e85f9d
cleanup
Mar 24, 2025
47fd1c2
merge
Mar 24, 2025
3e2e154
cleanup
Mar 24, 2025
622a694
revert token test
Mar 24, 2025
bf08766
more in bench test
Mar 24, 2025
bc072e0
revert ci3.yml
Mar 24, 2025
8f000a1
fix
Mar 24, 2025
1c6f718
amm and proper tallying
Mar 25, 2025
ee27f05
test helpers
Mar 25, 2025
b0ec099
cleanup
Mar 25, 2025
4086163
cleanup
Mar 26, 2025
c9047df
fix
Mar 26, 2025
71f8c40
fix talling
Mar 26, 2025
8bde642
fix
Mar 26, 2025
abe0bdf
unfix
Mar 26, 2025
5cbac04
cleanup
Mar 26, 2025
3115193
cleanup
Mar 26, 2025
bac8671
merge
Mar 26, 2025
a26e912
rename proving tester create to new
Mar 26, 2025
73eb5e5
fix comment
Mar 26, 2025
6f14c63
executor metrics for testing
Mar 27, 2025
9642476
subclasses of public tx simulator for metrics
Mar 27, 2025
bcc1292
subclasses
Mar 27, 2025
e09f98a
rm stale
Mar 27, 2025
c126bcb
rm bench.ts
Mar 27, 2025
bac743a
imports
Mar 27, 2025
6f9f1cb
cleanup
Mar 27, 2025
b0fbb66
fix
Mar 27, 2025
b22ebe7
single map for debug fns
Mar 27, 2025
25d7d91
fix
Mar 27, 2025
428f4d7
timer
Mar 27, 2025
9cc649e
pretty print
Mar 27, 2025
4d0c6b7
dependency cycle
Mar 27, 2025
f9b8fda
import
Mar 27, 2025
b3ae882
fixes
Mar 27, 2025
9537351
undo telemetry changes
Mar 27, 2025
80849ee
respond to PR comments
Mar 27, 2025
9f0191d
fix
Mar 27, 2025
45c643b
amm cleanup
Mar 27, 2025
a54add9
import
Mar 27, 2025
010377d
markdown
Mar 27, 2025
6b33a7b
markdown file
Mar 27, 2025
89abe9a
optional md file
Mar 27, 2025
993139e
json file
Mar 27, 2025
921bdf5
Merge branch 'master' into db/bench
dbanks12 Mar 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('AVM WitGen & Circuit – check circuit', () => {
let tester: AvmProvingTester;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('AVM WitGen & Circuit – check circuit', () => {
let tester: AvmProvingTester;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
Expand Down Expand Up @@ -44,7 +44,7 @@ describe('AVM WitGen & Circuit – check circuit', () => {
// 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);
const tester = await AvmProvingTester.new(/*checkCircuitOnly=*/ true);
await tester.simProveVerify(
sender,
/*setupCalls=*/ [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('AVM WitGen & Circuit – check circuit', () => {
let tester: AvmProvingTester;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('AVM WitGen & Circuit – check circuit - contract class limits', () =>
let avmTestContractAddress: AztecAddress;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly=*/ true);
tester = await AvmProvingTester.new(/*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++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest';
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
import { DEFAULT_BLOCK_NUMBER } from '@aztec/simulator/public/fixtures';
import { defaultGlobals } from '@aztec/simulator/public/fixtures';
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
import { ScheduledDelayChange, ScheduledValueChange, SharedMutableValuesWithHash } from '@aztec/stdlib/shared-mutable';
Expand Down Expand Up @@ -43,7 +43,8 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
async () => {
// Contract was not originally the avmTestContract
const originalClassId = new Fr(27);
const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
const globals = defaultGlobals();
const tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true, globals);

avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
Expand All @@ -59,7 +60,7 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
avmTestContractInstance.address,
avmTestContractInstance.originalContractClassId,
avmTestContractInstance.currentContractClassId,
DEFAULT_BLOCK_NUMBER,
globals.blockNumber.toNumber(),
);

await tester.simProveVerify(
Expand All @@ -80,8 +81,8 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
async () => {
// Contract was not originally the avmTestContract
const originalClassId = new Fr(27);

const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
const globals = defaultGlobals();
const tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true, globals);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
sender,
Expand All @@ -96,7 +97,7 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
avmTestContractInstance.address,
avmTestContractInstance.originalContractClassId,
avmTestContractInstance.currentContractClassId,
DEFAULT_BLOCK_NUMBER + 1,
globals.blockNumber.toNumber() + 1,
);

await expect(
Expand All @@ -120,7 +121,8 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
// Contract was not originally the avmTestContract
const newClassId = new Fr(27);

const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
const globals = defaultGlobals();
const tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true, globals);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
sender,
Expand All @@ -134,7 +136,7 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
avmTestContractInstance.address,
avmTestContractInstance.currentContractClassId,
newClassId,
DEFAULT_BLOCK_NUMBER + 1,
globals.blockNumber.toNumber() + 1,
);

await tester.simProveVerify(
Expand All @@ -156,7 +158,8 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
// Contract was not originally the avmTestContract
const newClassId = new Fr(27);

const tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
const globals = defaultGlobals();
const tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true, globals);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
sender,
Expand All @@ -170,7 +173,7 @@ describe.skip('AVM WitGen & Circuit - contract updates', () => {
avmTestContractInstance.address,
avmTestContractInstance.currentContractClassId,
newClassId,
DEFAULT_BLOCK_NUMBER - 1,
globals.blockNumber.toNumber() - 1,
);

await expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('AVM Witgen & Circuit apps tests: AMM', () => {
jest.setTimeout(TIMEOUT);
const admin = AztecAddress.fromNumber(42);
const liquidityProvider = AztecAddress.fromNumber(111);
const otherLiqduidityProvider = AztecAddress.fromNumber(222);
const otherLiquidityProvider = AztecAddress.fromNumber(222);
const swapper = AztecAddress.fromNumber(333);

let token0: ContractInstanceWithAddress;
Expand All @@ -25,7 +25,7 @@ describe('AVM Witgen & Circuit apps tests: AMM', () => {
let tester: AvmProvingTester;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true);
});

// TODO(dbanks12): add tester support for authwit and finish implementing this test
Expand All @@ -52,8 +52,8 @@ describe('AVM Witgen & Circuit apps tests: AMM', () => {

await mint(/*to=*/ liquidityProvider, /*amount=*/ INITIAL_TOKEN_BALANCE, token0);
await mint(/*to=*/ liquidityProvider, /*amount=*/ INITIAL_TOKEN_BALANCE, token1);
await mint(/*to=*/ otherLiqduidityProvider, /*amount=*/ INITIAL_TOKEN_BALANCE, token0);
await mint(/*to=*/ otherLiqduidityProvider, /*amount=*/ INITIAL_TOKEN_BALANCE, token1);
await mint(/*to=*/ otherLiquidityProvider, /*amount=*/ INITIAL_TOKEN_BALANCE, token0);
await mint(/*to=*/ otherLiquidityProvider, /*amount=*/ INITIAL_TOKEN_BALANCE, token1);
await mint(/*to=*/ swapper, /*amount=*/ INITIAL_TOKEN_BALANCE, token0);

//const ammBalancesBefore = await getAmmBalances();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('AVM Witgen & Circuit apps tests: TokenContract', () => {
let tester: AvmProvingTester;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true);

const constructorArgs = [admin, /*name=*/ 'Token', /*symbol=*/ 'TOK', /*decimals=*/ new Fr(18)];
token = await tester.registerAndDeployContract(constructorArgs, /*deployer=*/ admin, TokenContractArtifact);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('AVM WitGen & Circuit – proving and verification', () => {
let tester: AvmProvingTester;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly*/ false);
tester = await AvmProvingTester.new(/*checkCircuitOnly*/ false);
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
Expand Down
16 changes: 10 additions & 6 deletions yarn-project/bb-prover/src/avm_proving_tests/avm_proving_tester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { AvmCircuitInputs } from '@aztec/stdlib/avm';
import { AztecAddress } from '@aztec/stdlib/aztec-address';
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
import { makeAvmCircuitInputs } from '@aztec/stdlib/testing';
import type { GlobalVariables } from '@aztec/stdlib/tx';
import { VerificationKeyData } from '@aztec/stdlib/vks';
import { NativeWorldStateService } from '@aztec/world-state';

Expand All @@ -30,16 +31,18 @@ export class AvmProvingTester extends PublicTxSimulationTester {
private checkCircuitOnly: boolean,
merkleTree: MerkleTreeWriteOperations,
contractDataSource: SimpleContractDataSource,
globals?: GlobalVariables,
) {
super(merkleTree, contractDataSource);
super(merkleTree, contractDataSource, globals);
}

static override async create(checkCircuitOnly: boolean = false) {
// overriding parent class' create is a pain, so we use a different nam
static async new(checkCircuitOnly: boolean = false, globals?: GlobalVariables) {
const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));

const contractDataSource = new SimpleContractDataSource();
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly, merkleTrees, contractDataSource);
return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly, merkleTrees, contractDataSource, globals);
}

async prove(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult> {
Expand Down Expand Up @@ -108,16 +111,17 @@ export class AvmProvingTesterV2 extends PublicTxSimulationTester {
private bbWorkingDirectory: string,
contractDataSource: SimpleContractDataSource,
merkleTrees: MerkleTreeWriteOperations,
globals?: GlobalVariables,
) {
super(merkleTrees, contractDataSource);
super(merkleTrees, contractDataSource, globals);
}

static override async create() {
static async new(globals?: GlobalVariables) {
const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));

const contractDataSource = new SimpleContractDataSource();
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
return new AvmProvingTesterV2(bbWorkingDirectory, contractDataSource, merkleTrees);
return new AvmProvingTesterV2(bbWorkingDirectory, contractDataSource, merkleTrees, globals);
}

async proveV2(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('AVM WitGen & Circuit – public fee payment', () => {
let tester: AvmProvingTester;

beforeEach(async () => {
tester = await AvmProvingTester.create(/*checkCircuitOnly*/ true);
tester = await AvmProvingTester.new(/*checkCircuitOnly*/ true);

await tester.registerFeeJuiceContract();
await tester.setFeePayerBalance(feePayer, initialFeeJuiceBalance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('AVM v2', () => {
let tester: AvmProvingTesterV2;

beforeEach(async () => {
tester = await AvmProvingTesterV2.create();
tester = await AvmProvingTesterV2.new();
avmTestContractInstance = await tester.registerAndDeployContract(
/*constructorArgs=*/ [],
/*deployer=*/ AztecAddress.fromNumber(420),
Expand Down
28 changes: 0 additions & 28 deletions yarn-project/end-to-end/src/bench/utils.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import type { AztecNodeService } from '@aztec/aztec-node';
import { type AztecNode, BatchCall, INITIAL_L2_BLOCK_NUM, type SentTx, type WaitOpts } from '@aztec/aztec.js';
import { mean, stdDev, times } from '@aztec/foundation/collection';
import { randomInt } from '@aztec/foundation/crypto';
import { BenchmarkingContract } from '@aztec/noir-contracts.js/Benchmarking';
import { type PXEService, type PXEServiceConfig, createPXEService } from '@aztec/pxe/server';
import type { MetricsType } from '@aztec/telemetry-client';
import type { BenchmarkDataPoint, BenchmarkMetricsType, BenchmarkTelemetryClient } from '@aztec/telemetry-client/bench';

import { writeFileSync } from 'fs';
import { mkdirpSync } from 'fs-extra';
import { globSync } from 'glob';
import { join } from 'path';

import { type EndToEndContext, type SetupOptions, setup } from '../fixtures/utils.js';

Expand Down Expand Up @@ -94,30 +90,6 @@ function getMetricValues(points: BenchmarkDataPoint[]) {
}
}

/**
* Creates and returns a directory with the current job name and a random number.
* @param index - Index to merge into the dir path.
* @returns A path to a created dir.
*/
export function makeDataDirectory(index: number) {
const testName = expect.getState().currentTestName!.split(' ')[0].replaceAll('/', '_');
const db = join('data', testName, index.toString(), `${randomInt(99)}`);
mkdirpSync(db);
return db;
}

/**
* Returns the size in disk of a folder.
* @param path - Path to the folder.
* @returns Size in bytes.
*/
export function getFolderSize(path: string): number {
return globSync('**', { stat: true, cwd: path, nodir: true, withFileTypes: true }).reduce(
(accum, file) => accum + (file as any as { /** Size */ size: number }).size,
0,
);
}

/**
* Returns a call to the benchmark contract. Each call has a private execution (account entrypoint),
* a nested private call (create_note), a public call (increment_balance), and a nested public
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/end-to-end/src/e2e_block_building.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
PublicProcessorFactory,
type PublicTreesDB,
type PublicTxResult,
PublicTxSimulator,
TelemetryPublicTxSimulator,
} from '@aztec/simulator/server';
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
import type { Tx } from '@aztec/stdlib/tx';
Expand Down Expand Up @@ -608,7 +608,7 @@ async function sendAndWait(calls: ContractFunctionInteraction[]) {

const TEST_PUBLIC_TX_SIMULATION_DELAY_MS = 300;

class TestPublicTxSimulator extends PublicTxSimulator {
class TestPublicTxSimulator extends TelemetryPublicTxSimulator {
public override async simulate(tx: Tx): Promise<PublicTxResult> {
await sleep(TEST_PUBLIC_TX_SIMULATION_DELAY_MS);
return super.simulate(tx);
Expand All @@ -622,7 +622,7 @@ class TestPublicProcessorFactory extends PublicProcessorFactory {
doMerkleOperations: boolean,
skipFeeEnforcement: boolean,
telemetryClient?: TelemetryClient,
): PublicTxSimulator {
) {
return new TestPublicTxSimulator(
treesDB,
contractsDB,
Expand Down
6 changes: 6 additions & 0 deletions yarn-project/simulator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,9 @@ Same steps as any other library. They are detailed [here](../README.md#developme
### Testing

Same steps as any other library. They are detailed [here](../README.md#tests)

### Benchmarking

```
LOG_LEVEL=info yarn test src/public/public_tx_simulator/apps_tests/bench.test.ts
```
18 changes: 15 additions & 3 deletions yarn-project/simulator/src/public/avm/avm_contract_call_result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ export class AvmContractCallResult {
public output: Fr[],
public gasLeft: AvmGas,
public revertReason?: AvmRevertReason,
public totalInstructions: number = 0, // including nested calls
) {}

toString(): string {
let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(this.gasLeft)}`;
let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(
this.gasLeft,
)}, totalInstructions: ${this.totalInstructions}`;
if (this.revertReason) {
resultsStr += `, revertReason: ${this.revertReason}`;
}
Expand All @@ -29,7 +32,13 @@ export class AvmContractCallResult {

finalize(): AvmFinalizedCallResult {
const revertReason = this.revertReason ? createSimulationError(this.revertReason, this.output) : undefined;
return new AvmFinalizedCallResult(this.reverted, this.output, Gas.from(this.gasLeft), revertReason);
return new AvmFinalizedCallResult(
this.reverted,
this.output,
Gas.from(this.gasLeft),
revertReason,
this.totalInstructions,
);
}
}

Expand All @@ -43,10 +52,13 @@ export class AvmFinalizedCallResult {
public output: Fr[],
public gasLeft: Gas,
public revertReason?: SimulationError,
public totalInstructions: number = 0, // including nested calls
) {}

toString(): string {
let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(this.gasLeft)}`;
let resultsStr = `reverted: ${this.reverted}, output: ${this.output}, gasLeft: ${inspect(
this.gasLeft,
)}, totalInstructions: ${this.totalInstructions}`;
if (this.revertReason) {
resultsStr += `, revertReason: ${this.revertReason}`;
}
Expand Down
5 changes: 5 additions & 0 deletions yarn-project/simulator/src/public/avm/avm_machine_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ export class AvmMachineState {
/** Output data must NOT be modified once it is set */
private output: Fr[] = [];

// Metrics only - not needed for execution
/** instruction counter, including nested calls */
public instrCounter: number = 0;
// End metrics only

constructor(gasLeft: Gas);
constructor(l2GasLeft: number, daGasLeft: number);
constructor(gasLeftOrL2GasLeft: Gas | number, daGasLeft?: number) {
Expand Down
Loading