Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(simulator): initialize ACVM's SimulatedBackend separately (setup pedersen init only happens once) #1596

Merged
merged 14 commits into from
Aug 17, 2023
Merged
2 changes: 1 addition & 1 deletion yarn-project/acir-simulator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@aztec/circuits.js": "workspace:^",
"@aztec/foundation": "workspace:^",
"@aztec/types": "workspace:^",
"acvm_js": "github:noir-lang/acvm-simulator-wasm#b9d9ca9dfc5140839f23998d9466307215607c42",
"acvm_js": "github:dbanks12/acvm-simulator-wasm#db/init-sim-backend",
dbanks12 marked this conversation as resolved.
Show resolved Hide resolved
"levelup": "^5.1.1",
"memdown": "^6.1.1",
"tslib": "^2.4.0"
Expand Down
36 changes: 21 additions & 15 deletions yarn-project/acir-simulator/src/acvm/acvm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
import { createDebugLogger } from '@aztec/foundation/log';

import { ForeignCallInput, ForeignCallOutput, WitnessMap, executeCircuit } from 'acvm_js';
import { ForeignCallInput, ForeignCallOutput, SimulatedBackend, WitnessMap, executeCircuit } from 'acvm_js';

/**
* The format for fields on the ACVM.
Expand Down Expand Up @@ -69,26 +69,32 @@ export interface ACIRExecutionResult {
* The function call that executes an ACIR.
*/
export async function acvm(
backend: SimulatedBackend,
acir: Buffer,
initialWitness: ACVMWitness,
callback: ACIRCallback,
): Promise<ACIRExecutionResult> {
const logger = createDebugLogger('aztec:simulator:acvm');
const partialWitness = await executeCircuit(acir, initialWitness, async (name: string, args: ForeignCallInput[]) => {
try {
logger(`Oracle callback ${name}`);
const oracleFunction = callback[name as ORACLE_NAMES];
if (!oracleFunction) {
throw new Error(`Oracle callback ${name} not found`);
const partialWitness = await executeCircuit(
backend,
acir,
initialWitness,
async (name: string, args: ForeignCallInput[]) => {
try {
logger(`Oracle callback ${name}`);
const oracleFunction = callback[name as ORACLE_NAMES];
if (!oracleFunction) {
throw new Error(`Oracle callback ${name} not found`);
}

const result = await oracleFunction.call(callback, ...args);
return [result];
} catch (err: any) {
logger(`Error in oracle callback ${name}: ${err.message ?? err ?? 'Unknown'}`);
throw err;
}

const result = await oracleFunction.call(callback, ...args);
return [result];
} catch (err: any) {
logger(`Error in oracle callback ${name}: ${err.message ?? err ?? 'Unknown'}`);
throw err;
}
});
},
);
dbanks12 marked this conversation as resolved.
Show resolved Hide resolved
return Promise.resolve({ partialWitness });
}

Expand Down
4 changes: 2 additions & 2 deletions yarn-project/acir-simulator/src/client/private_execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
toAcvmCallPrivateStackItem,
toAcvmEnqueuePublicFunctionResult,
} from '../acvm/index.js';
import { ExecutionResult, NewNoteData, NewNullifierData } from '../index.js';
import { AcirSimulator, ExecutionResult, NewNoteData, NewNullifierData } from '../index.js';
import { ClientTxExecutionContext } from './client_execution_context.js';
import { acvmFieldMessageToString, oracleDebugCallToFormattedStr } from './debug.js';

