From b8b5f53f738f748d3d6f69d96da9aab78057553a Mon Sep 17 00:00:00 2001 From: PhilWindle <60546371+PhilWindle@users.noreply.github.com> Date: Tue, 14 May 2024 12:16:43 +0100 Subject: [PATCH] chore: Pw/refactor bb prover (#6349) This PR moves all native BB code into a new package used by both the `pxe` for client circuits and the `prover-client` for server circuits. This removes some of the duplication. Some duplication is still present. This will remain until we know more about the differences in proving client and server circuits. --- yarn-project/bb-prover/.eslintrc.cjs | 1 + yarn-project/bb-prover/package.json | 85 ++++ yarn-project/bb-prover/src/bb/cli.ts | 92 ++++ yarn-project/bb-prover/src/bb/execute.ts | 359 ++++++++++++++++ yarn-project/bb-prover/src/bb/index.ts | 23 + yarn-project/bb-prover/src/index.ts | 2 + .../bb-prover/src/mappings/mappings.ts | 41 ++ .../src/prover}/bb_native_proof_creator.ts | 400 +----------------- .../src/prover/bb_prover.ts | 31 +- yarn-project/bb-prover/src/prover/index.ts | 2 + .../src/prover/verification_key_data.ts | 16 + yarn-project/bb-prover/src/stats.ts | 82 ++++ yarn-project/bb-prover/src/test/index.ts | 1 + .../src/test}/test_circuit_prover.ts | 11 +- yarn-project/bb-prover/tsconfig.json | 26 ++ .../circuit-types/src/interfaces/index.ts | 2 + .../src/interfaces}/proof_creator.ts | 5 +- .../src/interfaces/server_circuit_prover.ts} | 48 +-- yarn-project/deploy_npm.sh | 1 + yarn-project/end-to-end/package.json | 1 + .../client_prover_integration.test.ts | 2 +- .../client_prover_test.ts | 3 +- yarn-project/end-to-end/src/fixtures/utils.ts | 9 +- yarn-project/end-to-end/tsconfig.json | 3 + yarn-project/package.json | 1 + yarn-project/prover-client/package.json | 4 +- yarn-project/prover-client/src/index.ts | 1 - .../prover-client/src/mocks/test_context.ts | 19 +- .../src/orchestrator/orchestrator.ts | 4 +- .../orchestrator_failures.test.ts | 7 +- .../orchestrator_lifecycle.test.ts | 7 +- .../orchestrator_workflow.test.ts | 6 +- .../src/prover-pool/memory-proving-queue.ts | 5 +- .../src/prover-pool/prover-agent.test.ts | 6 +- .../src/prover-pool/prover-agent.ts | 4 +- .../src/prover-pool/prover-pool.ts | 3 +- .../prover-client/src/prover/index.ts | 1 - yarn-project/prover-client/src/stats.ts | 25 +- .../bb_prover_base_rollup.test.ts | 11 +- .../bb_prover_full_rollup.test.ts | 11 +- .../{prover => test}/bb_prover_parity.test.ts | 8 +- .../bb_prover_public_kernel.test.ts | 10 +- yarn-project/prover-client/tsconfig.json | 5 +- yarn-project/pxe/package.json | 1 + yarn-project/pxe/src/index.ts | 3 - .../src/kernel_prover/kernel_prover.test.ts | 3 +- .../pxe/src/kernel_prover/kernel_prover.ts | 2 +- .../kernel_prover/test/test_circuit_prover.ts | 3 +- .../pxe/src/pxe_service/create_pxe_service.ts | 5 +- .../pxe/src/pxe_service/pxe_service.ts | 2 +- yarn-project/pxe/tsconfig.json | 3 + yarn-project/simulator/src/index.ts | 1 + yarn-project/simulator/src/rollup/index.ts | 1 + .../src/rollup}/rollup.ts | 0 yarn-project/simulator/src/stats/index.ts | 1 + yarn-project/simulator/src/stats/stats.ts | 20 + yarn-project/tsconfig.json | 1 + yarn-project/yarn.lock | 33 +- 58 files changed, 915 insertions(+), 548 deletions(-) create mode 100644 yarn-project/bb-prover/.eslintrc.cjs create mode 100644 yarn-project/bb-prover/package.json create mode 100644 yarn-project/bb-prover/src/bb/cli.ts create mode 100644 yarn-project/bb-prover/src/bb/execute.ts create mode 100644 yarn-project/bb-prover/src/bb/index.ts create mode 100644 yarn-project/bb-prover/src/index.ts create mode 100644 yarn-project/bb-prover/src/mappings/mappings.ts rename yarn-project/{pxe/src/kernel_prover/bb_prover => bb-prover/src/prover}/bb_native_proof_creator.ts (50%) rename yarn-project/{prover-client => bb-prover}/src/prover/bb_prover.ts (97%) create mode 100644 yarn-project/bb-prover/src/prover/index.ts create mode 100644 yarn-project/bb-prover/src/prover/verification_key_data.ts create mode 100644 yarn-project/bb-prover/src/stats.ts create mode 100644 yarn-project/bb-prover/src/test/index.ts rename yarn-project/{prover-client/src/prover => bb-prover/src/test}/test_circuit_prover.ts (95%) create mode 100644 yarn-project/bb-prover/tsconfig.json rename yarn-project/{pxe/src/kernel_prover/interface => circuit-types/src/interfaces}/proof_creator.ts (95%) rename yarn-project/{prover-client/src/prover/interface.ts => circuit-types/src/interfaces/server_circuit_prover.ts} (62%) delete mode 100644 yarn-project/prover-client/src/prover/index.ts rename yarn-project/prover-client/src/{prover => test}/bb_prover_base_rollup.test.ts (74%) rename yarn-project/prover-client/src/{prover => test}/bb_prover_full_rollup.test.ts (81%) rename yarn-project/prover-client/src/{prover => test}/bb_prover_parity.test.ts (91%) rename yarn-project/prover-client/src/{prover => test}/bb_prover_public_kernel.test.ts (90%) create mode 100644 yarn-project/simulator/src/rollup/index.ts rename yarn-project/{prover-client/src/simulator => simulator/src/rollup}/rollup.ts (100%) create mode 100644 yarn-project/simulator/src/stats/index.ts create mode 100644 yarn-project/simulator/src/stats/stats.ts diff --git a/yarn-project/bb-prover/.eslintrc.cjs b/yarn-project/bb-prover/.eslintrc.cjs new file mode 100644 index 00000000000..e659927475c --- /dev/null +++ b/yarn-project/bb-prover/.eslintrc.cjs @@ -0,0 +1 @@ +module.exports = require('@aztec/foundation/eslint'); diff --git a/yarn-project/bb-prover/package.json b/yarn-project/bb-prover/package.json new file mode 100644 index 00000000000..0d46748757b --- /dev/null +++ b/yarn-project/bb-prover/package.json @@ -0,0 +1,85 @@ +{ + "name": "@aztec/bb-prover", + "version": "0.1.0", + "type": "module", + "exports": { + ".": "./dest/index.js" + }, + "bin": { + "bb-cli": "./dest/bb/index.js" + }, + "typedocOptions": { + "entryPoints": [ + "./src/index.ts" + ], + "name": "BB Prover", + "tsconfig": "./tsconfig.json" + }, + "inherits": [ + "../package.common.json" + ], + "scripts": { + "build": "yarn clean && tsc -b", + "build:dev": "tsc -b --watch", + "clean": "rm -rf ./dest .tsbuildinfo", + "formatting": "run -T prettier --check ./src && run -T eslint ./src", + "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src", + "bb": "node --no-warnings ./dest/bb/index.js", + "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests" + }, + "jest": { + "moduleNameMapper": { + "^(\\.{1,2}/.*)\\.[cm]?js$": "$1" + }, + "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$", + "rootDir": "./src", + "transform": { + "^.+\\.tsx?$": [ + "@swc/jest" + ] + }, + "extensionsToTreatAsEsm": [ + ".ts" + ], + "reporters": [ + [ + "default", + { + "summaryThreshold": 9999 + } + ] + ] + }, + "dependencies": { + "@aztec/circuit-types": "workspace:^", + "@aztec/circuits.js": "workspace:^", + "@aztec/foundation": "workspace:^", + "@aztec/noir-protocol-circuits-types": "workspace:^", + "@aztec/simulator": "workspace:^", + "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi", + "@noir-lang/types": "portal:../../noir/packages/types", + "commander": "^9.0.0", + "source-map-support": "^0.5.21", + "tslib": "^2.4.0" + }, + "devDependencies": { + "@jest/globals": "^29.5.0", + "@types/jest": "^29.5.0", + "@types/memdown": "^3.0.0", + "@types/node": "^18.7.23", + "@types/source-map-support": "^0.5.10", + "jest": "^29.5.0", + "jest-mock-extended": "^3.0.3", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" + }, + "files": [ + "dest", + "src", + "!*.test.*" + ], + "types": "./dest/index.d.ts", + "engines": { + "node": ">=18" + } +} diff --git a/yarn-project/bb-prover/src/bb/cli.ts b/yarn-project/bb-prover/src/bb/cli.ts new file mode 100644 index 00000000000..e8f2314ba61 --- /dev/null +++ b/yarn-project/bb-prover/src/bb/cli.ts @@ -0,0 +1,92 @@ +import { type LogFn } from '@aztec/foundation/log'; +import { type ProtocolArtifact, ProtocolCircuitArtifacts } from '@aztec/noir-protocol-circuits-types'; + +import { Command } from 'commander'; +import * as fs from 'fs/promises'; + +import { generateKeyForNoirCircuit } from './execute.js'; + +const { BB_WORKING_DIRECTORY, BB_BINARY_PATH } = process.env; + +/** + * Returns commander program that defines the CLI. + * @param log - Console logger. + * @returns The CLI. + */ +export function getProgram(log: LogFn): Command { + const program = new Command(); + + program.name('bb-cli').description('CLI for interacting with Barretenberg.'); + + program + .command('protocol-circuits') + .description('Lists the available protocol circuit artifacts') + .action(() => { + log(Object.keys(ProtocolCircuitArtifacts).reduce((prev: string, x: string) => prev.concat(`\n${x}`))); + }); + + program + .command('write-pk') + .description('Generates the proving key for the specified circuit') + .requiredOption( + '-w, --working-directory ', + 'A directory to use for storing input/output files', + BB_WORKING_DIRECTORY, + ) + .requiredOption('-b, --bb-path ', 'The path to the BB binary', BB_BINARY_PATH) + .requiredOption('-c, --circuit ', 'The name of a protocol circuit') + .action(async options => { + const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact]; + if (!compiledCircuit) { + log(`Failed to find circuit ${options.circuit}`); + return; + } + try { + await fs.access(options.workingDirectory, fs.constants.W_OK); + } catch (error) { + log(`Working directory does not exist`); + return; + } + await generateKeyForNoirCircuit( + options.bbPath, + options.workingDirectory, + options.circuit, + compiledCircuit, + 'pk', + log, + ); + }); + + program + .command('write-vk') + .description('Generates the verification key for the specified circuit') + .requiredOption( + '-w, --working-directory ', + 'A directory to use for storing input/output files', + BB_WORKING_DIRECTORY, + ) + .requiredOption('-b, --bb-path ', 'The path to the BB binary', BB_BINARY_PATH) + .requiredOption('-c, --circuit ', 'The name of a protocol circuit') + .action(async options => { + const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact]; + if (!compiledCircuit) { + log(`Failed to find circuit ${options.circuit}`); + return; + } + try { + await fs.access(options.workingDirectory, fs.constants.W_OK); + } catch (error) { + log(`Working directory does not exist`); + return; + } + await generateKeyForNoirCircuit( + options.bbPath, + options.workingDirectory, + options.circuit, + compiledCircuit, + 'vk', + log, + ); + }); + return program; +} diff --git a/yarn-project/bb-prover/src/bb/execute.ts b/yarn-project/bb-prover/src/bb/execute.ts new file mode 100644 index 00000000000..d899d2a13a8 --- /dev/null +++ b/yarn-project/bb-prover/src/bb/execute.ts @@ -0,0 +1,359 @@ +import { sha256 } from '@aztec/foundation/crypto'; +import { type LogFn } from '@aztec/foundation/log'; +import { Timer } from '@aztec/foundation/timer'; +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import * as proc from 'child_process'; +import * as fs from 'fs/promises'; + +export const VK_FILENAME = 'vk'; +export const VK_FIELDS_FILENAME = 'vk_fields.json'; +export const PROOF_FILENAME = 'proof'; +export const PROOF_FIELDS_FILENAME = 'proof_fields.json'; + +export enum BB_RESULT { + SUCCESS, + FAILURE, + ALREADY_PRESENT, +} + +export type BBSuccess = { + status: BB_RESULT.SUCCESS | BB_RESULT.ALREADY_PRESENT; + duration: number; + pkPath?: string; + vkPath?: string; + proofPath?: string; +}; + +export type BBFailure = { + status: BB_RESULT.FAILURE; + reason: string; +}; + +export type BBResult = BBSuccess | BBFailure; + +/** + * Invokes the Barretenberg binary with the provided command and args + * @param pathToBB - The path to the BB binary + * @param command - The command to execute + * @param args - The arguments to pass + * @param logger - A log function + * @param resultParser - An optional handler for detecting success or failure + * @returns The completed partial witness outputted from the circuit + */ +export function executeBB( + pathToBB: string, + command: string, + args: string[], + logger: LogFn, + resultParser = (code: number) => code === 0, +) { + return new Promise((resolve, reject) => { + // spawn the bb process + const bb = proc.spawn(pathToBB, [command, ...args]); + bb.stdout.on('data', data => { + const message = data.toString('utf-8').replace(/\n$/, ''); + logger(message); + }); + bb.stderr.on('data', data => { + const message = data.toString('utf-8').replace(/\n$/, ''); + logger(message); + }); + bb.on('close', (code: number) => { + if (resultParser(code)) { + resolve(BB_RESULT.SUCCESS); + } else { + reject(); + } + }); + }).catch(_ => BB_RESULT.FAILURE); +} + +const bytecodeHashFilename = 'bytecode_hash'; +const bytecodeFilename = 'bytecode'; + +/** + * Used for generating either a proving or verification key, will exit early if the key already exists + * It assumes the provided working directory is one where the caller wishes to maintain a permanent set of keys + * It is not considered a temporary directory + * @param pathToBB - The full path to the bb binary + * @param workingDirectory - The directory into which the key should be created + * @param circuitName - An identifier for the circuit + * @param compiledCircuit - The compiled circuit + * @param key - The type of key, either 'pk' or 'vk' + * @param log - A logging function + * @param force - Force the key to be regenerated even if it already exists + * @returns An instance of BBResult + */ +export async function generateKeyForNoirCircuit( + pathToBB: string, + workingDirectory: string, + circuitName: string, + compiledCircuit: NoirCompiledCircuit, + key: 'vk' | 'pk', + log: LogFn, + force = false, +): Promise { + const bytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); + + // The key generation is written to e.g. /workingDirectory/pk/BaseParityArtifact/pk + // The bytecode hash file is also written here as /workingDirectory/pk/BaseParityArtifact/bytecode-hash + // The bytecode is written to e.g. /workingDirectory/pk/BaseParityArtifact/bytecode + // The bytecode is removed after the key is generated, leaving just the hash file + const circuitOutputDirectory = `${workingDirectory}/${key}/${circuitName}`; + const bytecodeHashPath = `${circuitOutputDirectory}/${bytecodeHashFilename}`; + const bytecodePath = `${circuitOutputDirectory}/${bytecodeFilename}`; + const bytecodeHash = sha256(bytecode); + + const outputPath = `${circuitOutputDirectory}`; + + // ensure the directory exists + await fs.mkdir(circuitOutputDirectory, { recursive: true }); + + // Generate the key if we have been told to, or there is no bytecode hash + let mustRegenerate = + force || + (await fs + .access(bytecodeHashPath, fs.constants.R_OK) + .then(_ => false) + .catch(_ => true)); + + if (!mustRegenerate) { + // Check to see if the bytecode hash has changed from the stored value + const data: Buffer = await fs.readFile(bytecodeHashPath).catch(_ => Buffer.alloc(0)); + mustRegenerate = data.length == 0 || !data.equals(bytecodeHash); + } + + if (!mustRegenerate) { + // No need to generate, early out + return { + status: BB_RESULT.ALREADY_PRESENT, + duration: 0, + pkPath: key === 'pk' ? outputPath : undefined, + vkPath: key === 'vk' ? outputPath : undefined, + proofPath: undefined, + }; + } + + // Check we have access to bb + const binaryPresent = await fs + .access(pathToBB, fs.constants.R_OK) + .then(_ => true) + .catch(_ => false); + if (!binaryPresent) { + return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; + } + + // We are now going to generate the key + try { + // Write the bytecode to the working directory + await fs.writeFile(bytecodePath, bytecode); + + // args are the output path and the input bytecode path + const args = ['-o', outputPath, '-b', bytecodePath]; + const timer = new Timer(); + let result = await executeBB(pathToBB, `write_${key}`, args, log); + // If we succeeded and the type of key if verification, have bb write the 'fields' version too + if (result == BB_RESULT.SUCCESS && key === 'vk') { + const asFieldsArgs = ['-k', `${outputPath}/${VK_FILENAME}`, '-o', `${outputPath}/${VK_FIELDS_FILENAME}`, '-v']; + result = await executeBB(pathToBB, `vk_as_fields`, asFieldsArgs, log); + } + const duration = timer.ms(); + // Cleanup the bytecode file + await fs.rm(bytecodePath, { force: true }); + if (result == BB_RESULT.SUCCESS) { + // Store the bytecode hash so we don't need to regenerate at a later time + await fs.writeFile(bytecodeHashPath, bytecodeHash); + return { + status: BB_RESULT.SUCCESS, + duration, + pkPath: key === 'pk' ? outputPath : undefined, + vkPath: key === 'vk' ? outputPath : undefined, + proofPath: undefined, + }; + } + // Not a great error message here but it is difficult to decipher what comes from bb + return { status: BB_RESULT.FAILURE, reason: `Failed to generate key` }; + } catch (error) { + return { status: BB_RESULT.FAILURE, reason: `${error}` }; + } +} + +/** + * Used for generating proofs of noir circuits. + * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof. + * @param pathToBB - The full path to the bb binary + * @param workingDirectory - A working directory for use by bb + * @param circuitName - An identifier for the circuit + * @param bytecode - The compiled circuit bytecode + * @param inputWitnessFile - The circuit input witness + * @param log - A logging function + * @returns An object containing a result indication, the location of the proof and the duration taken + */ +export async function generateProof( + pathToBB: string, + workingDirectory: string, + circuitName: string, + bytecode: Buffer, + inputWitnessFile: string, + log: LogFn, +): Promise { + // Check that the working directory exists + try { + await fs.access(workingDirectory); + } catch (error) { + return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` }; + } + + // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode + const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`; + + // The proof is written to e.g. /workingDirectory/proof + const outputPath = `${workingDirectory}`; + + const binaryPresent = await fs + .access(pathToBB, fs.constants.R_OK) + .then(_ => true) + .catch(_ => false); + if (!binaryPresent) { + return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; + } + + try { + // Write the bytecode to the working directory + await fs.writeFile(bytecodePath, bytecode); + const args = ['-o', outputPath, '-b', bytecodePath, '-w', inputWitnessFile, '-v']; + const timer = new Timer(); + const logFunction = (message: string) => { + log(`${circuitName} BB out - ${message}`); + }; + const result = await executeBB(pathToBB, 'prove_output_all', args, logFunction); + const duration = timer.ms(); + // cleanup the bytecode + await fs.rm(bytecodePath, { force: true }); + if (result == BB_RESULT.SUCCESS) { + return { + status: BB_RESULT.SUCCESS, + duration, + proofPath: `${outputPath}`, + pkPath: undefined, + vkPath: `${outputPath}`, + }; + } + // Not a great error message here but it is difficult to decipher what comes from bb + return { status: BB_RESULT.FAILURE, reason: `Failed to generate proof` }; + } catch (error) { + return { status: BB_RESULT.FAILURE, reason: `${error}` }; + } +} + +/** + * Used for verifying proofs of noir circuits + * @param pathToBB - The full path to the bb binary + * @param proofFullPath - The full path to the proof to be verified + * @param verificationKeyPath - The full path to the circuit verification key + * @param log - A logging function + * @returns An object containing a result indication and duration taken + */ +export async function verifyProof( + pathToBB: string, + proofFullPath: string, + verificationKeyPath: string, + log: LogFn, +): Promise { + const binaryPresent = await fs + .access(pathToBB, fs.constants.R_OK) + .then(_ => true) + .catch(_ => false); + if (!binaryPresent) { + return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; + } + + try { + const args = ['-p', proofFullPath, '-k', verificationKeyPath]; + const timer = new Timer(); + const result = await executeBB(pathToBB, 'verify', args, log); + const duration = timer.ms(); + if (result == BB_RESULT.SUCCESS) { + return { status: BB_RESULT.SUCCESS, duration }; + } + // Not a great error message here but it is difficult to decipher what comes from bb + return { status: BB_RESULT.FAILURE, reason: `Failed to verify proof` }; + } catch (error) { + return { status: BB_RESULT.FAILURE, reason: `${error}` }; + } +} + +/** + * Used for verifying proofs of noir circuits + * @param pathToBB - The full path to the bb binary + * @param verificationKeyPath - The directory containing the binary verification key + * @param verificationKeyFilename - The filename of the verification key + * @param log - A logging function + * @returns An object containing a result indication and duration taken + */ +export async function writeVkAsFields( + pathToBB: string, + verificationKeyPath: string, + verificationKeyFilename: string, + log: LogFn, +): Promise { + const binaryPresent = await fs + .access(pathToBB, fs.constants.R_OK) + .then(_ => true) + .catch(_ => false); + if (!binaryPresent) { + return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; + } + + try { + const args = ['-k', `${verificationKeyPath}/${verificationKeyFilename}`, '-v']; + const timer = new Timer(); + const result = await executeBB(pathToBB, 'vk_as_fields', args, log); + const duration = timer.ms(); + if (result == BB_RESULT.SUCCESS) { + return { status: BB_RESULT.SUCCESS, duration, vkPath: verificationKeyPath }; + } + // Not a great error message here but it is difficult to decipher what comes from bb + return { status: BB_RESULT.FAILURE, reason: `Failed to create vk as fields` }; + } catch (error) { + return { status: BB_RESULT.FAILURE, reason: `${error}` }; + } +} + +/** + * Used for verifying proofs of noir circuits + * @param pathToBB - The full path to the bb binary + * @param proofPath - The directory containing the binary proof + * @param proofFileName - The filename of the proof + * @param log - A logging function + * @returns An object containing a result indication and duration taken + */ +export async function writeProofAsFields( + pathToBB: string, + proofPath: string, + proofFileName: string, + log: LogFn, +): Promise { + const binaryPresent = await fs + .access(pathToBB, fs.constants.R_OK) + .then(_ => true) + .catch(_ => false); + if (!binaryPresent) { + return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; + } + + try { + const args = ['-p', `${proofPath}/${proofFileName}`, '-v']; + const timer = new Timer(); + const result = await executeBB(pathToBB, 'proof_as_fields', args, log); + const duration = timer.ms(); + if (result == BB_RESULT.SUCCESS) { + return { status: BB_RESULT.SUCCESS, duration, proofPath: proofPath }; + } + // Not a great error message here but it is difficult to decipher what comes from bb + return { status: BB_RESULT.FAILURE, reason: `Failed to create proof as fields` }; + } catch (error) { + return { status: BB_RESULT.FAILURE, reason: `${error}` }; + } +} diff --git a/yarn-project/bb-prover/src/bb/index.ts b/yarn-project/bb-prover/src/bb/index.ts new file mode 100644 index 00000000000..9a19d22b742 --- /dev/null +++ b/yarn-project/bb-prover/src/bb/index.ts @@ -0,0 +1,23 @@ +#!/usr/bin/env -S node --no-warnings +import { createConsoleLogger } from '@aztec/foundation/log'; + +import 'source-map-support/register.js'; + +import { getProgram } from './cli.js'; + +const log = createConsoleLogger(); + +/** CLI main entrypoint */ +async function main() { + process.once('SIGINT', () => process.exit(0)); + process.once('SIGTERM', () => process.exit(0)); + + const program = getProgram(log); + await program.parseAsync(process.argv); +} + +main().catch(err => { + log(`Error in command execution`); + log(err); + process.exit(1); +}); diff --git a/yarn-project/bb-prover/src/index.ts b/yarn-project/bb-prover/src/index.ts new file mode 100644 index 00000000000..defdca1a936 --- /dev/null +++ b/yarn-project/bb-prover/src/index.ts @@ -0,0 +1,2 @@ +export * from './prover/index.js'; +export * from './test/index.js'; diff --git a/yarn-project/bb-prover/src/mappings/mappings.ts b/yarn-project/bb-prover/src/mappings/mappings.ts new file mode 100644 index 00000000000..965ab4c3bde --- /dev/null +++ b/yarn-project/bb-prover/src/mappings/mappings.ts @@ -0,0 +1,41 @@ +import { PublicKernelType } from '@aztec/circuit-types'; +import { type PublicKernelCircuitPrivateInputs, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; +import { + type ServerProtocolArtifact, + convertPublicInnerRollupInputsToWitnessMap, + convertPublicInnerRollupOutputFromWitnessMap, + convertPublicSetupRollupInputsToWitnessMap, + convertPublicSetupRollupOutputFromWitnessMap, + convertPublicTeardownRollupInputsToWitnessMap, + convertPublicTeardownRollupOutputFromWitnessMap, +} from '@aztec/noir-protocol-circuits-types'; + +import { type WitnessMap } from '@noir-lang/types'; + +export type PublicKernelProvingOps = { + artifact: ServerProtocolArtifact; + convertInputs: (inputs: PublicKernelCircuitPrivateInputs) => WitnessMap; + convertOutputs: (outputs: WitnessMap) => PublicKernelCircuitPublicInputs; +}; + +export type KernelTypeToArtifact = Record; + +export const PublicKernelArtifactMapping: KernelTypeToArtifact = { + [PublicKernelType.NON_PUBLIC]: undefined, + [PublicKernelType.APP_LOGIC]: { + artifact: 'PublicKernelAppLogicArtifact', + convertInputs: convertPublicInnerRollupInputsToWitnessMap, + convertOutputs: convertPublicInnerRollupOutputFromWitnessMap, + }, + [PublicKernelType.SETUP]: { + artifact: 'PublicKernelSetupArtifact', + convertInputs: convertPublicSetupRollupInputsToWitnessMap, + convertOutputs: convertPublicSetupRollupOutputFromWitnessMap, + }, + [PublicKernelType.TEARDOWN]: { + artifact: 'PublicKernelTeardownArtifact', + convertInputs: convertPublicTeardownRollupInputsToWitnessMap, + convertOutputs: convertPublicTeardownRollupOutputFromWitnessMap, + }, + [PublicKernelType.TAIL]: undefined, +}; diff --git a/yarn-project/pxe/src/kernel_prover/bb_prover/bb_native_proof_creator.ts b/yarn-project/bb-prover/src/prover/bb_native_proof_creator.ts similarity index 50% rename from yarn-project/pxe/src/kernel_prover/bb_prover/bb_native_proof_creator.ts rename to yarn-project/bb-prover/src/prover/bb_native_proof_creator.ts index cfb7c5d8870..977200103a8 100644 --- a/yarn-project/pxe/src/kernel_prover/bb_prover/bb_native_proof_creator.ts +++ b/yarn-project/bb-prover/src/prover/bb_native_proof_creator.ts @@ -1,3 +1,4 @@ +import { type AppCircuitProofOutput, type KernelProofOutput, type ProofCreator } from '@aztec/circuit-types'; import { Fr, NESTED_RECURSIVE_PROOF_LENGTH, @@ -14,10 +15,9 @@ import { VerificationKeyAsFields, } from '@aztec/circuits.js'; import { siloNoteHash } from '@aztec/circuits.js/hash'; -import { randomBytes, sha256 } from '@aztec/foundation/crypto'; -import { type LogFn, createDebugLogger } from '@aztec/foundation/log'; +import { randomBytes } from '@aztec/foundation/crypto'; +import { createDebugLogger } from '@aztec/foundation/log'; import { type Tuple } from '@aztec/foundation/serialize'; -import { Timer } from '@aztec/foundation/timer'; import { ClientCircuitArtifacts, type ClientProtocolArtifact, @@ -33,378 +33,33 @@ import { import { type ACVMField, WASMSimulator } from '@aztec/simulator'; import { type NoirCompiledCircuit } from '@aztec/types/noir'; -import { type WitnessMap } from '@noir-lang/acvm_js'; import { serializeWitness } from '@noir-lang/noirc_abi'; -import * as proc from 'child_process'; +import { type WitnessMap } from '@noir-lang/types'; import * as fs from 'fs/promises'; -import { type AppCircuitProofOutput, type KernelProofOutput, type ProofCreator } from '../interface/proof_creator.js'; - -/** - * Temporary implementation of ProofCreator using the native bb binary. - * Will be replaced by the WASM equivalent once ready - */ - -const VK_FILENAME = 'vk'; -const VK_FIELDS_FILENAME = 'vk_fields.json'; -const PROOF_FILENAME = 'proof'; -const PROOF_FIELDS_FILENAME = 'proof_fields.json'; - -const AGGREGATION_OBJECT_SIZE = 16; -const CIRCUIT_SIZE_INDEX = 3; -const CIRCUIT_PUBLIC_INPUTS_INDEX = 4; -const CIRCUIT_RECURSIVE_INDEX = 5; - -enum BB_RESULT { - SUCCESS, - FAILURE, - ALREADY_PRESENT, -} - -type BBSuccess = { - status: BB_RESULT.SUCCESS | BB_RESULT.ALREADY_PRESENT; - duration: number; - pkPath?: string; - vkPath?: string; - proofPath?: string; -}; - -type BBFailure = { - status: BB_RESULT.FAILURE; - reason: string; -}; - -/** - * Invokes the Barretenberg binary with the provided command and args - * @param pathToBB - The path to the BB binary - * @param command - The command to execute - * @param args - The arguments to pass - * @param logger - A log function - * @param resultParser - An optional handler for detecting success or failure - * @returns The completed partial witness outputted from the circuit - */ -function executeBB( - pathToBB: string, - command: string, - args: string[], - logger: LogFn, - resultParser = (code: number) => code === 0, -) { - return new Promise((resolve, reject) => { - // spawn the bb process - const bb = proc.spawn(pathToBB, [command, ...args]); - bb.stdout.on('data', data => { - const message = data.toString('utf-8').replace(/\n$/, ''); - logger(message); - }); - bb.stderr.on('data', data => { - const message = data.toString('utf-8').replace(/\n$/, ''); - logger(message); - }); - bb.on('close', (code: number) => { - if (resultParser(code)) { - resolve(BB_RESULT.SUCCESS); - } else { - reject(); - } - }); - }).catch(_ => BB_RESULT.FAILURE); -} - -/** - * Used for generating proofs of noir circuits. - * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof. - * @param pathToBB - The full path to the bb binary - * @param workingDirectory - A working directory for use by bb - * @param circuitName - An identifier for the circuit - * @param bytecode - The compiled circuit bytecode - * @param inputWitnessFile - The circuit input witness - * @param log - A logging function - * @returns An object containing a result indication, the location of the proof and the duration taken - */ -export async function generateProof( - pathToBB: string, - workingDirectory: string, - circuitName: string, - bytecode: Buffer, - inputWitnessFile: string, - log: LogFn, -): Promise { - // Check that the working directory exists - try { - await fs.access(workingDirectory); - } catch (error) { - return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` }; - } - - // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode - const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`; - - // The proof is written to e.g. /workingDirectory/proof - const outputPath = `${workingDirectory}`; - - const binaryPresent = await fs - .access(pathToBB, fs.constants.R_OK) - .then(_ => true) - .catch(_ => false); - if (!binaryPresent) { - return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; - } - - try { - // Write the bytecode to the working directory - await fs.writeFile(bytecodePath, bytecode); - const args = ['-o', outputPath, '-b', bytecodePath, '-w', inputWitnessFile, '-v']; - const timer = new Timer(); - const logFunction = (message: string) => { - log(`${circuitName} BB out - ${message}`); - }; - const result = await executeBB(pathToBB, 'prove_output_all', args, logFunction); - const duration = timer.ms(); - // cleanup the bytecode - await fs.rm(bytecodePath, { force: true }); - if (result == BB_RESULT.SUCCESS) { - return { - status: BB_RESULT.SUCCESS, - duration, - proofPath: `${outputPath}`, - pkPath: undefined, - vkPath: `${outputPath}`, - }; - } - // Not a great error message here but it is difficult to decipher what comes from bb - return { status: BB_RESULT.FAILURE, reason: `Failed to generate proof` }; - } catch (error) { - return { status: BB_RESULT.FAILURE, reason: `${error}` }; - } -} - -/** - * Used for verifying proofs of noir circuits - * @param pathToBB - The full path to the bb binary - * @param proofFullPath - The full path to the proof to be verified - * @param verificationKeyPath - The full path to the circuit verification key - * @param log - A logging function - * @returns An object containing a result indication and duration taken - */ -async function verifyProof( - pathToBB: string, - proofFullPath: string, - verificationKeyPath: string, - log: LogFn, -): Promise { - const binaryPresent = await fs - .access(pathToBB, fs.constants.R_OK) - .then(_ => true) - .catch(_ => false); - if (!binaryPresent) { - return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; - } - - try { - const args = ['-p', proofFullPath, '-k', verificationKeyPath]; - const timer = new Timer(); - const result = await executeBB(pathToBB, 'verify', args, log); - const duration = timer.ms(); - if (result == BB_RESULT.SUCCESS) { - return { status: BB_RESULT.SUCCESS, duration }; - } - // Not a great error message here but it is difficult to decipher what comes from bb - return { status: BB_RESULT.FAILURE, reason: `Failed to verify proof` }; - } catch (error) { - return { status: BB_RESULT.FAILURE, reason: `${error}` }; - } -} - -const bytecodeHashFilename = 'bytecode_hash'; -const bytecodeFilename = 'bytecode'; - -/** - * Used for generating either a proving or verification key, will exit early if the key already exists - * It assumes the provided working directory is one where the caller wishes to maintain a permanent set of keys - * It is not considered a temporary directory - * @param pathToBB - The full path to the bb binary - * @param workingDirectory - The directory into which the key should be created - * @param circuitName - An identifier for the circuit - * @param compiledCircuit - The compiled circuit - * @param key - The type of key, either 'pk' or 'vk' - * @param log - A logging function - * @param force - Force the key to be regenerated even if it already exists - * @returns An instance of BBResult - */ -export async function generateKeyForNoirCircuit( - pathToBB: string, - workingDirectory: string, - circuitName: string, - compiledCircuit: NoirCompiledCircuit, - key: 'vk' | 'pk', - log: LogFn, - force = false, -): Promise { - const bytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); - - // The key generation is written to e.g. /workingDirectory/pk/BaseParityArtifact/pk - // The bytecode hash file is also written here as /workingDirectory/pk/BaseParityArtifact/bytecode-hash - // The bytecode is written to e.g. /workingDirectory/pk/BaseParityArtifact/bytecode - // The bytecode is removed after the key is generated, leaving just the hash file - const circuitOutputDirectory = `${workingDirectory}/${key}/${circuitName}`; - const bytecodeHashPath = `${circuitOutputDirectory}/${bytecodeHashFilename}`; - const bytecodePath = `${circuitOutputDirectory}/${bytecodeFilename}`; - const bytecodeHash = sha256(bytecode); - - const outputPath = `${circuitOutputDirectory}`; - - // ensure the directory exists - await fs.mkdir(circuitOutputDirectory, { recursive: true }); - - // Generate the key if we have been told to, or there is no bytecode hash - let mustRegenerate = - force || - (await fs - .access(bytecodeHashPath, fs.constants.R_OK) - .then(_ => false) - .catch(_ => true)); - - if (!mustRegenerate) { - // Check to see if the bytecode hash has changed from the stored value - const data: Buffer = await fs.readFile(bytecodeHashPath).catch(_ => Buffer.alloc(0)); - mustRegenerate = data.length == 0 || !data.equals(bytecodeHash); - } - - if (!mustRegenerate) { - // No need to generate, early out - return { - status: BB_RESULT.ALREADY_PRESENT, - duration: 0, - pkPath: key === 'pk' ? outputPath : undefined, - vkPath: key === 'vk' ? outputPath : undefined, - proofPath: undefined, - }; - } - - // Check we have access to bb - const binaryPresent = await fs - .access(pathToBB, fs.constants.R_OK) - .then(_ => true) - .catch(_ => false); - if (!binaryPresent) { - return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; - } - - // We are now going to generate the key - try { - // Write the bytecode to the working directory - await fs.writeFile(bytecodePath, bytecode); - - // args are the output path and the input bytecode path - const args = ['-o', `${outputPath}/${VK_FILENAME}`, '-b', bytecodePath]; - const timer = new Timer(); - let result = await executeBB(pathToBB, `write_${key}`, args, log); - // If we succeeded and the type of key if verification, have bb write the 'fields' version too - if (result == BB_RESULT.SUCCESS && key === 'vk') { - const asFieldsArgs = ['-k', `${outputPath}/${VK_FILENAME}`, '-o', `${outputPath}/${VK_FIELDS_FILENAME}`, '-v']; - result = await executeBB(pathToBB, `vk_as_fields`, asFieldsArgs, log); - } - const duration = timer.ms(); - // Cleanup the bytecode file - await fs.rm(bytecodePath, { force: true }); - if (result == BB_RESULT.SUCCESS) { - // Store the bytecode hash so we don't need to regenerate at a later time - await fs.writeFile(bytecodeHashPath, bytecodeHash); - return { - status: BB_RESULT.SUCCESS, - duration, - pkPath: key === 'pk' ? outputPath : undefined, - vkPath: key === 'vk' ? outputPath : undefined, - proofPath: undefined, - }; - } - // Not a great error message here but it is difficult to decipher what comes from bb - return { status: BB_RESULT.FAILURE, reason: `Failed to generate key` }; - } catch (error) { - return { status: BB_RESULT.FAILURE, reason: `${error}` }; - } -} - -/** - * Used for verifying proofs of noir circuits - * @param pathToBB - The full path to the bb binary - * @param verificationKeyPath - The directory containing the binary verification key - * @param verificationKeyFilename - The filename of the verification key - * @param log - A logging function - * @returns An object containing a result indication and duration taken - */ -// async function writeVkAsFields( -// pathToBB: string, -// verificationKeyPath: string, -// verificationKeyFilename: string, -// log: LogFn, -// ): Promise { -// const binaryPresent = await fs -// .access(pathToBB, fs.constants.R_OK) -// .then(_ => true) -// .catch(_ => false); -// if (!binaryPresent) { -// return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; -// } - -// try { -// const args = ['-k', `${verificationKeyPath}/${verificationKeyFilename}`, '-v']; -// const timer = new Timer(); -// const result = await executeBB(pathToBB, 'vk_as_fields', args, log); -// const duration = timer.ms(); -// if (result == BB_RESULT.SUCCESS) { -// return { status: BB_RESULT.SUCCESS, duration, vkPath: verificationKeyPath }; -// } -// // Not a great error message here but it is difficult to decipher what comes from bb -// return { status: BB_RESULT.FAILURE, reason: `Failed to create vk as fields` }; -// } catch (error) { -// return { status: BB_RESULT.FAILURE, reason: `${error}` }; -// } -// } - -/** - * Used for verifying proofs of noir circuits - * @param pathToBB - The full path to the bb binary - * @param proofPath - The directory containing the binary proof - * @param proofFileName - The filename of the proof - * @param log - A logging function - * @returns An object containing a result indication and duration taken - */ -// async function writeProofAsFields( -// pathToBB: string, -// proofPath: string, -// proofFileName: string, -// log: LogFn, -// ): Promise { -// const binaryPresent = await fs -// .access(pathToBB, fs.constants.R_OK) -// .then(_ => true) -// .catch(_ => false); -// if (!binaryPresent) { -// return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; -// } - -// try { -// const args = ['-p', `${proofPath}/${proofFileName}`, '-v']; -// const timer = new Timer(); -// const result = await executeBB(pathToBB, 'proof_as_fields', args, log); -// const duration = timer.ms(); -// if (result == BB_RESULT.SUCCESS) { -// return { status: BB_RESULT.SUCCESS, duration, proofPath: proofPath }; -// } -// // Not a great error message here but it is difficult to decipher what comes from bb -// return { status: BB_RESULT.FAILURE, reason: `Failed to create proof as fields` }; -// } catch (error) { -// return { status: BB_RESULT.FAILURE, reason: `${error}` }; -// } -// } +import { + BB_RESULT, + PROOF_FIELDS_FILENAME, + PROOF_FILENAME, + VK_FIELDS_FILENAME, + VK_FILENAME, + generateKeyForNoirCircuit, + generateProof, + verifyProof, +} from '../bb/execute.js'; +import { + AGGREGATION_OBJECT_SIZE, + CIRCUIT_PUBLIC_INPUTS_INDEX, + CIRCUIT_RECURSIVE_INDEX, + CIRCUIT_SIZE_INDEX, + type VerificationKeyData, +} from './verification_key_data.js'; type PrivateKernelProvingOps = { convertOutputs: (outputs: WitnessMap) => PrivateKernelCircuitPublicInputs | PrivateKernelTailCircuitPublicInputs; }; -const KernelArtifactMapping: Record = { +const PrivateKernelArtifactMapping: Record = { PrivateKernelInitArtifact: { convertOutputs: convertPrivateKernelInitOutputsFromWitnessMap, }, @@ -419,15 +74,6 @@ const KernelArtifactMapping: Record; - keyAsBytes: Buffer; - numPublicInputs: number; - circuitSize: number; - isRecursive: boolean; -}; - /** * This proof creator implementation uses the native bb binary. * This is a temporary implementation until we make the WASM version work. @@ -644,7 +290,7 @@ export class BBNativeProofCreator implements ProofCreator { this.log.debug(`Generated witness for ${circuitType}`); - const publicInputs = KernelArtifactMapping[circuitType].convertOutputs(outputWitness) as T; + const publicInputs = PrivateKernelArtifactMapping[circuitType].convertOutputs(outputWitness) as T; const proofOutput = await this.createProof( directory, diff --git a/yarn-project/prover-client/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts similarity index 97% rename from yarn-project/prover-client/src/prover/bb_prover.ts rename to yarn-project/bb-prover/src/prover/bb_prover.ts index fab61da5c1e..bca2596b015 100644 --- a/yarn-project/prover-client/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -4,6 +4,7 @@ import { type PublicKernelNonTailRequest, type PublicKernelTailRequest, PublicKernelType, + type ServerCircuitProver, makePublicInputsAndProof, } from '@aztec/circuit-types'; import { @@ -63,16 +64,19 @@ import { generateProof, verifyProof, } from '../bb/execute.js'; +import { PublicKernelArtifactMapping } from '../mappings/mappings.js'; import { circuitTypeToCircuitName, emitCircuitProvingStats, emitCircuitWitnessGenerationStats } from '../stats.js'; -import { type CircuitProver, KernelArtifactMapping } from './interface.js'; +import { + AGGREGATION_OBJECT_SIZE, + CIRCUIT_PUBLIC_INPUTS_INDEX, + CIRCUIT_RECURSIVE_INDEX, + CIRCUIT_SIZE_INDEX, + type VerificationKeyData, +} from './verification_key_data.js'; const logger = createDebugLogger('aztec:bb-prover'); const CIRCUITS_WITHOUT_AGGREGATION: Set = new Set(['BaseParityArtifact']); -const AGGREGATION_OBJECT_SIZE = 16; -const CIRCUIT_SIZE_INDEX = 3; -const CIRCUIT_PUBLIC_INPUTS_INDEX = 4; -const CIRCUIT_RECURSIVE_INDEX = 5; export type BBProverConfig = { bbBinaryPath: string; @@ -83,19 +87,10 @@ export type BBProverConfig = { circuitFilter?: ServerProtocolArtifact[]; }; -type VerificationKeyData = { - hash: Fr; - keyAsFields: Tuple; - keyAsBytes: Buffer; - numPublicInputs: number; - circuitSize: number; - isRecursive: boolean; -}; - /** * Prover implementation that uses barretenberg native proving */ -export class BBNativeRollupProver implements CircuitProver { +export class BBNativeRollupProver implements ServerCircuitProver { private verificationKeys: Map> = new Map< ServerProtocolArtifact, Promise @@ -164,7 +159,7 @@ export class BBNativeRollupProver implements CircuitProver { public async getPublicKernelProof( kernelRequest: PublicKernelNonTailRequest, ): Promise> { - const kernelOps = KernelArtifactMapping[kernelRequest.type]; + const kernelOps = PublicKernelArtifactMapping[kernelRequest.type]; if (kernelOps === undefined) { throw new Error(`Unable to prove kernel type ${PublicKernelType[kernelRequest.type]}`); } @@ -287,7 +282,7 @@ export class BBNativeRollupProver implements CircuitProver { this.config.bbBinaryPath, bbWorkingDirectory, circuitType, - artifact, + Buffer.from(artifact.bytecode, 'base64'), outputWitnessFile, logger.debug, ); @@ -374,7 +369,7 @@ export class BBNativeRollupProver implements CircuitProver { this.config.bbBinaryPath, bbWorkingDirectory, circuitType, - artifact, + Buffer.from(artifact.bytecode, 'base64'), outputWitnessFile, logger.debug, ); diff --git a/yarn-project/bb-prover/src/prover/index.ts b/yarn-project/bb-prover/src/prover/index.ts new file mode 100644 index 00000000000..e3f2298b127 --- /dev/null +++ b/yarn-project/bb-prover/src/prover/index.ts @@ -0,0 +1,2 @@ +export * from './bb_prover.js'; +export * from './bb_native_proof_creator.js'; diff --git a/yarn-project/bb-prover/src/prover/verification_key_data.ts b/yarn-project/bb-prover/src/prover/verification_key_data.ts new file mode 100644 index 00000000000..2e8215e74d2 --- /dev/null +++ b/yarn-project/bb-prover/src/prover/verification_key_data.ts @@ -0,0 +1,16 @@ +import { type Fr, type VERIFICATION_KEY_LENGTH_IN_FIELDS } from '@aztec/circuits.js'; +import { type Tuple } from '@aztec/foundation/serialize'; + +export const AGGREGATION_OBJECT_SIZE = 16; +export const CIRCUIT_SIZE_INDEX = 3; +export const CIRCUIT_PUBLIC_INPUTS_INDEX = 4; +export const CIRCUIT_RECURSIVE_INDEX = 5; + +export type VerificationKeyData = { + hash: Fr; + keyAsFields: Tuple; + keyAsBytes: Buffer; + numPublicInputs: number; + circuitSize: number; + isRecursive: boolean; +}; diff --git a/yarn-project/bb-prover/src/stats.ts b/yarn-project/bb-prover/src/stats.ts new file mode 100644 index 00000000000..fbd68bde90b --- /dev/null +++ b/yarn-project/bb-prover/src/stats.ts @@ -0,0 +1,82 @@ +import { type PublicKernelRequest, PublicKernelType } from '@aztec/circuit-types'; +import type { CircuitName, CircuitProvingStats, CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; +import { type Logger } from '@aztec/foundation/log'; +import { type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; + +export function emitCircuitWitnessGenerationStats( + circuitName: CircuitName, + duration: number, + inputSize: number, + outputSize: number, + logger: Logger, +) { + const stats: CircuitWitnessGenerationStats = { + eventName: 'circuit-witness-generation', + circuitName, + inputSize, + outputSize, + duration, + }; + + logger.debug('Circuit witness generation stats', stats); +} + +export function emitCircuitProvingStats( + circuitName: CircuitName, + duration: number, + inputSize: number, + outputSize: number, + proofSize: number, + logger: Logger, +) { + const stats: CircuitProvingStats = { + eventName: 'circuit-proving', + circuitName, + duration, + inputSize, + outputSize, + proofSize, + }; + + logger.debug('Circuit proving stats', stats); +} + +export function mapPublicKernelToCircuitName(kernelType: PublicKernelRequest['type']): CircuitName { + switch (kernelType) { + case PublicKernelType.SETUP: + return 'public-kernel-setup'; + case PublicKernelType.APP_LOGIC: + return 'public-kernel-app-logic'; + case PublicKernelType.TEARDOWN: + return 'public-kernel-teardown'; + case PublicKernelType.TAIL: + return 'public-kernel-tail'; + default: + throw new Error(`Unknown kernel type: ${kernelType}`); + } +} + +export function circuitTypeToCircuitName(circuitType: ServerProtocolArtifact): CircuitName { + switch (circuitType) { + case 'BaseParityArtifact': + return 'base-parity'; + case 'RootParityArtifact': + return 'root-parity'; + case 'BaseRollupArtifact': + return 'base-rollup'; + case 'MergeRollupArtifact': + return 'merge-rollup'; + case 'RootRollupArtifact': + return 'root-rollup'; + case 'PublicKernelSetupArtifact': + return 'public-kernel-setup'; + case 'PublicKernelAppLogicArtifact': + return 'public-kernel-app-logic'; + case 'PublicKernelTeardownArtifact': + return 'public-kernel-teardown'; + case 'PublicKernelTailArtifact': + return 'public-kernel-tail'; + default: + throw new Error(`Unknown circuit type: ${circuitType}`); + } +} diff --git a/yarn-project/bb-prover/src/test/index.ts b/yarn-project/bb-prover/src/test/index.ts new file mode 100644 index 00000000000..17fafbb7289 --- /dev/null +++ b/yarn-project/bb-prover/src/test/index.ts @@ -0,0 +1 @@ +export * from './test_circuit_prover.js'; diff --git a/yarn-project/prover-client/src/prover/test_circuit_prover.ts b/yarn-project/bb-prover/src/test/test_circuit_prover.ts similarity index 95% rename from yarn-project/prover-client/src/prover/test_circuit_prover.ts rename to yarn-project/bb-prover/src/test/test_circuit_prover.ts index 266405f2896..edc993fd260 100644 --- a/yarn-project/prover-client/src/prover/test_circuit_prover.ts +++ b/yarn-project/bb-prover/src/test/test_circuit_prover.ts @@ -3,6 +3,7 @@ import { type PublicKernelNonTailRequest, type PublicKernelTailRequest, PublicKernelType, + type ServerCircuitProver, makePublicInputsAndProof, } from '@aztec/circuit-types'; import { @@ -46,10 +47,10 @@ import { convertSimulatedBaseRollupInputsToWitnessMap, convertSimulatedBaseRollupOutputsFromWitnessMap, } from '@aztec/noir-protocol-circuits-types'; -import { type SimulationProvider, WASMSimulator } from '@aztec/simulator'; +import { type SimulationProvider, WASMSimulator, emitCircuitSimulationStats } from '@aztec/simulator'; -import { emitCircuitSimulationStats, mapPublicKernelToCircuitName } from '../stats.js'; -import { type CircuitProver, KernelArtifactMapping } from './interface.js'; +import { PublicKernelArtifactMapping } from '../mappings/mappings.js'; +import { mapPublicKernelToCircuitName } from '../stats.js'; const VERIFICATION_KEYS: Record = { BaseParityArtifact: VerificationKeyAsFields.makeFake(), @@ -67,7 +68,7 @@ const VERIFICATION_KEYS: Record * A class for use in testing situations (e2e, unit test etc) * Simulates circuits using the most efficient method and performs no proving */ -export class TestCircuitProver implements CircuitProver { +export class TestCircuitProver implements ServerCircuitProver { private wasmSimulator = new WASMSimulator(); constructor( @@ -217,7 +218,7 @@ export class TestCircuitProver implements CircuitProver { kernelRequest: PublicKernelNonTailRequest, ): Promise> { const timer = new Timer(); - const kernelOps = KernelArtifactMapping[kernelRequest.type]; + const kernelOps = PublicKernelArtifactMapping[kernelRequest.type]; if (kernelOps === undefined) { throw new Error(`Unable to prove for kernel type ${PublicKernelType[kernelRequest.type]}`); } diff --git a/yarn-project/bb-prover/tsconfig.json b/yarn-project/bb-prover/tsconfig.json new file mode 100644 index 00000000000..d2906818893 --- /dev/null +++ b/yarn-project/bb-prover/tsconfig.json @@ -0,0 +1,26 @@ +{ + "extends": "..", + "compilerOptions": { + "outDir": "dest", + "rootDir": "src", + "tsBuildInfoFile": ".tsbuildinfo" + }, + "references": [ + { + "path": "../circuit-types" + }, + { + "path": "../circuits.js" + }, + { + "path": "../foundation" + }, + { + "path": "../noir-protocol-circuits-types" + }, + { + "path": "../simulator" + } + ], + "include": ["src"] +} diff --git a/yarn-project/circuit-types/src/interfaces/index.ts b/yarn-project/circuit-types/src/interfaces/index.ts index 5b13506853c..33a88a846c5 100644 --- a/yarn-project/circuit-types/src/interfaces/index.ts +++ b/yarn-project/circuit-types/src/interfaces/index.ts @@ -7,3 +7,5 @@ export * from './nullifier_tree.js'; export * from './prover-client.js'; export * from './proving-job.js'; export * from './block-prover.js'; +export * from './server_circuit_prover.js'; +export * from './proof_creator.js'; diff --git a/yarn-project/pxe/src/kernel_prover/interface/proof_creator.ts b/yarn-project/circuit-types/src/interfaces/proof_creator.ts similarity index 95% rename from yarn-project/pxe/src/kernel_prover/interface/proof_creator.ts rename to yarn-project/circuit-types/src/interfaces/proof_creator.ts index 5b93d698058..5181864cbb1 100644 --- a/yarn-project/pxe/src/kernel_prover/interface/proof_creator.ts +++ b/yarn-project/circuit-types/src/interfaces/proof_creator.ts @@ -11,7 +11,8 @@ import { type VerificationKeyAsFields, } from '@aztec/circuits.js'; import { type Fr } from '@aztec/foundation/fields'; -import { type ACVMField } from '@aztec/simulator'; + +import { type WitnessMap } from '@noir-lang/acvm_js'; /** * Represents the output of the proof creation process for init and inner private kernel circuit. @@ -93,5 +94,5 @@ export interface ProofCreator { * @param bytecode - The circuit bytecode in gzipped bincode format * @returns A Promise resolving to a Proof object */ - createAppCircuitProof(partialWitness: Map, bytecode: Buffer): Promise; + createAppCircuitProof(partialWitness: WitnessMap, bytecode: Buffer): Promise; } diff --git a/yarn-project/prover-client/src/prover/interface.ts b/yarn-project/circuit-types/src/interfaces/server_circuit_prover.ts similarity index 62% rename from yarn-project/prover-client/src/prover/interface.ts rename to yarn-project/circuit-types/src/interfaces/server_circuit_prover.ts index bed9add0d50..9a2b59e1c6b 100644 --- a/yarn-project/prover-client/src/prover/interface.ts +++ b/yarn-project/circuit-types/src/interfaces/server_circuit_prover.ts @@ -2,7 +2,6 @@ import { type PublicInputsAndProof, type PublicKernelNonTailRequest, type PublicKernelTailRequest, - PublicKernelType, } from '@aztec/circuit-types'; import { type BaseOrMergeRollupPublicInputs, @@ -13,7 +12,6 @@ import { type NESTED_RECURSIVE_PROOF_LENGTH, type Proof, type PublicCircuitPublicInputs, - type PublicKernelCircuitPrivateInputs, type PublicKernelCircuitPublicInputs, type RECURSIVE_PROOF_LENGTH, type RootParityInput, @@ -21,50 +19,11 @@ import { type RootRollupInputs, type RootRollupPublicInputs, } from '@aztec/circuits.js'; -import { - type ServerProtocolArtifact, - convertPublicInnerRollupInputsToWitnessMap, - convertPublicInnerRollupOutputFromWitnessMap, - convertPublicSetupRollupInputsToWitnessMap, - convertPublicSetupRollupOutputFromWitnessMap, - convertPublicTeardownRollupInputsToWitnessMap, - convertPublicTeardownRollupOutputFromWitnessMap, -} from '@aztec/noir-protocol-circuits-types'; - -import { type WitnessMap } from '@noir-lang/types'; - -export type PublicKernelProvingOps = { - artifact: ServerProtocolArtifact; - convertInputs: (inputs: PublicKernelCircuitPrivateInputs) => WitnessMap; - convertOutputs: (outputs: WitnessMap) => PublicKernelCircuitPublicInputs; -}; - -export type KernelTypeToArtifact = Record; - -export const KernelArtifactMapping: KernelTypeToArtifact = { - [PublicKernelType.NON_PUBLIC]: undefined, - [PublicKernelType.APP_LOGIC]: { - artifact: 'PublicKernelAppLogicArtifact', - convertInputs: convertPublicInnerRollupInputsToWitnessMap, - convertOutputs: convertPublicInnerRollupOutputFromWitnessMap, - }, - [PublicKernelType.SETUP]: { - artifact: 'PublicKernelSetupArtifact', - convertInputs: convertPublicSetupRollupInputsToWitnessMap, - convertOutputs: convertPublicSetupRollupOutputFromWitnessMap, - }, - [PublicKernelType.TEARDOWN]: { - artifact: 'PublicKernelTeardownArtifact', - convertInputs: convertPublicTeardownRollupInputsToWitnessMap, - convertOutputs: convertPublicTeardownRollupOutputFromWitnessMap, - }, - [PublicKernelType.TAIL]: undefined, -}; /** * Generates proofs for parity and rollup circuits. */ -export interface CircuitProver { +export interface ServerCircuitProver { /** * Creates a proof for the given input. * @param input - Input to the circuit. @@ -127,11 +86,6 @@ export interface CircuitProver { kernelRequest: PublicKernelTailRequest, signal?: AbortSignal, ): Promise>; - - /** - * Verifies a circuit proof - */ - verifyProof(artifact: ServerProtocolArtifact, proof: Proof, signal?: AbortSignal): Promise; } /** diff --git a/yarn-project/deploy_npm.sh b/yarn-project/deploy_npm.sh index b64c347f168..ea877aae2f1 100755 --- a/yarn-project/deploy_npm.sh +++ b/yarn-project/deploy_npm.sh @@ -96,6 +96,7 @@ deploy_package kv-store deploy_package merkle-tree deploy_package noir-protocol-circuits-types deploy_package simulator +deploy_package bb-prover deploy_package key-store deploy_package pxe deploy_package archiver diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index ea3a6893cfd..8ed6dcfc2c2 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -24,6 +24,7 @@ "@aztec/archiver": "workspace:^", "@aztec/aztec-node": "workspace:^", "@aztec/aztec.js": "workspace:^", + "@aztec/bb-prover": "workspace:^", "@aztec/circuit-types": "workspace:^", "@aztec/circuits.js": "workspace:^", "@aztec/entrypoints": "workspace:^", diff --git a/yarn-project/end-to-end/src/client_prover_integration/client_prover_integration.test.ts b/yarn-project/end-to-end/src/client_prover_integration/client_prover_integration.test.ts index 2cda2f3aa0c..504cfd955a0 100644 --- a/yarn-project/end-to-end/src/client_prover_integration/client_prover_integration.test.ts +++ b/yarn-project/end-to-end/src/client_prover_integration/client_prover_integration.test.ts @@ -1,6 +1,6 @@ import { type Tx } from '@aztec/aztec.js'; +import { type BBNativeProofCreator } from '@aztec/bb-prover'; import { type ClientProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; -import { type BBNativeProofCreator } from '@aztec/pxe'; import { ClientProverTest } from './client_prover_test.js'; diff --git a/yarn-project/end-to-end/src/client_prover_integration/client_prover_test.ts b/yarn-project/end-to-end/src/client_prover_integration/client_prover_test.ts index 54318e1702c..079d222d4d8 100644 --- a/yarn-project/end-to-end/src/client_prover_integration/client_prover_test.ts +++ b/yarn-project/end-to-end/src/client_prover_integration/client_prover_test.ts @@ -12,8 +12,9 @@ import { computeSecretHash, createDebugLogger, } from '@aztec/aztec.js'; +import { BBNativeProofCreator } from '@aztec/bb-prover'; import { TokenContract } from '@aztec/noir-contracts.js'; -import { BBNativeProofCreator, type PXEService } from '@aztec/pxe'; +import { type PXEService } from '@aztec/pxe'; import { waitRegisteredAccountSynced } from '../benchmarks/utils.js'; import { getBBConfig } from '../fixtures/get_bb_config.js'; diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 725d35a6ab6..f7bb329fd92 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -27,6 +27,7 @@ import { } from '@aztec/aztec.js'; import { deployInstance, registerContractClass } from '@aztec/aztec.js/deployment'; import { DefaultMultiCallEntrypoint } from '@aztec/aztec.js/entrypoint'; +import { type BBNativeProofCreator } from '@aztec/bb-prover'; import { CANONICAL_KEY_REGISTRY_ADDRESS, computeContractAddressFromInstance, @@ -54,13 +55,7 @@ import { GasTokenContract } from '@aztec/noir-contracts.js/GasToken'; import { getCanonicalGasToken, getCanonicalGasTokenAddress } from '@aztec/protocol-contracts/gas-token'; import { getCanonicalKeyRegistry } from '@aztec/protocol-contracts/key-registry'; import { type ProverClient } from '@aztec/prover-client'; -import { - type BBNativeProofCreator, - PXEService, - type PXEServiceConfig, - createPXEService, - getPXEServiceConfig, -} from '@aztec/pxe'; +import { PXEService, type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; import { type SequencerClient } from '@aztec/sequencer-client'; import { type Anvil, createAnvil } from '@viem/anvil'; diff --git a/yarn-project/end-to-end/tsconfig.json b/yarn-project/end-to-end/tsconfig.json index b0e697f1148..7273cee65f5 100644 --- a/yarn-project/end-to-end/tsconfig.json +++ b/yarn-project/end-to-end/tsconfig.json @@ -18,6 +18,9 @@ { "path": "../aztec.js" }, + { + "path": "../bb-prover" + }, { "path": "../circuit-types" }, diff --git a/yarn-project/package.json b/yarn-project/package.json index 2f7eda90e7a..fa08f05b063 100644 --- a/yarn-project/package.json +++ b/yarn-project/package.json @@ -24,6 +24,7 @@ "archiver", "aztec-faucet", "aztec-node", + "bb-prover", "pxe", "aztec", "aztec.js", diff --git a/yarn-project/prover-client/package.json b/yarn-project/prover-client/package.json index fff69ca9878..9c5545541d9 100644 --- a/yarn-project/prover-client/package.json +++ b/yarn-project/prover-client/package.json @@ -6,9 +6,6 @@ ".": "./dest/index.js", "./prover-pool": "./dest/prover-pool/index.js" }, - "bin": { - "bb-cli": "./dest/bb/index.js" - }, "typedocOptions": { "entryPoints": [ "./src/index.ts" @@ -53,6 +50,7 @@ ] }, "dependencies": { + "@aztec/bb-prover": "workspace:^", "@aztec/circuit-types": "workspace:^", "@aztec/circuits.js": "workspace:^", "@aztec/foundation": "workspace:^", diff --git a/yarn-project/prover-client/src/index.ts b/yarn-project/prover-client/src/index.ts index 4331fcaff0e..6df5be08b59 100644 --- a/yarn-project/prover-client/src/index.ts +++ b/yarn-project/prover-client/src/index.ts @@ -6,4 +6,3 @@ export * from './dummy-prover.js'; // Exported for integration_l1_publisher.test.ts export { getVerificationKeys } from './mocks/verification_keys.js'; -export { RealRollupCircuitSimulator } from './simulator/rollup.js'; diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index deafb1d9ef7..72e40d59259 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -1,4 +1,11 @@ -import { type BlockProver, type ProcessedTx, type Tx, type TxValidator } from '@aztec/circuit-types'; +import { type BBProverConfig } from '@aztec/bb-prover'; +import { + type BlockProver, + type ProcessedTx, + type ServerCircuitProver, + type Tx, + type TxValidator, +} from '@aztec/circuit-types'; import { type Gas, GlobalVariables, Header, type Nullifier, type TxContext } from '@aztec/circuits.js'; import { type Fr } from '@aztec/foundation/fields'; import { type DebugLogger } from '@aztec/foundation/log'; @@ -20,13 +27,11 @@ import { type MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; import * as fs from 'fs/promises'; import { type MockProxy, mock } from 'jest-mock-extended'; +import { TestCircuitProver } from '../../../bb-prover/src/test/test_circuit_prover.js'; import { ProvingOrchestrator } from '../orchestrator/orchestrator.js'; import { MemoryProvingQueue } from '../prover-pool/memory-proving-queue.js'; import { ProverAgent } from '../prover-pool/prover-agent.js'; import { ProverPool } from '../prover-pool/prover-pool.js'; -import { type BBProverConfig } from '../prover/bb_prover.js'; -import { type CircuitProver } from '../prover/interface.js'; -import { TestCircuitProver } from '../prover/test_circuit_prover.js'; import { getEnvironmentConfig, getSimulationProvider, makeGlobals } from './fixtures.js'; export class TestContext { @@ -38,7 +43,7 @@ export class TestContext { public simulationProvider: SimulationProvider, public globalVariables: GlobalVariables, public actualDb: MerkleTreeOperations, - public prover: CircuitProver, + public prover: ServerCircuitProver, public proverPool: ProverPool, public orchestrator: ProvingOrchestrator, public blockNumber: number, @@ -49,7 +54,7 @@ export class TestContext { static async new( logger: DebugLogger, proverCount = 4, - createProver: (bbConfig: BBProverConfig) => Promise = _ => + createProver: (bbConfig: BBProverConfig) => Promise = _ => Promise.resolve(new TestCircuitProver(new WASMSimulator())), blockNumber = 3, ) { @@ -70,7 +75,7 @@ export class TestContext { publicWorldStateDB, ); - let localProver: CircuitProver; + let localProver: ServerCircuitProver; const config = await getEnvironmentConfig(logger); const simulationProvider = await getSimulationProvider({ acvmWorkingDirectory: config?.acvmWorkingDirectory, diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index 9e03c88b08e..302f35acd5c 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -13,6 +13,7 @@ import { type ProvingResult, type ProvingTicket, type PublicInputsAndProof, + type ServerCircuitProver, } from '@aztec/circuit-types/interfaces'; import { type BaseOrMergeRollupPublicInputs, @@ -43,7 +44,6 @@ import { type MerkleTreeOperations } from '@aztec/world-state'; import { inspect } from 'util'; -import { type CircuitProver } from '../prover/interface.js'; import { buildBaseRollupInput, createMergeRollupInputs, @@ -82,7 +82,7 @@ export class ProvingOrchestrator { private provingState: ProvingState | undefined = undefined; private pendingProvingJobs: AbortController[] = []; - constructor(private db: MerkleTreeOperations, private prover: CircuitProver) {} + constructor(private db: MerkleTreeOperations, private prover: ServerCircuitProver) {} /** * Starts off a new block diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts index 0c56061d87a..c5a5bc9184d 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_failures.test.ts @@ -1,16 +1,15 @@ -import { PROVING_STATUS } from '@aztec/circuit-types'; +import { PROVING_STATUS, type ServerCircuitProver } from '@aztec/circuit-types'; import { createDebugLogger } from '@aztec/foundation/log'; import { WASMSimulator } from '@aztec/simulator'; import { jest } from '@jest/globals'; +import { TestCircuitProver } from '../../../bb-prover/src/test/test_circuit_prover.js'; import { makeEmptyProcessedTestTx } from '../mocks/fixtures.js'; import { TestContext } from '../mocks/test_context.js'; import { MemoryProvingQueue } from '../prover-pool/memory-proving-queue.js'; import { ProverAgent } from '../prover-pool/prover-agent.js'; import { ProverPool } from '../prover-pool/prover-pool.js'; -import { type CircuitProver } from '../prover/index.js'; -import { TestCircuitProver } from '../prover/test_circuit_prover.js'; import { ProvingOrchestrator } from './orchestrator.js'; const logger = createDebugLogger('aztec:orchestrator-failures'); @@ -29,7 +28,7 @@ describe('prover/orchestrator/failures', () => { }); describe('error handling', () => { - let mockProver: CircuitProver; + let mockProver: ServerCircuitProver; let queue: MemoryProvingQueue; beforeEach(async () => { diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator_lifecycle.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator_lifecycle.test.ts index 26d46d62abb..17cb72bad39 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_lifecycle.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_lifecycle.test.ts @@ -1,4 +1,4 @@ -import { PROVING_STATUS, type ProvingFailure } from '@aztec/circuit-types'; +import { PROVING_STATUS, type ProvingFailure, type ServerCircuitProver } from '@aztec/circuit-types'; import { type GlobalVariables, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, @@ -12,10 +12,9 @@ import { sleep } from '@aztec/foundation/sleep'; import { jest } from '@jest/globals'; +import { TestCircuitProver } from '../../../bb-prover/src/test/test_circuit_prover.js'; import { makeBloatedProcessedTx, makeEmptyProcessedTestTx, makeGlobals } from '../mocks/fixtures.js'; import { TestContext } from '../mocks/test_context.js'; -import { type CircuitProver } from '../prover/interface.js'; -import { TestCircuitProver } from '../prover/test_circuit_prover.js'; import { ProvingOrchestrator } from './orchestrator.js'; const logger = createDebugLogger('aztec:orchestrator-lifecycle'); @@ -137,7 +136,7 @@ describe('prover/orchestrator/lifecycle', () => { }, 60000); it('cancels proving requests', async () => { - const prover: CircuitProver = new TestCircuitProver(); + const prover: ServerCircuitProver = new TestCircuitProver(); const orchestrator = new ProvingOrchestrator(context.actualDb, prover); const spy = jest.spyOn(prover, 'getBaseParityProof'); 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 90fa22a0051..45e3eb35e74 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator_workflow.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator_workflow.test.ts @@ -1,3 +1,4 @@ +import { type ServerCircuitProver } from '@aztec/circuit-types'; import { Fr, NESTED_RECURSIVE_PROOF_LENGTH, @@ -14,17 +15,16 @@ import { type MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; import { type MockProxy, mock } from 'jest-mock-extended'; import { makeEmptyProcessedTestTx } from '../mocks/fixtures.js'; -import { type CircuitProver } from '../prover/index.js'; import { ProvingOrchestrator } from './orchestrator.js'; describe('prover/orchestrator', () => { describe('workflow', () => { let orchestrator: ProvingOrchestrator; - let mockProver: MockProxy; + let mockProver: MockProxy; let actualDb: MerkleTreeOperations; beforeEach(async () => { actualDb = await MerkleTrees.new(openTmpStore()).then(t => t.asLatest()); - mockProver = mock(); + mockProver = mock(); orchestrator = new ProvingOrchestrator(actualDb, mockProver); }); diff --git a/yarn-project/prover-client/src/prover-pool/memory-proving-queue.ts b/yarn-project/prover-client/src/prover-pool/memory-proving-queue.ts index 9980a093e7e..9bc850f311c 100644 --- a/yarn-project/prover-client/src/prover-pool/memory-proving-queue.ts +++ b/yarn-project/prover-client/src/prover-pool/memory-proving-queue.ts @@ -7,6 +7,7 @@ import { type PublicInputsAndProof, type PublicKernelNonTailRequest, type PublicKernelTailRequest, + type ServerCircuitProver, } from '@aztec/circuit-types'; import type { BaseOrMergeRollupPublicInputs, @@ -28,8 +29,6 @@ import { MemoryFifo } from '@aztec/foundation/fifo'; import { createDebugLogger } from '@aztec/foundation/log'; import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise'; -import { type CircuitProver } from '../prover/interface.js'; - type ProvingJobWithResolvers = { id: string; request: T; @@ -41,7 +40,7 @@ const MAX_RETRIES = 3; const defaultIdGenerator = () => randomBytes(4).toString('hex'); -export class MemoryProvingQueue implements CircuitProver, ProvingJobSource { +export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource { private log = createDebugLogger('aztec:prover-client:prover-pool:queue'); private queue = new MemoryFifo(); private jobsInProgress = new Map(); diff --git a/yarn-project/prover-client/src/prover-pool/prover-agent.test.ts b/yarn-project/prover-client/src/prover-pool/prover-agent.test.ts index 5692141c75c..b63e37ad34e 100644 --- a/yarn-project/prover-client/src/prover-pool/prover-agent.test.ts +++ b/yarn-project/prover-client/src/prover-pool/prover-agent.test.ts @@ -1,3 +1,4 @@ +import { type ServerCircuitProver } from '@aztec/circuit-types'; import { RECURSIVE_PROOF_LENGTH, RootParityInput, @@ -8,17 +9,16 @@ import { makeBaseParityInputs, makeParityPublicInputs } from '@aztec/circuits.js import { type MockProxy, mock } from 'jest-mock-extended'; -import { type CircuitProver } from '../prover/interface.js'; import { MemoryProvingQueue } from './memory-proving-queue.js'; import { ProverAgent } from './prover-agent.js'; describe('ProverAgent', () => { let queue: MemoryProvingQueue; let agent: ProverAgent; - let prover: MockProxy; + let prover: MockProxy; beforeEach(() => { - prover = mock(); + prover = mock(); queue = new MemoryProvingQueue(); agent = new ProverAgent(prover); }); diff --git a/yarn-project/prover-client/src/prover-pool/prover-agent.ts b/yarn-project/prover-client/src/prover-pool/prover-agent.ts index 40ff2f22fcf..0fa07d7196a 100644 --- a/yarn-project/prover-client/src/prover-pool/prover-agent.ts +++ b/yarn-project/prover-client/src/prover-pool/prover-agent.ts @@ -3,6 +3,7 @@ import { type ProvingRequest, type ProvingRequestResult, ProvingRequestType, + type ServerCircuitProver, makePublicInputsAndProof, } from '@aztec/circuit-types'; import { makeEmptyProof } from '@aztec/circuits.js'; @@ -10,7 +11,6 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { RunningPromise } from '@aztec/foundation/running-promise'; import { elapsed } from '@aztec/foundation/timer'; -import { type CircuitProver } from '../prover/interface.js'; import { ProvingError } from './proving-error.js'; export class ProverAgent { @@ -18,7 +18,7 @@ export class ProverAgent { constructor( /** The prover implementation to defer jobs to */ - private prover: CircuitProver, + private prover: ServerCircuitProver, /** How long to wait between jobs */ private intervalMs = 10, /** A name for this agent (if there are multiple agents running) */ diff --git a/yarn-project/prover-client/src/prover-pool/prover-pool.ts b/yarn-project/prover-client/src/prover-pool/prover-pool.ts index 8dc7a320ff4..0a46a4281ad 100644 --- a/yarn-project/prover-client/src/prover-pool/prover-pool.ts +++ b/yarn-project/prover-client/src/prover-pool/prover-pool.ts @@ -1,3 +1,4 @@ +import { BBNativeRollupProver, type BBProverConfig, TestCircuitProver } from '@aztec/bb-prover'; import { type ProvingJobSource } from '@aztec/circuit-types'; import { sleep } from '@aztec/foundation/sleep'; import { type SimulationProvider } from '@aztec/simulator'; @@ -5,8 +6,6 @@ import { type SimulationProvider } from '@aztec/simulator'; import { mkdtemp } from 'fs/promises'; import { join } from 'path'; -import { BBNativeRollupProver, type BBProverConfig } from '../prover/bb_prover.js'; -import { TestCircuitProver } from '../prover/test_circuit_prover.js'; import { ProverAgent } from './prover-agent.js'; /** diff --git a/yarn-project/prover-client/src/prover/index.ts b/yarn-project/prover-client/src/prover/index.ts deleted file mode 100644 index 8a595f1c973..00000000000 --- a/yarn-project/prover-client/src/prover/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './interface.js'; diff --git a/yarn-project/prover-client/src/stats.ts b/yarn-project/prover-client/src/stats.ts index bf1672a467b..fbd68bde90b 100644 --- a/yarn-project/prover-client/src/stats.ts +++ b/yarn-project/prover-client/src/stats.ts @@ -1,31 +1,8 @@ import { type PublicKernelRequest, PublicKernelType } from '@aztec/circuit-types'; -import type { - CircuitName, - CircuitProvingStats, - CircuitSimulationStats, - CircuitWitnessGenerationStats, -} from '@aztec/circuit-types/stats'; +import type { CircuitName, CircuitProvingStats, CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; import { type Logger } from '@aztec/foundation/log'; import { type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; -export function emitCircuitSimulationStats( - circuitName: CircuitName, - duration: number, - inputSize: number, - outputSize: number, - logger: Logger, -) { - const stats: CircuitSimulationStats = { - eventName: 'circuit-simulation', - circuitName, - inputSize, - outputSize, - duration, - }; - - logger.debug('Circuit simulation stats', stats); -} - export function emitCircuitWitnessGenerationStats( circuitName: CircuitName, duration: number, diff --git a/yarn-project/prover-client/src/prover/bb_prover_base_rollup.test.ts b/yarn-project/prover-client/src/test/bb_prover_base_rollup.test.ts similarity index 74% rename from yarn-project/prover-client/src/prover/bb_prover_base_rollup.test.ts rename to yarn-project/prover-client/src/test/bb_prover_base_rollup.test.ts index f560008db23..e8286455a24 100644 --- a/yarn-project/prover-client/src/prover/bb_prover_base_rollup.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_base_rollup.test.ts @@ -1,19 +1,20 @@ +import { BBNativeRollupProver, type BBProverConfig } from '@aztec/bb-prover'; import { createDebugLogger } from '@aztec/foundation/log'; import { makeBloatedProcessedTx } from '../mocks/fixtures.js'; import { TestContext } from '../mocks/test_context.js'; import { buildBaseRollupInput } from '../orchestrator/block-building-helpers.js'; -import { BBNativeRollupProver, type BBProverConfig } from './bb_prover.js'; const logger = createDebugLogger('aztec:bb-prover-base-rollup'); describe('prover/bb_prover/base-rollup', () => { let context: TestContext; + let prover: BBNativeRollupProver; beforeAll(async () => { - const buildProver = (bbConfig: BBProverConfig) => { - bbConfig.circuitFilter = ['BaseRollupArtifact']; - return BBNativeRollupProver.new(bbConfig); + const buildProver = async (bbConfig: BBProverConfig) => { + prover = await BBNativeRollupProver.new(bbConfig); + return prover; }; context = await TestContext.new(logger, 1, buildProver); }); @@ -30,6 +31,6 @@ describe('prover/bb_prover/base-rollup', () => { logger.verbose('Proving base rollups'); const proofOutputs = await context.prover.getBaseRollupProof(baseRollupInputs); logger.verbose('Verifying base rollups'); - await expect(context.prover.verifyProof('BaseRollupArtifact', proofOutputs.proof)).resolves.not.toThrow(); + await expect(prover.verifyProof('BaseRollupArtifact', proofOutputs.proof)).resolves.not.toThrow(); }); }); diff --git a/yarn-project/prover-client/src/prover/bb_prover_full_rollup.test.ts b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts similarity index 81% rename from yarn-project/prover-client/src/prover/bb_prover_full_rollup.test.ts rename to yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts index 8fda8107161..7a9d5272a04 100644 --- a/yarn-project/prover-client/src/prover/bb_prover_full_rollup.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts @@ -1,3 +1,4 @@ +import { BBNativeRollupProver, type BBProverConfig } from '@aztec/bb-prover'; import { PROVING_STATUS, makeEmptyProcessedTx, mockTx } from '@aztec/circuit-types'; import { Fr, Header, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js'; import { makeTuple } from '@aztec/foundation/array'; @@ -5,15 +6,19 @@ import { times } from '@aztec/foundation/collection'; import { createDebugLogger } from '@aztec/foundation/log'; import { TestContext } from '../mocks/test_context.js'; -import { BBNativeRollupProver } from './bb_prover.js'; const logger = createDebugLogger('aztec:bb-prover-full-rollup'); describe('prover/bb_prover/full-rollup', () => { let context: TestContext; + let prover: BBNativeRollupProver; beforeAll(async () => { - context = await TestContext.new(logger, 1, BBNativeRollupProver.new); + const buildProver = async (bbConfig: BBProverConfig) => { + prover = await BBNativeRollupProver.new(bbConfig); + return prover; + }; + context = await TestContext.new(logger, 1, buildProver); }); afterAll(async () => { @@ -57,6 +62,6 @@ describe('prover/bb_prover/full-rollup', () => { const blockResult = await context.orchestrator.finaliseBlock(); - await expect(context.prover.verifyProof('RootRollupArtifact', blockResult.proof)).resolves.not.toThrow(); + await expect(prover.verifyProof('RootRollupArtifact', blockResult.proof)).resolves.not.toThrow(); }); }); diff --git a/yarn-project/prover-client/src/prover/bb_prover_parity.test.ts b/yarn-project/prover-client/src/test/bb_prover_parity.test.ts similarity index 91% rename from yarn-project/prover-client/src/prover/bb_prover_parity.test.ts rename to yarn-project/prover-client/src/test/bb_prover_parity.test.ts index 091f00662c1..dce5d3cbffa 100644 --- a/yarn-project/prover-client/src/prover/bb_prover_parity.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_parity.test.ts @@ -1,3 +1,4 @@ +import { BBNativeRollupProver, type BBProverConfig } from '@aztec/bb-prover'; import { BaseParityInputs, Fr, @@ -16,7 +17,6 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { type Tuple } from '@aztec/foundation/serialize'; import { TestContext } from '../mocks/test_context.js'; -import { BBNativeRollupProver, type BBProverConfig } from './bb_prover.js'; const logger = createDebugLogger('aztec:bb-prover-parity'); @@ -53,7 +53,7 @@ describe('prover/bb_prover/parity', () => { // Verify the base parity proofs await expect( - Promise.all(rootInputs.map(input => context.prover.verifyProof('BaseParityArtifact', input.proof.binaryProof))), + Promise.all(rootInputs.map(input => bbProver.verifyProof('BaseParityArtifact', input.proof.binaryProof))), ).resolves.not.toThrow(); // Now generate the root parity proof @@ -63,7 +63,7 @@ describe('prover/bb_prover/parity', () => { const rootOutput = await context.prover.getRootParityProof(rootParityInputs); // Verify the root parity proof - await expect(context.prover.verifyProof('RootParityArtifact', rootOutput.proof.binaryProof)).resolves.not.toThrow(); + await expect(bbProver.verifyProof('RootParityArtifact', rootOutput.proof.binaryProof)).resolves.not.toThrow(); // Now test for negative cases. We will try and generate 3 invalid proofs. // One where a single child has an invalid proof @@ -125,7 +125,7 @@ describe('prover/bb_prover/parity', () => { for (const t of defectiveTuples) { try { const result = await context.prover.getRootParityProof(new RootParityInputs(t)); - await context.prover.verifyProof('RootParityArtifact', result.proof.binaryProof); + await bbProver.verifyProof('RootParityArtifact', result.proof.binaryProof); fail('Proof should not be generated and verified'); } catch (error) { expect([ diff --git a/yarn-project/prover-client/src/prover/bb_prover_public_kernel.test.ts b/yarn-project/prover-client/src/test/bb_prover_public_kernel.test.ts similarity index 90% rename from yarn-project/prover-client/src/prover/bb_prover_public_kernel.test.ts rename to yarn-project/prover-client/src/test/bb_prover_public_kernel.test.ts index e9ee0389d44..2c55cf28fd4 100644 --- a/yarn-project/prover-client/src/prover/bb_prover_public_kernel.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_public_kernel.test.ts @@ -1,3 +1,4 @@ +import { BBNativeRollupProver, type BBProverConfig } from '@aztec/bb-prover'; import { PublicKernelType, mockTx } from '@aztec/circuit-types'; import { type Proof, makeEmptyProof } from '@aztec/circuits.js'; import { makePublicCallRequest } from '@aztec/circuits.js/testing'; @@ -5,22 +6,23 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; import { TestContext } from '../mocks/test_context.js'; -import { BBNativeRollupProver, type BBProverConfig } from './bb_prover.js'; const logger = createDebugLogger('aztec:bb-prover-public-kernel'); describe('prover/bb_prover/public-kernel', () => { let context: TestContext; + let prover: BBNativeRollupProver; beforeAll(async () => { - const buildProver = (bbConfig: BBProverConfig) => { + const buildProver = async (bbConfig: BBProverConfig) => { bbConfig.circuitFilter = [ 'PublicKernelAppLogicArtifact', 'PublicKernelSetupArtifact', 'PublicKernelTailArtifact', 'PublicKernelTeardownArtifact', ]; - return BBNativeRollupProver.new(bbConfig); + prover = await BBNativeRollupProver.new(bbConfig); + return prover; }; context = await TestContext.new(logger, 1, buildProver); }); @@ -84,7 +86,7 @@ describe('prover/bb_prover/public-kernel', () => { } logger.verbose(`Verifying kernel type: ${PublicKernelType[request.type]}`); - await expect(context.prover.verifyProof(artifact, proof)).resolves.not.toThrow(); + await expect(prover.verifyProof(artifact, proof)).resolves.not.toThrow(); } }); }); diff --git a/yarn-project/prover-client/tsconfig.json b/yarn-project/prover-client/tsconfig.json index a9fab4069e1..5f4666ebf03 100644 --- a/yarn-project/prover-client/tsconfig.json +++ b/yarn-project/prover-client/tsconfig.json @@ -6,6 +6,9 @@ "tsBuildInfoFile": ".tsbuildinfo" }, "references": [ + { + "path": "../bb-prover" + }, { "path": "../circuit-types" }, @@ -28,5 +31,5 @@ "path": "../world-state" } ], - "include": ["src"] + "include": ["src", "../bb-prover/src/test/test_circuit_prover.ts"] } diff --git a/yarn-project/pxe/package.json b/yarn-project/pxe/package.json index 6d81c8f3f7e..9d3e04fee0c 100644 --- a/yarn-project/pxe/package.json +++ b/yarn-project/pxe/package.json @@ -48,6 +48,7 @@ ] }, "dependencies": { + "@aztec/bb-prover": "workspace:^", "@aztec/bb.js": "portal:../../barretenberg/ts", "@aztec/builder": "workspace:^", "@aztec/circuit-types": "workspace:^", diff --git a/yarn-project/pxe/src/index.ts b/yarn-project/pxe/src/index.ts index df1d9447e6f..d7cf6d57253 100644 --- a/yarn-project/pxe/src/index.ts +++ b/yarn-project/pxe/src/index.ts @@ -9,6 +9,3 @@ export * from '@aztec/foundation/fields'; export * from '@aztec/foundation/eth-address'; export * from '@aztec/foundation/aztec-address'; export * from '@aztec/key-store'; - -// Temporarily used in e2e client prover integration test -export { BBNativeProofCreator } from './kernel_prover/bb_prover/bb_native_proof_creator.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 733774b5d01..b6d86e6ae70 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -1,4 +1,4 @@ -import { Note } from '@aztec/circuit-types'; +import { Note, type ProofCreator } from '@aztec/circuit-types'; import { FunctionData, FunctionSelector, @@ -28,7 +28,6 @@ import { type ExecutionResult, type NoteAndSlot } from '@aztec/simulator'; import { mock } from 'jest-mock-extended'; -import { type ProofCreator } from './interface/proof_creator.js'; import { KernelProver } from './kernel_prover.js'; import { type ProvingDataOracle } from './proving_data_oracle.js'; diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index f6b324aad45..aa180e23b03 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -1,3 +1,4 @@ +import { type KernelProofOutput, type ProofCreator } from '@aztec/circuit-types'; import { CallRequest, Fr, @@ -24,7 +25,6 @@ import { assertLength } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; import { type ExecutionResult, collectNoteHashLeafIndexMap, collectNullifiedNoteHashCounters } from '@aztec/simulator'; -import { type KernelProofOutput, type ProofCreator } from './interface/proof_creator.js'; import { buildPrivateKernelInnerHints, buildPrivateKernelTailHints, 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 index 6b3a29e72b8..ee18de6092d 100644 --- a/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts @@ -1,3 +1,4 @@ +import { type AppCircuitProofOutput, type KernelProofOutput, type ProofCreator } from '@aztec/circuit-types'; import { type CircuitSimulationStats } from '@aztec/circuit-types/stats'; import { NESTED_RECURSIVE_PROOF_LENGTH, @@ -16,8 +17,6 @@ import { createDebugLogger } from '@aztec/foundation/log'; import { elapsed } from '@aztec/foundation/timer'; import { executeInit, executeInner, executeTail, executeTailForPublic } from '@aztec/noir-protocol-circuits-types'; -import { type AppCircuitProofOutput, type KernelProofOutput, type ProofCreator } from '../interface/proof_creator.js'; - /** * Test Proof Creator executes circuit simulations and provides fake proofs. */ diff --git a/yarn-project/pxe/src/pxe_service/create_pxe_service.ts b/yarn-project/pxe/src/pxe_service/create_pxe_service.ts index e2895e3d2c4..47e0bf633d1 100644 --- a/yarn-project/pxe/src/pxe_service/create_pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/create_pxe_service.ts @@ -1,4 +1,5 @@ -import { type AztecNode } from '@aztec/circuit-types'; +import { BBNativeProofCreator } from '@aztec/bb-prover'; +import { type AztecNode, type ProofCreator } from '@aztec/circuit-types'; import { randomBytes } from '@aztec/foundation/crypto'; import { TestKeyStore } from '@aztec/key-store'; import { AztecLmdbStore } from '@aztec/kv-store/lmdb'; @@ -13,8 +14,6 @@ import { join } from 'path'; import { type PXEServiceConfig } from '../config/index.js'; import { KVPxeDatabase } from '../database/kv_pxe_database.js'; -import { BBNativeProofCreator } from '../kernel_prover/bb_prover/bb_native_proof_creator.js'; -import { type ProofCreator } from '../kernel_prover/interface/proof_creator.js'; import { TestProofCreator } from '../kernel_prover/test/test_circuit_prover.js'; import { PXEService } from './pxe_service.js'; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index c4b4aa1cd98..b7de7347716 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -11,6 +11,7 @@ import { MerkleTreeId, type NoteFilter, type PXE, + type ProofCreator, SimulatedTx, SimulationError, Tx, @@ -58,7 +59,6 @@ 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 { type ProofCreator } from '../kernel_prover/interface/proof_creator.js'; import { KernelProver } from '../kernel_prover/kernel_prover.js'; import { getAcirSimulator } from '../simulator/index.js'; import { Synchronizer } from '../synchronizer/index.js'; diff --git a/yarn-project/pxe/tsconfig.json b/yarn-project/pxe/tsconfig.json index a9b056c037d..1db338e8540 100644 --- a/yarn-project/pxe/tsconfig.json +++ b/yarn-project/pxe/tsconfig.json @@ -6,6 +6,9 @@ "tsBuildInfoFile": ".tsbuildinfo" }, "references": [ + { + "path": "../bb-prover" + }, { "path": "../builder" }, diff --git a/yarn-project/simulator/src/index.ts b/yarn-project/simulator/src/index.ts index 6701aa44352..d01941776a2 100644 --- a/yarn-project/simulator/src/index.ts +++ b/yarn-project/simulator/src/index.ts @@ -4,3 +4,4 @@ export * from './common/index.js'; export * from './public/index.js'; export * from './simulator/index.js'; export * from './mocks/index.js'; +export * from './stats/index.js'; diff --git a/yarn-project/simulator/src/rollup/index.ts b/yarn-project/simulator/src/rollup/index.ts new file mode 100644 index 00000000000..f35e118a5a1 --- /dev/null +++ b/yarn-project/simulator/src/rollup/index.ts @@ -0,0 +1 @@ +export * from './rollup.js'; diff --git a/yarn-project/prover-client/src/simulator/rollup.ts b/yarn-project/simulator/src/rollup/rollup.ts similarity index 100% rename from yarn-project/prover-client/src/simulator/rollup.ts rename to yarn-project/simulator/src/rollup/rollup.ts diff --git a/yarn-project/simulator/src/stats/index.ts b/yarn-project/simulator/src/stats/index.ts new file mode 100644 index 00000000000..0502f09568b --- /dev/null +++ b/yarn-project/simulator/src/stats/index.ts @@ -0,0 +1 @@ +export * from './stats.js'; diff --git a/yarn-project/simulator/src/stats/stats.ts b/yarn-project/simulator/src/stats/stats.ts new file mode 100644 index 00000000000..31839bb4f06 --- /dev/null +++ b/yarn-project/simulator/src/stats/stats.ts @@ -0,0 +1,20 @@ +import { type CircuitName, type CircuitSimulationStats } from '@aztec/circuit-types/stats'; +import { type Logger } from '@aztec/foundation/log'; + +export function emitCircuitSimulationStats( + circuitName: CircuitName, + duration: number, + inputSize: number, + outputSize: number, + logger: Logger, +) { + const stats: CircuitSimulationStats = { + eventName: 'circuit-simulation', + circuitName, + inputSize, + outputSize, + duration, + }; + + logger.debug('Circuit simulation stats', stats); +} diff --git a/yarn-project/tsconfig.json b/yarn-project/tsconfig.json index 9cd760e9a18..8fa1304b81d 100644 --- a/yarn-project/tsconfig.json +++ b/yarn-project/tsconfig.json @@ -25,6 +25,7 @@ { "path": "aztec-faucet/tsconfig.json" }, { "path": "aztec.js/tsconfig.json" }, { "path": "aztec-node/tsconfig.json" }, + { "path": "bb-prover/tsconfig.json" }, { "path": "pxe/tsconfig.json" }, { "path": "aztec/tsconfig.json" }, { "path": "circuits.js/tsconfig.json" }, diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 397a3702793..f3871f72580 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -220,6 +220,34 @@ __metadata: languageName: unknown linkType: soft +"@aztec/bb-prover@workspace:^, @aztec/bb-prover@workspace:bb-prover": + version: 0.0.0-use.local + resolution: "@aztec/bb-prover@workspace:bb-prover" + dependencies: + "@aztec/circuit-types": "workspace:^" + "@aztec/circuits.js": "workspace:^" + "@aztec/foundation": "workspace:^" + "@aztec/noir-protocol-circuits-types": "workspace:^" + "@aztec/simulator": "workspace:^" + "@jest/globals": ^29.5.0 + "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi" + "@noir-lang/types": "portal:../../noir/packages/types" + "@types/jest": ^29.5.0 + "@types/memdown": ^3.0.0 + "@types/node": ^18.7.23 + "@types/source-map-support": ^0.5.10 + commander: ^9.0.0 + jest: ^29.5.0 + jest-mock-extended: ^3.0.3 + source-map-support: ^0.5.21 + ts-node: ^10.9.1 + tslib: ^2.4.0 + typescript: ^5.0.4 + bin: + bb-cli: ./dest/bb/index.js + languageName: unknown + linkType: soft + "@aztec/bb.js@portal:../barretenberg/ts::locator=%40aztec%2Faztec3-packages%40workspace%3A.": version: 0.0.0-use.local resolution: "@aztec/bb.js@portal:../barretenberg/ts::locator=%40aztec%2Faztec3-packages%40workspace%3A." @@ -330,6 +358,7 @@ __metadata: "@aztec/archiver": "workspace:^" "@aztec/aztec-node": "workspace:^" "@aztec/aztec.js": "workspace:^" + "@aztec/bb-prover": "workspace:^" "@aztec/circuit-types": "workspace:^" "@aztec/circuits.js": "workspace:^" "@aztec/entrypoints": "workspace:^" @@ -683,6 +712,7 @@ __metadata: version: 0.0.0-use.local resolution: "@aztec/prover-client@workspace:prover-client" dependencies: + "@aztec/bb-prover": "workspace:^" "@aztec/circuit-types": "workspace:^" "@aztec/circuits.js": "workspace:^" "@aztec/foundation": "workspace:^" @@ -704,8 +734,6 @@ __metadata: ts-node: ^10.9.1 tslib: ^2.4.0 typescript: ^5.0.4 - bin: - bb-cli: ./dest/bb/index.js languageName: unknown linkType: soft @@ -713,6 +741,7 @@ __metadata: version: 0.0.0-use.local resolution: "@aztec/pxe@workspace:pxe" dependencies: + "@aztec/bb-prover": "workspace:^" "@aztec/bb.js": "portal:../../barretenberg/ts" "@aztec/builder": "workspace:^" "@aztec/circuit-types": "workspace:^"