Skip to content

Commit

Permalink
chore(simulator): initialize ACVM's SimulatedBackend separately (setu…
Browse files Browse the repository at this point in the history
…p pedersen init only happens once) (#1596)

Resolves #1553
  • Loading branch information
dbanks12 authored Aug 17, 2023
1 parent ee00df5 commit 1a260ed
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 26 deletions.
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:noir-lang/acvm-js-wasm#db/init-sim-backend",
"levelup": "^5.1.1",
"memdown": "^6.1.1",
"tslib": "^2.4.0"
Expand Down
42 changes: 27 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,13 @@ 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,
WasmBlackBoxFunctionSolver,
WitnessMap,
executeCircuitWithBlackBoxSolver,
} from 'acvm_js';

/**
* The format for fields on the ACVM.
Expand Down Expand Up @@ -69,26 +75,32 @@ export interface ACIRExecutionResult {
* The function call that executes an ACIR.
*/
export async function acvm(
solver: WasmBlackBoxFunctionSolver,
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 executeCircuitWithBlackBoxSolver(
solver,
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(`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(`Error in oracle callback ${name}: ${err.message ?? err ?? 'Unknown'}`);
throw err;
}
});
},
);
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.getSolver(), 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 { WasmBlackBoxFunctionSolver, createBlackBoxSolver } 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 solver: WasmBlackBoxFunctionSolver; // ACVM's backend
private log: DebugLogger;

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

/**
* Gets or initializes the ACVM WasmBlackBoxFunctionSolver.
*
* @remarks
*
* Occurs only once across all instances of AcirSimulator.
* Speeds up execution by only performing setup tasks (like pedersen
* generator initialization) one time.
* TODO(https://github.com/AztecProtocol/aztec-packages/issues/1627):
* determine whether this requires a lock
*
* @returns ACVM WasmBlackBoxFunctionSolver
*/
public static async getSolver(): Promise<WasmBlackBoxFunctionSolver> {
if (!this.solver) this.solver = await createBlackBoxSolver();
return this.solver;
}

/**
* 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.getSolver(), 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.getSolver(), acir, initialWitness, {
packArguments: async args => {
return toACVMField(await packedArgs.pack(args.map(fromACVMField)));
},
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_account_contracts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function itShouldBehaveLikeAnAccountContract(getAccountContract: (encryptionKey:
).getWallet();
const childWithInvalidWallet = await ChildContract.at(child.address, invalidWallet);
await expect(childWithInvalidWallet.methods.value(42).simulate()).rejects.toThrowError(
/could not satisfy all constraints/,
/Cannot satisfy constraint Resolved\([0-9]+\)/,
);
});
});
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:noir-lang/acvm-js-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:noir-lang/acvm-js-wasm#db/init-sim-backend":
version: 0.21.0
resolution: "acvm_js@https://github.com/noir-lang/acvm-js-wasm.git#commit=b2cc89d9a67c11ad6cb59c9b9acad1e2be4bd938"
checksum: a65383c053fc59ef55e65f181277a5edc4ac22c4c0180fc5b05788121360f03fa24fe176da78de51d36892bce76893178c79d1c0284f834d1d6ed5e8209ff1b4
languageName: node
linkType: hard

Expand Down

0 comments on commit 1a260ed

Please sign in to comment.