Expand Down Expand Up @@ -63,7 +63,7 @@ export class PrivateFunctionExecution {
const encryptedLogs = new FunctionL2Logs([]);
const unencryptedLogs = new FunctionL2Logs([]);

const { partialWitness } = await acvm(acir, initialWitness, {
const { partialWitness } = await acvm(await AcirSimulator.getBackend(), acir, initialWitness, {
packArguments: async args => {
return toACVMField(await this.context.packedArgsCache.pack(args.map(fromACVMField)));
},
Expand Down
21 changes: 21 additions & 0 deletions yarn-project/acir-simulator/src/client/simulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Fr } from '@aztec/foundation/fields';
import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
import { AztecNode, FunctionCall, TxExecutionRequest } from '@aztec/types';

import { SimulatedBackend, createBackend } from 'acvm_js';

import { PackedArgsCache } from '../packed_args_cache.js';
import { ClientTxExecutionContext } from './client_execution_context.js';
import { DBOracle } from './db_oracle.js';
Expand All @@ -20,12 +22,31 @@ import { UnconstrainedFunctionExecution } from './unconstrained_execution.js';
* The ACIR simulator.
*/
export class AcirSimulator {
private static backend: SimulatedBackend; // ACVM's backend
private log: DebugLogger;

constructor(private db: DBOracle) {
this.log = createDebugLogger('aztec:simulator');
}

/**
* Gets or initializes the ACVM SimulatedBackend.
*
* @remarks
*
* Occurs only once across all instances of AcirSimulator.
* Speeds up execution by only performing setup tasks (like pedersen
* generator initialization) one time.
* WARNING: it is unclear whether this will work in a multi-threaded
dbanks12 marked this conversation as resolved.
Show resolved Hide resolved
* environment where multiple threads seek to use the same backend.
*
* @returns ACVM SimulatedBackend
*/
public static async getBackend(): Promise<SimulatedBackend> {
if (!this.backend) this.backend = await createBackend();
return this.backend;
}

/**
* Runs a private function.
* @param request - The transaction request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AztecNode } from '@aztec/types';

import { extractReturnWitness, frToAztecAddress } from '../acvm/deserialize.js';
import { ACVMField, ZERO_ACVM_FIELD, acvm, fromACVMField, toACVMField, toACVMWitness } from '../acvm/index.js';
import { AcirSimulator } from '../index.js';
import { ClientTxExecutionContext } from './client_execution_context.js';
import { oracleDebugCallToFormattedStr } from './debug.js';

Expand Down Expand Up @@ -40,7 +41,7 @@ export class UnconstrainedFunctionExecution {
const acir = Buffer.from(this.abi.bytecode, 'base64');
const initialWitness = toACVMWitness(1, this.args);

const { partialWitness } = await acvm(acir, initialWitness, {
const { partialWitness } = await acvm(await AcirSimulator.getBackend(), acir, initialWitness, {
getSecretKey: ([ownerX], [ownerY]) => this.context.getSecretKey(this.contractAddress, ownerX, ownerY),
getPublicKey: async ([acvmAddress]) => {
const address = frToAztecAddress(fromACVMField(acvmAddress));
Expand Down
3 changes: 2 additions & 1 deletion yarn-project/acir-simulator/src/public/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
toAcvmL1ToL2MessageLoadOracleInputs,
} from '../acvm/index.js';
import { oracleDebugCallToFormattedStr } from '../client/debug.js';
import { AcirSimulator } from '../index.js';
import { PackedArgsCache } from '../packed_args_cache.js';
import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js';
import { PublicExecution, PublicExecutionResult } from './execution.js';
Expand Down Expand Up @@ -71,7 +72,7 @@ export class PublicExecutor {
// We use this cache to hold the packed arguments.
const packedArgs = await PackedArgsCache.create([]);

const { partialWitness } = await acvm(acir, initialWitness, {
const { partialWitness } = await acvm(await AcirSimulator.getBackend(), acir, initialWitness, {
packArguments: async args => {
return toACVMField(await packedArgs.pack(args.map(fromACVMField)));
},
Expand Down
10 changes: 5 additions & 5 deletions yarn-project/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ __metadata:
"@rushstack/eslint-patch": ^1.1.4
"@types/jest": ^29.5.0
"@types/node": ^18.7.23
acvm_js: "github:noir-lang/acvm-simulator-wasm#b9d9ca9dfc5140839f23998d9466307215607c42"
acvm_js: "github:dbanks12/acvm-simulator-wasm#db/init-sim-backend"
jest: ^29.5.0
jest-mock-extended: ^3.0.4
levelup: ^5.1.1
Expand Down Expand Up @@ -4018,10 +4018,10 @@ __metadata:
languageName: node
linkType: hard

"acvm_js@github:noir-lang/acvm-simulator-wasm#b9d9ca9dfc5140839f23998d9466307215607c42":
version: 0.0.0-d576736
resolution: "acvm_js@https://github.com/noir-lang/acvm-simulator-wasm.git#commit=b9d9ca9dfc5140839f23998d9466307215607c42"
checksum: ea88c231451e7aeab2ecf4219c062d1193860c5bd782ea1b0d8f778990798a27ab983ae5036e2cb99248cb75d22d961d1dd4b9c1c8c0ce0215e955f00e07944f
"acvm_js@github:dbanks12/acvm-simulator-wasm#db/init-sim-backend":
version: 0.21.0
resolution: "acvm_js@https://github.com/dbanks12/acvm-simulator-wasm.git#commit=15662eefb304eb79eb84497302da8ea83d6a7b63"
checksum: 3177d578421b65c164483f0ef2f83a74790df22b68b482116ce6880c1be096882ba1764caa25c182e642321df8346723e69fef8102fdb8fe54c7ffdcc7465058
languageName: node
linkType: hard

Expand Down