diff --git a/boxes/boxes/vite/package.json b/boxes/boxes/vite/package.json index c3301be3c0d..e05608b11c9 100644 --- a/boxes/boxes/vite/package.json +++ b/boxes/boxes/vite/package.json @@ -21,9 +21,7 @@ "@aztec/key-store": "link:../../../yarn-project/key-store", "@aztec/kv-store": "portal:../../../yarn-project/kv-store", "@aztec/pxe": "link:../../../yarn-project/pxe", - "@noir-lang/acvm_js": "link:../../../noir/packages/acvm_js", - "@noir-lang/noirc_abi": "link:../../../noir/packages/noirc_abi", - "buffer": "^6.0.3", + "@aztec/simulator": "link:../../../yarn-project/simulator", "react": "^18.3.1", "react-dom": "^18.3.1", "react-toastify": "^10.0.6" diff --git a/boxes/boxes/vite/src/App.tsx b/boxes/boxes/vite/src/App.tsx index daf6f6d9d8d..3633028ec16 100644 --- a/boxes/boxes/vite/src/App.tsx +++ b/boxes/boxes/vite/src/App.tsx @@ -2,33 +2,13 @@ import { ToastContainer } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import "./App.css"; import { Home } from "./pages/home"; -import { useEffect, useState } from "react"; -import initACVM from "@noir-lang/acvm_js/web/acvm_js"; -import initABI from "@noir-lang/noirc_abi/web/noirc_abi_wasm"; -import acvmURL from "@noir-lang/acvm_js/web/acvm_js_bg.wasm?url"; -import abiURL from "@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm?url"; - -const InitWasm = ({ children }: any) => { - const [init, setInit] = useState(false); - useEffect(() => { - (async () => { - await Promise.all([ - initACVM(new URL(acvmURL, import.meta.url).toString()), - initABI(new URL(abiURL, import.meta.url).toString()), - ]); - setInit(true); - })(); - }, []); - - return
{init && children}
; -}; function App() { return ( - + <> - + ); } diff --git a/boxes/boxes/vite/src/config.ts b/boxes/boxes/vite/src/config.ts index 2413b3f5ff8..dbd86001d89 100644 --- a/boxes/boxes/vite/src/config.ts +++ b/boxes/boxes/vite/src/config.ts @@ -1,5 +1,4 @@ import { - AztecNode, Fr, createLogger, deriveMasterIncomingViewingSecretKey, @@ -12,10 +11,10 @@ import { PXEService } from "@aztec/pxe/service"; import { PXEServiceConfig, getPXEServiceConfig } from "@aztec/pxe/config"; import { KVPxeDatabase } from "@aztec/pxe/database"; import { KeyStore } from "@aztec/key-store"; -import { PrivateKernelProver } from "@aztec/circuit-types"; import { L2TipsStore } from "@aztec/kv-store/stores"; import { createStore } from "@aztec/kv-store/indexeddb"; import { BBWASMLazyPrivateKernelProver } from "@aztec/bb-prover/wasm/lazy"; +import { WASMSimulator } from "@aztec/simulator/client"; process.env = Object.keys(import.meta.env).reduce((acc, key) => { acc[key.replace("VITE_", "")] = import.meta.env[key]; @@ -39,25 +38,11 @@ export class PrivateEnv { config.dataDirectory = "pxe"; config.proverEnabled = true; const aztecNode = await createAztecNodeClient(this.nodeURL); - const proofCreator = new BBWASMLazyPrivateKernelProver(16); - this.pxe = await this.createPXEService(aztecNode, config, proofCreator); - const encryptionPrivateKey = deriveMasterIncomingViewingSecretKey( - this.secretKey, + const simulationProvider = new WASMSimulator(); + const proofCreator = new BBWASMLazyPrivateKernelProver( + simulationProvider, + 16, ); - this.accountContract = new SchnorrAccountContract(encryptionPrivateKey); - this.account = new AccountManager( - this.pxe, - this.secretKey, - this.accountContract, - ); - await this.account.deploy().wait(); - } - - async createPXEService( - aztecNode: AztecNode, - config: PXEServiceConfig, - proofCreator?: PrivateKernelProver, - ) { const l1Contracts = await aztecNode.getL1ContractAddresses(); const configWithContracts = { ...config, @@ -75,16 +60,26 @@ export class PrivateEnv { const db = await KVPxeDatabase.create(store); const tips = new L2TipsStore(store, "pxe"); - const pxe = new PXEService( + this.pxe = new PXEService( keyStore, aztecNode, db, tips, proofCreator, + simulationProvider, config, ); - await pxe.init(); - return pxe; + await this.pxe.init(); + const encryptionPrivateKey = deriveMasterIncomingViewingSecretKey( + this.secretKey, + ); + this.accountContract = new SchnorrAccountContract(encryptionPrivateKey); + this.account = new AccountManager( + this.pxe, + this.secretKey, + this.accountContract, + ); + await this.account.deploy().wait(); } async getWallet() { diff --git a/boxes/boxes/vite/vite.config.ts b/boxes/boxes/vite/vite.config.ts index 309b5eabdee..602fc1c226f 100644 --- a/boxes/boxes/vite/vite.config.ts +++ b/boxes/boxes/vite/vite.config.ts @@ -32,6 +32,8 @@ export default defineConfig({ allow: [ searchForWorkspaceRoot(process.cwd()), "../../../yarn-project/noir-protocol-circuits-types/artifacts", + "../../../noir/packages/noirc_abi/web", + "../../../noir/packages/acvm_js/web", ], }, }, @@ -51,7 +53,4 @@ export default defineConfig({ }, }, }, - optimizeDeps: { - exclude: ["@noir-lang/acvm_js", "@noir-lang/noirc_abi", "@aztec/bb-prover"], - }, }); diff --git a/boxes/yarn.lock b/boxes/yarn.lock index 79699d7e7f0..6f430a0fd08 100644 --- a/boxes/yarn.lock +++ b/boxes/yarn.lock @@ -139,6 +139,12 @@ __metadata: languageName: unknown linkType: soft +"@aztec/simulator@link:../../../yarn-project/simulator::locator=vite%40workspace%3Aboxes%2Fvite": + version: 0.0.0-use.local + resolution: "@aztec/simulator@link:../../../yarn-project/simulator::locator=vite%40workspace%3Aboxes%2Fvite" + languageName: node + linkType: soft + "@aztec/types@link:../yarn-project/types::locator=aztec-app%40workspace%3A.": version: 0.0.0-use.local resolution: "@aztec/types@link:../yarn-project/types::locator=aztec-app%40workspace%3A." @@ -1664,18 +1670,6 @@ __metadata: languageName: node linkType: hard -"@noir-lang/acvm_js@link:../../../noir/packages/acvm_js::locator=vite%40workspace%3Aboxes%2Fvite": - version: 0.0.0-use.local - resolution: "@noir-lang/acvm_js@link:../../../noir/packages/acvm_js::locator=vite%40workspace%3Aboxes%2Fvite" - languageName: node - linkType: soft - -"@noir-lang/noirc_abi@link:../../../noir/packages/noirc_abi::locator=vite%40workspace%3Aboxes%2Fvite": - version: 0.0.0-use.local - resolution: "@noir-lang/noirc_abi@link:../../../noir/packages/noirc_abi::locator=vite%40workspace%3Aboxes%2Fvite" - languageName: node - linkType: soft - "@nolyfill/is-core-module@npm:1.0.39": version: 1.0.39 resolution: "@nolyfill/is-core-module@npm:1.0.39" @@ -12162,13 +12156,11 @@ __metadata: "@aztec/key-store": "link:../../../yarn-project/key-store" "@aztec/kv-store": "portal:../../../yarn-project/kv-store" "@aztec/pxe": "link:../../../yarn-project/pxe" + "@aztec/simulator": "link:../../../yarn-project/simulator" "@eslint/js": "npm:^9.13.0" - "@noir-lang/acvm_js": "link:../../../noir/packages/acvm_js" - "@noir-lang/noirc_abi": "link:../../../noir/packages/noirc_abi" "@types/react": "npm:^18.3.12" "@types/react-dom": "npm:^18.3.1" "@vitejs/plugin-react-swc": "npm:^3.7.2" - buffer: "npm:^6.0.3" eslint: "npm:^9.13.0" eslint-plugin-react-hooks: "npm:^5.1.0" eslint-plugin-react-refresh: "npm:^0.4.16" diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 67e96b8e77c..647cf72f49d 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -73,7 +73,7 @@ import { createValidatorForAcceptingTxs, getDefaultAllowedSetupFunctions, } from '@aztec/sequencer-client'; -import { PublicProcessorFactory } from '@aztec/simulator'; +import { PublicProcessorFactory } from '@aztec/simulator/server'; import { Attributes, type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { createValidatorClient } from '@aztec/validator-client'; diff --git a/yarn-project/bb-prover/src/prover/bb_native_private_kernel_prover.ts b/yarn-project/bb-prover/src/prover/bb_native_private_kernel_prover.ts index cdb000404ec..87f9978db98 100644 --- a/yarn-project/bb-prover/src/prover/bb_native_private_kernel_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_native_private_kernel_prover.ts @@ -2,6 +2,7 @@ import { type ClientIvcProof } from '@aztec/circuits.js'; import { runInDirectory } from '@aztec/foundation/fs'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { BundleArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/bundle'; +import { type SimulationProvider } from '@aztec/simulator/server'; import { encode } from '@msgpack/msgpack'; import { serializeWitness } from '@noir-lang/noirc_abi'; @@ -22,14 +23,21 @@ export class BBNativePrivateKernelProver extends BBPrivateKernelProver { private bbBinaryPath: string, private bbWorkingDirectory: string, private skipCleanup: boolean, + protected override simulationProvider: SimulationProvider, protected override log = createLogger('bb-prover:native'), ) { - super(new BundleArtifactProvider(), log); + super(new BundleArtifactProvider(), simulationProvider, log); } - public static async new(config: BBConfig, log?: Logger) { + public static async new(config: BBConfig, simulationProvider: SimulationProvider, log?: Logger) { await fs.mkdir(config.bbWorkingDirectory, { recursive: true }); - return new BBNativePrivateKernelProver(config.bbBinaryPath, config.bbWorkingDirectory, !!config.bbSkipCleanup, log); + return new BBNativePrivateKernelProver( + config.bbBinaryPath, + config.bbWorkingDirectory, + !!config.bbSkipCleanup, + simulationProvider, + log, + ); } private async _createClientIvcProof( diff --git a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts index 74dd829b09c..e8d530d7043 100644 --- a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts @@ -27,7 +27,7 @@ import { } from '@aztec/noir-protocol-circuits-types/client'; import { type ArtifactProvider, type ClientProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types'; import { ClientCircuitVks } from '@aztec/noir-protocol-circuits-types/vks'; -import { WASMSimulator } from '@aztec/simulator/client'; +import { type SimulationProvider } from '@aztec/simulator/client'; import { type NoirCompiledCircuit } from '@aztec/types/noir'; import { type Abi, type WitnessMap } from '@noir-lang/types'; @@ -35,9 +35,11 @@ import { type Abi, type WitnessMap } from '@noir-lang/types'; import { mapProtocolArtifactNameToCircuitName } from '../stats.js'; export abstract class BBPrivateKernelProver implements PrivateKernelProver { - protected simulator = new WASMSimulator(); - - constructor(protected artifactProvider: ArtifactProvider, protected log = createLogger('bb-prover')) {} + constructor( + protected artifactProvider: ArtifactProvider, + protected simulationProvider: SimulationProvider, + protected log = createLogger('bb-prover'), + ) {} public async generateInitOutput( inputs: PrivateKernelInitCircuitPrivateInputs, @@ -164,7 +166,7 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver { const witnessMap = convertInputs(inputs, compiledCircuit.abi); const timer = new Timer(); - const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit); + const outputWitness = await this.simulationProvider.executeProtocolCircuit(witnessMap, compiledCircuit); const output = convertOutputs(outputWitness, compiledCircuit.abi); this.log.debug(`Simulated ${circuitType}`, { @@ -194,7 +196,7 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver { const witnessMap = convertInputs(inputs, compiledCircuit.abi); const timer = new Timer(); - const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit); + const outputWitness = await this.simulationProvider.executeProtocolCircuit(witnessMap, compiledCircuit); const output = convertOutputs(outputWitness, compiledCircuit.abi); this.log.debug(`Generated witness for ${circuitType}`, { diff --git a/yarn-project/bb-prover/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts index 28e7b7e3636..c702d668aa2 100644 --- a/yarn-project/bb-prover/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -69,7 +69,7 @@ import { convertSingleTxBlockRootRollupInputsToWitnessMap, convertSingleTxBlockRootRollupOutputsFromWitnessMap, } from '@aztec/noir-protocol-circuits-types/server'; -import { NativeACVMSimulator } from '@aztec/simulator'; +import { NativeACVMSimulator } from '@aztec/simulator/server'; import { Attributes, type TelemetryClient, trackSpan } from '@aztec/telemetry-client'; import { type WitnessMap } from '@noir-lang/types'; @@ -427,7 +427,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { const inputWitness = convertInput(input); const timer = new Timer(); - const outputWitness = await simulator.simulateCircuit(inputWitness, artifact); + const outputWitness = await simulator.executeProtocolCircuit(inputWitness, artifact); const output = convertOutput(outputWitness); const circuitName = mapProtocolArtifactNameToCircuitName(circuitType); diff --git a/yarn-project/bb-prover/src/test/test_avm.ts b/yarn-project/bb-prover/src/test/test_avm.ts index 7dd0954dfe6..b94488520cd 100644 --- a/yarn-project/bb-prover/src/test/test_avm.ts +++ b/yarn-project/bb-prover/src/test/test_avm.ts @@ -28,7 +28,7 @@ import { } from '@aztec/circuits.js'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; import { padArrayEnd } from '@aztec/foundation/collection'; -import { type PublicFunctionCallResult } from '@aztec/simulator'; +import { type PublicFunctionCallResult } from '@aztec/simulator/server'; // TODO: pub somewhere more usable - copied from abstract phase manager export function getPublicInputs(result: PublicFunctionCallResult): PublicCircuitPublicInputs { diff --git a/yarn-project/bb-prover/src/test/test_circuit_prover.ts b/yarn-project/bb-prover/src/test/test_circuit_prover.ts index 3cfbc0f5e74..756ef24ff9b 100644 --- a/yarn-project/bb-prover/src/test/test_circuit_prover.ts +++ b/yarn-project/bb-prover/src/test/test_circuit_prover.ts @@ -63,7 +63,7 @@ import { convertSimulatedSingleTxBlockRootRollupOutputsFromWitnessMap, } from '@aztec/noir-protocol-circuits-types/server'; import { ProtocolCircuitVks } from '@aztec/noir-protocol-circuits-types/vks'; -import { type SimulationProvider, WASMSimulatorWithBlobs, emitCircuitSimulationStats } from '@aztec/simulator'; +import { type SimulationProvider, WASMSimulatorWithBlobs, emitCircuitSimulationStats } from '@aztec/simulator/server'; import { type TelemetryClient, trackSpan } from '@aztec/telemetry-client'; import { type WitnessMap } from '@noir-lang/types'; @@ -324,7 +324,10 @@ export class TestCircuitProver implements ServerCircuitProver { // the blob operations with an oracle. Appears to be no way to provide nativeACVM with a foreign call hander. simulationProvider = this.wasmSimulator; } - const witness = await simulationProvider.simulateCircuit(witnessMap, SimulatedServerCircuitArtifacts[artifactName]); + const witness = await simulationProvider.executeProtocolCircuit( + witnessMap, + SimulatedServerCircuitArtifacts[artifactName], + ); const result = convertOutput(witness); diff --git a/yarn-project/bb-prover/src/wasm/bb_wasm_private_kernel_prover.ts b/yarn-project/bb-prover/src/wasm/bb_wasm_private_kernel_prover.ts index afcac61ea93..c5f8eb5aeeb 100644 --- a/yarn-project/bb-prover/src/wasm/bb_wasm_private_kernel_prover.ts +++ b/yarn-project/bb-prover/src/wasm/bb_wasm_private_kernel_prover.ts @@ -3,6 +3,7 @@ import { ClientIvcProof } from '@aztec/circuits.js'; import { createLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { type ArtifactProvider } from '@aztec/noir-protocol-circuits-types/types'; +import { type SimulationProvider } from '@aztec/simulator/client'; import { serializeWitness } from '@noir-lang/noirc_abi'; import { type WitnessMap } from '@noir-lang/types'; @@ -13,10 +14,11 @@ import { BBPrivateKernelProver } from '../prover/bb_private_kernel_prover.js'; export abstract class BBWASMPrivateKernelProver extends BBPrivateKernelProver { constructor( protected override artifactProvider: ArtifactProvider, + protected override simulationProvider: SimulationProvider, private threads: number = 1, protected override log = createLogger('bb-prover:wasm'), ) { - super(artifactProvider, log); + super(artifactProvider, simulationProvider, log); } public override async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise { diff --git a/yarn-project/bb-prover/src/wasm/bundle.ts b/yarn-project/bb-prover/src/wasm/bundle.ts index ae448752d63..8bb327b7f45 100644 --- a/yarn-project/bb-prover/src/wasm/bundle.ts +++ b/yarn-project/bb-prover/src/wasm/bundle.ts @@ -1,10 +1,11 @@ import { createLogger } from '@aztec/foundation/log'; import { BundleArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/bundle'; +import { type SimulationProvider } from '@aztec/simulator/client'; import { BBWASMPrivateKernelProver } from './bb_wasm_private_kernel_prover.js'; export class BBWASMBundlePrivateKernelProver extends BBWASMPrivateKernelProver { - constructor(threads = 1, log = createLogger('bb-prover:wasm:bundle')) { - super(new BundleArtifactProvider(), threads, log); + constructor(simulationProvider: SimulationProvider, threads = 1, log = createLogger('bb-prover:wasm:bundle')) { + super(new BundleArtifactProvider(), simulationProvider, threads, log); } } diff --git a/yarn-project/bb-prover/src/wasm/lazy.ts b/yarn-project/bb-prover/src/wasm/lazy.ts index 16fc1c04c90..625b90e2ca6 100644 --- a/yarn-project/bb-prover/src/wasm/lazy.ts +++ b/yarn-project/bb-prover/src/wasm/lazy.ts @@ -1,10 +1,11 @@ import { createLogger } from '@aztec/foundation/log'; import { LazyArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/lazy'; +import { type SimulationProvider } from '@aztec/simulator/client'; import { BBWASMPrivateKernelProver } from './bb_wasm_private_kernel_prover.js'; export class BBWASMLazyPrivateKernelProver extends BBWASMPrivateKernelProver { - constructor(threads = 1, log = createLogger('bb-prover:wasm:lazy')) { - super(new LazyArtifactProvider(), threads, log); + constructor(simulationProvider: SimulationProvider, threads = 1, log = createLogger('bb-prover:wasm:lazy')) { + super(new LazyArtifactProvider(), simulationProvider, threads, log); } } diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index 148b090eab8..97e0e550f6f 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -31,7 +31,12 @@ import { TestContract } from '@aztec/noir-contracts.js/Test'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { type SequencerClient, SequencerState } from '@aztec/sequencer-client'; import { type TestSequencerClient } from '@aztec/sequencer-client/test'; -import { PublicProcessorFactory, type PublicTxResult, PublicTxSimulator, type WorldStateDB } from '@aztec/simulator'; +import { + PublicProcessorFactory, + type PublicTxResult, + PublicTxSimulator, + type WorldStateDB, +} from '@aztec/simulator/server'; import { type TelemetryClient } from '@aztec/telemetry-client'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index 03b54a2ff26..a56390821d8 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -355,7 +355,7 @@ describe('e2e_crowdfunding_and_claim', () => { donorWallets[1].setScopes([donorWallets[1].getAddress(), crowdfundingContract.address]); await expect(donorWallets[1].simulateTx(request, true, operatorWallet.getAddress())).rejects.toThrow( - 'Assertion failed', + 'Circuit execution failed: Users cannot set msg_sender in first call', ); }); diff --git a/yarn-project/prover-client/src/mocks/fixtures.ts b/yarn-project/prover-client/src/mocks/fixtures.ts index a59340bd7d2..69c5084f65f 100644 --- a/yarn-project/prover-client/src/mocks/fixtures.ts +++ b/yarn-project/prover-client/src/mocks/fixtures.ts @@ -13,7 +13,7 @@ import { padArrayEnd } from '@aztec/foundation/collection'; import { randomBytes } from '@aztec/foundation/crypto'; import { type Logger } from '@aztec/foundation/log'; import { fileURLToPath } from '@aztec/foundation/url'; -import { NativeACVMSimulator, type SimulationProvider, WASMSimulatorWithBlobs } from '@aztec/simulator'; +import { NativeACVMSimulator, type SimulationProvider, WASMSimulatorWithBlobs } from '@aztec/simulator/server'; import { promises as fs } from 'fs'; import path from 'path'; diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index 41847b26e66..a00642bb55f 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -26,7 +26,7 @@ import { type SimulationProvider, WASMSimulatorWithBlobs, type WorldStateDB, -} from '@aztec/simulator'; +} from '@aztec/simulator/server'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { type MerkleTreeAdminDatabase } from '@aztec/world-state'; import { NativeWorldStateService } from '@aztec/world-state/native'; diff --git a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts index ed16c5bb7be..9b7a68ab4a8 100644 --- a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts +++ b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts @@ -52,7 +52,7 @@ import { type Tuple, assertLength, serializeToBuffer, toFriendlyJSON } from '@az import { computeUnbalancedMerkleRoot } from '@aztec/foundation/trees'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; -import { computeFeePayerBalanceLeafSlot } from '@aztec/simulator'; +import { computeFeePayerBalanceLeafSlot } from '@aztec/simulator/server'; import { type MerkleTreeReadOperations } from '@aztec/world-state'; import { inspect } from 'util'; diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts index c5c88dd8ed0..7d09489a01f 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts @@ -2,7 +2,7 @@ import { TestCircuitProver } from '@aztec/bb-prover'; import { type ServerCircuitProver } from '@aztec/circuit-types'; import { timesAsync } from '@aztec/foundation/collection'; import { createLogger } from '@aztec/foundation/log'; -import { WASMSimulatorWithBlobs } from '@aztec/simulator'; +import { WASMSimulatorWithBlobs } from '@aztec/simulator/server'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { jest } from '@jest/globals'; diff --git a/yarn-project/prover-client/src/prover-client/prover-client.ts b/yarn-project/prover-client/src/prover-client/prover-client.ts index a7d7f645949..f179ba758d0 100644 --- a/yarn-project/prover-client/src/prover-client/prover-client.ts +++ b/yarn-project/prover-client/src/prover-client/prover-client.ts @@ -12,7 +12,7 @@ import { import { Fr } from '@aztec/circuits.js'; import { times } from '@aztec/foundation/collection'; import { createLogger } from '@aztec/foundation/log'; -import { NativeACVMSimulator } from '@aztec/simulator'; +import { NativeACVMSimulator } from '@aztec/simulator/server'; import { type TelemetryClient } from '@aztec/telemetry-client'; import { type ProverClientConfig } from '../config.js'; diff --git a/yarn-project/prover-node/src/job/epoch-proving-job.test.ts b/yarn-project/prover-node/src/job/epoch-proving-job.test.ts index 4576c377f2b..80240ae2b5a 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job.test.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job.test.ts @@ -13,7 +13,7 @@ import { RootRollupPublicInputs } from '@aztec/circuits.js/rollup'; import { times } from '@aztec/foundation/collection'; import { sleep } from '@aztec/foundation/sleep'; import { type L1Publisher } from '@aztec/sequencer-client'; -import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator'; +import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator/server'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { type MockProxy, mock } from 'jest-mock-extended'; diff --git a/yarn-project/prover-node/src/job/epoch-proving-job.ts b/yarn-project/prover-node/src/job/epoch-proving-job.ts index d22787f85c0..d060ebac229 100644 --- a/yarn-project/prover-node/src/job/epoch-proving-job.ts +++ b/yarn-project/prover-node/src/job/epoch-proving-job.ts @@ -14,7 +14,7 @@ import { createLogger } from '@aztec/foundation/log'; import { promiseWithResolvers } from '@aztec/foundation/promise'; import { Timer } from '@aztec/foundation/timer'; import { type L1Publisher } from '@aztec/sequencer-client'; -import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator'; +import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator/server'; import { Attributes, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client'; import * as crypto from 'node:crypto'; diff --git a/yarn-project/prover-node/src/prover-node.test.ts b/yarn-project/prover-node/src/prover-node.test.ts index d784fbea92d..0d555b8efe7 100644 --- a/yarn-project/prover-node/src/prover-node.test.ts +++ b/yarn-project/prover-node/src/prover-node.test.ts @@ -25,7 +25,7 @@ import { openTmpStore } from '@aztec/kv-store/lmdb'; import { type BootstrapNode, InMemoryTxPool, MemoryEpochProofQuotePool, P2PClient } from '@aztec/p2p'; import { createBootstrapNode, createTestLibP2PService } from '@aztec/p2p/mocks'; import { type L1Publisher } from '@aztec/sequencer-client'; -import { type PublicProcessorFactory } from '@aztec/simulator'; +import { type PublicProcessorFactory } from '@aztec/simulator/server'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { jest } from '@jest/globals'; diff --git a/yarn-project/prover-node/src/prover-node.ts b/yarn-project/prover-node/src/prover-node.ts index 3fc7e9a07ee..a5692dead4b 100644 --- a/yarn-project/prover-node/src/prover-node.ts +++ b/yarn-project/prover-node/src/prover-node.ts @@ -27,7 +27,7 @@ import { DateProvider } from '@aztec/foundation/timer'; import { type Maybe } from '@aztec/foundation/types'; import { type P2P } from '@aztec/p2p'; import { type L1Publisher } from '@aztec/sequencer-client'; -import { PublicProcessorFactory } from '@aztec/simulator'; +import { PublicProcessorFactory } from '@aztec/simulator/server'; import { Attributes, type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client'; import { type BondManager } from './bond/bond-manager.js'; diff --git a/yarn-project/pxe/src/database/note_dao.ts b/yarn-project/pxe/src/database/note_dao.ts index b4cb311fd46..af8357a7e33 100644 --- a/yarn-project/pxe/src/database/note_dao.ts +++ b/yarn-project/pxe/src/database/note_dao.ts @@ -3,7 +3,7 @@ import { AztecAddress, Fr, Point, type PublicKey } from '@aztec/circuits.js'; import { NoteSelector } from '@aztec/foundation/abi'; import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { type NoteData } from '@aztec/simulator/acvm'; +import { type NoteData } from '@aztec/simulator/client'; import { type NoteInfo } from '../note_decryption_utils/index.js'; diff --git a/yarn-project/pxe/src/pxe_service/error_enriching.ts b/yarn-project/pxe/src/pxe_service/error_enriching.ts index f8ff9663206..928c4b14ca4 100644 --- a/yarn-project/pxe/src/pxe_service/error_enriching.ts +++ b/yarn-project/pxe/src/pxe_service/error_enriching.ts @@ -4,7 +4,7 @@ import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { type Logger } from '@aztec/foundation/log'; -import { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '@aztec/simulator/errors'; +import { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '@aztec/simulator/client'; import { type ContractDataOracle, type PxeDatabase } from '../index.js'; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index b6b4eba6cd6..8b2e8348b78 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -65,7 +65,7 @@ import { type KeyStore } from '@aztec/key-store'; import { type L2TipsStore } from '@aztec/kv-store/stores'; import { ProtocolContractAddress, protocolContractNames } from '@aztec/protocol-contracts'; import { getCanonicalProtocolContract } from '@aztec/protocol-contracts/bundle'; -import { type AcirSimulator } from '@aztec/simulator/client'; +import { type AcirSimulator, type SimulationProvider } from '@aztec/simulator/client'; import { inspect } from 'util'; @@ -97,13 +97,14 @@ export class PXEService implements PXE { private db: PxeDatabase, tipsStore: L2TipsStore, private proofCreator: PrivateKernelProver, + private simulationProvider: SimulationProvider, config: PXEServiceConfig, logSuffix?: string, ) { this.log = createLogger(logSuffix ? `pxe:service:${logSuffix}` : `pxe:service`); this.synchronizer = new Synchronizer(node, db, tipsStore, config, logSuffix); this.contractDataOracle = new ContractDataOracle(db); - this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle); + this.simulator = getAcirSimulator(db, node, keyStore, this.simulationProvider, this.contractDataOracle); this.packageVersion = getPackageInfo().version; this.proverEnabled = !!config.proverEnabled; } diff --git a/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts b/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts index b442f4a2d40..3bfeb2973b6 100644 --- a/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts +++ b/yarn-project/pxe/src/pxe_service/test/pxe_service.test.ts @@ -1,11 +1,19 @@ import { BBWASMBundlePrivateKernelProver } from '@aztec/bb-prover/wasm/bundle'; -import { type AztecNode, type PXE, TxEffect, mockTx, randomInBlock } from '@aztec/circuit-types'; +import { + type AztecNode, + type PXE, + type PrivateKernelProver, + TxEffect, + mockTx, + randomInBlock, +} from '@aztec/circuit-types'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants'; import { type L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses'; import { EthAddress } from '@aztec/foundation/eth-address'; import { KeyStore } from '@aztec/key-store'; import { openTmpStore } from '@aztec/kv-store/lmdb'; import { L2TipsStore } from '@aztec/kv-store/stores'; +import { type SimulationProvider, WASMSimulator } from '@aztec/simulator/client'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -20,6 +28,8 @@ async function createPXEService(): Promise { const keyStore = new KeyStore(kvStore); const node = mock(); const db = await KVPxeDatabase.create(kvStore); + const simulationProvider = new WASMSimulator(); + const kernelProver = new BBWASMBundlePrivateKernelProver(simulationProvider); const tips = new L2TipsStore(kvStore, 'pxe'); const config: PXEServiceConfig = { l2StartingBlock: INITIAL_L2_BLOCK_NUM, @@ -48,7 +58,7 @@ async function createPXEService(): Promise { }; node.getL1ContractAddresses.mockResolvedValue(mockedContracts); - return Promise.resolve(new PXEService(keyStore, node, db, tips, new BBWASMBundlePrivateKernelProver(), config)); + return Promise.resolve(new PXEService(keyStore, node, db, tips, kernelProver, simulationProvider, config)); } pxeTestSuite('PXEService', createPXEService); @@ -57,6 +67,8 @@ describe('PXEService', () => { let keyStore: KeyStore; let node: MockProxy; let db: PxeDatabase; + let simulationProvider: SimulationProvider; + let kernelProver: PrivateKernelProver; let config: PXEServiceConfig; let tips: L2TipsStore; @@ -66,6 +78,9 @@ describe('PXEService', () => { node = mock(); tips = new L2TipsStore(kvStore, 'pxe'); db = await KVPxeDatabase.create(kvStore); + simulationProvider = new WASMSimulator(); + kernelProver = new BBWASMBundlePrivateKernelProver(simulationProvider); + config = { l2StartingBlock: INITIAL_L2_BLOCK_NUM, proverEnabled: false, @@ -81,7 +96,7 @@ describe('PXEService', () => { node.getTxEffect.mockResolvedValue(randomInBlock(settledTx)); - const pxe = new PXEService(keyStore, node, db, tips, new BBWASMBundlePrivateKernelProver(), config); + const pxe = new PXEService(keyStore, node, db, tips, kernelProver, simulationProvider, config); await expect(pxe.sendTx(duplicateTx)).rejects.toThrow(/A settled tx with equal hash/); }); }); diff --git a/yarn-project/pxe/src/simulator/index.ts b/yarn-project/pxe/src/simulator/index.ts index 8f41547a15e..e1ee9ab457b 100644 --- a/yarn-project/pxe/src/simulator/index.ts +++ b/yarn-project/pxe/src/simulator/index.ts @@ -1,6 +1,6 @@ import { type AztecNode } from '@aztec/circuit-types'; import { type KeyStore } from '@aztec/key-store'; -import { AcirSimulator } from '@aztec/simulator/client'; +import { AcirSimulator, type SimulationProvider } from '@aztec/simulator/client'; import { ContractDataOracle } from '../contract_data_oracle/index.js'; import { type PxeDatabase } from '../database/pxe_database.js'; @@ -13,6 +13,7 @@ export function getAcirSimulator( db: PxeDatabase, aztecNode: AztecNode, keyStore: KeyStore, + simulationProvider: SimulationProvider, contractDataOracle?: ContractDataOracle, ) { const simulatorOracle = new SimulatorOracle( @@ -20,6 +21,7 @@ export function getAcirSimulator( db, keyStore, aztecNode, + simulationProvider, ); - return new AcirSimulator(simulatorOracle, aztecNode); + return new AcirSimulator(simulatorOracle, aztecNode, simulationProvider); } diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 019ca15c7fc..e7331879869 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -30,8 +30,12 @@ import { type FunctionArtifact, getFunctionArtifact } from '@aztec/foundation/ab import { poseidon2Hash } from '@aztec/foundation/crypto'; import { createLogger } from '@aztec/foundation/log'; import { type KeyStore } from '@aztec/key-store'; -import { MessageLoadOracleInputs } from '@aztec/simulator/acvm'; -import { type AcirSimulator, type DBOracle } from '@aztec/simulator/client'; +import { + type AcirSimulator, + type DBOracle, + MessageLoadOracleInputs, + type SimulationProvider, +} from '@aztec/simulator/client'; import { type ContractDataOracle } from '../contract_data_oracle/index.js'; import { type PxeDatabase } from '../database/index.js'; @@ -49,6 +53,7 @@ export class SimulatorOracle implements DBOracle { private db: PxeDatabase, private keyStore: KeyStore, private aztecNode: AztecNode, + private simulationProvider: SimulationProvider, private log = createLogger('pxe:simulator_oracle'), ) {} @@ -605,7 +610,8 @@ export class SimulatorOracle implements DBOracle { // I don't like this at all, but we need a simulator to run `computeNoteHashAndOptionallyANullifier`. This generates // a chicken-and-egg problem due to this oracle requiring a simulator, which in turn requires this oracle. Furthermore, since jest doesn't allow // mocking ESM exports, we have to pollute the method even more by providing a simulator parameter so tests can inject a fake one. - simulator ?? getAcirSimulator(this.db, this.aztecNode, this.keyStore, this.contractDataOracle), + simulator ?? + getAcirSimulator(this.db, this.aztecNode, this.keyStore, this.simulationProvider, this.contractDataOracle), this.db, notePayload ? recipient.toAddressPoint() : undefined, payload!, diff --git a/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts b/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts index 11e9a6aaaf4..6d7037a7de8 100644 --- a/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts +++ b/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts @@ -26,7 +26,7 @@ import { import { pedersenHash, poseidon2Hash } from '@aztec/foundation/crypto'; import { KeyStore } from '@aztec/key-store'; import { openTmpStore } from '@aztec/kv-store/lmdb'; -import { type AcirSimulator } from '@aztec/simulator/client'; +import { type AcirSimulator, type SimulationProvider, WASMSimulator } from '@aztec/simulator/client'; import { jest } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; @@ -118,6 +118,7 @@ describe('Simulator oracle', () => { let contractDataOracle: ContractDataOracle; let simulatorOracle: SimulatorOracle; let keyStore: KeyStore; + let simulationProvider: SimulationProvider; let recipient: CompleteAddress; let contractAddress: AztecAddress; @@ -129,7 +130,8 @@ describe('Simulator oracle', () => { contractDataOracle = new ContractDataOracle(database); jest.spyOn(contractDataOracle, 'getDebugContractName').mockImplementation(() => Promise.resolve('TestContract')); keyStore = new KeyStore(db); - simulatorOracle = new SimulatorOracle(contractDataOracle, database, keyStore, aztecNode); + simulationProvider = new WASMSimulator(); + simulatorOracle = new SimulatorOracle(contractDataOracle, database, keyStore, aztecNode, simulationProvider); // Set up contract address contractAddress = AztecAddress.random(); // Set up recipient account diff --git a/yarn-project/pxe/src/utils/create_pxe_service.ts b/yarn-project/pxe/src/utils/create_pxe_service.ts index 1e288dd3fd9..4a093f17d56 100644 --- a/yarn-project/pxe/src/utils/create_pxe_service.ts +++ b/yarn-project/pxe/src/utils/create_pxe_service.ts @@ -6,6 +6,7 @@ import { createLogger } from '@aztec/foundation/log'; import { KeyStore } from '@aztec/key-store'; import { createStore } from '@aztec/kv-store/lmdb'; import { L2TipsStore } from '@aztec/kv-store/stores'; +import { type SimulationProvider, WASMSimulator } from '@aztec/simulator/client'; import { type PXEServiceConfig } from '../config/index.js'; import { KVPxeDatabase } from '../database/kv_pxe_database.js'; @@ -45,20 +46,20 @@ export async function createPXEService( const db = await KVPxeDatabase.create(store); const tips = new L2TipsStore(store, 'pxe'); - - const prover = proofCreator ?? (await createProver(config, logSuffix)); - const pxe = new PXEService(keyStore, aztecNode, db, tips, prover, config, logSuffix); + const simulationProvider = new WASMSimulator(); + const prover = proofCreator ?? (await createProver(config, simulationProvider, logSuffix)); + const pxe = new PXEService(keyStore, aztecNode, db, tips, prover, simulationProvider, config, logSuffix); await pxe.init(); return pxe; } -function createProver(config: PXEServiceConfig, logSuffix?: string) { +function createProver(config: PXEServiceConfig, simulationProvider: SimulationProvider, logSuffix?: string) { if (!config.bbBinaryPath || !config.bbWorkingDirectory) { - return new BBWASMBundlePrivateKernelProver(16); + return new BBWASMBundlePrivateKernelProver(simulationProvider, 16); } else { const bbConfig = config as Required> & PXEServiceConfig; const log = createLogger('pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : '')); - return BBNativePrivateKernelProver.new({ bbSkipCleanup: false, ...bbConfig }, log); + return BBNativePrivateKernelProver.new({ bbSkipCleanup: false, ...bbConfig }, simulationProvider, log); } } diff --git a/yarn-project/sequencer-client/src/client/sequencer-client.ts b/yarn-project/sequencer-client/src/client/sequencer-client.ts index 10119d98057..7bc7a5ad786 100644 --- a/yarn-project/sequencer-client/src/client/sequencer-client.ts +++ b/yarn-project/sequencer-client/src/client/sequencer-client.ts @@ -6,7 +6,7 @@ import { type EthAddress } from '@aztec/foundation/eth-address'; import { type DateProvider } from '@aztec/foundation/timer'; import { type P2P } from '@aztec/p2p'; import { LightweightBlockBuilderFactory } from '@aztec/prover-client/block-builder'; -import { PublicProcessorFactory } from '@aztec/simulator'; +import { PublicProcessorFactory } from '@aztec/simulator/server'; import { type TelemetryClient } from '@aztec/telemetry-client'; import { type ValidatorClient } from '@aztec/validator-client'; diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 7a9c96e898e..76d19334f51 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -38,7 +38,7 @@ import { type Logger, createLogger } from '@aztec/foundation/log'; import { TestDateProvider } from '@aztec/foundation/timer'; import { type P2P, P2PClientState } from '@aztec/p2p'; import { type BlockBuilderFactory } from '@aztec/prover-client/block-builder'; -import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator'; +import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator/server'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { type ValidatorClient } from '@aztec/validator-client'; diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 8991a6e3f01..68f634ea878 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -32,7 +32,7 @@ import { pickFromSchema } from '@aztec/foundation/schemas'; import { type DateProvider, Timer, elapsed } from '@aztec/foundation/timer'; import { type P2P } from '@aztec/p2p'; import { type BlockBuilderFactory } from '@aztec/prover-client/block-builder'; -import { type PublicProcessorFactory } from '@aztec/simulator'; +import { type PublicProcessorFactory } from '@aztec/simulator/server'; import { Attributes, type TelemetryClient, type Tracer, trackSpan } from '@aztec/telemetry-client'; import { type ValidatorClient } from '@aztec/validator-client'; diff --git a/yarn-project/sequencer-client/src/test/index.ts b/yarn-project/sequencer-client/src/test/index.ts index a7f466b485b..7a1304461ae 100644 --- a/yarn-project/sequencer-client/src/test/index.ts +++ b/yarn-project/sequencer-client/src/test/index.ts @@ -1,4 +1,4 @@ -import { type PublicProcessorFactory } from '@aztec/simulator'; +import { type PublicProcessorFactory } from '@aztec/simulator/server'; import { SequencerClient } from '../client/sequencer-client.js'; import { type L1Publisher } from '../publisher/l1-publisher.js'; diff --git a/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts b/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts index b5ee24df54c..4f5bc03692b 100644 --- a/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts +++ b/yarn-project/sequencer-client/src/tx_validator/gas_validator.ts @@ -1,7 +1,7 @@ import { type Tx, TxExecutionPhase, type TxValidationResult, type TxValidator } from '@aztec/circuit-types'; import { type AztecAddress, type Fr, FunctionSelector, type GasFees } from '@aztec/circuits.js'; import { createLogger } from '@aztec/foundation/log'; -import { computeFeePayerBalanceStorageSlot, getExecutionRequestsByPhase } from '@aztec/simulator'; +import { computeFeePayerBalanceStorageSlot, getExecutionRequestsByPhase } from '@aztec/simulator/server'; /** Provides a view into public contract state */ export interface PublicStateSource { diff --git a/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts b/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts index 2d885f68ce6..38112a20ccf 100644 --- a/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts +++ b/yarn-project/sequencer-client/src/tx_validator/phases_validator.ts @@ -8,7 +8,7 @@ import { } from '@aztec/circuit-types'; import { type ContractDataSource } from '@aztec/circuits.js'; import { createLogger } from '@aztec/foundation/log'; -import { ContractsDataSourcePublicDB, getExecutionRequestsByPhase } from '@aztec/simulator'; +import { ContractsDataSourcePublicDB, getExecutionRequestsByPhase } from '@aztec/simulator/server'; export class PhasesTxValidator implements TxValidator { #log = createLogger('sequencer:tx_validator:tx_phases'); diff --git a/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts b/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts index 6e752d9971f..0c0e48f6c9c 100644 --- a/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts +++ b/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts @@ -16,7 +16,7 @@ import { TxProofValidator, } from '@aztec/p2p'; import { ProtocolContractAddress } from '@aztec/protocol-contracts'; -import { readPublicState } from '@aztec/simulator'; +import { readPublicState } from '@aztec/simulator/server'; import { ArchiveCache } from './archive_cache.js'; import { GasTxValidator, type PublicStateSource } from './gas_validator.js'; diff --git a/yarn-project/simulator/package.json b/yarn-project/simulator/package.json index a0bde2ce857..c3a54db4863 100644 --- a/yarn-project/simulator/package.json +++ b/yarn-project/simulator/package.json @@ -3,10 +3,9 @@ "version": "0.1.0", "type": "module", "exports": { - ".": "./dest/index.js", + "./common": "./dest/common.js", + "./server": "./dest/server.js", "./client": "./dest/client/index.js", - "./acvm": "./dest/acvm/index.js", - "./errors": "./dest/common/errors.js", "./public/fixtures": "./dest/public/fixtures/index.js" }, "typedocOptions": { diff --git a/yarn-project/simulator/src/acvm/acvm.ts b/yarn-project/simulator/src/acvm/acvm.ts index 7e0c18395cd..66298190bed 100644 --- a/yarn-project/simulator/src/acvm/acvm.ts +++ b/yarn-project/simulator/src/acvm/acvm.ts @@ -16,7 +16,7 @@ import { type ORACLE_NAMES } from './oracle/index.js'; /** * The callback interface for the ACIR. */ -type ACIRCallback = Record< +export type ACIRCallback = Record< ORACLE_NAMES, ( ...args: ForeignCallInput[] diff --git a/yarn-project/simulator/src/acvm/index.ts b/yarn-project/simulator/src/acvm/index.ts index 23067f6094b..b3c6a274ff2 100644 --- a/yarn-project/simulator/src/acvm/index.ts +++ b/yarn-project/simulator/src/acvm/index.ts @@ -1,4 +1,4 @@ -export * from './acvm.js'; +export { extractCallStack, type ACIRCallback, type ACIRExecutionResult } from './acvm.js'; export * from './acvm_types.js'; export * from './deserialize.js'; export * from './oracle/index.js'; diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index cd529fdd3ac..d228db9776f 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -5,7 +5,6 @@ import { type NoteStatus, type NullifierMembershipWitness, type PublicDataWitness, - type SiblingPath, type UnencryptedL2Log, } from '@aztec/circuit-types'; import { @@ -19,6 +18,8 @@ import { type FunctionSelector, type NoteSelector } from '@aztec/foundation/abi' import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; +import { type MessageLoadOracleInputs } from '../../common/message_load_oracle_inputs.js'; + /** * Information about a note needed during execution. */ @@ -39,19 +40,6 @@ export interface NoteData { index?: bigint; } -export class MessageLoadOracleInputs { - constructor( - /** The index of the message commitment in the merkle tree. */ - public index: bigint, - /** The path in the merkle tree to the message. */ - public siblingPath: SiblingPath, - ) {} - - toFields(): Fr[] { - return [new Fr(this.index), ...this.siblingPath.toFields()]; - } -} - class OracleMethodNotAvailableError extends Error { constructor(methodName: string) { super(`Oracle method ${methodName} is not available.`); diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index 494a500f412..9ad3778127a 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -10,8 +10,9 @@ import { strict as assert } from 'assert'; import { mock } from 'jest-mock-extended'; import merge from 'lodash.merge'; -import { type WorldStateDB, resolveAssertionMessageFromRevertData, traverseCauseChain } from '../../index.js'; +import { resolveAssertionMessageFromRevertData, traverseCauseChain } from '../../common.js'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; +import { type WorldStateDB } from '../../server.js'; import { AvmContext } from '../avm_context.js'; import { AvmExecutionEnvironment } from '../avm_execution_environment.js'; import { AvmMachineState } from '../avm_machine_state.js'; diff --git a/yarn-project/simulator/src/avm/journal/nullifiers.test.ts b/yarn-project/simulator/src/avm/journal/nullifiers.test.ts index 02fc2a04495..a2975fd7db4 100644 --- a/yarn-project/simulator/src/avm/journal/nullifiers.test.ts +++ b/yarn-project/simulator/src/avm/journal/nullifiers.test.ts @@ -2,7 +2,7 @@ import { Fr } from '@aztec/foundation/fields'; import { type MockProxy, mock } from 'jest-mock-extended'; -import { type CommitmentsDB } from '../../index.js'; +import { type CommitmentsDB } from '../../server.js'; import { NullifierManager } from './nullifiers.js'; describe('avm nullifier caching', () => { diff --git a/yarn-project/simulator/src/avm/journal/nullifiers.ts b/yarn-project/simulator/src/avm/journal/nullifiers.ts index 8e482108990..a3b60c8aaf6 100644 --- a/yarn-project/simulator/src/avm/journal/nullifiers.ts +++ b/yarn-project/simulator/src/avm/journal/nullifiers.ts @@ -1,6 +1,6 @@ import { Fr } from '@aztec/foundation/fields'; -import type { CommitmentsDB } from '../../index.js'; +import type { CommitmentsDB } from '../../server.js'; /** * A class to manage new nullifier staging and existence checks during a contract call's AVM simulation. diff --git a/yarn-project/simulator/src/avm/journal/public_storage.test.ts b/yarn-project/simulator/src/avm/journal/public_storage.test.ts index 6db7f7e7bbf..65fe4587172 100644 --- a/yarn-project/simulator/src/avm/journal/public_storage.test.ts +++ b/yarn-project/simulator/src/avm/journal/public_storage.test.ts @@ -3,7 +3,7 @@ import { Fr } from '@aztec/foundation/fields'; import { type MockProxy, mock } from 'jest-mock-extended'; -import { type PublicStateDB } from '../../index.js'; +import { type PublicStateDB } from '../../server.js'; import { PublicStorage } from './public_storage.js'; describe('avm public storage', () => { diff --git a/yarn-project/simulator/src/avm/journal/public_storage.ts b/yarn-project/simulator/src/avm/journal/public_storage.ts index 64abe824ddb..f0b260dbe0c 100644 --- a/yarn-project/simulator/src/avm/journal/public_storage.ts +++ b/yarn-project/simulator/src/avm/journal/public_storage.ts @@ -1,7 +1,7 @@ import { type AztecAddress } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; -import type { PublicStateDB } from '../../index.js'; +import type { PublicStateDB } from '../../server.js'; type PublicStorageReadResult = { value: Fr; diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts index c4ac6fafc9b..3c2c761f356 100644 --- a/yarn-project/simulator/src/client/client_execution_context.ts +++ b/yarn-project/simulator/src/client/client_execution_context.ts @@ -27,6 +27,7 @@ import { createLogger } from '@aztec/foundation/log'; import { type NoteData, toACVMWitness } from '../acvm/index.js'; import { type PackedValuesCache } from '../common/packed_values_cache.js'; +import { type SimulationProvider } from '../server.js'; import { type DBOracle } from './db_oracle.js'; import { type ExecutionNoteCache } from './execution_note_cache.js'; import { pickNotes } from './pick_notes.js'; @@ -73,6 +74,7 @@ export class ClientExecutionContext extends ViewDataOracle { private readonly noteCache: ExecutionNoteCache, db: DBOracle, private node: AztecNode, + private provider: SimulationProvider, protected sideEffectCounter: number = 0, log = createLogger('simulator:client_execution_context'), scopes?: AztecAddress[], @@ -373,12 +375,14 @@ export class ClientExecutionContext extends ViewDataOracle { this.noteCache, this.db, this.node, + this.provider, sideEffectCounter, this.log, this.scopes, ); const childExecutionResult = await executePrivateFunction( + this.provider, context, targetArtifact, targetContractAddress, diff --git a/yarn-project/simulator/src/client/index.ts b/yarn-project/simulator/src/client/index.ts index 3bff1cb6ec7..608da797f92 100644 --- a/yarn-project/simulator/src/client/index.ts +++ b/yarn-project/simulator/src/client/index.ts @@ -1,6 +1,14 @@ -export * from './simulator.js'; -export * from './db_oracle.js'; +export { AcirSimulator } from './simulator.js'; +export { DBOracle, ContractClassNotFoundError, ContractNotFoundError } from './db_oracle.js'; export * from './pick_notes.js'; -export * from './execution_note_cache.js'; +export { ExecutionNoteCache } from './execution_note_cache.js'; export { extractPrivateCircuitPublicInputs } from './private_execution.js'; +export { witnessMapToFields } from '../acvm/deserialize.js'; +export { toACVMWitness } from '../acvm/serialize.js'; +export { extractCallStack } from '../acvm/acvm.js'; export { WASMSimulator } from '../providers/acvm_wasm.js'; +export { NoteData, TypedOracle } from '../acvm/oracle/typed_oracle.js'; +export { Oracle } from '../acvm/oracle/oracle.js'; +export { type SimulationProvider } from '../common/simulation_provider.js'; +export { MessageLoadOracleInputs } from '../common/message_load_oracle_inputs.js'; +export { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '../common/errors.js'; diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index cc38e3ad1fa..57d751c6151 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -66,7 +66,8 @@ import { jest } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; import { toFunctionSelector } from 'viem'; -import { MessageLoadOracleInputs } from '../acvm/index.js'; +import { MessageLoadOracleInputs } from '../common/message_load_oracle_inputs.js'; +import { WASMSimulator } from '../providers/acvm_wasm.js'; import { buildL1ToL2Message } from '../test/utils.js'; import { type DBOracle } from './db_oracle.js'; import { AcirSimulator } from './simulator.js'; @@ -74,9 +75,10 @@ import { AcirSimulator } from './simulator.js'; jest.setTimeout(60_000); describe('Private Execution test suite', () => { + const simulationProvider = new WASMSimulator(); + let oracle: MockProxy; let node: MockProxy; - let acirSimulator: AcirSimulator; let header = BlockHeader.empty(); @@ -245,7 +247,7 @@ describe('Private Execution test suite', () => { }, ); - acirSimulator = new AcirSimulator(oracle, node); + acirSimulator = new AcirSimulator(oracle, node, simulationProvider); }); describe('no constructor', () => { diff --git a/yarn-project/simulator/src/client/private_execution.ts b/yarn-project/simulator/src/client/private_execution.ts index 199d395696b..2e7a6cbef7d 100644 --- a/yarn-project/simulator/src/client/private_execution.ts +++ b/yarn-project/simulator/src/client/private_execution.ts @@ -12,14 +12,16 @@ import { createLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { fromACVMField, witnessMapToFields } from '../acvm/deserialize.js'; -import { type ACVMWitness, Oracle, acvm, extractCallStack } from '../acvm/index.js'; +import { type ACVMWitness, Oracle, extractCallStack } from '../acvm/index.js'; import { ExecutionError, resolveAssertionMessageFromError } from '../common/errors.js'; +import { type SimulationProvider } from '../server.js'; import { type ClientExecutionContext } from './client_execution_context.js'; /** * Execute a private function and return the execution result. */ export async function executePrivateFunction( + simulator: SimulationProvider, context: ClientExecutionContext, artifact: FunctionArtifact, contractAddress: AztecAddress, @@ -32,18 +34,20 @@ export async function executePrivateFunction( const initialWitness = context.getInitialWitness(artifact); const acvmCallback = new Oracle(context); const timer = new Timer(); - const acirExecutionResult = await acvm(acir, initialWitness, acvmCallback).catch((err: Error) => { - err.message = resolveAssertionMessageFromError(err, artifact); - throw new ExecutionError( - err.message, - { - contractAddress, - functionSelector, - }, - extractCallStack(err, artifact.debug), - { cause: err }, - ); - }); + const acirExecutionResult = await simulator + .executeUserCircuit(acir, initialWitness, acvmCallback) + .catch((err: Error) => { + err.message = resolveAssertionMessageFromError(err, artifact); + throw new ExecutionError( + err.message, + { + contractAddress, + functionSelector, + }, + extractCallStack(err, artifact.debug), + { cause: err }, + ); + }); const duration = timer.ms(); const partialWitness = acirExecutionResult.partialWitness; const publicInputs = extractPrivateCircuitPublicInputs(artifact, partialWitness); diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index bf67b300f06..2e243f400ac 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -7,10 +7,13 @@ import { TokenBlacklistContractArtifact } from '@aztec/noir-contracts.js/TokenBl import { type MockProxy, mock } from 'jest-mock-extended'; +import { WASMSimulator } from '../providers/acvm_wasm.js'; import { type DBOracle } from './db_oracle.js'; import { AcirSimulator } from './simulator.js'; describe('Simulator', () => { + const simulationProvider = new WASMSimulator(); + let oracle: MockProxy; let node: MockProxy; @@ -40,7 +43,7 @@ describe('Simulator', () => { ); oracle.getCompleteAddress.mockResolvedValue(ownerCompleteAddress); - simulator = new AcirSimulator(oracle, node); + simulator = new AcirSimulator(oracle, node, simulationProvider); }); describe('computeNoteHashAndOptionallyANullifier', () => { diff --git a/yarn-project/simulator/src/client/simulator.ts b/yarn-project/simulator/src/client/simulator.ts index 9bcdc07bd7d..bc0bb302540 100644 --- a/yarn-project/simulator/src/client/simulator.ts +++ b/yarn-project/simulator/src/client/simulator.ts @@ -14,6 +14,7 @@ import { type Logger, createLogger } from '@aztec/foundation/log'; import { createSimulationError } from '../common/errors.js'; import { PackedValuesCache } from '../common/packed_values_cache.js'; +import { type SimulationProvider } from '../common/simulation_provider.js'; import { ClientExecutionContext } from './client_execution_context.js'; import { type DBOracle } from './db_oracle.js'; import { ExecutionNoteCache } from './execution_note_cache.js'; @@ -27,7 +28,7 @@ import { ViewDataOracle } from './view_data_oracle.js'; export class AcirSimulator { private log: Logger; - constructor(private db: DBOracle, private node: AztecNode) { + constructor(private db: DBOracle, private node: AztecNode, private simulationProvider: SimulationProvider) { this.log = createLogger('simulator'); } @@ -81,6 +82,7 @@ export class AcirSimulator { new ExecutionNoteCache(txHash), this.db, this.node, + this.simulationProvider, startSideEffectCounter, undefined, scopes, @@ -88,6 +90,7 @@ export class AcirSimulator { try { const executionResult = await executePrivateFunction( + this.simulationProvider, context, entryPointArtifact, contractAddress, @@ -120,6 +123,7 @@ export class AcirSimulator { try { return await executeUnconstrainedFunction( + this.simulationProvider, context, entryPointArtifact, contractAddress, diff --git a/yarn-project/simulator/src/client/unconstrained_execution.test.ts b/yarn-project/simulator/src/client/unconstrained_execution.test.ts index 498ac7cd886..ad270fc9864 100644 --- a/yarn-project/simulator/src/client/unconstrained_execution.test.ts +++ b/yarn-project/simulator/src/client/unconstrained_execution.test.ts @@ -7,10 +7,13 @@ import { StatefulTestContractArtifact } from '@aztec/noir-contracts.js/StatefulT import { mock } from 'jest-mock-extended'; +import { WASMSimulator } from '../providers/acvm_wasm.js'; import { type DBOracle } from './db_oracle.js'; import { AcirSimulator } from './simulator.js'; describe('Unconstrained Execution test suite', () => { + const simulationProvider = new WASMSimulator(); + let oracle: ReturnType>; let node: ReturnType>; let acirSimulator: AcirSimulator; @@ -23,7 +26,7 @@ describe('Unconstrained Execution test suite', () => { node.getChainId.mockResolvedValue(1); node.getVersion.mockResolvedValue(1); - acirSimulator = new AcirSimulator(oracle, node); + acirSimulator = new AcirSimulator(oracle, node, simulationProvider); }); describe('private token contract', () => { diff --git a/yarn-project/simulator/src/client/unconstrained_execution.ts b/yarn-project/simulator/src/client/unconstrained_execution.ts index b9066fd0500..f29bf3c311f 100644 --- a/yarn-project/simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/simulator/src/client/unconstrained_execution.ts @@ -4,8 +4,9 @@ import { type Fr } from '@aztec/foundation/fields'; import { createLogger } from '@aztec/foundation/log'; import { witnessMapToFields } from '../acvm/deserialize.js'; -import { Oracle, acvm, extractCallStack, toACVMWitness } from '../acvm/index.js'; +import { Oracle, extractCallStack, toACVMWitness } from '../acvm/index.js'; import { ExecutionError, resolveAssertionMessageFromError } from '../common/errors.js'; +import { type SimulationProvider } from '../server.js'; import { type ViewDataOracle } from './view_data_oracle.js'; // docs:start:execute_unconstrained_function @@ -13,6 +14,7 @@ import { type ViewDataOracle } from './view_data_oracle.js'; * Execute an unconstrained function and return the decoded values. */ export async function executeUnconstrainedFunction( + simulatorProvider: SimulationProvider, oracle: ViewDataOracle, artifact: FunctionArtifact, contractAddress: AztecAddress, @@ -24,18 +26,20 @@ export async function executeUnconstrainedFunction( const acir = artifact.bytecode; const initialWitness = toACVMWitness(0, args); - const acirExecutionResult = await acvm(acir, initialWitness, new Oracle(oracle)).catch((err: Error) => { - err.message = resolveAssertionMessageFromError(err, artifact); - throw new ExecutionError( - err.message, - { - contractAddress, - functionSelector, - }, - extractCallStack(err, artifact.debug), - { cause: err }, - ); - }); + const acirExecutionResult = await simulatorProvider + .executeUserCircuit(acir, initialWitness, new Oracle(oracle)) + .catch((err: Error) => { + err.message = resolveAssertionMessageFromError(err, artifact); + throw new ExecutionError( + err.message, + { + contractAddress, + functionSelector, + }, + extractCallStack(err, artifact.debug), + { cause: err }, + ); + }); const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness); return decodeFromAbi(artifact.returnTypes, returnWitness); diff --git a/yarn-project/simulator/src/common.ts b/yarn-project/simulator/src/common.ts new file mode 100644 index 00000000000..c3b15cc2eaf --- /dev/null +++ b/yarn-project/simulator/src/common.ts @@ -0,0 +1 @@ +export * from './common/index.js'; diff --git a/yarn-project/simulator/src/common/message_load_oracle_inputs.ts b/yarn-project/simulator/src/common/message_load_oracle_inputs.ts new file mode 100644 index 00000000000..d6757f4459b --- /dev/null +++ b/yarn-project/simulator/src/common/message_load_oracle_inputs.ts @@ -0,0 +1,15 @@ +import { type SiblingPath } from '@aztec/circuit-types'; +import { Fr } from '@aztec/circuits.js'; + +export class MessageLoadOracleInputs { + constructor( + /** The index of the message commitment in the merkle tree. */ + public index: bigint, + /** The path in the merkle tree to the message. */ + public siblingPath: SiblingPath, + ) {} + + toFields(): Fr[] { + return [new Fr(this.index), ...this.siblingPath.toFields()]; + } +} diff --git a/yarn-project/simulator/src/common/simulation_provider.ts b/yarn-project/simulator/src/common/simulation_provider.ts new file mode 100644 index 00000000000..f927741af8f --- /dev/null +++ b/yarn-project/simulator/src/common/simulation_provider.ts @@ -0,0 +1,45 @@ +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import { type ExecutionError } from '@noir-lang/acvm_js'; +import { abiDecodeError } from '@noir-lang/noirc_abi'; +import { type Abi, type WitnessMap } from '@noir-lang/types'; + +import { type ACIRCallback, type ACIRExecutionResult } from '../acvm/acvm.js'; +import { type ACVMWitness } from '../acvm/acvm_types.js'; + +/** + * Low level simulation interface + */ +export interface SimulationProvider { + executeProtocolCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise; + executeUserCircuit(acir: Buffer, initialWitness: ACVMWitness, callback: ACIRCallback): Promise; +} + +export type ErrorWithPayload = ExecutionError & { decodedAssertionPayload?: any }; + +// Error handling taken from noir/noir-repo/tooling/noir_js/src/witness_generation.ts. +// TODO: import this in isolation without having to import noir_js in its entirety. +export function parseErrorPayload(abi: Abi, originalError: ExecutionError): Error { + const payload = originalError.rawAssertionPayload; + if (!payload) { + return originalError; + } + const enrichedError = originalError as ErrorWithPayload; + + try { + // Decode the payload + const decodedPayload = abiDecodeError(abi, payload); + + if (typeof decodedPayload === 'string') { + // If it's a string, just add it to the error message + enrichedError.message = `Circuit execution failed: ${decodedPayload}`; + } else { + // If not, attach the payload to the original error + enrichedError.decodedAssertionPayload = decodedPayload; + } + } catch (_errorDecoding) { + // Ignore errors decoding the payload + } + + return enrichedError; +} diff --git a/yarn-project/simulator/src/providers/acvm_native.ts b/yarn-project/simulator/src/providers/acvm_native.ts index eba2d06b999..66613be1003 100644 --- a/yarn-project/simulator/src/providers/acvm_native.ts +++ b/yarn-project/simulator/src/providers/acvm_native.ts @@ -7,7 +7,9 @@ import { type WitnessMap } from '@noir-lang/types'; import * as proc from 'child_process'; import { promises as fs } from 'fs'; -import { type SimulationProvider } from './simulation_provider.js'; +import { type ACIRCallback, type ACIRExecutionResult } from '../acvm/acvm.js'; +import { type ACVMWitness } from '../acvm/acvm_types.js'; +import { type SimulationProvider } from '../common/simulation_provider.js'; const logger = createLogger('simulator:acvm-native'); @@ -134,7 +136,7 @@ export async function executeNativeCircuit( export class NativeACVMSimulator implements SimulationProvider { constructor(private workingDirectory: string, private pathToAcvm: string, private witnessFilename?: string) {} - async simulateCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise { + async executeProtocolCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise { // Execute the circuit on those initial witness values const operation = async (directory: string) => { @@ -158,4 +160,12 @@ export class NativeACVMSimulator implements SimulationProvider { return await runInDirectory(this.workingDirectory, operation, false); } + + executeUserCircuit( + _acir: Buffer, + _initialWitness: ACVMWitness, + _callback: ACIRCallback, + ): Promise { + throw new Error('Not implemented'); + } } diff --git a/yarn-project/simulator/src/providers/acvm_wasm.ts b/yarn-project/simulator/src/providers/acvm_wasm.ts index 244e6e168a0..5656db2aa4d 100644 --- a/yarn-project/simulator/src/providers/acvm_wasm.ts +++ b/yarn-project/simulator/src/providers/acvm_wasm.ts @@ -1,25 +1,52 @@ import { foreignCallHandler } from '@aztec/noir-protocol-circuits-types/client'; import { type NoirCompiledCircuit } from '@aztec/types/noir'; -import { executeCircuit } from '@noir-lang/acvm_js'; +import initACVM, { type ExecutionError, executeCircuit } from '@noir-lang/acvm_js'; +import initAbi from '@noir-lang/noirc_abi'; import { type WitnessMap } from '@noir-lang/types'; -import { type SimulationProvider } from './simulation_provider.js'; +import { type ACIRCallback, acvm } from '../acvm/acvm.js'; +import { type ACVMWitness } from '../acvm/acvm_types.js'; +import { type SimulationProvider, parseErrorPayload } from '../common/simulation_provider.js'; export class WASMSimulator implements SimulationProvider { - async simulateCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise { + async init(): Promise { + // If these are available, then we are in the + // web environment. For the node environment, this + // is a no-op. + if (typeof initAbi === 'function') { + /** @ts-expect-error The node bundle doesn't include these default imports, so TS complains */ + await Promise.all([initAbi(), initACVM()]); + } + } + + async executeProtocolCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise { + await this.init(); // Execute the circuit on those initial witness values // // Decode the bytecode from base64 since the acvm does not know about base64 encoding const decodedBytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); // // Execute the circuit - const _witnessMap = await executeCircuit( - decodedBytecode, - input, - foreignCallHandler, // handle calls to debug_log - ); + try { + const _witnessMap = await executeCircuit( + decodedBytecode, + input, + foreignCallHandler, // handle calls to debug_log + ); + + return _witnessMap; + } catch (err) { + // Typescript types catched errors as unknown or any, so we need to narrow its type to check if it has raw assertion payload. + if (typeof err === 'object' && err !== null && 'rawAssertionPayload' in err) { + throw parseErrorPayload(compiledCircuit.abi, err as ExecutionError); + } + throw new Error(`Circuit execution failed: ${err}`); + } + } - return _witnessMap; + async executeUserCircuit(acir: Buffer, initialWitness: ACVMWitness, callback: ACIRCallback) { + await this.init(); + return acvm(acir, initialWitness, callback); } } diff --git a/yarn-project/simulator/src/providers/acvm_wasm_with_blobs.ts b/yarn-project/simulator/src/providers/acvm_wasm_with_blobs.ts index 3940e97b1d2..f85970b6497 100644 --- a/yarn-project/simulator/src/providers/acvm_wasm_with_blobs.ts +++ b/yarn-project/simulator/src/providers/acvm_wasm_with_blobs.ts @@ -1,25 +1,50 @@ import { foreignCallHandler } from '@aztec/noir-protocol-circuits-types/server'; import { type NoirCompiledCircuit } from '@aztec/types/noir'; -import { executeCircuit } from '@noir-lang/acvm_js'; +import { type ExecutionError, executeCircuit } from '@noir-lang/acvm_js'; import { type WitnessMap } from '@noir-lang/types'; -import { type SimulationProvider } from './simulation_provider.js'; +import { type ACIRCallback, type ACIRExecutionResult } from '../acvm/acvm.js'; +import { type ACVMWitness } from '../acvm/acvm_types.js'; +import { type SimulationProvider, parseErrorPayload } from '../common/simulation_provider.js'; +/** + * A simulation provider that uses the WASM simulator with the ability to handle blobs via the foreign call handler. + * This class is temporary while brillig cannot handle the blob math, and it is kept separate + * because the zkg commitment library used in the blob code is not browser compatible. + * + * It is only used in the context of server-side code executing simulated protocol circuits. + */ export class WASMSimulatorWithBlobs implements SimulationProvider { - async simulateCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise { + async executeProtocolCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise { // Execute the circuit on those initial witness values // // Decode the bytecode from base64 since the acvm does not know about base64 encoding const decodedBytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); // // Execute the circuit - const _witnessMap = await executeCircuit( - decodedBytecode, - input, - foreignCallHandler, // handle calls to debug_log and evaluate_blobs mock - ); + try { + const _witnessMap = await executeCircuit( + decodedBytecode, + input, + foreignCallHandler, // handle calls to debug_log and evaluate_blobs mock + ); - return _witnessMap; + return _witnessMap; + } catch (err) { + // Typescript types catched errors as unknown or any, so we need to narrow its type to check if it has raw assertion payload. + if (typeof err === 'object' && err !== null && 'rawAssertionPayload' in err) { + throw parseErrorPayload(compiledCircuit.abi, err as ExecutionError); + } + throw new Error(`Circuit execution failed: ${err}`); + } + } + + executeUserCircuit( + _acir: Buffer, + _initialWitness: ACVMWitness, + _callback: ACIRCallback, + ): Promise { + throw new Error('Not implemented'); } } diff --git a/yarn-project/simulator/src/providers/factory.ts b/yarn-project/simulator/src/providers/factory.ts index 6dedea7495a..cf8f919cb00 100644 --- a/yarn-project/simulator/src/providers/factory.ts +++ b/yarn-project/simulator/src/providers/factory.ts @@ -2,9 +2,9 @@ import { type Logger, createLogger } from '@aztec/foundation/log'; import { promises as fs } from 'fs'; +import { type SimulationProvider } from '../common/simulation_provider.js'; import { NativeACVMSimulator } from './acvm_native.js'; import { WASMSimulator } from './acvm_wasm.js'; -import { type SimulationProvider } from './simulation_provider.js'; export type SimulationProviderConfig = { acvmBinaryPath?: string; diff --git a/yarn-project/simulator/src/providers/index.ts b/yarn-project/simulator/src/providers/index.ts index b4a832329bf..3efa01c9234 100644 --- a/yarn-project/simulator/src/providers/index.ts +++ b/yarn-project/simulator/src/providers/index.ts @@ -1,4 +1,4 @@ export * from './acvm_native.js'; export * from './acvm_wasm_with_blobs.js'; -export * from './simulation_provider.js'; +export * from '../common/simulation_provider.js'; export * from './factory.js'; diff --git a/yarn-project/simulator/src/providers/simulation_provider.ts b/yarn-project/simulator/src/providers/simulation_provider.ts deleted file mode 100644 index e0a087fcc37..00000000000 --- a/yarn-project/simulator/src/providers/simulation_provider.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { type NoirCompiledCircuit } from '@aztec/types/noir'; - -import { type WitnessMap } from '@noir-lang/types'; - -/** - * Low level simulation interface - */ -export interface SimulationProvider { - simulateCircuit(input: WitnessMap, compiledCircuit: NoirCompiledCircuit): Promise; -} diff --git a/yarn-project/simulator/src/public/db_interfaces.ts b/yarn-project/simulator/src/public/db_interfaces.ts index b8d022080cc..ef37858d92b 100644 --- a/yarn-project/simulator/src/public/db_interfaces.ts +++ b/yarn-project/simulator/src/public/db_interfaces.ts @@ -7,7 +7,7 @@ import { import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type Fr } from '@aztec/foundation/fields'; -import { type MessageLoadOracleInputs } from '../acvm/index.js'; +import { type MessageLoadOracleInputs } from '../common/message_load_oracle_inputs.js'; /** * Database interface for providing access to public state. diff --git a/yarn-project/simulator/src/public/fixtures/index.ts b/yarn-project/simulator/src/public/fixtures/index.ts index 17cca0600ce..e7d4ce26b6f 100644 --- a/yarn-project/simulator/src/public/fixtures/index.ts +++ b/yarn-project/simulator/src/public/fixtures/index.ts @@ -32,19 +32,16 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; import { openTmpStore } from '@aztec/kv-store/lmdb'; import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest'; -import { - AvmEphemeralForest, - AvmSimulator, - PublicEnqueuedCallSideEffectTrace, - PublicTxSimulator, - WorldStateDB, -} from '@aztec/simulator'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { MerkleTrees } from '@aztec/world-state'; import { strict as assert } from 'assert'; import { initContext, initExecutionEnvironment, initPersistableStateManager } from '../../avm/fixtures/index.js'; +import { AvmEphemeralForest, AvmSimulator } from '../../server.js'; +import { PublicEnqueuedCallSideEffectTrace } from '../enqueued_call_side_effect_trace.js'; +import { WorldStateDB } from '../public_db_sources.js'; +import { PublicTxSimulator } from '../public_tx_simulator.js'; const TIMESTAMP = new Fr(99833); diff --git a/yarn-project/simulator/src/public/public_db_sources.ts b/yarn-project/simulator/src/public/public_db_sources.ts index f9c64fe38f7..7a4185ed72a 100644 --- a/yarn-project/simulator/src/public/public_db_sources.ts +++ b/yarn-project/simulator/src/public/public_db_sources.ts @@ -24,12 +24,9 @@ import { createLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { ContractClassRegisteredEvent } from '@aztec/protocol-contracts/class-registerer'; import { ContractInstanceDeployedEvent } from '@aztec/protocol-contracts/instance-deployer'; -import { - type CommitmentsDB, - MessageLoadOracleInputs, - type PublicContractsDB, - type PublicStateDB, -} from '@aztec/simulator'; + +import { MessageLoadOracleInputs } from '../common/message_load_oracle_inputs.js'; +import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db_interfaces.js'; /** * Implements the PublicContractsDB using a ContractDataSource. diff --git a/yarn-project/simulator/src/index.ts b/yarn-project/simulator/src/server.ts similarity index 71% rename from yarn-project/simulator/src/index.ts rename to yarn-project/simulator/src/server.ts index f8095f6baf7..07f29d743bc 100644 --- a/yarn-project/simulator/src/index.ts +++ b/yarn-project/simulator/src/server.ts @@ -1,6 +1,4 @@ -export * from './acvm/index.js'; export * from './avm/index.js'; -export * from './client/index.js'; export * from './common/index.js'; export * from './public/index.js'; export * from './providers/index.js'; diff --git a/yarn-project/txe/src/oracle/txe_oracle.ts b/yarn-project/txe/src/oracle/txe_oracle.ts index 07965dbce20..aa25f0b241b 100644 --- a/yarn-project/txe/src/oracle/txe_oracle.ts +++ b/yarn-project/txe/src/oracle/txe_oracle.ts @@ -63,25 +63,27 @@ import { Timer } from '@aztec/foundation/timer'; import { type KeyStore } from '@aztec/key-store'; import { ContractDataOracle, SimulatorOracle, enrichPublicSimulationError } from '@aztec/pxe'; import { - ExecutionError, ExecutionNoteCache, type MessageLoadOracleInputs, type NoteData, Oracle, - type PackedValuesCache, - type PublicTxResult, - PublicTxSimulator, type TypedOracle, - acvm, - createSimulationError, + WASMSimulator, extractCallStack, extractPrivateCircuitPublicInputs, pickNotes, - resolveAssertionMessageFromError, toACVMWitness, witnessMapToFields, -} from '@aztec/simulator'; +} from '@aztec/simulator/client'; import { createTxForPublicCall } from '@aztec/simulator/public/fixtures'; +import { + ExecutionError, + type PackedValuesCache, + type PublicTxResult, + PublicTxSimulator, + createSimulationError, + resolveAssertionMessageFromError, +} from '@aztec/simulator/server'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { MerkleTreeSnapshotOperationsFacade, type MerkleTrees } from '@aztec/world-state'; @@ -116,6 +118,8 @@ export class TXE implements TypedOracle { private node = new TXENode(this.blockNumber); + private simulationProvider = new WASMSimulator(); + debug: LogFn; constructor( @@ -130,7 +134,13 @@ export class TXE implements TypedOracle { this.contractAddress = AztecAddress.random(); // Default msg_sender (for entrypoints) is now Fr.max_value rather than 0 addr (see #7190 & #7404) this.msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE); - this.simulatorOracle = new SimulatorOracle(this.contractDataOracle, txeDatabase, keyStore, this.node); + this.simulatorOracle = new SimulatorOracle( + this.contractDataOracle, + txeDatabase, + keyStore, + this.node, + this.simulationProvider, + ); this.debug = createDebugOnlyLogger('aztec:kv-pxe-database'); } @@ -701,21 +711,23 @@ export class TXE implements TypedOracle { const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall); const acvmCallback = new Oracle(this); const timer = new Timer(); - const acirExecutionResult = await acvm(acir, initialWitness, acvmCallback).catch((err: Error) => { - err.message = resolveAssertionMessageFromError(err, artifact); - - const execError = new ExecutionError( - err.message, - { - contractAddress: targetContractAddress, - functionSelector, - }, - extractCallStack(err, artifact.debug), - { cause: err }, - ); - this.logger.debug(`Error executing private function ${targetContractAddress}:${functionSelector}`); - throw createSimulationError(execError); - }); + const acirExecutionResult = await this.simulationProvider + .executeUserCircuit(acir, initialWitness, acvmCallback) + .catch((err: Error) => { + err.message = resolveAssertionMessageFromError(err, artifact); + + const execError = new ExecutionError( + err.message, + { + contractAddress: targetContractAddress, + functionSelector, + }, + extractCallStack(err, artifact.debug), + { cause: err }, + ); + this.logger.debug(`Error executing private function ${targetContractAddress}:${functionSelector}`); + throw createSimulationError(execError); + }); const duration = timer.ms(); const publicInputs = extractPrivateCircuitPublicInputs(artifact, acirExecutionResult.partialWitness); diff --git a/yarn-project/txe/src/txe_service/txe_service.ts b/yarn-project/txe/src/txe_service/txe_service.ts index e0b46aa45b5..0164be15d6e 100644 --- a/yarn-project/txe/src/txe_service/txe_service.ts +++ b/yarn-project/txe/src/txe_service/txe_service.ts @@ -18,7 +18,8 @@ import { openTmpStore } from '@aztec/kv-store/lmdb'; import { protocolContractNames } from '@aztec/protocol-contracts'; import { getCanonicalProtocolContract } from '@aztec/protocol-contracts/bundle'; import { enrichPublicSimulationError } from '@aztec/pxe'; -import { ExecutionNoteCache, PackedValuesCache, type TypedOracle } from '@aztec/simulator'; +import { ExecutionNoteCache, type TypedOracle } from '@aztec/simulator/client'; +import { PackedValuesCache } from '@aztec/simulator/server'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { MerkleTrees } from '@aztec/world-state'; diff --git a/yarn-project/txe/src/util/txe_world_state_db.ts b/yarn-project/txe/src/util/txe_world_state_db.ts index d1a2b6f1737..d617ee5e72e 100644 --- a/yarn-project/txe/src/util/txe_world_state_db.ts +++ b/yarn-project/txe/src/util/txe_world_state_db.ts @@ -7,7 +7,7 @@ import { type PublicDataTreeLeafPreimage, } from '@aztec/circuits.js'; import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash'; -import { WorldStateDB } from '@aztec/simulator'; +import { WorldStateDB } from '@aztec/simulator/server'; export class TXEWorldStateDB extends WorldStateDB { constructor(private merkleDb: MerkleTreeWriteOperations, dataSource: ContractDataSource) {