From 393e8438b082db7d45a45c78e0bf39719b11c56b Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Thu, 9 Jan 2025 14:19:09 +0100 Subject: [PATCH] feat: browser chunking (#11102) Further modularises `noir-protocol-circuits-types`, exposing a `client/lazy` API that allow browser bundles to not import every single JSON artifact at once, but rather pull them on demand. `/server` and `/vks` entrypoints are also provided to aid in startup CLI times, jest cache and general cleanup. This is very important due to the sheer amount of different reset variants we currently have. However, a regular `/client/bundle` is still exposed in case dynamic imports are not supported in the target platform. This takes our bundle sizes in the example vite box (with PXE in the browser and proving) from 50MB (30 compressed) to ~3MB before meaningful content is displayed. After that, `bb.js` is an additional 8-9 and each circuit hovers around 0.3-1, but only the ones used in the transactions are pulled when required. Also removed the `TestPrivateKernelProver`, and replaced it by each of our prover implementations providing a cleaner simulation vs. witgen+proving interface. This way, the prover is now 100% a PXE plugin (which will allow us to even delegate proving!) --- boxes/boxes/vite/src/config.ts | 5 +- boxes/boxes/vite/vite.config.ts | 19 +- yarn-project/.gitignore | 3 + yarn-project/aztec/src/sandbox.ts | 2 +- yarn-project/bb-prover/package.json | 3 +- yarn-project/bb-prover/src/bb/cli.ts | 10 +- yarn-project/bb-prover/src/honk.ts | 32 +- .../prover/bb_native_private_kernel_prover.ts | 110 ++++++ .../src/prover/bb_private_kernel_prover.ts | 337 +++++++----------- .../bb-prover/src/prover/bb_prover.ts | 4 +- yarn-project/bb-prover/src/prover/index.ts | 2 +- yarn-project/bb-prover/src/stats.ts | 8 +- .../bb-prover/src/test/test_circuit_prover.ts | 4 +- .../bb-prover/src/verifier/bb_verifier.ts | 21 +- .../src/wasm/bb_wasm_private_kernel_prover.ts | 40 +++ yarn-project/bb-prover/src/wasm/bundle.ts | 10 + yarn-project/bb-prover/src/wasm/index.ts | 155 -------- yarn-project/bb-prover/src/wasm/lazy.ts | 10 + yarn-project/bootstrap.sh | 2 +- .../src/interfaces/private_kernel_prover.ts | 48 ++- yarn-project/cli/src/utils/aztec.ts | 2 +- .../composed/integration_l1_publisher.test.ts | 2 +- .../src/e2e_crowdfunding_and_claim.test.ts | 2 +- .../src/e2e_prover/e2e_prover_test.ts | 4 +- .../src/fixtures/setup_l1_contracts.ts | 2 +- yarn-project/end-to-end/src/fixtures/utils.ts | 2 +- .../noir-protocol-circuits-types/package.json | 15 +- .../src/artifacts/client.ts | 38 -- .../src/artifacts/client/bundle.ts | 38 ++ .../src/artifacts/client/lazy.ts | 14 + .../src/artifacts/index.ts | 14 - .../src/artifacts/server.ts | 15 +- .../src/artifacts/types.ts | 31 ++ .../src/client.ts | 24 -- .../src/entrypoint/client/bundle.ts | 5 + .../src/entrypoint/client/common.ts | 21 ++ .../src/entrypoint/client/lazy.ts | 1 + .../src/entrypoint/server.ts | 6 + .../src/{ => entrypoint}/vks.ts | 38 +- .../src/execution/client.ts | 263 +++----------- .../src/execution/index.ts | 2 - .../noir-protocol-circuits-types/src/index.ts | 7 - .../generate_client_artifacts_helper.ts | 91 +++++ .../generate_private_kernel_reset_data.ts | 66 +++- .../src/scripts/generate_ts_from_abi.ts | 6 +- .../src/utils/private_kernel_reset.ts | 4 +- .../src/block_builder/light.test.ts | 2 +- .../prover-client/src/block_builder/light.ts | 2 +- .../prover-client/src/mocks/test_context.ts | 2 +- .../orchestrator/block-building-helpers.ts | 2 +- .../src/orchestrator/orchestrator.ts | 2 +- ...rchestrator_multi_public_functions.test.ts | 2 +- .../orchestrator_public_functions.test.ts | 2 +- .../orchestrator_workflow.test.ts | 2 +- .../src/orchestrator/tx-proving-state.ts | 2 +- .../src/test/bb_prover_base_rollup.test.ts | 2 +- .../src/test/bb_prover_full_rollup.test.ts | 2 +- .../src/test/bb_prover_parity.test.ts | 2 +- yarn-project/pxe/package.json | 1 - yarn-project/pxe/src/kernel_oracle/index.ts | 2 +- yarn-project/pxe/src/kernel_prover/index.ts | 2 - .../src/kernel_prover/kernel_prover.test.ts | 22 +- .../pxe/src/kernel_prover/kernel_prover.ts | 52 ++- .../kernel_prover/test/test_circuit_prover.ts | 122 ------- .../pxe/src/pxe_service/pxe_service.ts | 60 ++-- .../src/pxe_service/test/pxe_service.test.ts | 6 +- .../pxe/src/utils/create_pxe_service.ts | 10 +- .../src/providers/acvm_wasm_with_blobs.ts | 2 +- yarn-project/yarn.lock | 2 - 69 files changed, 870 insertions(+), 973 deletions(-) create mode 100644 yarn-project/bb-prover/src/prover/bb_native_private_kernel_prover.ts create mode 100644 yarn-project/bb-prover/src/wasm/bb_wasm_private_kernel_prover.ts create mode 100644 yarn-project/bb-prover/src/wasm/bundle.ts delete mode 100644 yarn-project/bb-prover/src/wasm/index.ts create mode 100644 yarn-project/bb-prover/src/wasm/lazy.ts delete mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/client/bundle.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/client/lazy.ts delete mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/types.ts delete mode 100644 yarn-project/noir-protocol-circuits-types/src/client.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/entrypoint/client/bundle.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/entrypoint/client/common.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/entrypoint/client/lazy.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/entrypoint/server.ts rename yarn-project/noir-protocol-circuits-types/src/{ => entrypoint}/vks.ts (70%) delete mode 100644 yarn-project/noir-protocol-circuits-types/src/execution/index.ts delete mode 100644 yarn-project/noir-protocol-circuits-types/src/index.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/scripts/generate_client_artifacts_helper.ts delete mode 100644 yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts diff --git a/boxes/boxes/vite/src/config.ts b/boxes/boxes/vite/src/config.ts index 734f450c80a..2413b3f5ff8 100644 --- a/boxes/boxes/vite/src/config.ts +++ b/boxes/boxes/vite/src/config.ts @@ -15,7 +15,7 @@ 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 { BBWasmPrivateKernelProver } from "@aztec/bb-prover/wasm"; +import { BBWASMLazyPrivateKernelProver } from "@aztec/bb-prover/wasm/lazy"; process.env = Object.keys(import.meta.env).reduce((acc, key) => { acc[key.replace("VITE_", "")] = import.meta.env[key]; @@ -37,8 +37,9 @@ export class PrivateEnv { async init() { const config = getPXEServiceConfig(); config.dataDirectory = "pxe"; + config.proverEnabled = true; const aztecNode = await createAztecNodeClient(this.nodeURL); - const proofCreator = new BBWasmPrivateKernelProver(16); + const proofCreator = new BBWASMLazyPrivateKernelProver(16); this.pxe = await this.createPXEService(aztecNode, config, proofCreator); const encryptionPrivateKey = deriveMasterIncomingViewingSecretKey( this.secretKey, diff --git a/boxes/boxes/vite/vite.config.ts b/boxes/boxes/vite/vite.config.ts index 94bade805b8..309b5eabdee 100644 --- a/boxes/boxes/vite/vite.config.ts +++ b/boxes/boxes/vite/vite.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from "vite"; +import { defineConfig, searchForWorkspaceRoot } from "vite"; import react from "@vitejs/plugin-react-swc"; import { PolyfillOptions, nodePolyfills } from "vite-plugin-node-polyfills"; import topLevelAwait from "vite-plugin-top-level-await"; @@ -28,12 +28,29 @@ export default defineConfig({ "Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Embedder-Policy": "require-corp", }, + fs: { + allow: [ + searchForWorkspaceRoot(process.cwd()), + "../../../yarn-project/noir-protocol-circuits-types/artifacts", + ], + }, }, plugins: [ react(), nodePolyfillsFix({ include: ["buffer", "process", "path"] }), topLevelAwait(), ], + build: { + rollupOptions: { + output: { + manualChunks(id: string) { + if (id.includes("bb-prover")) { + return "@aztec/bb-prover"; + } + }, + }, + }, + }, optimizeDeps: { exclude: ["@noir-lang/acvm_js", "@noir-lang/noirc_abi", "@aztec/bb-prover"], }, diff --git a/yarn-project/.gitignore b/yarn-project/.gitignore index abacb3d21aa..131191bc25f 100644 --- a/yarn-project/.gitignore +++ b/yarn-project/.gitignore @@ -37,6 +37,9 @@ builder/src/crs builder/src/types noir-protocol-circuits-types/artifacts noir-protocol-circuits-types/src/private_kernel_reset_data.ts +noir-protocol-circuits-types/src/private_kernel_reset_vks.ts +noir-protocol-circuits-types/src/private_kernel_reset_types.ts +noir-protocol-circuits-types/src/client_artifacts_helper.ts noir-protocol-circuits-types/src/types/ ivc-integration/artifacts ivc-integration/src/types/ diff --git a/yarn-project/aztec/src/sandbox.ts b/yarn-project/aztec/src/sandbox.ts index 19f0f9b1653..c6a7dd8363c 100644 --- a/yarn-project/aztec/src/sandbox.ts +++ b/yarn-project/aztec/src/sandbox.ts @@ -13,7 +13,7 @@ import { getL1ContractsConfigEnvVars, } from '@aztec/ethereum'; import { createLogger } from '@aztec/foundation/log'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; import { type TelemetryClient } from '@aztec/telemetry-client'; diff --git a/yarn-project/bb-prover/package.json b/yarn-project/bb-prover/package.json index 6606d7e14d4..4e0f86a7276 100644 --- a/yarn-project/bb-prover/package.json +++ b/yarn-project/bb-prover/package.json @@ -4,7 +4,8 @@ "type": "module", "exports": { ".": "./dest/index.js", - "./wasm": "./dest/wasm/index.js", + "./wasm/bundle": "./dest/wasm/bundle.js", + "./wasm/lazy": "./dest/wasm/lazy.js", "./prover": "./dest/prover/index.js", "./verifier": "./dest/verifier/index.js", "./test": "./dest/test/index.js", diff --git a/yarn-project/bb-prover/src/bb/cli.ts b/yarn-project/bb-prover/src/bb/cli.ts index 97a6724e2e8..f1bb7547fee 100644 --- a/yarn-project/bb-prover/src/bb/cli.ts +++ b/yarn-project/bb-prover/src/bb/cli.ts @@ -1,5 +1,8 @@ import { type LogFn } from '@aztec/foundation/log'; -import { type ProtocolArtifact, ProtocolCircuitArtifacts } from '@aztec/noir-protocol-circuits-types'; +import { ClientCircuitArtifacts } from '@aztec/noir-protocol-circuits-types/client/bundle'; +import { ServerCircuitArtifacts } from '@aztec/noir-protocol-circuits-types/server'; +import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types'; +import { type NoirCompiledCircuit } from '@aztec/types/noir'; import { Command } from 'commander'; import { promises as fs } from 'fs'; @@ -8,6 +11,11 @@ import { generateContractForCircuit, generateKeyForNoirCircuit } from './execute const { BB_WORKING_DIRECTORY, BB_BINARY_PATH } = process.env; +export const ProtocolCircuitArtifacts: Record = { + ...ClientCircuitArtifacts, + ...ServerCircuitArtifacts, +}; + /** * Returns commander program that defines the CLI. * @param log - Console logger. diff --git a/yarn-project/bb-prover/src/honk.ts b/yarn-project/bb-prover/src/honk.ts index 8c4b013176c..0527a7916aa 100644 --- a/yarn-project/bb-prover/src/honk.ts +++ b/yarn-project/bb-prover/src/honk.ts @@ -1,35 +1,35 @@ -import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; +import { type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/server'; export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_rollup_honk'; -const UltraKeccakHonkCircuits = ['RootRollupArtifact'] as const satisfies ProtocolArtifact[]; +const UltraKeccakHonkCircuits = ['RootRollupArtifact'] as const satisfies ServerProtocolArtifact[]; const UltraHonkCircuits = [ // 'EmptyNestedArtifact', // 'PrivateKernelEmptyArtifact', 'BaseParityArtifact', 'RootParityArtifact', -] as const satisfies ProtocolArtifact[]; +] as const satisfies ServerProtocolArtifact[]; -export type UltraKeccakHonkProtocolArtifact = (typeof UltraKeccakHonkCircuits)[number]; -export type UltraHonkProtocolArtifact = (typeof UltraHonkCircuits)[number]; -export type UltraRollupHonkProtocolArtifact = Exclude< - Exclude, - UltraHonkProtocolArtifact +export type UltraKeccakHonkServerProtocolArtifact = (typeof UltraKeccakHonkCircuits)[number]; +export type UltraHonkServerProtocolArtifact = (typeof UltraHonkCircuits)[number]; +export type UltraRollupHonkServerProtocolArtifact = Exclude< + Exclude, + UltraHonkServerProtocolArtifact >; -export function getUltraHonkFlavorForCircuit(artifact: UltraKeccakHonkProtocolArtifact): 'ultra_keccak_honk'; -export function getUltraHonkFlavorForCircuit(artifact: UltraHonkProtocolArtifact): 'ultra_honk'; -export function getUltraHonkFlavorForCircuit(artifact: UltraRollupHonkProtocolArtifact): 'ultra_rollup_honk'; -export function getUltraHonkFlavorForCircuit(artifact: ProtocolArtifact): UltraHonkFlavor; -export function getUltraHonkFlavorForCircuit(artifact: ProtocolArtifact): UltraHonkFlavor { +export function getUltraHonkFlavorForCircuit(artifact: UltraKeccakHonkServerProtocolArtifact): 'ultra_keccak_honk'; +export function getUltraHonkFlavorForCircuit(artifact: UltraHonkServerProtocolArtifact): 'ultra_honk'; +export function getUltraHonkFlavorForCircuit(artifact: UltraRollupHonkServerProtocolArtifact): 'ultra_rollup_honk'; +export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor; +export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor { if (isUltraKeccakHonkCircuit(artifact)) { return 'ultra_keccak_honk'; - } else if (UltraHonkCircuits.includes(artifact as UltraHonkProtocolArtifact)) { + } else if (UltraHonkCircuits.includes(artifact as UltraHonkServerProtocolArtifact)) { return 'ultra_honk'; } return 'ultra_rollup_honk'; } -function isUltraKeccakHonkCircuit(artifact: ProtocolArtifact): artifact is UltraKeccakHonkProtocolArtifact { - return UltraKeccakHonkCircuits.includes(artifact as UltraKeccakHonkProtocolArtifact); +function isUltraKeccakHonkCircuit(artifact: ServerProtocolArtifact): artifact is UltraKeccakHonkServerProtocolArtifact { + return UltraKeccakHonkCircuits.includes(artifact as UltraKeccakHonkServerProtocolArtifact); } 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 new file mode 100644 index 00000000000..cdb000404ec --- /dev/null +++ b/yarn-project/bb-prover/src/prover/bb_native_private_kernel_prover.ts @@ -0,0 +1,110 @@ +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 { encode } from '@msgpack/msgpack'; +import { serializeWitness } from '@noir-lang/noirc_abi'; +import { type WitnessMap } from '@noir-lang/types'; +import { promises as fs } from 'fs'; +import path from 'path'; + +import { BB_RESULT, computeGateCountForCircuit, executeBbClientIvcProof } from '../bb/execute.js'; +import { type BBConfig } from '../config.js'; +import { BBPrivateKernelProver } from './bb_private_kernel_prover.js'; +import { readFromOutputDirectory } from './client_ivc_proof_utils.js'; + +/** + * This proof creator implementation uses the native bb binary. + */ +export class BBNativePrivateKernelProver extends BBPrivateKernelProver { + private constructor( + private bbBinaryPath: string, + private bbWorkingDirectory: string, + private skipCleanup: boolean, + protected override log = createLogger('bb-prover:native'), + ) { + super(new BundleArtifactProvider(), log); + } + + public static async new(config: BBConfig, log?: Logger) { + await fs.mkdir(config.bbWorkingDirectory, { recursive: true }); + return new BBNativePrivateKernelProver(config.bbBinaryPath, config.bbWorkingDirectory, !!config.bbSkipCleanup, log); + } + + private async _createClientIvcProof( + directory: string, + acirs: Buffer[], + witnessStack: WitnessMap[], + ): Promise { + // TODO(#7371): Longer term we won't use this hacked together msgpack format + // and instead properly create the bincode serialization from rust + await fs.writeFile(path.join(directory, 'acir.msgpack'), encode(acirs)); + await fs.writeFile( + path.join(directory, 'witnesses.msgpack'), + encode(witnessStack.map(map => serializeWitness(map))), + ); + const provingResult = await executeBbClientIvcProof( + this.bbBinaryPath, + directory, + path.join(directory, 'acir.msgpack'), + path.join(directory, 'witnesses.msgpack'), + this.log.info, + ); + + if (provingResult.status === BB_RESULT.FAILURE) { + this.log.error(`Failed to generate client ivc proof`); + throw new Error(provingResult.reason); + } + + const proof = await readFromOutputDirectory(directory); + + this.log.info(`Generated IVC proof`, { + duration: provingResult.durationMs, + eventName: 'circuit-proving', + }); + + return proof; + } + + public override async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise { + this.log.info(`Generating Client IVC proof`); + const operation = async (directory: string) => { + return await this._createClientIvcProof(directory, acirs, witnessStack); + }; + return await this.runInDirectory(operation); + } + + public override async computeGateCountForCircuit(bytecode: Buffer, circuitName: string): Promise { + const logFunction = (message: string) => { + this.log.debug(`$bb gates ${circuitName} - ${message}`); + }; + + const result = await computeGateCountForCircuit( + this.bbBinaryPath, + this.bbWorkingDirectory, + circuitName, + bytecode, + 'mega_honk', + logFunction, + ); + if (result.status === BB_RESULT.FAILURE) { + throw new Error(result.reason); + } + + return result.circuitSize as number; + } + + private runInDirectory(fn: (dir: string) => Promise) { + const log = this.log; + return runInDirectory( + this.bbWorkingDirectory, + (dir: string) => + fn(dir).catch(err => { + log.error(`Error running operation at ${dir}: ${err}`); + throw err; + }), + this.skipCleanup, + ); + } +} 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 5bdf4f6b9cb..e3b2da29ee0 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 @@ -1,5 +1,5 @@ import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types'; -import { type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; +import { type CircuitSimulationStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; import { type ClientIvcProof, type PrivateKernelCircuitPublicInputs, @@ -8,264 +8,192 @@ import { type PrivateKernelResetCircuitPrivateInputs, type PrivateKernelTailCircuitPrivateInputs, type PrivateKernelTailCircuitPublicInputs, - type Proof, - type VerificationKeyData, } from '@aztec/circuits.js'; -import { runInDirectory } from '@aztec/foundation/fs'; -import { type Logger, createLogger } from '@aztec/foundation/log'; +import { createLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { - ClientCircuitArtifacts, - ClientCircuitVks, - type ClientProtocolArtifact, - ProtocolCircuitVks, - convertPrivateKernelInitInputsToWitnessMap, - convertPrivateKernelInitOutputsFromWitnessMap, - convertPrivateKernelInnerInputsToWitnessMap, - convertPrivateKernelInnerOutputsFromWitnessMap, - convertPrivateKernelResetInputsToWitnessMap, - convertPrivateKernelResetOutputsFromWitnessMap, - convertPrivateKernelTailForPublicOutputsFromWitnessMap, - convertPrivateKernelTailInputsToWitnessMap, - convertPrivateKernelTailOutputsFromWitnessMap, - convertPrivateKernelTailToPublicInputsToWitnessMap, + convertPrivateKernelInitInputsToWitnessMapWithAbi, + convertPrivateKernelInitOutputsFromWitnessMapWithAbi, + convertPrivateKernelInnerInputsToWitnessMapWithAbi, + convertPrivateKernelInnerOutputsFromWitnessMapWithAbi, + convertPrivateKernelResetInputsToWitnessMapWithAbi, + convertPrivateKernelResetOutputsFromWitnessMapWithAbi, + convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi, + convertPrivateKernelTailInputsToWitnessMapWithAbi, + convertPrivateKernelTailOutputsFromWitnessMapWithAbi, + convertPrivateKernelTailToPublicInputsToWitnessMapWithAbi, getPrivateKernelResetArtifactName, -} from '@aztec/noir-protocol-circuits-types'; -import { WASMSimulatorWithBlobs } from '@aztec/simulator'; +} 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 NoirCompiledCircuit } from '@aztec/types/noir'; -import { encode } from '@msgpack/msgpack'; -import { serializeWitness } from '@noir-lang/noirc_abi'; -import { type WitnessMap } from '@noir-lang/types'; -import { promises as fs } from 'fs'; -import path from 'path'; +import { type Abi, type WitnessMap } from '@noir-lang/types'; -import { BB_RESULT, computeGateCountForCircuit, executeBbClientIvcProof, verifyProof } from '../bb/execute.js'; -import { type BBConfig } from '../config.js'; -import { type UltraHonkFlavor, getUltraHonkFlavorForCircuit } from '../honk.js'; import { mapProtocolArtifactNameToCircuitName } from '../stats.js'; -import { extractVkData } from '../verification_key/verification_key_data.js'; -import { readFromOutputDirectory } from './client_ivc_proof_utils.js'; -/** - * This proof creator implementation uses the native bb binary. - * This is a temporary implementation until we make the WASM version work. - * TODO(#7368): this class grew 'organically' aka it could use a look at its resposibilities - */ -export class BBNativePrivateKernelProver implements PrivateKernelProver { - private simulator = new WASMSimulatorWithBlobs(); +export abstract class BBPrivateKernelProver implements PrivateKernelProver { + protected simulator = new WASMSimulator(); - private verificationKeys: Map> = new Map< - ClientProtocolArtifact, - Promise - >(); + constructor(protected artifactProvider: ArtifactProvider, protected log = createLogger('bb-prover')) {} - private constructor( - private bbBinaryPath: string, - private bbWorkingDirectory: string, - private skipCleanup: boolean, - private log = createLogger('bb-prover:native'), - ) {} - - public static async new(config: BBConfig, log?: Logger) { - await fs.mkdir(config.bbWorkingDirectory, { recursive: true }); - return new BBNativePrivateKernelProver(config.bbBinaryPath, config.bbWorkingDirectory, !!config.bbSkipCleanup, log); - } - - private async _createClientIvcProof( - directory: string, - acirs: Buffer[], - witnessStack: WitnessMap[], - ): Promise { - // TODO(#7371): Longer term we won't use this hacked together msgpack format - // and instead properly create the bincode serialization from rust - await fs.writeFile(path.join(directory, 'acir.msgpack'), encode(acirs)); - await fs.writeFile( - path.join(directory, 'witnesses.msgpack'), - encode(witnessStack.map(map => serializeWitness(map))), - ); - const provingResult = await executeBbClientIvcProof( - this.bbBinaryPath, - directory, - path.join(directory, 'acir.msgpack'), - path.join(directory, 'witnesses.msgpack'), - this.log.info, + public async generateInitOutput( + inputs: PrivateKernelInitCircuitPrivateInputs, + ): Promise> { + return await this.generateCircuitOutput( + inputs, + 'PrivateKernelInitArtifact', + convertPrivateKernelInitInputsToWitnessMapWithAbi, + convertPrivateKernelInitOutputsFromWitnessMapWithAbi, ); - - if (provingResult.status === BB_RESULT.FAILURE) { - this.log.error(`Failed to generate client ivc proof`); - throw new Error(provingResult.reason); - } - - const proof = await readFromOutputDirectory(directory); - - this.log.info(`Generated IVC proof`, { - duration: provingResult.durationMs, - eventName: 'circuit-proving', - }); - - return proof; } - async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise { - this.log.info(`Generating Client IVC proof`); - const operation = async (directory: string) => { - return await this._createClientIvcProof(directory, acirs, witnessStack); - }; - return await this.runInDirectory(operation); - } - - public async simulateProofInit( + public async simulateInit( inputs: PrivateKernelInitCircuitPrivateInputs, ): Promise> { - return await this.simulate( + return await this.simulateCircuitOutput( inputs, 'PrivateKernelInitArtifact', - convertPrivateKernelInitInputsToWitnessMap, - convertPrivateKernelInitOutputsFromWitnessMap, + convertPrivateKernelInitInputsToWitnessMapWithAbi, + convertPrivateKernelInitOutputsFromWitnessMapWithAbi, + ); + } + + public async generateInnerOutput( + inputs: PrivateKernelInnerCircuitPrivateInputs, + ): Promise> { + return await this.generateCircuitOutput( + inputs, + 'PrivateKernelInnerArtifact', + convertPrivateKernelInnerInputsToWitnessMapWithAbi, + convertPrivateKernelInnerOutputsFromWitnessMapWithAbi, ); } - public async simulateProofInner( + public async simulateInner( inputs: PrivateKernelInnerCircuitPrivateInputs, ): Promise> { - return await this.simulate( + return await this.simulateCircuitOutput( inputs, 'PrivateKernelInnerArtifact', - convertPrivateKernelInnerInputsToWitnessMap, - convertPrivateKernelInnerOutputsFromWitnessMap, + convertPrivateKernelInnerInputsToWitnessMapWithAbi, + convertPrivateKernelInnerOutputsFromWitnessMapWithAbi, ); } - public async simulateProofReset( + public async generateResetOutput( inputs: PrivateKernelResetCircuitPrivateInputs, ): Promise> { const variantInputs = inputs.trimToSizes(); const artifactName = getPrivateKernelResetArtifactName(inputs.dimensions); - return await this.simulate( + return await this.generateCircuitOutput( variantInputs, artifactName, - variantInputs => convertPrivateKernelResetInputsToWitnessMap(variantInputs, artifactName), - output => convertPrivateKernelResetOutputsFromWitnessMap(output, artifactName), + convertPrivateKernelResetInputsToWitnessMapWithAbi, + convertPrivateKernelResetOutputsFromWitnessMapWithAbi, ); } - public async simulateProofTail( + public async simulateReset( + inputs: PrivateKernelResetCircuitPrivateInputs, + ): Promise> { + const variantInputs = inputs.trimToSizes(); + const artifactName = getPrivateKernelResetArtifactName(inputs.dimensions); + return await this.simulateCircuitOutput( + variantInputs, + artifactName, + convertPrivateKernelResetInputsToWitnessMapWithAbi, + convertPrivateKernelResetOutputsFromWitnessMapWithAbi, + ); + } + + public async generateTailOutput( inputs: PrivateKernelTailCircuitPrivateInputs, ): Promise> { if (!inputs.isForPublic()) { - return await this.simulate( + return await this.generateCircuitOutput( inputs, 'PrivateKernelTailArtifact', - convertPrivateKernelTailInputsToWitnessMap, - convertPrivateKernelTailOutputsFromWitnessMap, + convertPrivateKernelTailInputsToWitnessMapWithAbi, + convertPrivateKernelTailOutputsFromWitnessMapWithAbi, ); } - return await this.simulate( + return await this.generateCircuitOutput( inputs, 'PrivateKernelTailToPublicArtifact', - convertPrivateKernelTailToPublicInputsToWitnessMap, - convertPrivateKernelTailForPublicOutputsFromWitnessMap, + convertPrivateKernelTailToPublicInputsToWitnessMapWithAbi, + convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi, ); } - /** - * Verifies a proof, will generate the verification key if one is not cached internally - * @param circuitType - The type of circuit whose proof is to be verified - * @param proof - The proof to be verified - */ - public async verifyProofForProtocolCircuit(circuitType: ClientProtocolArtifact, proof: Proof) { - const verificationKey = ProtocolCircuitVks[circuitType]; - - this.log.debug(`Verifying with key: ${verificationKey.keyAsFields.hash.toString()}`); - - const logFunction = (message: string) => { - this.log.debug(`${circuitType} BB out - ${message}`); - }; - - const result = await this.verifyProofFromKey( - getUltraHonkFlavorForCircuit(circuitType), - verificationKey.keyAsBytes, - proof, - logFunction, - ); - - if (result.status === BB_RESULT.FAILURE) { - const errorMessage = `Failed to verify ${circuitType} proof!`; - throw new Error(errorMessage); + public async simulateTail( + inputs: PrivateKernelTailCircuitPrivateInputs, + ): Promise> { + if (!inputs.isForPublic()) { + return await this.simulateCircuitOutput( + inputs, + 'PrivateKernelTailArtifact', + convertPrivateKernelTailInputsToWitnessMapWithAbi, + convertPrivateKernelTailOutputsFromWitnessMapWithAbi, + ); } - - this.log.info(`Successfully verified ${circuitType} proof in ${Math.ceil(result.durationMs)} ms`); + return await this.simulateCircuitOutput( + inputs, + 'PrivateKernelTailToPublicArtifact', + convertPrivateKernelTailToPublicInputsToWitnessMapWithAbi, + convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi, + ); } - public async computeGateCountForCircuit(bytecode: Buffer, circuitName: string): Promise { - const logFunction = (message: string) => { - this.log.debug(`$bb gates ${circuitName} - ${message}`); - }; - - const result = await computeGateCountForCircuit( - this.bbBinaryPath, - this.bbWorkingDirectory, - circuitName, - bytecode, - 'mega_honk', - logFunction, + public async simulateCircuitOutput< + I extends { toBuffer: () => Buffer }, + O extends PrivateKernelCircuitPublicInputs | PrivateKernelTailCircuitPublicInputs, + >( + inputs: I, + circuitType: ClientProtocolArtifact, + convertInputs: (inputs: I, abi: Abi) => WitnessMap, + convertOutputs: (outputs: WitnessMap, abi: Abi) => O, + ): Promise> { + const compiledCircuit: NoirCompiledCircuit = await this.artifactProvider.getSimulatedClientCircuitArtifactByName( + circuitType, ); - if (result.status === BB_RESULT.FAILURE) { - throw new Error(result.reason); - } - return result.circuitSize as number; - } + const witnessMap = convertInputs(inputs, compiledCircuit.abi); - private async verifyProofFromKey( - flavor: UltraHonkFlavor, - verificationKey: Buffer, - proof: Proof, - logFunction: (message: string) => void = () => {}, - ) { - const operation = async (bbWorkingDirectory: string) => { - const proofFileName = `${bbWorkingDirectory}/proof`; - const verificationKeyPath = `${bbWorkingDirectory}/vk`; + const timer = new Timer(); + const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit); + const output = convertOutputs(outputWitness, compiledCircuit.abi); - await fs.writeFile(proofFileName, proof.buffer); - await fs.writeFile(verificationKeyPath, verificationKey); - return await verifyProof(this.bbBinaryPath, proofFileName, verificationKeyPath!, flavor, logFunction); - }; - return await this.runInDirectory(operation); - } + this.log.debug(`Simulated ${circuitType}`, { + eventName: 'circuit-simulation', + circuitName: mapProtocolArtifactNameToCircuitName(circuitType), + duration: timer.ms(), + inputSize: inputs.toBuffer().length, + outputSize: output.toBuffer().length, + } satisfies CircuitSimulationStats); - /** - * Ensures our verification key cache includes the key data located at the specified directory - * @param filePath - The directory containing the verification key data files - * @param circuitType - The type of circuit to which the verification key corresponds - */ - private async updateVerificationKeyAfterSimulation(filePath: string, circuitType: ClientProtocolArtifact) { - let promise = this.verificationKeys.get(circuitType); - if (!promise) { - promise = extractVkData(filePath); - this.log.debug(`Updated verification key for circuit: ${circuitType}`); - this.verificationKeys.set(circuitType, promise); - } - return await promise; + return this.makeEmptyKernelSimulateOutput(output, circuitType); } - private async simulate< + public async generateCircuitOutput< I extends { toBuffer: () => Buffer }, O extends PrivateKernelCircuitPublicInputs | PrivateKernelTailCircuitPublicInputs, >( inputs: I, circuitType: ClientProtocolArtifact, - convertInputs: (inputs: I) => WitnessMap, - convertOutputs: (outputs: WitnessMap) => O, + convertInputs: (inputs: I, abi: Abi) => WitnessMap, + convertOutputs: (outputs: WitnessMap, abi: Abi) => O, ): Promise> { this.log.debug(`Generating witness for ${circuitType}`); - const compiledCircuit: NoirCompiledCircuit = ClientCircuitArtifacts[circuitType]; + const compiledCircuit: NoirCompiledCircuit = await this.artifactProvider.getClientCircuitArtifactByName( + circuitType, + ); - const witnessMap = convertInputs(inputs); + const witnessMap = convertInputs(inputs, compiledCircuit.abi); const timer = new Timer(); const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit); - const output = convertOutputs(outputWitness); + const output = convertOutputs(outputWitness, compiledCircuit.abi); this.log.debug(`Generated witness for ${circuitType}`, { eventName: 'circuit-witness-generation', @@ -287,16 +215,23 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver { return kernelOutput; } - private runInDirectory(fn: (dir: string) => Promise) { - const log = this.log; - return runInDirectory( - this.bbWorkingDirectory, - (dir: string) => - fn(dir).catch(err => { - log.error(`Error running operation at ${dir}: ${err}`); - throw err; - }), - this.skipCleanup, - ); + public makeEmptyKernelSimulateOutput< + PublicInputsType extends PrivateKernelTailCircuitPublicInputs | PrivateKernelCircuitPublicInputs, + >(publicInputs: PublicInputsType, circuitType: ClientProtocolArtifact) { + const kernelProofOutput: PrivateKernelSimulateOutput = { + publicInputs, + verificationKey: ClientCircuitVks[circuitType].keyAsFields, + outputWitness: new Map(), + bytecode: Buffer.from([]), + }; + return kernelProofOutput; + } + + public createClientIvcProof(_acirs: Buffer[], _witnessStack: WitnessMap[]): Promise { + throw new Error('Not implemented'); + } + + public computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise { + throw new Error('Not implemented'); } } diff --git a/yarn-project/bb-prover/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts index 1f6f3706275..fcff9c3d67a 100644 --- a/yarn-project/bb-prover/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -51,7 +51,6 @@ import { createLogger } from '@aztec/foundation/log'; import { BufferReader } from '@aztec/foundation/serialize'; import { Timer } from '@aztec/foundation/timer'; import { - ProtocolCircuitVks, ServerCircuitArtifacts, type ServerProtocolArtifact, convertBaseParityInputsToWitnessMap, @@ -74,7 +73,8 @@ import { convertRootParityOutputsFromWitnessMap, convertRootRollupInputsToWitnessMap, convertRootRollupOutputsFromWitnessMap, -} from '@aztec/noir-protocol-circuits-types'; +} from '@aztec/noir-protocol-circuits-types/server'; +import { ProtocolCircuitVks } from '@aztec/noir-protocol-circuits-types/vks'; import { NativeACVMSimulator } from '@aztec/simulator'; import { Attributes, type TelemetryClient, trackSpan } from '@aztec/telemetry-client'; diff --git a/yarn-project/bb-prover/src/prover/index.ts b/yarn-project/bb-prover/src/prover/index.ts index 4079e27943c..81cf1fdf416 100644 --- a/yarn-project/bb-prover/src/prover/index.ts +++ b/yarn-project/bb-prover/src/prover/index.ts @@ -1,3 +1,3 @@ export * from './bb_prover.js'; -export * from './bb_private_kernel_prover.js'; +export * from './bb_native_private_kernel_prover.js'; export * from './client_ivc_proof_utils.js'; diff --git a/yarn-project/bb-prover/src/stats.ts b/yarn-project/bb-prover/src/stats.ts index 8cb7c0c0ab4..7032d949bfb 100644 --- a/yarn-project/bb-prover/src/stats.ts +++ b/yarn-project/bb-prover/src/stats.ts @@ -1,9 +1,7 @@ import type { CircuitName } from '@aztec/circuit-types/stats'; -import { type ClientProtocolArtifact, type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; +import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types'; -export function mapProtocolArtifactNameToCircuitName( - artifact: ServerProtocolArtifact | ClientProtocolArtifact, -): CircuitName { +export function mapProtocolArtifactNameToCircuitName(artifact: ProtocolArtifact): CircuitName { switch (artifact) { case 'BaseParityArtifact': return 'base-parity'; @@ -44,7 +42,7 @@ export function mapProtocolArtifactNameToCircuitName( } } -export function isProtocolArtifactRecursive(artifact: ServerProtocolArtifact | ClientProtocolArtifact): boolean { +export function isProtocolArtifactRecursive(artifact: ProtocolArtifact): boolean { switch (artifact) { case 'EmptyNestedArtifact': case 'PrivateKernelEmptyArtifact': 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 b1d9f46a308..44c4ecc39a1 100644 --- a/yarn-project/bb-prover/src/test/test_circuit_prover.ts +++ b/yarn-project/bb-prover/src/test/test_circuit_prover.ts @@ -42,7 +42,6 @@ import { createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; import { Timer } from '@aztec/foundation/timer'; import { - ProtocolCircuitVks, type ServerProtocolArtifact, SimulatedServerCircuitArtifacts, convertBaseParityInputsToWitnessMap, @@ -65,7 +64,8 @@ import { convertSimulatedPrivateKernelEmptyOutputsFromWitnessMap, convertSimulatedPublicBaseRollupInputsToWitnessMap, convertSimulatedPublicBaseRollupOutputsFromWitnessMap, -} from '@aztec/noir-protocol-circuits-types'; +} 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 TelemetryClient, trackSpan } from '@aztec/telemetry-client'; diff --git a/yarn-project/bb-prover/src/verifier/bb_verifier.ts b/yarn-project/bb-prover/src/verifier/bb_verifier.ts index e1f5b17def2..ccf19dcf057 100644 --- a/yarn-project/bb-prover/src/verifier/bb_verifier.ts +++ b/yarn-project/bb-prover/src/verifier/bb_verifier.ts @@ -3,11 +3,12 @@ import { type CircuitVerificationStats } from '@aztec/circuit-types/stats'; import { type Proof, type VerificationKeyData } from '@aztec/circuits.js'; import { runInDirectory } from '@aztec/foundation/fs'; import { type LogFn, type Logger, createLogger } from '@aztec/foundation/log'; +import { ServerCircuitArtifacts } from '@aztec/noir-protocol-circuits-types/server'; import { type ClientProtocolArtifact, type ProtocolArtifact, - ProtocolCircuitArtifacts, -} from '@aztec/noir-protocol-circuits-types'; + type ServerProtocolArtifact, +} from '@aztec/noir-protocol-circuits-types/types'; import { promises as fs } from 'fs'; import * as path from 'path'; @@ -22,7 +23,7 @@ import { verifyProof, } from '../bb/execute.js'; import { type BBConfig } from '../config.js'; -import { type UltraKeccakHonkProtocolArtifact, getUltraHonkFlavorForCircuit } from '../honk.js'; +import { type UltraKeccakHonkServerProtocolArtifact, getUltraHonkFlavorForCircuit } from '../honk.js'; import { writeToOutputDirectory } from '../prover/client_ivc_proof_utils.js'; import { isProtocolArtifactRecursive, mapProtocolArtifactNameToCircuitName } from '../stats.js'; import { extractVkData } from '../verification_key/verification_key_data.js'; @@ -36,7 +37,7 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { public static async new( config: BBConfig, - initialCircuits: ProtocolArtifact[] = [], + initialCircuits: ServerProtocolArtifact[] = [], logger = createLogger('bb-prover:verifier'), ) { await fs.mkdir(config.bbWorkingDirectory, { recursive: true }); @@ -54,7 +55,7 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { } private static async generateVerificationKey( - circuit: ProtocolArtifact, + circuit: ServerProtocolArtifact, bbPath: string, workingDirectory: string, logFn: LogFn, @@ -63,7 +64,7 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { bbPath, workingDirectory, circuit, - ProtocolCircuitArtifacts[circuit], + ServerCircuitArtifacts[circuit], isProtocolArtifactRecursive(circuit), getUltraHonkFlavorForCircuit(circuit), logFn, @@ -76,7 +77,7 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { }); } - public async getVerificationKeyData(circuit: ProtocolArtifact) { + public async getVerificationKeyData(circuit: ServerProtocolArtifact) { let promise = this.verificationKeys.get(circuit); if (!promise) { promise = BBCircuitVerifier.generateVerificationKey( @@ -91,7 +92,7 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { return vk.clone(); } - public async verifyProofForCircuit(circuit: ProtocolArtifact, proof: Proof) { + public async verifyProofForCircuit(circuit: ServerProtocolArtifact, proof: Proof) { const operation = async (bbWorkingDirectory: string) => { const proofFileName = path.join(bbWorkingDirectory, PROOF_FILENAME); const verificationKeyPath = path.join(bbWorkingDirectory, VK_FILENAME); @@ -129,12 +130,12 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { await runInDirectory(this.config.bbWorkingDirectory, operation, this.config.bbSkipCleanup); } - public async generateSolidityContract(circuit: UltraKeccakHonkProtocolArtifact, contractName: string) { + public async generateSolidityContract(circuit: UltraKeccakHonkServerProtocolArtifact, contractName: string) { const result = await generateContractForCircuit( this.config.bbBinaryPath, this.config.bbWorkingDirectory, circuit, - ProtocolCircuitArtifacts[circuit], + ServerCircuitArtifacts[circuit], contractName, this.logger.debug, ); 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 new file mode 100644 index 00000000000..afcac61ea93 --- /dev/null +++ b/yarn-project/bb-prover/src/wasm/bb_wasm_private_kernel_prover.ts @@ -0,0 +1,40 @@ +import { AztecClientBackend } from '@aztec/bb.js'; +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 { serializeWitness } from '@noir-lang/noirc_abi'; +import { type WitnessMap } from '@noir-lang/types'; +import { ungzip } from 'pako'; + +import { BBPrivateKernelProver } from '../prover/bb_private_kernel_prover.js'; + +export abstract class BBWASMPrivateKernelProver extends BBPrivateKernelProver { + constructor( + protected override artifactProvider: ArtifactProvider, + private threads: number = 1, + protected override log = createLogger('bb-prover:wasm'), + ) { + super(artifactProvider, log); + } + + public override async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise { + const timer = new Timer(); + this.log.info(`Generating ClientIVC proof...`); + const backend = new AztecClientBackend( + acirs.map(acir => ungzip(acir)), + { threads: this.threads }, + ); + + const [proof, vk] = await backend.prove(witnessStack.map(witnessMap => ungzip(serializeWitness(witnessMap)))); + await backend.destroy(); + this.log.info(`Generated ClientIVC proof`, { + eventName: 'client-ivc-proof-generation', + duration: timer.ms(), + proofSize: proof.length, + vkSize: vk.length, + }); + return new ClientIvcProof(Buffer.from(proof), Buffer.from(vk)); + } +} diff --git a/yarn-project/bb-prover/src/wasm/bundle.ts b/yarn-project/bb-prover/src/wasm/bundle.ts new file mode 100644 index 00000000000..ae448752d63 --- /dev/null +++ b/yarn-project/bb-prover/src/wasm/bundle.ts @@ -0,0 +1,10 @@ +import { createLogger } from '@aztec/foundation/log'; +import { BundleArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/bundle'; + +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); + } +} diff --git a/yarn-project/bb-prover/src/wasm/index.ts b/yarn-project/bb-prover/src/wasm/index.ts deleted file mode 100644 index 9163848db9e..00000000000 --- a/yarn-project/bb-prover/src/wasm/index.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { AztecClientBackend } from '@aztec/bb.js'; -import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types'; -import { - ClientIvcProof, - type PrivateKernelCircuitPublicInputs, - type PrivateKernelInitCircuitPrivateInputs, - type PrivateKernelInnerCircuitPrivateInputs, - type PrivateKernelResetCircuitPrivateInputs, - type PrivateKernelTailCircuitPrivateInputs, - type PrivateKernelTailCircuitPublicInputs, -} from '@aztec/circuits.js'; -import { createLogger } from '@aztec/foundation/log'; -import { Timer } from '@aztec/foundation/timer'; -import { - ClientCircuitArtifacts, - ClientCircuitVks, - type ClientProtocolArtifact, - convertPrivateKernelInitInputsToWitnessMap, - convertPrivateKernelInitOutputsFromWitnessMap, - convertPrivateKernelInnerInputsToWitnessMap, - convertPrivateKernelInnerOutputsFromWitnessMap, - convertPrivateKernelResetInputsToWitnessMap, - convertPrivateKernelResetOutputsFromWitnessMap, - convertPrivateKernelTailForPublicOutputsFromWitnessMap, - convertPrivateKernelTailInputsToWitnessMap, - convertPrivateKernelTailOutputsFromWitnessMap, - convertPrivateKernelTailToPublicInputsToWitnessMap, - getPrivateKernelResetArtifactName, -} from '@aztec/noir-protocol-circuits-types/client'; -import { WASMSimulator } from '@aztec/simulator/client'; -import { type NoirCompiledCircuit } from '@aztec/types/noir'; - -import { type WitnessMap } from '@noir-lang/noir_js'; -import { serializeWitness } from '@noir-lang/noirc_abi'; -import { ungzip } from 'pako'; - -export class BBWasmPrivateKernelProver implements PrivateKernelProver { - private simulator = new WASMSimulator(); - - constructor(private threads: number = 1, private log = createLogger('bb-prover:wasm')) {} - - public async simulateProofInit( - inputs: PrivateKernelInitCircuitPrivateInputs, - ): Promise> { - return await this.simulate( - inputs, - 'PrivateKernelInitArtifact', - convertPrivateKernelInitInputsToWitnessMap, - convertPrivateKernelInitOutputsFromWitnessMap, - ); - } - - public async simulateProofInner( - inputs: PrivateKernelInnerCircuitPrivateInputs, - ): Promise> { - return await this.simulate( - inputs, - 'PrivateKernelInnerArtifact', - convertPrivateKernelInnerInputsToWitnessMap, - convertPrivateKernelInnerOutputsFromWitnessMap, - ); - } - - public async simulateProofReset( - inputs: PrivateKernelResetCircuitPrivateInputs, - ): Promise> { - const variantInputs = inputs.trimToSizes(); - const artifactName = getPrivateKernelResetArtifactName(inputs.dimensions); - return await this.simulate( - variantInputs, - artifactName, - variantInputs => convertPrivateKernelResetInputsToWitnessMap(variantInputs, artifactName), - output => convertPrivateKernelResetOutputsFromWitnessMap(output, artifactName), - ); - } - - public async simulateProofTail( - inputs: PrivateKernelTailCircuitPrivateInputs, - ): Promise> { - if (!inputs.isForPublic()) { - return await this.simulate( - inputs, - 'PrivateKernelTailArtifact', - convertPrivateKernelTailInputsToWitnessMap, - convertPrivateKernelTailOutputsFromWitnessMap, - ); - } - return await this.simulate( - inputs, - 'PrivateKernelTailToPublicArtifact', - convertPrivateKernelTailToPublicInputsToWitnessMap, - convertPrivateKernelTailForPublicOutputsFromWitnessMap, - ); - } - - private async simulate< - I extends { toBuffer: () => Buffer }, - O extends PrivateKernelCircuitPublicInputs | PrivateKernelTailCircuitPublicInputs, - >( - inputs: I, - circuitType: ClientProtocolArtifact, - convertInputs: (inputs: I) => WitnessMap, - convertOutputs: (outputs: WitnessMap) => O, - ): Promise> { - this.log.debug(`Generating witness for ${circuitType}`); - const compiledCircuit: NoirCompiledCircuit = ClientCircuitArtifacts[circuitType]; - - const witnessMap = convertInputs(inputs); - const timer = new Timer(); - const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit); - const output = convertOutputs(outputWitness); - - this.log.debug(`Generated witness for ${circuitType}`, { - eventName: 'circuit-witness-generation', - circuitName: circuitType, - duration: timer.ms(), - inputSize: inputs.toBuffer().length, - outputSize: output.toBuffer().length, - }); - - const verificationKey = ClientCircuitVks[circuitType].keyAsFields; - const bytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); - - const kernelOutput: PrivateKernelSimulateOutput = { - publicInputs: output, - verificationKey, - outputWitness, - bytecode, - }; - return kernelOutput; - } - - async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise { - const timer = new Timer(); - this.log.info(`Generating ClientIVC proof...`); - const backend = new AztecClientBackend( - acirs.map(acir => ungzip(acir)), - { threads: this.threads }, - ); - - const [proof, vk] = await backend.prove(witnessStack.map(witnessMap => ungzip(serializeWitness(witnessMap)))); - await backend.destroy(); - this.log.info(`Generated ClientIVC proof`, { - eventName: 'client-ivc-proof-generation', - duration: timer.ms(), - proofSize: proof.length, - vkSize: vk.length, - }); - return new ClientIvcProof(Buffer.from(proof), Buffer.from(vk)); - } - - computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise { - return Promise.resolve(0); - } -} diff --git a/yarn-project/bb-prover/src/wasm/lazy.ts b/yarn-project/bb-prover/src/wasm/lazy.ts new file mode 100644 index 00000000000..16fc1c04c90 --- /dev/null +++ b/yarn-project/bb-prover/src/wasm/lazy.ts @@ -0,0 +1,10 @@ +import { createLogger } from '@aztec/foundation/log'; +import { LazyArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/lazy'; + +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); + } +} diff --git a/yarn-project/bootstrap.sh b/yarn-project/bootstrap.sh index 5fa2254cf34..376d79102cf 100755 --- a/yarn-project/bootstrap.sh +++ b/yarn-project/bootstrap.sh @@ -47,7 +47,7 @@ function build { end-to-end/src/web/{main.js,main.js.LICENSE.txt} \ ivc-integration/src/types/ \ noir-contracts.js/{codegenCache.json,src/} \ - noir-protocol-circuits-types/src/{private_kernel_reset_data.ts,types/} \ + noir-protocol-circuits-types/src/{private_kernel_reset_data.ts,private_kernel_reset_vks.ts,private_kernel_reset_types.ts,client_artifacts_helper.ts,types/} \ pxe/src/config/package_info.ts \ protocol-contracts/src/protocol_contract_data.ts echo diff --git a/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts b/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts index f1ca3b8c0c6..d92e373d09d 100644 --- a/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts +++ b/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts @@ -57,7 +57,17 @@ export interface PrivateKernelProver { * @param privateKernelInputsInit - The private data structure for the initial iteration. * @returns A Promise resolving to a ProofOutput object containing public inputs and the kernel proof. */ - simulateProofInit( + generateInitOutput( + privateKernelInputsInit: PrivateKernelInitCircuitPrivateInputs, + ): Promise>; + + /** + * Executes the first kernel iteration without generating a proof. + * + * @param privateKernelInputsInit - The private data structure for the initial iteration. + * @returns A Promise resolving to a ProofOutput object containing public inputs and an empty kernel proof. + */ + simulateInit( privateKernelInputsInit: PrivateKernelInitCircuitPrivateInputs, ): Promise>; @@ -67,7 +77,17 @@ export interface PrivateKernelProver { * @param privateKernelInputsInner - The private input data structure for the inner iteration. * @returns A Promise resolving to a ProofOutput object containing public inputs and the kernel proof. */ - simulateProofInner( + generateInnerOutput( + privateKernelInputsInner: PrivateKernelInnerCircuitPrivateInputs, + ): Promise>; + + /** + * Executes an inner kernel iteration without generating a proof. + * + * @param privateKernelInputsInit - The private data structure for the initial iteration. + * @returns A Promise resolving to a ProofOutput object containing public inputs and an empty kernel proof. + */ + simulateInner( privateKernelInputsInner: PrivateKernelInnerCircuitPrivateInputs, ): Promise>; @@ -77,7 +97,17 @@ export interface PrivateKernelProver { * @param privateKernelInputsTail - The private input data structure for the reset circuit. * @returns A Promise resolving to a ProofOutput object containing public inputs and the kernel proof. */ - simulateProofReset( + generateResetOutput( + privateKernelInputsReset: PrivateKernelResetCircuitPrivateInputs, + ): Promise>; + + /** + * Executes the reset circuit without generating a proof + * + * @param privateKernelInputsTail - The private input data structure for the reset circuit. + * @returns A Promise resolving to a ProofOutput object containing public inputs an empty kernel proof. + */ + simulateReset( privateKernelInputsReset: PrivateKernelResetCircuitPrivateInputs, ): Promise>; @@ -87,7 +117,17 @@ export interface PrivateKernelProver { * @param privateKernelInputsTail - The private input data structure for the final ordering iteration. * @returns A Promise resolving to a ProofOutput object containing public inputs and the kernel proof. */ - simulateProofTail( + generateTailOutput( + privateKernelInputsTail: PrivateKernelTailCircuitPrivateInputs, + ): Promise>; + + /** + * Executes the final ordering iteration circuit. + * + * @param privateKernelInputsTail - The private input data structure for the final ordering iteration. + * @returns A Promise resolving to a ProofOutput object containing public inputs an empty kernel proof. + */ + simulateTail( privateKernelInputsTail: PrivateKernelTailCircuitPrivateInputs, ): Promise>; diff --git a/yarn-project/cli/src/utils/aztec.ts b/yarn-project/cli/src/utils/aztec.ts index aa7388ab478..d409f009eca 100644 --- a/yarn-project/cli/src/utils/aztec.ts +++ b/yarn-project/cli/src/utils/aztec.ts @@ -62,7 +62,7 @@ export async function deployAztecContracts( : privateKeyToAccount(`${privateKey.startsWith('0x') ? '' : '0x'}${privateKey}` as `0x${string}`); const chain = createEthereumChain(rpcUrl, chainId); - const { getVKTreeRoot } = await import('@aztec/noir-protocol-circuits-types'); + const { getVKTreeRoot } = await import('@aztec/noir-protocol-circuits-types/vks'); return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger, { l2FeeJuiceAddress: ProtocolContractAddress.FeeJuice, diff --git a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts index 17ca49f88bc..e8a44267b74 100644 --- a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts @@ -27,7 +27,7 @@ import { sha256, sha256ToField } from '@aztec/foundation/crypto'; import { openTmpStore } from '@aztec/kv-store/lmdb'; import { OutboxAbi, RollupAbi } from '@aztec/l1-artifacts'; import { SHA256Trunc, StandardTree } from '@aztec/merkle-tree'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { LightweightBlockBuilder } from '@aztec/prover-client/block-builder'; import { L1Publisher } from '@aztec/sequencer-client'; 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 a56390821d8..03b54a2ff26 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( - 'Circuit execution failed: Users cannot set msg_sender in first call', + 'Assertion failed', ); }); diff --git a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts index d27c217dea9..11a67f90b41 100644 --- a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts @@ -18,7 +18,7 @@ import { BBCircuitVerifier, type ClientProtocolCircuitVerifier, TestCircuitVerifier, - type UltraKeccakHonkProtocolArtifact, + type UltraKeccakHonkServerProtocolArtifact, } from '@aztec/bb-prover'; import { createBlobSinkClient } from '@aztec/blob-sink/client'; import { type BlobSinkServer } from '@aztec/blob-sink/server'; @@ -394,7 +394,7 @@ export class FullProverTest { // REFACTOR: Extract this method to a common package. We need a package that deals with L1 // but also has a reference to L1 artifacts and bb-prover. - const setupVerifier = async (artifact: UltraKeccakHonkProtocolArtifact) => { + const setupVerifier = async (artifact: UltraKeccakHonkServerProtocolArtifact) => { const contract = await verifier.generateSolidityContract(artifact, 'UltraHonkVerifier.sol'); const { abi, bytecode } = compileContract('UltraHonkVerifier.sol', 'HonkVerifier', contract, solc); const { address: verifierAddress } = await deployL1Contract(walletClient, publicClient, abi, bytecode); diff --git a/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts b/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts index 8c14ea9ded5..0a90dbcc2e1 100644 --- a/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts +++ b/yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts @@ -1,6 +1,6 @@ import { type Logger, deployL1Contracts } from '@aztec/aztec.js'; import { type DeployL1ContractsArgs, type L1ContractsConfig } from '@aztec/ethereum'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { type HDAccount, type PrivateKeyAccount } from 'viem'; diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index a6f86d27355..14aaf2f7d91 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -42,7 +42,7 @@ import { randomBytes } from '@aztec/foundation/crypto'; import { retryUntil } from '@aztec/foundation/retry'; import { TestDateProvider } from '@aztec/foundation/timer'; import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { type ProverNode, type ProverNodeConfig, createProverNode } from '@aztec/prover-node'; import { type PXEService, type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; diff --git a/yarn-project/noir-protocol-circuits-types/package.json b/yarn-project/noir-protocol-circuits-types/package.json index 720ff230865..1193df56f13 100644 --- a/yarn-project/noir-protocol-circuits-types/package.json +++ b/yarn-project/noir-protocol-circuits-types/package.json @@ -3,9 +3,12 @@ "version": "0.1.0", "type": "module", "exports": { - ".": "./dest/index.js", - "./client": "./dest/client.js", - "./types": "./dest/types/index.js" + "./server": "./dest/entrypoint/server.js", + "./client": "./dest/entrypoint/client/common.js", + "./client/bundle": "./dest/entrypoint/client/bundle.js", + "./client/lazy": "./dest/entrypoint/client/lazy.js", + "./types": "./dest/types/index.js", + "./vks": "./dest/entrypoint/vks.js" }, "inherits": [ "../package.common.json", @@ -18,12 +21,13 @@ "formatting": "run -T prettier --check ./src && run -T eslint ./src", "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src", "formatting:fix:types": "NODE_OPTIONS='--max-old-space-size=8096' run -T eslint --fix ./src/types && run -T prettier -w ./src/types", - "generate": "yarn generate:copy-artifacts && yarn generate:vk-hashes && yarn generate:noir-circuits && yarn generate:reset-data", + "generate": "yarn generate:copy-artifacts && yarn generate:vk-hashes && yarn generate:noir-circuits && yarn generate:reset-data && yarn generate:client-artifacts-helper", "generate:copy-artifacts": "mkdir -p ./artifacts && cp -r ../../noir-projects/noir-protocol-circuits/target/* ./artifacts && node --no-warnings --loader ts-node/esm src/scripts/generate_declaration_files.ts ", "generate:cleanup-artifacts": "node --no-warnings --loader ts-node/esm src/scripts/cleanup_artifacts.ts", "generate:vk-hashes": "node --no-warnings --loader ts-node/esm src/scripts/generate_vk_hashes.ts", "generate:noir-circuits": "node --no-warnings --loader ts-node/esm src/scripts/generate_ts_from_abi.ts && run -T prettier -w ./src/types", - "generate:reset-data": "node --no-warnings --loader ts-node/esm src/scripts/generate_private_kernel_reset_data.ts && run -T prettier -w src/private_kernel_reset_data.ts", + "generate:reset-data": "node --no-warnings --loader ts-node/esm src/scripts/generate_private_kernel_reset_data.ts && run -T prettier -w src/private_kernel_reset_*.ts", + "generate:client-artifacts-helper": "node --no-warnings --loader ts-node/esm src/scripts/generate_client_artifacts_helper.ts && run -T prettier -w src/client_artifacts_helper.ts", "test": "HARDWARE_CONCURRENCY=${HARDWARE_CONCURRENCY:-16} RAYON_NUM_THREADS=${RAYON_NUM_THREADS:-4} NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}", "codegen": "yarn noir-codegen", "build:dev": "tsc -b --watch" @@ -67,7 +71,6 @@ "@aztec/types": "workspace:^", "@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js", "@noir-lang/noir_codegen": "portal:../../noir/packages/noir_codegen", - "@noir-lang/noir_js": "file:../../noir/packages/noir_js", "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi", "@noir-lang/types": "portal:../../noir/packages/types", "change-case": "^5.4.4", diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts deleted file mode 100644 index 256ac0405dd..00000000000 --- a/yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { type NoirCompiledCircuit } from '@aztec/types/noir'; - -import PrivateKernelInitJson from '../../artifacts/private_kernel_init.json' assert { type: 'json' }; -import PrivateKernelInitSimulatedJson from '../../artifacts/private_kernel_init_simulated.json' assert { type: 'json' }; -import PrivateKernelInnerJson from '../../artifacts/private_kernel_inner.json' assert { type: 'json' }; -import PrivateKernelInnerSimulatedJson from '../../artifacts/private_kernel_inner_simulated.json' assert { type: 'json' }; -import PrivateKernelTailJson from '../../artifacts/private_kernel_tail.json' assert { type: 'json' }; -import PrivateKernelTailSimulatedJson from '../../artifacts/private_kernel_tail_simulated.json' assert { type: 'json' }; -import PrivateKernelTailToPublicJson from '../../artifacts/private_kernel_tail_to_public.json' assert { type: 'json' }; -import PrivateKernelTailToPublicSimulatedJson from '../../artifacts/private_kernel_tail_to_public_simulated.json' assert { type: 'json' }; -import { - PrivateKernelResetArtifacts, - PrivateKernelResetSimulatedArtifacts, - type PrivateResetArtifact, -} from '../private_kernel_reset_data.js'; - -export type ClientProtocolArtifact = - | 'PrivateKernelInitArtifact' - | 'PrivateKernelInnerArtifact' - | 'PrivateKernelTailArtifact' - | 'PrivateKernelTailToPublicArtifact' - | PrivateResetArtifact; - -export const ClientCircuitArtifacts: Record = { - PrivateKernelInitArtifact: PrivateKernelInitJson as NoirCompiledCircuit, - PrivateKernelInnerArtifact: PrivateKernelInnerJson as NoirCompiledCircuit, - PrivateKernelTailArtifact: PrivateKernelTailJson as NoirCompiledCircuit, - PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicJson as NoirCompiledCircuit, - ...PrivateKernelResetArtifacts, -}; - -export const SimulatedClientCircuitArtifacts: Record = { - PrivateKernelInitArtifact: PrivateKernelInitSimulatedJson as NoirCompiledCircuit, - PrivateKernelInnerArtifact: PrivateKernelInnerSimulatedJson as NoirCompiledCircuit, - PrivateKernelTailArtifact: PrivateKernelTailSimulatedJson as NoirCompiledCircuit, - PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicSimulatedJson as NoirCompiledCircuit, - ...PrivateKernelResetSimulatedArtifacts, -}; diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/client/bundle.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/client/bundle.ts new file mode 100644 index 00000000000..46818227243 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/client/bundle.ts @@ -0,0 +1,38 @@ +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import PrivateKernelInitJson from '../../../artifacts/private_kernel_init.json' assert { type: 'json' }; +import PrivateKernelInitSimulatedJson from '../../../artifacts/private_kernel_init_simulated.json' assert { type: 'json' }; +import PrivateKernelInnerJson from '../../../artifacts/private_kernel_inner.json' assert { type: 'json' }; +import PrivateKernelInnerSimulatedJson from '../../../artifacts/private_kernel_inner_simulated.json' assert { type: 'json' }; +import PrivateKernelTailJson from '../../../artifacts/private_kernel_tail.json' assert { type: 'json' }; +import PrivateKernelTailSimulatedJson from '../../../artifacts/private_kernel_tail_simulated.json' assert { type: 'json' }; +import PrivateKernelTailToPublicJson from '../../../artifacts/private_kernel_tail_to_public.json' assert { type: 'json' }; +import PrivateKernelTailToPublicSimulatedJson from '../../../artifacts/private_kernel_tail_to_public_simulated.json' assert { type: 'json' }; +import { PrivateKernelResetArtifacts, PrivateKernelResetSimulatedArtifacts } from '../../private_kernel_reset_data.js'; +import { type ArtifactProvider, type ClientProtocolArtifact } from '../types.js'; + +export const ClientCircuitArtifacts: Record = { + PrivateKernelInitArtifact: PrivateKernelInitJson as NoirCompiledCircuit, + PrivateKernelInnerArtifact: PrivateKernelInnerJson as NoirCompiledCircuit, + PrivateKernelTailArtifact: PrivateKernelTailJson as NoirCompiledCircuit, + PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicJson as NoirCompiledCircuit, + ...PrivateKernelResetArtifacts, +}; + +export const SimulatedClientCircuitArtifacts: Record = { + PrivateKernelInitArtifact: PrivateKernelInitSimulatedJson as NoirCompiledCircuit, + PrivateKernelInnerArtifact: PrivateKernelInnerSimulatedJson as NoirCompiledCircuit, + PrivateKernelTailArtifact: PrivateKernelTailSimulatedJson as NoirCompiledCircuit, + PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicSimulatedJson as NoirCompiledCircuit, + ...PrivateKernelResetSimulatedArtifacts, +}; + +export class BundleArtifactProvider implements ArtifactProvider { + getClientCircuitArtifactByName(artifact: ClientProtocolArtifact): Promise { + return Promise.resolve(ClientCircuitArtifacts[artifact]); + } + + getSimulatedClientCircuitArtifactByName(artifact: ClientProtocolArtifact): Promise { + return Promise.resolve(SimulatedClientCircuitArtifacts[artifact]); + } +} diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/client/lazy.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/client/lazy.ts new file mode 100644 index 00000000000..55f57a37029 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/client/lazy.ts @@ -0,0 +1,14 @@ +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import { ClientCircuitArtifactNames, getClientCircuitArtifact } from '../../client_artifacts_helper.js'; +import { type ArtifactProvider, type ClientProtocolArtifact } from '../types.js'; + +export class LazyArtifactProvider implements ArtifactProvider { + getClientCircuitArtifactByName(artifact: ClientProtocolArtifact): Promise { + return getClientCircuitArtifact(ClientCircuitArtifactNames[artifact], false); + } + + getSimulatedClientCircuitArtifactByName(artifact: ClientProtocolArtifact): Promise { + return getClientCircuitArtifact(ClientCircuitArtifactNames[artifact], true); + } +} diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts deleted file mode 100644 index acf23c28593..00000000000 --- a/yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { type NoirCompiledCircuit } from '@aztec/types/noir'; - -import { ClientCircuitArtifacts, type ClientProtocolArtifact } from './client.js'; -import { ServerCircuitArtifacts, type ServerProtocolArtifact } from './server.js'; - -export * from './client.js'; -export * from './server.js'; - -export type ProtocolArtifact = ServerProtocolArtifact | ClientProtocolArtifact; - -export const ProtocolCircuitArtifacts: Record = { - ...ClientCircuitArtifacts, - ...ServerCircuitArtifacts, -}; diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts index 4952f994f19..b8dc3f05d47 100644 --- a/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts @@ -16,20 +16,7 @@ import EmptyBlockRootRollupJson from '../../artifacts/rollup_block_root_empty.js import BlockRootRollupSimulatedJson from '../../artifacts/rollup_block_root_simulated.json' assert { type: 'json' }; import MergeRollupJson from '../../artifacts/rollup_merge.json' assert { type: 'json' }; import RootRollupJson from '../../artifacts/rollup_root.json' assert { type: 'json' }; - -// These are all circuits that should generate proofs with the `recursive` flag. -export type ServerProtocolArtifact = - | 'EmptyNestedArtifact' - | 'PrivateKernelEmptyArtifact' - | 'BaseParityArtifact' - | 'RootParityArtifact' - | 'PrivateBaseRollupArtifact' - | 'PublicBaseRollupArtifact' - | 'MergeRollupArtifact' - | 'BlockRootRollupArtifact' - | 'EmptyBlockRootRollupArtifact' - | 'BlockMergeRollupArtifact' - | 'RootRollupArtifact'; +import { type ServerProtocolArtifact } from './types.js'; export const ServerCircuitArtifacts: Record = { EmptyNestedArtifact: EmptyNestedJson as NoirCompiledCircuit, diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/types.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/types.ts new file mode 100644 index 00000000000..18de3b7d12e --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/types.ts @@ -0,0 +1,31 @@ +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import { type PrivateResetArtifact } from '../private_kernel_reset_types.js'; + +export type ClientProtocolArtifact = + | 'PrivateKernelInitArtifact' + | 'PrivateKernelInnerArtifact' + | 'PrivateKernelTailArtifact' + | 'PrivateKernelTailToPublicArtifact' + | PrivateResetArtifact; + +// These are all circuits that should generate proofs with the `recursive` flag. +export type ServerProtocolArtifact = + | 'EmptyNestedArtifact' + | 'PrivateKernelEmptyArtifact' + | 'BaseParityArtifact' + | 'RootParityArtifact' + | 'PrivateBaseRollupArtifact' + | 'PublicBaseRollupArtifact' + | 'MergeRollupArtifact' + | 'BlockRootRollupArtifact' + | 'EmptyBlockRootRollupArtifact' + | 'BlockMergeRollupArtifact' + | 'RootRollupArtifact'; + +export type ProtocolArtifact = ServerProtocolArtifact | ClientProtocolArtifact; + +export interface ArtifactProvider { + getClientCircuitArtifactByName(artifact: ClientProtocolArtifact): Promise; + getSimulatedClientCircuitArtifactByName(artifact: ClientProtocolArtifact): Promise; +} diff --git a/yarn-project/noir-protocol-circuits-types/src/client.ts b/yarn-project/noir-protocol-circuits-types/src/client.ts deleted file mode 100644 index 597e3be73ec..00000000000 --- a/yarn-project/noir-protocol-circuits-types/src/client.ts +++ /dev/null @@ -1,24 +0,0 @@ -export { - convertPrivateKernelInitInputsToWitnessMap, - convertPrivateKernelInitOutputsFromWitnessMap, - convertPrivateKernelInnerInputsToWitnessMap, - convertPrivateKernelInnerOutputsFromWitnessMap, - convertPrivateKernelResetInputsToWitnessMap, - convertPrivateKernelResetOutputsFromWitnessMap, - convertPrivateKernelTailForPublicOutputsFromWitnessMap, - convertPrivateKernelTailInputsToWitnessMap, - convertPrivateKernelTailOutputsFromWitnessMap, - convertPrivateKernelTailToPublicInputsToWitnessMap, - executeInit, - executeInner, - executeReset, - executeTail, - executeTailForPublic, -} from './execution/client.js'; - -export { ClientCircuitArtifacts, type ClientProtocolArtifact } from './artifacts/client.js'; - -export { getPrivateKernelResetArtifactName } from './utils/private_kernel_reset.js'; -export { maxPrivateKernelResetDimensions, privateKernelResetDimensionsConfig } from './private_kernel_reset_data.js'; -export { foreignCallHandler } from './utils/client/foreign_call_handler.js'; -export { ClientCircuitVks, getVKIndex, getVKTreeRoot, getVKSiblingPath } from './vks.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/bundle.ts b/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/bundle.ts new file mode 100644 index 00000000000..23a8b57a85f --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/bundle.ts @@ -0,0 +1,5 @@ +export { + BundleArtifactProvider, + ClientCircuitArtifacts, + SimulatedClientCircuitArtifacts, +} from '../../artifacts/client/bundle.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/common.ts b/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/common.ts new file mode 100644 index 00000000000..389870ae9de --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/common.ts @@ -0,0 +1,21 @@ +export { + convertPrivateKernelInitInputsToWitnessMapWithAbi, + convertPrivateKernelInitOutputsFromWitnessMapWithAbi, + convertPrivateKernelInnerInputsToWitnessMapWithAbi, + convertPrivateKernelInnerOutputsFromWitnessMapWithAbi, + convertPrivateKernelResetInputsToWitnessMapWithAbi, + convertPrivateKernelResetOutputsFromWitnessMapWithAbi, + convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi, + convertPrivateKernelTailInputsToWitnessMapWithAbi, + convertPrivateKernelTailOutputsFromWitnessMapWithAbi, + convertPrivateKernelTailToPublicInputsToWitnessMapWithAbi, +} from '../../execution/client.js'; + +export { getPrivateKernelResetArtifactName } from '../../utils/private_kernel_reset.js'; +export { + maxPrivateKernelResetDimensions, + privateKernelResetDimensionsConfig, +} from '../../private_kernel_reset_types.js'; +export { foreignCallHandler } from '../../utils/client/foreign_call_handler.js'; + +export { type ClientProtocolArtifact } from '../../artifacts/types.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/lazy.ts b/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/lazy.ts new file mode 100644 index 00000000000..0f573c2317d --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/entrypoint/client/lazy.ts @@ -0,0 +1 @@ +export { LazyArtifactProvider } from '../../artifacts/client/lazy.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/entrypoint/server.ts b/yarn-project/noir-protocol-circuits-types/src/entrypoint/server.ts new file mode 100644 index 00000000000..b8c031654a2 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/entrypoint/server.ts @@ -0,0 +1,6 @@ +export * from '../artifacts/server.js'; +export * from '../execution/server.js'; + +export { type ServerProtocolArtifact } from '../artifacts/types.js'; + +export { foreignCallHandler } from '../utils/server/foreign_call_handler.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/vks.ts b/yarn-project/noir-protocol-circuits-types/src/entrypoint/vks.ts similarity index 70% rename from yarn-project/noir-protocol-circuits-types/src/vks.ts rename to yarn-project/noir-protocol-circuits-types/src/entrypoint/vks.ts index dbf31a3a6e3..1a155376366 100644 --- a/yarn-project/noir-protocol-circuits-types/src/vks.ts +++ b/yarn-project/noir-protocol-circuits-types/src/entrypoint/vks.ts @@ -25,25 +25,25 @@ import { import { poseidon2Hash } from '@aztec/foundation/crypto'; import { assertLength } from '@aztec/foundation/serialize'; -import EmptyNestedVkJson from '../artifacts/keys/empty_nested.vk.data.json' assert { type: 'json' }; -import BaseParityVkJson from '../artifacts/keys/parity_base.vk.data.json' assert { type: 'json' }; -import RootParityVkJson from '../artifacts/keys/parity_root.vk.data.json' assert { type: 'json' }; -import PrivateKernelEmptyVkJson from '../artifacts/keys/private_kernel_empty.vk.data.json' assert { type: 'json' }; -import PrivateKernelInitVkJson from '../artifacts/keys/private_kernel_init.vk.data.json' assert { type: 'json' }; -import PrivateKernelInnerVkJson from '../artifacts/keys/private_kernel_inner.vk.data.json' assert { type: 'json' }; -import PrivateKernelTailVkJson from '../artifacts/keys/private_kernel_tail.vk.data.json' assert { type: 'json' }; -import PrivateKernelTailToPublicVkJson from '../artifacts/keys/private_kernel_tail_to_public.vk.data.json' assert { type: 'json' }; -import PrivateBaseRollupVkJson from '../artifacts/keys/rollup_base_private.vk.data.json' assert { type: 'json' }; -import PublicBaseRollupVkJson from '../artifacts/keys/rollup_base_public.vk.data.json' assert { type: 'json' }; -import BlockMergeRollupVkJson from '../artifacts/keys/rollup_block_merge.vk.data.json' assert { type: 'json' }; -import BlockRootRollupVkJson from '../artifacts/keys/rollup_block_root.vk.data.json' assert { type: 'json' }; -import EmptyBlockRootRollupVkJson from '../artifacts/keys/rollup_block_root_empty.vk.data.json' assert { type: 'json' }; -import MergeRollupVkJson from '../artifacts/keys/rollup_merge.vk.data.json' assert { type: 'json' }; -import RootRollupVkJson from '../artifacts/keys/rollup_root.vk.data.json' assert { type: 'json' }; -import TubeVkJson from '../artifacts/keys/tube.vk.data.json' assert { type: 'json' }; -import { type ClientProtocolArtifact, type ProtocolArtifact, type ServerProtocolArtifact } from './artifacts/index.js'; -import { PrivateKernelResetVkIndexes, PrivateKernelResetVks } from './private_kernel_reset_data.js'; -import { keyJsonToVKData } from './utils/vk_json.js'; +import EmptyNestedVkJson from '../../artifacts/keys/empty_nested.vk.data.json' assert { type: 'json' }; +import BaseParityVkJson from '../../artifacts/keys/parity_base.vk.data.json' assert { type: 'json' }; +import RootParityVkJson from '../../artifacts/keys/parity_root.vk.data.json' assert { type: 'json' }; +import PrivateKernelEmptyVkJson from '../../artifacts/keys/private_kernel_empty.vk.data.json' assert { type: 'json' }; +import PrivateKernelInitVkJson from '../../artifacts/keys/private_kernel_init.vk.data.json' assert { type: 'json' }; +import PrivateKernelInnerVkJson from '../../artifacts/keys/private_kernel_inner.vk.data.json' assert { type: 'json' }; +import PrivateKernelTailVkJson from '../../artifacts/keys/private_kernel_tail.vk.data.json' assert { type: 'json' }; +import PrivateKernelTailToPublicVkJson from '../../artifacts/keys/private_kernel_tail_to_public.vk.data.json' assert { type: 'json' }; +import PrivateBaseRollupVkJson from '../../artifacts/keys/rollup_base_private.vk.data.json' assert { type: 'json' }; +import PublicBaseRollupVkJson from '../../artifacts/keys/rollup_base_public.vk.data.json' assert { type: 'json' }; +import BlockMergeRollupVkJson from '../../artifacts/keys/rollup_block_merge.vk.data.json' assert { type: 'json' }; +import BlockRootRollupVkJson from '../../artifacts/keys/rollup_block_root.vk.data.json' assert { type: 'json' }; +import EmptyBlockRootRollupVkJson from '../../artifacts/keys/rollup_block_root_empty.vk.data.json' assert { type: 'json' }; +import MergeRollupVkJson from '../../artifacts/keys/rollup_merge.vk.data.json' assert { type: 'json' }; +import RootRollupVkJson from '../../artifacts/keys/rollup_root.vk.data.json' assert { type: 'json' }; +import TubeVkJson from '../../artifacts/keys/tube.vk.data.json' assert { type: 'json' }; +import { type ClientProtocolArtifact, type ProtocolArtifact, type ServerProtocolArtifact } from '../artifacts/types.js'; +import { PrivateKernelResetVkIndexes, PrivateKernelResetVks } from '../private_kernel_reset_vks.js'; +import { keyJsonToVKData } from '../utils/vk_json.js'; // TODO Include this in the normal maps when the tube is implemented in noir export const TubeVk = keyJsonToVKData(TubeVkJson); diff --git a/yarn-project/noir-protocol-circuits-types/src/execution/client.ts b/yarn-project/noir-protocol-circuits-types/src/execution/client.ts index 35dd960f42b..faaf222c7dd 100644 --- a/yarn-project/noir-protocol-circuits-types/src/execution/client.ts +++ b/yarn-project/noir-protocol-circuits-types/src/execution/client.ts @@ -2,18 +2,16 @@ import { type PrivateKernelCircuitPublicInputs, type PrivateKernelInitCircuitPrivateInputs, type PrivateKernelInnerCircuitPrivateInputs, - type PrivateKernelResetCircuitPrivateInputs, type PrivateKernelResetCircuitPrivateInputsVariants, - type PrivateKernelResetDimensions, type PrivateKernelTailCircuitPrivateInputs, type PrivateKernelTailCircuitPublicInputs, } from '@aztec/circuits.js'; import { pushTestData } from '@aztec/foundation/testing'; -import { type CompiledCircuit, type InputMap, Noir, type WitnessMap } from '@noir-lang/noir_js'; -import { type Abi, abiDecode, abiEncode } from '@noir-lang/noirc_abi'; +import { type WitnessMap } from '@noir-lang/acvm_js'; +import { abiDecode, abiEncode } from '@noir-lang/noirc_abi'; +import { type Abi, type InputMap } from '@noir-lang/types'; -import { ClientCircuitArtifacts, SimulatedClientCircuitArtifacts } from '../artifacts/client.js'; import { mapPrivateCallDataToNoir, mapPrivateCircuitPublicInputsToNoir, @@ -26,192 +24,27 @@ import { mapTxRequestToNoir, } from '../conversion/client.js'; import { mapFieldToNoir } from '../conversion/common.js'; -import { type PrivateResetArtifact } from '../private_kernel_reset_data.js'; import { type PrivateKernelInitReturnType, type PrivateKernelInnerReturnType, type PrivateKernelResetReturnType, type PrivateKernelTailReturnType, type PrivateKernelTailToPublicReturnType, - PrivateKernelInit as executePrivateKernelInitWithACVM, - PrivateKernelInner as executePrivateKernelInnerWithACVM, - PrivateKernelTailToPublic as executePrivateKernelTailToPublicWithACVM, - PrivateKernelTail as executePrivateKernelTailWithACVM, } from '../types/index.js'; -import { foreignCallHandler } from '../utils/client/foreign_call_handler.js'; import { type DecodedInputs } from '../utils/decoded_inputs.js'; -import { getPrivateKernelResetArtifactName } from '../utils/private_kernel_reset.js'; /* eslint-disable camelcase */ -/** - * Executes the init private kernel. - * @param privateKernelInitCircuitPrivateInputs - The private inputs to the initial private kernel. - * @returns The public inputs. - */ -export async function executeInit( - privateKernelInitCircuitPrivateInputs: PrivateKernelInitCircuitPrivateInputs, -): Promise { - const inputs = { - tx_request: mapTxRequestToNoir(privateKernelInitCircuitPrivateInputs.txRequest), - vk_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.vkTreeRoot), - protocol_contract_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), - private_call: mapPrivateCallDataToNoir(privateKernelInitCircuitPrivateInputs.privateCall), - is_private_only: privateKernelInitCircuitPrivateInputs.isPrivateOnly, - app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInitCircuitPrivateInputs.privateCall.publicInputs, - ), - }; - - pushTestData('private-kernel-init', inputs); - - const returnType = await executePrivateKernelInitWithACVM( - inputs.tx_request, - inputs.vk_tree_root, - inputs.protocol_contract_tree_root, - inputs.private_call, - inputs.is_private_only, - inputs.app_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelInitArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Executes the inner private kernel. - * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the inner private kernel. - * @returns The public inputs. - */ -export async function executeInner( - privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, -): Promise { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelInnerCircuitPrivateInputs.previousKernel.publicInputs, - ), - private_call: mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), - app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs, - ), - }; - - pushTestData('private-kernel-inner', inputs); - - const returnType = await executePrivateKernelInnerWithACVM( - inputs.previous_kernel, - inputs.previous_kernel_public_inputs, - inputs.private_call, - inputs.app_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelInnerArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Executes the inner private kernel. - * @param privateKernelResetCircuitPrivateInputs - The private inputs to the reset private kernel. - * @returns The public inputs. - */ -export async function executeReset< - NH_RR_PENDING extends number, - NH_RR_SETTLED extends number, - NLL_RR_PENDING extends number, - NLL_RR_SETTLED extends number, - KEY_VALIDATION_REQUESTS extends number, - NUM_TRANSIENT_DATA_HINTS extends number, ->( - privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputsVariants< - NH_RR_PENDING, - NH_RR_SETTLED, - NLL_RR_PENDING, - NLL_RR_SETTLED, - KEY_VALIDATION_REQUESTS, - NUM_TRANSIENT_DATA_HINTS - >, - dimensions: PrivateKernelResetDimensions, - // TODO: This input is a hack so we can write full reset inputs to a Prover.toml. Ideally we remove it in favour of adding a test that runs a full reset. - untrimmedPrivateKernelResetCircuitPrivateInputs?: PrivateKernelResetCircuitPrivateInputs, -): Promise { - const artifact = SimulatedClientCircuitArtifacts[getPrivateKernelResetArtifactName(dimensions)]; - const program = new Noir(artifact as CompiledCircuit); - if (untrimmedPrivateKernelResetCircuitPrivateInputs) { - updateResetCircuitSampleInputs(untrimmedPrivateKernelResetCircuitPrivateInputs); - } - const args: InputMap = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, - ), - hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), - }; - const { returnValue } = await program.execute(args, foreignCallHandler); - return mapPrivateKernelCircuitPublicInputsFromNoir(returnValue as any); -} - -/** - * Executes the tail private kernel. - * @param privateKernelCircuitPrivateInputs - The private inputs to the tail private kernel. - * @returns The public inputs. - */ -export async function executeTail( - privateInputs: PrivateKernelTailCircuitPrivateInputs, -): Promise { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir(privateInputs.previousKernel.publicInputs), - }; - - pushTestData('private-kernel-tail', inputs); - - const returnType = await executePrivateKernelTailWithACVM( - inputs.previous_kernel, - inputs.previous_kernel_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelTailArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir(returnType); -} - -/** - * Executes the tail private kernel. - * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the tail private kernel. - * @returns The public inputs. - */ -export async function executeTailForPublic( - privateInputs: PrivateKernelTailCircuitPrivateInputs, -): Promise { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir(privateInputs.previousKernel.publicInputs), - }; - - pushTestData('private-kernel-tail-to-public', inputs); - - const returnType = await executePrivateKernelTailToPublicWithACVM( - inputs.previous_kernel, - inputs.previous_kernel_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelTailToPublicArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir(returnType); -} - /** * Converts the inputs of the private kernel init circuit into a witness map * @param inputs - The private kernel inputs. * @returns The witness map */ -export function convertPrivateKernelInitInputsToWitnessMap( +export function convertPrivateKernelInitInputsToWitnessMapWithAbi( privateKernelInitCircuitPrivateInputs: PrivateKernelInitCircuitPrivateInputs, + privateKernelInitAbi: Abi, ): WitnessMap { - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelInitArtifact.abi, { + const mapped = { tx_request: mapTxRequestToNoir(privateKernelInitCircuitPrivateInputs.txRequest), vk_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.vkTreeRoot), protocol_contract_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), @@ -220,7 +53,9 @@ export function convertPrivateKernelInitInputsToWitnessMap( app_public_inputs: mapPrivateCircuitPublicInputsToNoir( privateKernelInitCircuitPrivateInputs.privateCall.publicInputs, ), - }); + }; + pushTestData('private-kernel-init', mapped); + const initialWitnessMap = abiEncode(privateKernelInitAbi, mapped); return initialWitnessMap; } @@ -229,10 +64,11 @@ export function convertPrivateKernelInitInputsToWitnessMap( * @param inputs - The private kernel inputs. * @returns The witness map */ -export function convertPrivateKernelInnerInputsToWitnessMap( +export function convertPrivateKernelInnerInputsToWitnessMapWithAbi( privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, + privateKernelInnerAbi: Abi, ): WitnessMap { - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelInnerArtifact.abi, { + const mapped = { previous_kernel: mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( privateKernelInnerCircuitPrivateInputs.previousKernel.publicInputs, @@ -241,7 +77,9 @@ export function convertPrivateKernelInnerInputsToWitnessMap( app_public_inputs: mapPrivateCircuitPublicInputsToNoir( privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs, ), - }); + }; + pushTestData('private-kernel-inner', mapped); + const initialWitnessMap = abiEncode(privateKernelInnerAbi, mapped); return initialWitnessMap; } @@ -250,7 +88,7 @@ export function convertPrivateKernelInnerInputsToWitnessMap( * @param inputs - The private kernel inputs. * @returns The witness map */ -export function convertPrivateKernelResetInputsToWitnessMap< +export function convertPrivateKernelResetInputsToWitnessMapWithAbi< NH_RR_PENDING extends number, NH_RR_SETTLED extends number, NLL_RR_PENDING extends number, @@ -266,17 +104,17 @@ export function convertPrivateKernelResetInputsToWitnessMap< KEY_VALIDATION_REQUESTS, NUM_TRANSIENT_DATA_HINTS >, - artifactName: PrivateResetArtifact, + resetAbi: Abi, ): WitnessMap { - const args: InputMap = { + const mapped: InputMap = { previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, ), hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), }; - const artifact = ClientCircuitArtifacts[artifactName]; - const initialWitnessMap = abiEncode(artifact.abi as Abi, args); + pushTestData('private-kernel-reset', mapped); + const initialWitnessMap = abiEncode(resetAbi, mapped); return initialWitnessMap; } @@ -285,16 +123,18 @@ export function convertPrivateKernelResetInputsToWitnessMap< * @param inputs - The private kernel inputs. * @returns The witness map */ -export function convertPrivateKernelTailInputsToWitnessMap( +export function convertPrivateKernelTailInputsToWitnessMapWithAbi( privateKernelTailCircuitPrivateInputs: PrivateKernelTailCircuitPrivateInputs, + privateKernelTailAbi: Abi, ): WitnessMap { - const args: InputMap = { + const mapped: InputMap = { previous_kernel: mapPrivateKernelDataToNoir(privateKernelTailCircuitPrivateInputs.previousKernel), previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( privateKernelTailCircuitPrivateInputs.previousKernel.publicInputs, ), }; - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelTailArtifact.abi, args); + pushTestData('private-kernel-tail', mapped); + const initialWitnessMap = abiEncode(privateKernelTailAbi, mapped); return initialWitnessMap; } @@ -303,16 +143,18 @@ export function convertPrivateKernelTailInputsToWitnessMap( * @param inputs - The private kernel inputs. * @returns The witness map */ -export function convertPrivateKernelTailToPublicInputsToWitnessMap( +export function convertPrivateKernelTailToPublicInputsToWitnessMapWithAbi( privateKernelTailToPublicCircuitPrivateInputs: PrivateKernelTailCircuitPrivateInputs, + privateKernelTailToPublicAbi: Abi, ): WitnessMap { - const args: InputMap = { + const mapped: InputMap = { previous_kernel: mapPrivateKernelDataToNoir(privateKernelTailToPublicCircuitPrivateInputs.previousKernel), previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( privateKernelTailToPublicCircuitPrivateInputs.previousKernel.publicInputs, ), }; - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelTailToPublicArtifact.abi, args); + pushTestData('private-kernel-tail-to-public', mapped); + const initialWitnessMap = abiEncode(privateKernelTailToPublicAbi, mapped); return initialWitnessMap; } @@ -321,9 +163,12 @@ export function convertPrivateKernelTailToPublicInputsToWitnessMap( * @param outputs - The private kernel outputs as a witness map. * @returns The public inputs. */ -export function convertPrivateKernelInitOutputsFromWitnessMap(outputs: WitnessMap): PrivateKernelCircuitPublicInputs { +export function convertPrivateKernelInitOutputsFromWitnessMapWithAbi( + outputs: WitnessMap, + privateKernelInitAbi: Abi, +): PrivateKernelCircuitPublicInputs { // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelInitArtifact.abi, outputs); + const decodedInputs: DecodedInputs = abiDecode(privateKernelInitAbi, outputs); // Cast the inputs as the return type const returnType = decodedInputs.return_value as PrivateKernelInitReturnType; @@ -336,9 +181,12 @@ export function convertPrivateKernelInitOutputsFromWitnessMap(outputs: WitnessMa * @param outputs - The private kernel outputs as a witness map. * @returns The public inputs. */ -export function convertPrivateKernelInnerOutputsFromWitnessMap(outputs: WitnessMap): PrivateKernelCircuitPublicInputs { +export function convertPrivateKernelInnerOutputsFromWitnessMapWithAbi( + outputs: WitnessMap, + privateKernelInnerAbi: Abi, +): PrivateKernelCircuitPublicInputs { // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelInnerArtifact.abi, outputs); + const decodedInputs: DecodedInputs = abiDecode(privateKernelInnerAbi, outputs); // Cast the inputs as the return type const returnType = decodedInputs.return_value as PrivateKernelInnerReturnType; @@ -351,13 +199,12 @@ export function convertPrivateKernelInnerOutputsFromWitnessMap(outputs: WitnessM * @param outputs - The private kernel outputs as a witness map. * @returns The public inputs. */ -export function convertPrivateKernelResetOutputsFromWitnessMap( +export function convertPrivateKernelResetOutputsFromWitnessMapWithAbi( outputs: WitnessMap, - artifactName: PrivateResetArtifact, + resetAbi: Abi, ): PrivateKernelCircuitPublicInputs { // Decode the witness map into two fields, the return values and the inputs - const artifact = ClientCircuitArtifacts[artifactName]; - const decodedInputs: DecodedInputs = abiDecode(artifact.abi as Abi, outputs); + const decodedInputs: DecodedInputs = abiDecode(resetAbi, outputs); // Cast the inputs as the return type const returnType = decodedInputs.return_value as PrivateKernelResetReturnType; @@ -370,11 +217,12 @@ export function convertPrivateKernelResetOutputsFromWitnessMap( * @param outputs - The private kernel outputs as a witness map. * @returns The public inputs. */ -export function convertPrivateKernelTailOutputsFromWitnessMap( +export function convertPrivateKernelTailOutputsFromWitnessMapWithAbi( outputs: WitnessMap, + privateKernelTailAbi: Abi, ): PrivateKernelTailCircuitPublicInputs { // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelTailArtifact.abi, outputs); + const decodedInputs: DecodedInputs = abiDecode(privateKernelTailAbi, outputs); // Cast the inputs as the return type const returnType = decodedInputs.return_value as PrivateKernelTailReturnType; @@ -387,28 +235,15 @@ export function convertPrivateKernelTailOutputsFromWitnessMap( * @param outputs - The private kernel outputs as a witness map. * @returns The public inputs. */ -export function convertPrivateKernelTailForPublicOutputsFromWitnessMap( +export function convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi( outputs: WitnessMap, + privateKernelTailToPublicAbi: Abi, ): PrivateKernelTailCircuitPublicInputs { // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelTailToPublicArtifact.abi, outputs); + const decodedInputs: DecodedInputs = abiDecode(privateKernelTailToPublicAbi, outputs); // Cast the inputs as the return type const returnType = decodedInputs.return_value as PrivateKernelTailToPublicReturnType; return mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir(returnType); } - -function updateResetCircuitSampleInputs( - privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputs, -) { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, - ), - hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), - }; - - pushTestData('private-kernel-reset', inputs); -} diff --git a/yarn-project/noir-protocol-circuits-types/src/execution/index.ts b/yarn-project/noir-protocol-circuits-types/src/execution/index.ts deleted file mode 100644 index 9ab6d0fec4c..00000000000 --- a/yarn-project/noir-protocol-circuits-types/src/execution/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './client.js'; -export * from './server.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts deleted file mode 100644 index 553be46a7de..00000000000 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './artifacts/index.js'; -export * from './execution/index.js'; - -export { getPrivateKernelResetArtifactName } from './utils/private_kernel_reset.js'; -export { maxPrivateKernelResetDimensions, privateKernelResetDimensionsConfig } from './private_kernel_reset_data.js'; -export { foreignCallHandler } from './utils/server/foreign_call_handler.js'; -export * from './vks.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_client_artifacts_helper.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_client_artifacts_helper.ts new file mode 100644 index 00000000000..103f077c44e --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_client_artifacts_helper.ts @@ -0,0 +1,91 @@ +import { createConsoleLogger } from '@aztec/foundation/log'; + +import { promises as fs } from 'fs'; + +import { ClientProtocolArtifact } from '../artifacts/types.js'; +import { PrivateKernelResetArtifactFileNames } from '../private_kernel_reset_types.js'; + +const log = createConsoleLogger('autogenerate'); + +const outputFilename = './src/client_artifacts_helper.ts'; + +const ClientCircuitArtifactNames: Record = { + PrivateKernelInitArtifact: 'private_kernel_init', + PrivateKernelInnerArtifact: 'private_kernel_inner', + PrivateKernelTailArtifact: 'private_kernel_tail', + PrivateKernelTailToPublicArtifact: 'private_kernel_tail_to_public', + ...PrivateKernelResetArtifactFileNames, +}; + +function generateImports() { + return ` + import { type NoirCompiledCircuit } from '@aztec/types/noir'; + import { type ClientProtocolArtifact } from './artifacts/types.js'; +`; +} + +function generateArtifactNames() { + const names = Object.entries(ClientCircuitArtifactNames).map(([artifact, name]) => { + return `${artifact}: '${name}',`; + }); + return ` + export const ClientCircuitArtifactNames: Record = { + ${names.join('\n')} + } + `; +} + +function generateImportFunction() { + const cases = Object.values(ClientCircuitArtifactNames) + .flatMap(artifactName => { + const isReset = artifactName.includes('private_kernel_reset'); + const simulatedArtifactName = isReset + ? artifactName.replace('private_kernel_reset', 'private_kernel_reset_simulated') + : `${artifactName}_simulated`; + return [artifactName, simulatedArtifactName]; + }) + .map(artifactName => { + return `case '${artifactName}': { + const { default: compiledCircuit } = await import(\`../artifacts/${artifactName}.json\`, { + assert: { type: 'json' }, + }); + return compiledCircuit as NoirCompiledCircuit; + }`; + }); + + return ` + export async function getClientCircuitArtifact(artifactName: string, simulated: boolean): Promise { + const isReset = artifactName.includes('private_kernel_reset'); + const normalizedArtifactName = isReset + ? \`\${simulated ? artifactName.replace('private_kernel_reset', 'private_kernel_reset_simulated') : artifactName}\` + : \`\${artifactName}\${simulated ? '_simulated' : ''}\`; + switch(normalizedArtifactName) { + ${cases.join('\n')} + default: throw new Error(\`Unknown artifact: \${artifactName}\`); + } + } + `; +} + +const main = async () => { + const content = ` + /* eslint-disable camelcase */ + // GENERATED FILE - DO NOT EDIT. RUN \`yarn generate\` or \`yarn generate:client-artifacts-helper\` + + ${generateImports()} + + ${generateArtifactNames()} + + ${generateImportFunction()} + + `; + + await fs.writeFile(outputFilename, content); +}; + +try { + await main(); +} catch (err: unknown) { + log(`Error generating client circuits dynamic imports: ${err}`); + process.exit(1); +} diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_private_kernel_reset_data.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_private_kernel_reset_data.ts index 3b27d0dae74..63bd8a0a7a7 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_private_kernel_reset_data.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_private_kernel_reset_data.ts @@ -17,6 +17,8 @@ import { promises as fs } from 'fs'; const log = createConsoleLogger('autogenerate'); const outputFilename = './src/private_kernel_reset_data.ts'; +const outputTypesFilename = './src/private_kernel_reset_types.ts'; +const outputVksFilename = './src/private_kernel_reset_vks.ts'; // Must match the values in noir-projects/noir-protocol-circuits/crates/private-kernel-reset/src/main.nr const maxDimensions = [ @@ -31,14 +33,41 @@ const maxDimensions = [ MAX_PRIVATE_LOGS_PER_TX, ]; -function generateImports() { +function generateTypeFileImports() { return ` - import { PrivateKernelResetDimensions, type PrivateKernelResetDimensionsConfig, type VerificationKeyData } from '@aztec/circuits.js'; - import { type NoirCompiledCircuit } from '@aztec/types/noir'; + import { PrivateKernelResetDimensions, type PrivateKernelResetDimensionsConfig } from '@aztec/circuits.js'; + `; +} + +function generateVkFileImports() { + return ` + import { type VerificationKeyData } from '@aztec/circuits.js'; import { keyJsonToVKData } from './utils/vk_json.js'; + + import { type PrivateResetArtifact } from './private_kernel_reset_types.js'; `; } +function generateDataFileImports() { + return ` + import { type NoirCompiledCircuit } from '@aztec/types/noir'; + + import { type PrivateResetArtifact } from './private_kernel_reset_types.js'; + `; +} + +function generateArtifactFileNames(importTags: string[], maxDimensionsTag: string) { + const names = importTags.map( + tag => + `${getArtifactName(tag)}: '${ + tag === `_${maxDimensionsTag}` ? 'private_kernel_reset' : `private_kernel_reset${tag}` + }'`, + ); + return `export const PrivateKernelResetArtifactFileNames = { + ${names.join(',')} + }`; +} + function generateArtifactImports(importTags: string[]) { return importTags .map( @@ -170,20 +199,24 @@ const main = async () => { /* eslint-disable camelcase */ // GENERATED FILE - DO NOT EDIT. RUN \`yarn generate\` or \`yarn generate:reset-data\` - ${generateImports()} + ${generateDataFileImports()} ${generateArtifactImports(importTags)} ${generateSimulatedArtifactImports(importTags)} - ${generateVksImports(importTags)} - - ${generateArtifactNames(resetVariantTags)} ${generateArtifacts(resetVariantTags, importTags)} ${generateSimulatedArtifacts(resetVariantTags, importTags)} + `; - ${generateVks(resetVariantTags, importTags)} + const typeFileContent = ` + /* eslint-disable camelcase */ + // GENERATED FILE - DO NOT EDIT. RUN \`yarn generate\` or \`yarn generate:reset-data\` - ${generateVkIndexes(resetVariantTags)} + ${generateTypeFileImports()} + + ${generateArtifactNames(resetVariantTags)} + + ${generateArtifactFileNames(resetVariantTags, maxDimensionsTag)} export const privateKernelResetDimensionsConfig: PrivateKernelResetDimensionsConfig = ${JSON.stringify(config)}; @@ -192,7 +225,22 @@ const main = async () => { )}]); `; + const vkFileContent = ` + /* eslint-disable camelcase */ + // GENERATED FILE - DO NOT EDIT. RUN \`yarn generate\` or \`yarn generate:reset-data\` + + ${generateVkFileImports()} + + ${generateVksImports(importTags)} + + ${generateVks(resetVariantTags, importTags)} + + ${generateVkIndexes(resetVariantTags)} + `; + await fs.writeFile(outputFilename, content); + await fs.writeFile(outputTypesFilename, typeFileContent); + await fs.writeFile(outputVksFilename, vkFileContent); }; try { diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index 2a9d4a3f74f..0c175f034bd 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -45,11 +45,15 @@ const main = async () => { const abiObj: CompiledCircuit = JSON.parse(rawData); programs.push([pascalCase(circuit), abiObj]); } - const code = codegen( + let code = codegen( programs, false, // Don't embed artifacts true, // Use fixed length arrays ); + + code += ` + export * from '../artifacts/types.js'; + `; await fs.writeFile('./src/types/index.ts', code); }; diff --git a/yarn-project/noir-protocol-circuits-types/src/utils/private_kernel_reset.ts b/yarn-project/noir-protocol-circuits-types/src/utils/private_kernel_reset.ts index b050469c4d9..5fd87b7336b 100644 --- a/yarn-project/noir-protocol-circuits-types/src/utils/private_kernel_reset.ts +++ b/yarn-project/noir-protocol-circuits-types/src/utils/private_kernel_reset.ts @@ -1,6 +1,6 @@ import { type PrivateKernelResetDimensions, privateKernelResetDimensionNames } from '@aztec/circuits.js'; -import { PrivateKernelResetArtifacts, type PrivateResetArtifact } from '../private_kernel_reset_data.js'; +import { PrivateKernelResetArtifactFileNames, type PrivateResetArtifact } from '../private_kernel_reset_types.js'; export function createPrivateKernelResetTag(dimensions: PrivateKernelResetDimensions) { return privateKernelResetDimensionNames.map(name => dimensions[name]).join('_'); @@ -9,7 +9,7 @@ export function createPrivateKernelResetTag(dimensions: PrivateKernelResetDimens export function getPrivateKernelResetArtifactName(dimensions: PrivateKernelResetDimensions) { const tag = createPrivateKernelResetTag(dimensions); const name = `PrivateKernelResetArtifact_${tag}` as PrivateResetArtifact; - if (!PrivateKernelResetArtifacts[name]) { + if (!PrivateKernelResetArtifactFileNames[name]) { throw new Error(`Unknown private reset artifact: ${name}`); } return name; diff --git a/yarn-project/prover-client/src/block_builder/light.test.ts b/yarn-project/prover-client/src/block_builder/light.test.ts index e92e7d6fa0e..b6d86c0fe66 100644 --- a/yarn-project/prover-client/src/block_builder/light.test.ts +++ b/yarn-project/prover-client/src/block_builder/light.test.ts @@ -54,7 +54,7 @@ import { getVKIndex, getVKSiblingPath, getVKTreeRoot, -} from '@aztec/noir-protocol-circuits-types'; +} from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { type MerkleTreeAdminDatabase, NativeWorldStateService } from '@aztec/world-state'; diff --git a/yarn-project/prover-client/src/block_builder/light.ts b/yarn-project/prover-client/src/block_builder/light.ts index 39d5b7a2185..69c95afd831 100644 --- a/yarn-project/prover-client/src/block_builder/light.ts +++ b/yarn-project/prover-client/src/block_builder/light.ts @@ -12,7 +12,7 @@ import { Fr, type GlobalVariables, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@ import { SpongeBlob } from '@aztec/circuits.js/blobs'; import { padArrayEnd } from '@aztec/foundation/collection'; import { createLogger } from '@aztec/foundation/log'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { type TelemetryClient } from '@aztec/telemetry-client'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index ee2740b5ebb..41847b26e66 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -18,7 +18,7 @@ import { times } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; import { type Logger } from '@aztec/foundation/log'; import { TestDateProvider } from '@aztec/foundation/timer'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { PublicProcessor, 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 31b25d55e73..f8238127aa3 100644 --- a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts +++ b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts @@ -59,7 +59,7 @@ import { sha256Trunc } from '@aztec/foundation/crypto'; import { type Logger } from '@aztec/foundation/log'; import { type Tuple, assertLength, serializeToBuffer, toFriendlyJSON } from '@aztec/foundation/serialize'; import { computeUnbalancedMerkleRoot } from '@aztec/foundation/trees'; -import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { computeFeePayerBalanceLeafSlot } from '@aztec/simulator'; import { type MerkleTreeReadOperations } from '@aztec/world-state'; diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index d3a2f725ec2..8a67ad25bfe 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -55,7 +55,7 @@ import { promiseWithResolvers } from '@aztec/foundation/promise'; import { type Tuple } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; import { elapsed } from '@aztec/foundation/timer'; -import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { Attributes, type TelemetryClient, type Tracer, trackSpan, wrapCallbackInSpan } from '@aztec/telemetry-client'; diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator_multi_public_functions.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator_multi_public_functions.test.ts index 768bf80046e..e19fe554dce 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_multi_public_functions.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_multi_public_functions.test.ts @@ -1,7 +1,7 @@ import { mockTx } from '@aztec/circuit-types'; import { times } from '@aztec/foundation/collection'; import { createLogger } from '@aztec/foundation/log'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { TestContext } from '../mocks/test_context.js'; diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts index b0d111a15ed..e7fe4973e45 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_public_functions.test.ts @@ -1,6 +1,6 @@ import { mockTx } from '@aztec/circuit-types'; import { createLogger } from '@aztec/foundation/log'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { TestContext } from '../mocks/test_context.js'; diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator_workflow.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator_workflow.test.ts index 8c9cccc45b9..179223e86b5 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_workflow.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_workflow.test.ts @@ -16,7 +16,7 @@ import { makeParityPublicInputs } from '@aztec/circuits.js/testing'; import { createLogger } from '@aztec/foundation/log'; import { promiseWithResolvers } from '@aztec/foundation/promise'; import { sleep } from '@aztec/foundation/sleep'; -import { ProtocolCircuitVks } from '@aztec/noir-protocol-circuits-types'; +import { ProtocolCircuitVks } from '@aztec/noir-protocol-circuits-types/vks'; import { type MockProxy, mock } from 'jest-mock-extended'; diff --git a/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts b/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts index 0460b11b3b0..12416e2c1bc 100644 --- a/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts +++ b/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts @@ -18,7 +18,7 @@ import { PublicTubeData, TubeInputs, } from '@aztec/circuits.js/rollup'; -import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types'; +import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/vks'; /** * Helper class to manage the proving cycle of a transaction diff --git a/yarn-project/prover-client/src/test/bb_prover_base_rollup.test.ts b/yarn-project/prover-client/src/test/bb_prover_base_rollup.test.ts index cd977e38d3d..6c4e62b17fb 100644 --- a/yarn-project/prover-client/src/test/bb_prover_base_rollup.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_base_rollup.test.ts @@ -4,7 +4,7 @@ import { PRIVATE_KERNEL_EMPTY_INDEX, PrivateKernelEmptyInputData, VkWitnessData import { SpongeBlob } from '@aztec/circuits.js/blobs'; import { type PrivateBaseRollupHints, PrivateBaseRollupInputs, PrivateTubeData } from '@aztec/circuits.js/rollup'; import { createLogger } from '@aztec/foundation/log'; -import { getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; diff --git a/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts index f7e5fb2194f..263c0dfe9b6 100644 --- a/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts @@ -6,7 +6,7 @@ import { times } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { getTestData, isGenerateTestDataEnabled } from '@aztec/foundation/testing'; import { writeTestData } from '@aztec/foundation/testing/files'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { buildBlock } from '../block_builder/light.js'; diff --git a/yarn-project/prover-client/src/test/bb_prover_parity.test.ts b/yarn-project/prover-client/src/test/bb_prover_parity.test.ts index 12a3b16e000..2db1248ac9d 100644 --- a/yarn-project/prover-client/src/test/bb_prover_parity.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_parity.test.ts @@ -19,7 +19,7 @@ import { ServerCircuitVks, getVKSiblingPath, getVKTreeRoot, -} from '@aztec/noir-protocol-circuits-types'; +} from '@aztec/noir-protocol-circuits-types/vks'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { TestContext } from '../mocks/test_context.js'; diff --git a/yarn-project/pxe/package.json b/yarn-project/pxe/package.json index 59069d0f5dc..530972c30d4 100644 --- a/yarn-project/pxe/package.json +++ b/yarn-project/pxe/package.json @@ -80,7 +80,6 @@ "@aztec/simulator": "workspace:^", "@aztec/types": "workspace:^", "@msgpack/msgpack": "^3.0.0-beta2", - "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi", "@noir-lang/types": "workspace:*", "koa": "^2.14.2", "koa-router": "^12.0.0", diff --git a/yarn-project/pxe/src/kernel_oracle/index.ts b/yarn-project/pxe/src/kernel_oracle/index.ts index 030f8d4cf0f..29364ebad86 100644 --- a/yarn-project/pxe/src/kernel_oracle/index.ts +++ b/yarn-project/pxe/src/kernel_oracle/index.ts @@ -15,7 +15,7 @@ import { import { createLogger } from '@aztec/foundation/log'; import { type Tuple } from '@aztec/foundation/serialize'; import { type KeyStore } from '@aztec/key-store'; -import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/client'; +import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/vks'; import { type ContractDataOracle } from '../contract_data_oracle/index.js'; import { type ProvingDataOracle } from './../kernel_prover/proving_data_oracle.js'; diff --git a/yarn-project/pxe/src/kernel_prover/index.ts b/yarn-project/pxe/src/kernel_prover/index.ts index f37c2c857ca..94bc7f6892d 100644 --- a/yarn-project/pxe/src/kernel_prover/index.ts +++ b/yarn-project/pxe/src/kernel_prover/index.ts @@ -1,4 +1,2 @@ -export { TestPrivateKernelProver } from './test/test_circuit_prover.js'; - export * from './kernel_prover.js'; export * from './proving_data_oracle.js'; diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index 7795a069f7e..cfece3f2deb 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -112,18 +112,18 @@ describe('Kernel Prover', () => { }; const expectExecution = (fns: string[]) => { - const callStackItemsInit = proofCreator.simulateProofInit.mock.calls.map(args => + const callStackItemsInit = proofCreator.simulateInit.mock.calls.map(args => String.fromCharCode(args[0].privateCall.publicInputs.callContext.functionSelector.value), ); - const callStackItemsInner = proofCreator.simulateProofInner.mock.calls.map(args => + const callStackItemsInner = proofCreator.simulateInner.mock.calls.map(args => String.fromCharCode(args[0].privateCall.publicInputs.callContext.functionSelector.value), ); - expect(proofCreator.simulateProofInit).toHaveBeenCalledTimes(Math.min(1, fns.length)); - expect(proofCreator.simulateProofInner).toHaveBeenCalledTimes(Math.max(0, fns.length - 1)); + expect(proofCreator.simulateInit).toHaveBeenCalledTimes(Math.min(1, fns.length)); + expect(proofCreator.simulateInner).toHaveBeenCalledTimes(Math.max(0, fns.length - 1)); expect(callStackItemsInit.concat(callStackItemsInner)).toEqual(fns); - proofCreator.simulateProofInner.mockClear(); - proofCreator.simulateProofInit.mockClear(); + proofCreator.simulateInner.mockClear(); + proofCreator.simulateInit.mockClear(); }; const prove = (executionResult: PrivateExecutionResult) => prover.prove(txRequest, executionResult); @@ -147,12 +147,12 @@ describe('Kernel Prover', () => { }); proofCreator = mock(); - proofCreator.simulateProofInit.mockResolvedValue(simulateProofOutput([])); - proofCreator.simulateProofInner.mockResolvedValue(simulateProofOutput([])); - proofCreator.simulateProofReset.mockResolvedValue(simulateProofOutput([])); - proofCreator.simulateProofTail.mockResolvedValue(simulateProofOutputFinal([])); + proofCreator.simulateInit.mockResolvedValue(simulateProofOutput([])); + proofCreator.simulateInner.mockResolvedValue(simulateProofOutput([])); + proofCreator.simulateReset.mockResolvedValue(simulateProofOutput([])); + proofCreator.simulateTail.mockResolvedValue(simulateProofOutputFinal([])); - prover = new KernelProver(oracle, proofCreator); + prover = new KernelProver(oracle, proofCreator, true); }); it('should create proofs in correct order', async () => { diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index f35cd8a2277..29febdd36e8 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -10,6 +10,7 @@ import { } from '@aztec/circuit-types'; import { CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, + ClientIvcProof, Fr, PROTOCOL_CONTRACT_TREE_HEIGHT, PrivateCallData, @@ -32,7 +33,7 @@ import { createLogger } from '@aztec/foundation/log'; import { assertLength } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; import { Timer } from '@aztec/foundation/timer'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/client'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks'; import { getProtocolContractSiblingPath, isProtocolContract, @@ -89,6 +90,12 @@ const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput> { + if (simulate && profile) { + throw new Error('Cannot simulate and profile at the same time'); + } + + simulate = simulate || this.fakeProofs; + const timer = new Timer(); const isPrivateOnlyTx = this.isPrivateOnly(executionResult); @@ -156,7 +172,9 @@ export class KernelProver { ); while (resetBuilder.needsReset()) { const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap); - output = await this.proofCreator.simulateProofReset(privateInputs); + output = simulate + ? await this.proofCreator.simulateReset(privateInputs) + : await this.proofCreator.generateResetOutput(privateInputs); // TODO(#7368) consider refactoring this redundant bytecode pushing acirs.push(output.bytecode); witnessStack.push(output.outputWitness); @@ -203,7 +221,9 @@ export class KernelProver { pushTestData('private-kernel-inputs-init', proofInput); - output = await this.proofCreator.simulateProofInit(proofInput); + output = simulate + ? await this.proofCreator.simulateInit(proofInput) + : await this.proofCreator.generateInitOutput(proofInput); acirs.push(output.bytecode); witnessStack.push(output.outputWitness); @@ -222,7 +242,9 @@ export class KernelProver { pushTestData('private-kernel-inputs-inner', proofInput); - output = await this.proofCreator.simulateProofInner(proofInput); + output = simulate + ? await this.proofCreator.simulateInner(proofInput) + : await this.proofCreator.generateInnerOutput(proofInput); acirs.push(output.bytecode); witnessStack.push(output.outputWitness); @@ -242,7 +264,9 @@ export class KernelProver { ); while (resetBuilder.needsReset()) { const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap); - output = await this.proofCreator.simulateProofReset(privateInputs); + output = simulate + ? await this.proofCreator.simulateReset(privateInputs) + : await this.proofCreator.generateResetOutput(privateInputs); acirs.push(output.bytecode); witnessStack.push(output.outputWitness); @@ -275,7 +299,9 @@ export class KernelProver { pushTestData('private-kernel-inputs-ordering', privateInputs); - const tailOutput = await this.proofCreator.simulateProofTail(privateInputs); + const tailOutput = simulate + ? await this.proofCreator.simulateTail(privateInputs) + : await this.proofCreator.generateTailOutput(privateInputs); if (tailOutput.publicInputs.forPublic) { const privateLogs = privateInputs.previousKernel.publicInputs.end.privateLogs; const nonRevertiblePrivateLogs = tailOutput.publicInputs.forPublic.nonRevertibleAccumulatedData.privateLogs; @@ -290,12 +316,16 @@ export class KernelProver { tailOutput.profileResult = { gateCounts }; } - this.log.verbose(`Private kernel witness generation took ${timer.ms()}ms`); + if (!simulate) { + this.log.info(`Private kernel witness generation took ${timer.ms()}ms`); + } // TODO(#7368) how do we 'bincode' encode these inputs? - if (!dryRun) { + if (!dryRun && !simulate) { const ivcProof = await this.proofCreator.createClientIvcProof(acirs, witnessStack); tailOutput.clientIvcProof = ivcProof; + } else { + tailOutput.clientIvcProof = ClientIvcProof.empty(); } return tailOutput; diff --git a/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts b/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts deleted file mode 100644 index b6e4e918077..00000000000 --- a/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types'; -import type { CircuitSimulationStats } from '@aztec/circuit-types/stats'; -import { - ClientIvcProof, - type PrivateKernelCircuitPublicInputs, - type PrivateKernelInitCircuitPrivateInputs, - type PrivateKernelInnerCircuitPrivateInputs, - type PrivateKernelResetCircuitPrivateInputs, - type PrivateKernelTailCircuitPrivateInputs, - type PrivateKernelTailCircuitPublicInputs, -} from '@aztec/circuits.js'; -import { createLogger } from '@aztec/foundation/log'; -import { elapsed } from '@aztec/foundation/timer'; -import { - ClientCircuitVks, - type ClientProtocolArtifact, - executeInit, - executeInner, - executeReset, - executeTail, - executeTailForPublic, - getPrivateKernelResetArtifactName, - maxPrivateKernelResetDimensions, -} from '@aztec/noir-protocol-circuits-types/client'; - -import { type WitnessMap } from '@noir-lang/types'; - -/** - * Test Proof Creator executes circuit simulations and provides fake proofs. - */ -export class TestPrivateKernelProver implements PrivateKernelProver { - constructor(private log = createLogger('pxe:test_proof_creator')) {} - - createClientIvcProof(_acirs: Buffer[], _witnessStack: WitnessMap[]): Promise { - return Promise.resolve(ClientIvcProof.empty()); - } - - public async simulateProofInit( - privateInputs: PrivateKernelInitCircuitPrivateInputs, - ): Promise> { - const [duration, result] = await elapsed(() => executeInit(privateInputs)); - this.log.debug(`Simulated private kernel init`, { - eventName: 'circuit-simulation', - circuitName: 'private-kernel-init', - duration, - inputSize: privateInputs.toBuffer().length, - outputSize: result.toBuffer().length, - } satisfies CircuitSimulationStats); - return this.makeEmptyKernelSimulateOutput(result, 'PrivateKernelInitArtifact'); - } - - public async simulateProofInner( - privateInputs: PrivateKernelInnerCircuitPrivateInputs, - ): Promise> { - const [duration, result] = await elapsed(() => executeInner(privateInputs)); - this.log.debug(`Simulated private kernel inner`, { - eventName: 'circuit-simulation', - circuitName: 'private-kernel-inner', - duration, - inputSize: privateInputs.toBuffer().length, - outputSize: result.toBuffer().length, - } satisfies CircuitSimulationStats); - return this.makeEmptyKernelSimulateOutput(result, 'PrivateKernelInnerArtifact'); - } - - public async simulateProofReset( - privateInputs: PrivateKernelResetCircuitPrivateInputs, - ): Promise> { - const variantPrivateInputs = privateInputs.trimToSizes(); - const [duration, result] = await elapsed(() => - executeReset(variantPrivateInputs, privateInputs.dimensions, privateInputs), - ); - this.log.debug(`Simulated private kernel reset`, { - eventName: 'circuit-simulation', - circuitName: 'private-kernel-reset', - duration, - inputSize: variantPrivateInputs.toBuffer().length, - outputSize: result.toBuffer().length, - } satisfies CircuitSimulationStats); - return this.makeEmptyKernelSimulateOutput( - result, - getPrivateKernelResetArtifactName(maxPrivateKernelResetDimensions), - ); - } - - public async simulateProofTail( - privateInputs: PrivateKernelTailCircuitPrivateInputs, - ): Promise> { - const isForPublic = privateInputs.isForPublic(); - const [duration, result] = await elapsed(() => - isForPublic ? executeTailForPublic(privateInputs) : executeTail(privateInputs), - ); - this.log.debug(`Simulated private kernel ordering`, { - eventName: 'circuit-simulation', - circuitName: 'private-kernel-tail', - duration, - inputSize: privateInputs.toBuffer().length, - outputSize: result.toBuffer().length, - } satisfies CircuitSimulationStats); - return this.makeEmptyKernelSimulateOutput( - result, - isForPublic ? 'PrivateKernelTailToPublicArtifact' : 'PrivateKernelTailArtifact', - ); - } - - public computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise { - // No gates in test prover - return Promise.resolve(0); - } - - private makeEmptyKernelSimulateOutput< - PublicInputsType extends PrivateKernelTailCircuitPublicInputs | PrivateKernelCircuitPublicInputs, - >(publicInputs: PublicInputsType, circuitType: ClientProtocolArtifact) { - const kernelProofOutput: PrivateKernelSimulateOutput = { - publicInputs, - verificationKey: ClientCircuitVks[circuitType].keyAsFields, - outputWitness: new Map(), - bytecode: Buffer.from([]), - }; - return kernelProofOutput; - } -} diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 0697fbc72e0..6082a3cc1eb 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -75,8 +75,7 @@ import { ContractDataOracle } from '../contract_data_oracle/index.js'; import { type PxeDatabase } from '../database/index.js'; import { NoteDao } from '../database/note_dao.js'; import { KernelOracle } from '../kernel_oracle/index.js'; -import { KernelProver } from '../kernel_prover/kernel_prover.js'; -import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js'; +import { KernelProver, type ProvingConfig } from '../kernel_prover/kernel_prover.js'; import { getAcirSimulator } from '../simulator/index.js'; import { Synchronizer } from '../synchronizer/index.js'; import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js'; @@ -90,6 +89,7 @@ export class PXEService implements PXE { private simulator: AcirSimulator; private log: Logger; private packageVersion: string; + private proverEnabled: boolean; constructor( private keyStore: KeyStore, @@ -105,6 +105,7 @@ export class PXEService implements PXE { this.contractDataOracle = new ContractDataOracle(db); this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle); this.packageVersion = getPackageInfo().version; + this.proverEnabled = !!config.proverEnabled; } /** @@ -453,20 +454,16 @@ export class PXEService implements PXE { return await this.node.getCurrentBaseFees(); } - async #simulateKernels( - txRequest: TxExecutionRequest, - privateExecutionResult: PrivateExecutionResult, - ): Promise { - const result = await this.#prove(txRequest, new TestPrivateKernelProver(), privateExecutionResult); - return result.publicInputs; - } - public async proveTx( txRequest: TxExecutionRequest, privateExecutionResult: PrivateExecutionResult, ): Promise { try { - const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult); + const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, { + simulate: false, + profile: false, + dryRun: false, + }); return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!); } catch (err: any) { throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult)); @@ -501,17 +498,11 @@ export class PXEService implements PXE { await this.synchronizer.sync(); const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes); - let publicInputs: PrivateKernelTailCircuitPublicInputs; - let profileResult; - if (profile) { - ({ publicInputs, profileResult } = await this.#profileKernelProver( - txRequest, - this.proofCreator, - privateExecutionResult, - )); - } else { - publicInputs = await this.#simulateKernels(txRequest, privateExecutionResult); - } + const { publicInputs, profileResult } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, { + simulate: !profile, + profile, + dryRun: true, + }); const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs); const simulatedTx = privateSimulationResult.toSimulatedTx(); @@ -795,20 +786,6 @@ export class PXEService implements PXE { } } - async #profileKernelProver( - txExecutionRequest: TxExecutionRequest, - proofCreator: PrivateKernelProver, - privateExecutionResult: PrivateExecutionResult, - ): Promise> { - const block = privateExecutionResult.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber(); - const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node, block); - const kernelProver = new KernelProver(kernelOracle, proofCreator); - - // Dry run the prover with profiler enabled - const result = await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, true, true); - return result; - } - /** * Generate a kernel proof, and create a private kernel output. * The function takes in a transaction execution request, and the result of private execution @@ -823,13 +800,18 @@ export class PXEService implements PXE { txExecutionRequest: TxExecutionRequest, proofCreator: PrivateKernelProver, privateExecutionResult: PrivateExecutionResult, + { simulate, profile, dryRun }: ProvingConfig, ): Promise> { // use the block the tx was simulated against const block = privateExecutionResult.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber(); const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node, block); - const kernelProver = new KernelProver(kernelOracle, proofCreator); - this.log.debug(`Executing kernel prover...`); - return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult); + const kernelProver = new KernelProver(kernelOracle, proofCreator, !this.proverEnabled); + this.log.debug(`Executing kernel prover (simulate: ${simulate}, profile: ${profile}, dryRun: ${dryRun})...`); + return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, { + simulate, + profile, + dryRun, + }); } public async isContractClassPubliclyRegistered(id: Fr): Promise { 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 f000655f45f..b442f4a2d40 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,3 +1,4 @@ +import { BBWASMBundlePrivateKernelProver } from '@aztec/bb-prover/wasm/bundle'; import { type AztecNode, type PXE, 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'; @@ -11,7 +12,6 @@ import { type MockProxy, mock } from 'jest-mock-extended'; import { KVPxeDatabase } from '../../database/kv_pxe_database.js'; import { type PxeDatabase } from '../../database/pxe_database.js'; import { type PXEServiceConfig } from '../../index.js'; -import { TestPrivateKernelProver } from '../../kernel_prover/test/test_circuit_prover.js'; import { PXEService } from '../pxe_service.js'; import { pxeTestSuite } from './pxe_test_suite.js'; @@ -48,7 +48,7 @@ async function createPXEService(): Promise { }; node.getL1ContractAddresses.mockResolvedValue(mockedContracts); - return Promise.resolve(new PXEService(keyStore, node, db, tips, new TestPrivateKernelProver(), config)); + return Promise.resolve(new PXEService(keyStore, node, db, tips, new BBWASMBundlePrivateKernelProver(), config)); } pxeTestSuite('PXEService', createPXEService); @@ -81,7 +81,7 @@ describe('PXEService', () => { node.getTxEffect.mockResolvedValue(randomInBlock(settledTx)); - const pxe = new PXEService(keyStore, node, db, tips, new TestPrivateKernelProver(), config); + const pxe = new PXEService(keyStore, node, db, tips, new BBWASMBundlePrivateKernelProver(), config); await expect(pxe.sendTx(duplicateTx)).rejects.toThrow(/A settled tx with equal hash/); }); }); diff --git a/yarn-project/pxe/src/utils/create_pxe_service.ts b/yarn-project/pxe/src/utils/create_pxe_service.ts index 18783887ffb..1e288dd3fd9 100644 --- a/yarn-project/pxe/src/utils/create_pxe_service.ts +++ b/yarn-project/pxe/src/utils/create_pxe_service.ts @@ -1,5 +1,5 @@ import { BBNativePrivateKernelProver } from '@aztec/bb-prover'; -import { BBWasmPrivateKernelProver } from '@aztec/bb-prover/wasm'; +import { BBWASMBundlePrivateKernelProver } from '@aztec/bb-prover/wasm/bundle'; import { type AztecNode, type PrivateKernelProver } from '@aztec/circuit-types'; import { randomBytes } from '@aztec/foundation/crypto'; import { createLogger } from '@aztec/foundation/log'; @@ -9,7 +9,6 @@ import { L2TipsStore } from '@aztec/kv-store/stores'; import { type PXEServiceConfig } from '../config/index.js'; import { KVPxeDatabase } from '../database/kv_pxe_database.js'; -import { TestPrivateKernelProver } from '../kernel_prover/test/test_circuit_prover.js'; import { PXEService } from '../pxe_service/pxe_service.js'; /** @@ -54,13 +53,8 @@ export async function createPXEService( } function createProver(config: PXEServiceConfig, logSuffix?: string) { - if (!config.proverEnabled) { - return new TestPrivateKernelProver(); - } - - // (@PhilWindle) Temporary validation until WASM is implemented if (!config.bbBinaryPath || !config.bbWorkingDirectory) { - return new BBWasmPrivateKernelProver(16); + return new BBWASMBundlePrivateKernelProver(16); } else { const bbConfig = config as Required> & PXEServiceConfig; 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 78d2f8992a2..3940e97b1d2 100644 --- a/yarn-project/simulator/src/providers/acvm_wasm_with_blobs.ts +++ b/yarn-project/simulator/src/providers/acvm_wasm_with_blobs.ts @@ -1,4 +1,4 @@ -import { foreignCallHandler } from '@aztec/noir-protocol-circuits-types'; +import { foreignCallHandler } from '@aztec/noir-protocol-circuits-types/server'; import { type NoirCompiledCircuit } from '@aztec/types/noir'; import { executeCircuit } from '@noir-lang/acvm_js'; diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index f73b616c338..49f73203701 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -914,7 +914,6 @@ __metadata: "@jest/globals": "npm:^29.5.0" "@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js" "@noir-lang/noir_codegen": "portal:../../noir/packages/noir_codegen" - "@noir-lang/noir_js": "file:../../noir/packages/noir_js" "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi" "@noir-lang/types": "portal:../../noir/packages/types" "@types/jest": "npm:^29.5.0" @@ -1138,7 +1137,6 @@ __metadata: "@aztec/types": "workspace:^" "@jest/globals": "npm:^29.5.0" "@msgpack/msgpack": "npm:^3.0.0-beta2" - "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi" "@noir-lang/types": "workspace:*" "@types/jest": "npm:^29.5.0" "@types/lodash.omit": "npm:^4.5.7"