diff --git a/build_manifest.yml b/build_manifest.yml index 6c79c6810d45..becb85033e70 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -223,6 +223,7 @@ end-to-end: - noir-projects - noir - yarn-project + - barretenberg-x86_64-linux-clang runDependencies: - aztec diff --git a/yarn-project/aztec/src/cli/cmds/start_prover.ts b/yarn-project/aztec/src/cli/cmds/start_prover.ts index 103ca97c8df0..7c39fe6e16a7 100644 --- a/yarn-project/aztec/src/cli/cmds/start_prover.ts +++ b/yarn-project/aztec/src/cli/cmds/start_prover.ts @@ -1,6 +1,8 @@ import { type ProvingJobSource } from '@aztec/circuit-types'; import { ProverPool, createProvingJobSourceClient } from '@aztec/prover-client/prover-pool'; +import { tmpdir } from 'node:os'; + import { type ServiceStarter, parseModuleOptions } from '../util.js'; type ProverOptions = Partial<{ @@ -35,6 +37,8 @@ export const startProver: ServiceStarter = async (options, signalHandlers, logge { acvmBinaryPath: proverOptions.acvmBinaryPath, bbBinaryPath: proverOptions.bbBinaryPath, + acvmWorkingDirectory: tmpdir(), + bbWorkingDirectory: tmpdir(), }, agentCount, ); diff --git a/yarn-project/end-to-end/Dockerfile b/yarn-project/end-to-end/Dockerfile index 215a0fb1f977..22e364841da1 100644 --- a/yarn-project/end-to-end/Dockerfile +++ b/yarn-project/end-to-end/Dockerfile @@ -2,6 +2,7 @@ FROM --platform=linux/amd64 aztecprotocol/bb.js as bb.js FROM --platform=linux/amd64 aztecprotocol/noir-packages as noir-packages FROM --platform=linux/amd64 aztecprotocol/l1-contracts as contracts FROM --platform=linux/amd64 aztecprotocol/noir-projects as noir-projects +FROM --platform=linux/amd64 aztecprotocol/barretenberg-x86_64-linux-clang as bb FROM aztecprotocol/noir as noir FROM node:18.19.0 as builder @@ -13,6 +14,7 @@ COPY --from=noir-packages /usr/src/noir/packages /usr/src/noir/packages COPY --from=contracts /usr/src/l1-contracts /usr/src/l1-contracts COPY --from=noir-projects /usr/src/noir-projects /usr/src/noir-projects COPY --from=noir /usr/src/noir/noir-repo/target/release/acvm /usr/src/noir/noir-repo/target/release/acvm +COPY --from=bb /usr/src/barretenberg/cpp/build/bin/bb /usr/src/barretenberg/cpp/build/bin/bb WORKDIR /usr/src/yarn-project COPY . . @@ -43,7 +45,7 @@ RUN /root/.foundry/bin/foundryup --version nightly-de33b6af53005037b463318d2628b # Create minimal image. FROM node:18.19.1-slim -RUN apt-get update && apt-get install jq gnupg wget netcat-openbsd -y && \ +RUN apt-get update && apt-get install jq gnupg wget curl netcat-openbsd -y && \ wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \ apt-get update && \ @@ -52,4 +54,4 @@ RUN apt-get update && apt-get install jq gnupg wget netcat-openbsd -y && \ ENV CHROME_BIN="/usr/bin/google-chrome-stable" COPY --from=builder /usr/src /usr/src WORKDIR /usr/src/yarn-project/end-to-end -ENTRYPOINT ["yarn", "test"] \ No newline at end of file +ENTRYPOINT ["yarn", "test"] diff --git a/yarn-project/end-to-end/Earthfile b/yarn-project/end-to-end/Earthfile index 8ff7a7f9aa18..145440ee8c3e 100644 --- a/yarn-project/end-to-end/Earthfile +++ b/yarn-project/end-to-end/Earthfile @@ -98,3 +98,11 @@ bench-tx-size: ARG COMMIT_HASH DO +E2E_COMPOSE_TEST --test=benchmarks/bench_tx_size_fees.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --enable_gas=1 --compose_file=./scripts/docker-compose-no-sandbox.yml DO +UPLOAD_LOGS --e2e_mode=$e2e_mode --PULL_REQUEST=$PULL_REQUEST --BRANCH=$BRANCH --COMMIT_HASH=$COMMIT_HASH + +bench-proving: + ARG e2e_mode=local + ARG PULL_REQUEST + ARG BRANCH + ARG COMMIT_HASH + DO +E2E_TEST --test=benchmarks/bench_tx_size_fees.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --enable_gas=0 --compose_file=./scripts/docker-compose-no-sandbox.yml + DO +UPLOAD_LOGS --e2e_mode=$e2e_mode --PULL_REQUEST=$PULL_REQUEST --BRANCH=$BRANCH --COMMIT_HASH=$COMMIT_HASH diff --git a/yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts new file mode 100644 index 000000000000..d92dc7abe73d --- /dev/null +++ b/yarn-project/end-to-end/src/benchmarks/bench_proving.test.ts @@ -0,0 +1,70 @@ +import { getSchnorrAccount } from '@aztec/accounts/schnorr'; +import { BatchCall, EthAddress, Fq, Fr, TxStatus, type Wallet } from '@aztec/aztec.js'; +import { TestContract } from '@aztec/noir-contracts.js'; + +import { jest } from '@jest/globals'; + +import { getACVMConfig } from '../fixtures/get_acvm_config.js'; +import { getBBConfig } from '../fixtures/get_bb_config.js'; +import { type EndToEndContext, setupNoL2Deploy } from '../fixtures/utils.js'; + +jest.setTimeout(1_000_000); + +// seconds! +const txTimeoutSec = 200; + +describe('benchmarks/proving', () => { + let ctx: Omit; + let wallet: Wallet; + let testContract: TestContract; + let acvmCleanup: () => Promise; + let bbCleanup: () => Promise; + + // setup the environment + beforeAll(async () => { + const [acvmConfig, bbConfig] = await Promise.all([getACVMConfig(ctx.logger), getBBConfig(ctx.logger)]); + if (!acvmConfig || !bbConfig) { + throw new Error('Missing ACVM or BB config'); + } + + ctx = await setupNoL2Deploy({ + acvmBinaryPath: acvmConfig.acvmBinaryPath, + acvmWorkingDirectory: acvmConfig.acvmWorkingDirectory, + bbBinaryPath: bbConfig.bbBinaryPath, + bbWorkingDirectory: bbConfig.bbWorkingDirectory, + proverAgents: 4, + proverAgentPollInterval: 10, + }); + + acvmCleanup = acvmConfig.cleanup; + bbCleanup = bbConfig.cleanup; + + wallet = await getSchnorrAccount(ctx.pxe, Fr.random(), Fq.random()).deploy().getWallet({ + timeout: txTimeoutSec, + }); + testContract = await TestContract.deploy(wallet).send().deployed({ + timeout: txTimeoutSec, + }); + }); + + afterAll(async () => { + await ctx.teardown(); + + await acvmCleanup(); + await bbCleanup(); + }); + + it('executes a batch call', async () => { + const call = new BatchCall(wallet, [ + testContract.methods.emit_nullifier(42).request(), + testContract.methods.call_create_note(43, wallet.getAddress(), 44).request(), + testContract.methods.create_l2_to_l1_message_public(45, 46, EthAddress.random()).request(), + testContract.methods.emit_unencrypted(47).request(), + ]); + + const receipt = await call.send().wait({ + timeout: txTimeoutSec, + }); + expect(receipt.status).toBe(TxStatus.MINED); + }); +}); diff --git a/yarn-project/end-to-end/src/fixtures/get_acvm_config.ts b/yarn-project/end-to-end/src/fixtures/get_acvm_config.ts index 556726411137..a8c8349a6cec 100644 --- a/yarn-project/end-to-end/src/fixtures/get_acvm_config.ts +++ b/yarn-project/end-to-end/src/fixtures/get_acvm_config.ts @@ -13,14 +13,21 @@ const { } = process.env; // Determines if we have access to the acvm binary and a tmp folder for temp files -export async function getACVMConfig(logger: DebugLogger) { +export async function getACVMConfig(logger: DebugLogger): Promise< + | { + acvmWorkingDirectory: string; + acvmBinaryPath: string; + cleanup: () => Promise; + } + | undefined +> { try { - const expectedAcvmPath = ACVM_BINARY_PATH ? ACVM_BINARY_PATH : `../../noir/${NOIR_RELEASE_DIR}/acvm`; - await fs.access(expectedAcvmPath, fs.constants.R_OK); + const acvmBinaryPath = ACVM_BINARY_PATH ? ACVM_BINARY_PATH : `../../noir/${NOIR_RELEASE_DIR}/acvm`; + await fs.access(acvmBinaryPath, fs.constants.R_OK); const tempWorkingDirectory = `${TEMP_DIR}/${randomBytes(4).toString('hex')}`; const acvmWorkingDirectory = ACVM_WORKING_DIRECTORY ? ACVM_WORKING_DIRECTORY : `${tempWorkingDirectory}/acvm`; await fs.mkdir(acvmWorkingDirectory, { recursive: true }); - logger.verbose(`Using native ACVM binary at ${expectedAcvmPath} with working directory ${acvmWorkingDirectory}`); + logger.verbose(`Using native ACVM binary at ${acvmBinaryPath} with working directory ${acvmWorkingDirectory}`); const directoryToCleanup = ACVM_WORKING_DIRECTORY ? undefined : tempWorkingDirectory; @@ -33,7 +40,7 @@ export async function getACVMConfig(logger: DebugLogger) { return { acvmWorkingDirectory, - expectedAcvmPath, + acvmBinaryPath, cleanup, }; } catch (err) { diff --git a/yarn-project/end-to-end/src/fixtures/get_bb_config.ts b/yarn-project/end-to-end/src/fixtures/get_bb_config.ts new file mode 100644 index 000000000000..412c93164579 --- /dev/null +++ b/yarn-project/end-to-end/src/fixtures/get_bb_config.ts @@ -0,0 +1,46 @@ +import { type DebugLogger, fileURLToPath } from '@aztec/aztec.js'; + +import fs from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import path from 'path'; + +const { + BB_RELEASE_DIR = 'barretenberg/cpp/build/bin', + BB_BINARY_PATH, + TEMP_DIR = tmpdir(), + BB_WORKING_DIRECTORY = '', +} = process.env; + +export const getBBConfig = async ( + logger: DebugLogger, +): Promise<{ bbBinaryPath: string; bbWorkingDirectory: string; cleanup: () => Promise } | undefined> => { + try { + const bbBinaryPath = + BB_BINARY_PATH ?? + path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../', BB_RELEASE_DIR, 'bb'); + await fs.access(bbBinaryPath, fs.constants.R_OK); + + let bbWorkingDirectory: string; + let directoryToCleanup: string | undefined; + + if (BB_WORKING_DIRECTORY) { + bbWorkingDirectory = BB_WORKING_DIRECTORY; + } else { + bbWorkingDirectory = await fs.mkdtemp(path.join(TEMP_DIR, 'bb-')); + directoryToCleanup = bbWorkingDirectory; + } + + await fs.mkdir(bbWorkingDirectory, { recursive: true }); + + const cleanup = async () => { + if (directoryToCleanup) { + await fs.rm(directoryToCleanup, { recursive: true, force: true }); + } + }; + + return { bbBinaryPath, bbWorkingDirectory, cleanup }; + } catch (err) { + logger.error(`Native BB not available, error: ${err}`); + return undefined; + } +}; diff --git a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts index 9fe93aafd776..a77f661f34c2 100644 --- a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts +++ b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts @@ -202,7 +202,7 @@ export class SnapshotManager { const acvmConfig = await getACVMConfig(this.logger); if (acvmConfig) { aztecNodeConfig.acvmWorkingDirectory = acvmConfig.acvmWorkingDirectory; - aztecNodeConfig.acvmBinaryPath = acvmConfig.expectedAcvmPath; + aztecNodeConfig.acvmBinaryPath = acvmConfig.acvmBinaryPath; } this.logger.verbose('Creating and synching an aztec node...'); @@ -254,7 +254,7 @@ export class SnapshotManager { const acvmConfig = await getACVMConfig(this.logger); if (acvmConfig) { aztecNodeConfig.acvmWorkingDirectory = acvmConfig.acvmWorkingDirectory; - aztecNodeConfig.acvmBinaryPath = acvmConfig.expectedAcvmPath; + aztecNodeConfig.acvmBinaryPath = acvmConfig.acvmBinaryPath; } this.logger.verbose('Creating aztec node...'); diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index df58258d1f69..f951a181a0eb 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -22,7 +22,6 @@ import { createDebugLogger, createPXEClient, deployL1Contracts, - fileURLToPath, makeFetch, waitForPXE, } from '@aztec/aztec.js'; @@ -33,7 +32,6 @@ import { computeContractAddressFromInstance, getContractClassFromArtifact, } from '@aztec/circuits.js'; -import { randomBytes } from '@aztec/foundation/crypto'; import { makeBackoff, retry } from '@aztec/foundation/retry'; import { AvailabilityOracleAbi, @@ -55,11 +53,11 @@ import { KeyRegistryContract } from '@aztec/noir-contracts.js'; 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 { PXEService, type PXEServiceConfig, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; import { type SequencerClient } from '@aztec/sequencer-client'; import { type Anvil, createAnvil } from '@viem/anvil'; -import * as fs from 'fs/promises'; import getPort from 'get-port'; import * as path from 'path'; import { @@ -77,44 +75,17 @@ import { mnemonicToAccount } from 'viem/accounts'; import { foundry } from 'viem/chains'; import { MNEMONIC } from './fixtures.js'; +import { getACVMConfig } from './get_acvm_config.js'; import { isMetricsLoggingRequested, setupMetricsLogger } from './logging.js'; export { deployAndInitializeTokenAndBridgeContracts } from '../shared/cross_chain_test_harness.js'; -const { - PXE_URL = '', - NOIR_RELEASE_DIR = 'noir-repo/target/release', - TEMP_DIR = '/tmp', - ACVM_BINARY_PATH = '', - ACVM_WORKING_DIRECTORY = '', -} = process.env; +const { PXE_URL = '' } = process.env; const getAztecUrl = () => { return PXE_URL; }; -// Determines if we have access to the acvm binary and a tmp folder for temp files -const getACVMConfig = async (logger: DebugLogger) => { - try { - const expectedAcvmPath = ACVM_BINARY_PATH - ? ACVM_BINARY_PATH - : `${path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../noir/', NOIR_RELEASE_DIR)}/acvm`; - await fs.access(expectedAcvmPath, fs.constants.R_OK); - const tempWorkingDirectory = `${TEMP_DIR}/${randomBytes(4).toString('hex')}`; - const acvmWorkingDirectory = ACVM_WORKING_DIRECTORY ? ACVM_WORKING_DIRECTORY : `${tempWorkingDirectory}/acvm`; - await fs.mkdir(acvmWorkingDirectory, { recursive: true }); - logger.info(`Using native ACVM binary at ${expectedAcvmPath} with working directory ${acvmWorkingDirectory}`); - return { - acvmWorkingDirectory, - expectedAcvmPath, - directoryToCleanup: ACVM_WORKING_DIRECTORY ? undefined : tempWorkingDirectory, - }; - } catch (err) { - logger.error(`Native ACVM not available, error: ${err}`); - return undefined; - } -}; - export const setupL1Contracts = async ( l1RpcUrl: string, account: HDAccount | PrivateKeyAccount, @@ -279,7 +250,7 @@ async function setupWithRemoteEnvironment( const { chainId, protocolVersion } = await pxeClient.getNodeInfo(); // this contract might already have been deployed - // the following deployin functions are idempotent + // the following deploying functions are idempotent await deployCanonicalKeyRegistry( new SignerlessWallet(pxeClient, new DefaultMultiCallEntrypoint(chainId, protocolVersion)), ); @@ -293,6 +264,7 @@ async function setupWithRemoteEnvironment( return { aztecNode, sequencer: undefined, + prover: undefined, pxe: pxeClient, deployL1ContractsValues, accounts: await pxeClient!.getRegisteredAccounts(), @@ -333,22 +305,17 @@ export type EndToEndContext = { logger: DebugLogger; /** The cheat codes. */ cheatCodes: CheatCodes; + /** Proving jobs */ + prover: ProverClient | undefined; /** Function to stop the started services. */ teardown: () => Promise; }; -/** - * Sets up the environment for the end-to-end tests. - * @param numberOfAccounts - The number of new accounts to be created once the PXE is initiated. - * @param opts - Options to pass to the node initialization and to the setup script. - * @param pxeOpts - Options to pass to the PXE initialization. - */ -export async function setup( - numberOfAccounts = 1, +export async function setupNoL2Deploy( opts: SetupOptions = {}, pxeOpts: Partial = {}, - enableGas = false, -): Promise { +): Promise> { + const logger = getLogger(); const config = { ...getConfigEnvVars(), ...opts }; let anvil: Anvil | undefined; @@ -380,6 +347,7 @@ export async function setup( // Enable logging metrics to a local file named after the test suite if (isMetricsLoggingRequested()) { const filename = path.join('log', getJobName() + '.jsonl'); + logger.info(`Logging metrics to ${filename}`); setupMetricsLogger(filename); } @@ -388,14 +356,13 @@ export async function setup( await ethCheatCodes.loadChainState(opts.stateLoad); } - const logger = getLogger(); const hdAccount = mnemonicToAccount(MNEMONIC); const privKeyRaw = hdAccount.getHdKey().privateKey; const publisherPrivKey = privKeyRaw === null ? null : Buffer.from(privKeyRaw); if (PXE_URL) { // we are setting up against a remote environment, l1 contracts are assumed to already be deployed - return await setupWithRemoteEnvironment(hdAccount, config, logger, numberOfAccounts, enableGas); + return setupWithRemoteEnvironment(hdAccount, config, logger, 0, false); } const deployL1ContractsValues = @@ -409,26 +376,15 @@ export async function setup( const acvmConfig = await getACVMConfig(logger); if (acvmConfig) { config.acvmWorkingDirectory = acvmConfig.acvmWorkingDirectory; - config.acvmBinaryPath = acvmConfig.expectedAcvmPath; + config.acvmBinaryPath = acvmConfig.acvmBinaryPath; } config.l1BlockPublishRetryIntervalMS = 100; const aztecNode = await AztecNodeService.createAndSync(config); const sequencer = aztecNode.getSequencer(); + const prover = aztecNode.getProver(); logger.verbose('Creating a pxe...'); - const { pxe, wallets } = await setupPXEService(numberOfAccounts, aztecNode!, pxeOpts, logger); - - logger.verbose('Deploying key registry...'); - await deployCanonicalKeyRegistry( - new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(config.chainId, config.version)), - ); - - if (enableGas) { - logger.verbose('Deploying gas token...'); - await deployCanonicalGasToken( - new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(config.chainId, config.version)), - ); - } + const { pxe } = await setupPXEService(0, aztecNode!, pxeOpts, logger, false); const cheatCodes = CheatCodes.create(config.rpcUrl, pxe!); @@ -440,10 +396,10 @@ export async function setup( await pxe?.stop(); } - if (acvmConfig?.directoryToCleanup) { + if (acvmConfig?.cleanup) { // remove the temp directory created for the acvm - logger.verbose(`Cleaning up ACVM temp directory ${acvmConfig.directoryToCleanup}`); - await fs.rm(acvmConfig.directoryToCleanup, { recursive: true, force: true }); + logger.verbose(`Cleaning up ACVM state`); + await acvmConfig.cleanup(); } await anvil?.stop(); @@ -454,15 +410,54 @@ export async function setup( pxe, deployL1ContractsValues, config, - wallet: wallets[0], - wallets, logger, cheatCodes, sequencer, + prover, + wallets: [], teardown, }; } +/** + * Sets up the environment for the end-to-end tests. + * @param numberOfAccounts - The number of new accounts to be created once the PXE is initiated. + * @param opts - Options to pass to the node initialization and to the setup script. + * @param pxeOpts - Options to pass to the PXE initialization. + */ +export async function setup( + numberOfAccounts = 1, + opts: SetupOptions = {}, + pxeOpts: Partial = {}, + enableGas = false, +): Promise { + const ctx = await setupNoL2Deploy(opts, pxeOpts); + const wallets = await getDeployedTestAccountsWallets(ctx.pxe); + if (wallets.length < numberOfAccounts) { + const numNewAccounts = numberOfAccounts - wallets.length; + ctx.logger.verbose(`Deploying ${numNewAccounts} accounts...`); + wallets.push(...(await createAccounts(ctx.pxe, numNewAccounts))); + } + + ctx.logger.verbose('Deploying key registry...'); + await deployCanonicalKeyRegistry( + new SignerlessWallet(ctx.pxe, new DefaultMultiCallEntrypoint(ctx.config.chainId, ctx.config.version)), + ); + + if (enableGas) { + ctx.logger.verbose('Deploying gas token...'); + await deployCanonicalGasToken( + new SignerlessWallet(ctx.pxe, new DefaultMultiCallEntrypoint(ctx.config.chainId, ctx.config.version)), + ); + } + + return { + ...ctx, + wallets, + wallet: wallets[0], + }; +} + /** * Registers the contract class used for test accounts and publicly deploys the instances requested. * Use this when you need to make a public call to an account contract, such as for requesting a public authwit. @@ -594,7 +589,7 @@ export async function expectMapping( /** * Deploy the protocol contracts to a running instance. */ -export async function deployCanonicalGasToken(deployer: Wallet) { +export async function deployCanonicalGasToken(deployer: Wallet, timeout?: number) { // "deploy" the Gas token as it contains public functions const gasPortalAddress = (await deployer.getNodeInfo()).l1ContractAddresses.gasPortalAddress; const canonicalGasToken = getCanonicalGasToken(gasPortalAddress); @@ -605,14 +600,14 @@ export async function deployCanonicalGasToken(deployer: Wallet) { const gasToken = await GasTokenContract.deploy(deployer, gasPortalAddress) .send({ contractAddressSalt: canonicalGasToken.instance.salt, universalDeploy: true }) - .deployed(); + .deployed({ timeout }); await expect(deployer.isContractClassPubliclyRegistered(gasToken.instance.contractClassId)).resolves.toBe(true); await expect(deployer.getContractInstance(gasToken.address)).resolves.toBeDefined(); await expect(deployer.isContractPubliclyDeployed(gasToken.address)).resolves.toBe(true); } -async function deployCanonicalKeyRegistry(deployer: Wallet) { +async function deployCanonicalKeyRegistry(deployer: Wallet, timeout?: number) { const canonicalKeyRegistry = getCanonicalKeyRegistry(); // We check to see if there exists a contract at the canonical Key Registry address with the same contract class id as we expect. This means that @@ -628,7 +623,7 @@ async function deployCanonicalKeyRegistry(deployer: Wallet) { const keyRegistry = await KeyRegistryContract.deploy(deployer) .send({ contractAddressSalt: canonicalKeyRegistry.instance.salt, universalDeploy: true }) - .deployed(); + .deployed({ timeout }); if ( !keyRegistry.address.equals(canonicalKeyRegistry.address) || diff --git a/yarn-project/prover-client/src/bb/execute.ts b/yarn-project/prover-client/src/bb/execute.ts index f53950dd0f5c..58a7cb968a61 100644 --- a/yarn-project/prover-client/src/bb/execute.ts +++ b/yarn-project/prover-client/src/bb/execute.ts @@ -50,16 +50,16 @@ export function executeBB( ) { return new Promise((resolve, reject) => { // spawn the bb process - const acvm = proc.spawn(pathToBB, [command, ...args]); - acvm.stdout.on('data', data => { + const bb = proc.spawn(pathToBB, [command, ...args]); + bb.stdout.on('data', data => { const message = data.toString('utf-8').replace(/\n$/, ''); logger(message); }); - acvm.stderr.on('data', data => { + bb.stderr.on('data', data => { const message = data.toString('utf-8').replace(/\n$/, ''); logger(message); }); - acvm.on('close', (code: number) => { + bb.on('close', (code: number) => { if (resultParser(code)) { resolve(BB_RESULT.SUCCESS); } else { diff --git a/yarn-project/prover-client/src/config.ts b/yarn-project/prover-client/src/config.ts index 0b8f7cce6ea1..261fce51f7ab 100644 --- a/yarn-project/prover-client/src/config.ts +++ b/yarn-project/prover-client/src/config.ts @@ -16,6 +16,8 @@ export interface ProverConfig { proverAgents: number; /** Enable proving. If true, must set bb env vars */ realProofs: boolean; + /** The interval agents poll for jobs at */ + proverAgentPollInterval: number; } /** @@ -30,11 +32,16 @@ export function getProverEnvVars(): ProverConfig { BB_WORKING_DIRECTORY = tmpdir(), BB_BINARY_PATH = '', PROVER_AGENTS = '1', + PROVER_AGENT_POLL_INTERVAL_MS = '10', PROVER_REAL_PROOFS = '', } = process.env; const parsedProverAgents = parseInt(PROVER_AGENTS, 10); const proverAgents = Number.isSafeInteger(parsedProverAgents) ? parsedProverAgents : 0; + const parsedProverAgentPollInterval = parseInt(PROVER_AGENT_POLL_INTERVAL_MS, 10); + const proverAgentPollInterval = Number.isSafeInteger(parsedProverAgentPollInterval) + ? parsedProverAgentPollInterval + : 10; return { acvmWorkingDirectory: ACVM_WORKING_DIRECTORY, @@ -43,5 +50,6 @@ export function getProverEnvVars(): ProverConfig { bbWorkingDirectory: BB_WORKING_DIRECTORY, proverAgents, realProofs: ['1', 'true'].includes(PROVER_REAL_PROOFS), + proverAgentPollInterval, }; } diff --git a/yarn-project/prover-client/src/index.ts b/yarn-project/prover-client/src/index.ts index c47f1852f991..4331fcaff0ea 100644 --- a/yarn-project/prover-client/src/index.ts +++ b/yarn-project/prover-client/src/index.ts @@ -1,3 +1,5 @@ +export { ProverClient } from '@aztec/circuit-types'; + export * from './tx-prover/tx-prover.js'; export * from './config.js'; export * from './dummy-prover.js'; 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 0750b41520e1..ebb5b7b15da5 100644 --- a/yarn-project/prover-client/src/prover-pool/prover-pool.ts +++ b/yarn-project/prover-client/src/prover-pool/prover-pool.ts @@ -2,7 +2,6 @@ import { type ProvingJobSource } from '@aztec/circuit-types'; import { type SimulationProvider } from '@aztec/simulator'; import { mkdtemp } from 'fs/promises'; -import { tmpdir } from 'os'; import { join } from 'path'; import { BBNativeRollupProver, type BBProverConfig } from '../prover/bb_prover.js'; @@ -55,22 +54,18 @@ export class ProverPool { ); } - static nativePool( - { acvmBinaryPath, bbBinaryPath }: Pick, - size: number, - agentPollIntervalMS = 10, - ): ProverPool { + static nativePool(config: Omit, size: number, agentPollIntervalMS = 10): ProverPool { // TODO generate keys ahead of time so that each agent doesn't have to do it return new ProverPool(size, async i => { const [acvmWorkingDirectory, bbWorkingDirectory] = await Promise.all([ - mkdtemp(join(tmpdir(), 'acvm-')), - mkdtemp(join(tmpdir(), 'bb-')), + mkdtemp(join(config.acvmWorkingDirectory, 'agent-')), + mkdtemp(join(config.bbWorkingDirectory, 'agent-')), ]); return new ProverAgent( await BBNativeRollupProver.new({ - acvmBinaryPath, + acvmBinaryPath: config.acvmBinaryPath, acvmWorkingDirectory, - bbBinaryPath, + bbBinaryPath: config.bbBinaryPath, bbWorkingDirectory, }), agentPollIntervalMS, diff --git a/yarn-project/prover-client/src/tx-prover/tx-prover.ts b/yarn-project/prover-client/src/tx-prover/tx-prover.ts index e5b08a74560d..ae4370f89a57 100644 --- a/yarn-project/prover-client/src/tx-prover/tx-prover.ts +++ b/yarn-project/prover-client/src/tx-prover/tx-prover.ts @@ -68,9 +68,9 @@ export class TxProver implements ProverClient { throw new Error(); } - pool = ProverPool.nativePool(config, config.proverAgents, 10); + pool = ProverPool.nativePool(config, config.proverAgents, config.proverAgentPollInterval); } else { - pool = ProverPool.testPool(simulationProvider, config.proverAgents, 10); + pool = ProverPool.testPool(simulationProvider, config.proverAgents, config.proverAgentPollInterval); } const prover = new TxProver(worldStateSynchronizer, getVerificationKeys(), pool);