From 88f9d345f9883dcb7b1d0e6280963f2beb6c896f Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Mon, 12 Aug 2024 16:47:18 +0000 Subject: [PATCH 1/4] feat: enable UltraHonk verifier Fix #7373 --- yarn-project/bb-prover/src/bb/execute.ts | 2 +- .../src/e2e_prover/e2e_prover_test.ts | 109 +++++++++--------- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/yarn-project/bb-prover/src/bb/execute.ts b/yarn-project/bb-prover/src/bb/execute.ts index 4021001da96..a26a31ba5df 100644 --- a/yarn-project/bb-prover/src/bb/execute.ts +++ b/yarn-project/bb-prover/src/bb/execute.ts @@ -811,7 +811,7 @@ export async function generateContractForVerificationKey( try { const args = ['-k', vkFilePath, '-o', contractPath, '-v']; const timer = new Timer(); - const result = await executeBB(pathToBB, 'contract', args, log); + const result = await executeBB(pathToBB, 'contract_ultra_honk', args, log); const duration = timer.ms(); if (result.status == BB_RESULT.SUCCESS) { return { status: BB_RESULT.SUCCESS, durationMs: duration, contractPath }; diff --git a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts index b98823ebe95..8dd6605f764 100644 --- a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts @@ -11,18 +11,19 @@ import { type PXE, type TxHash, computeSecretHash, - createDebugLogger, // TODO(#7373): Deploy honk solidity verifier - // deployL1Contract, + createDebugLogger, + deployL1Contract, } from '@aztec/aztec.js'; import { BBCircuitVerifier } from '@aztec/bb-prover'; -// import { RollupAbi } from '@aztec/l1-artifacts'; +import { RollupAbi } from '@aztec/l1-artifacts'; import { TokenContract } from '@aztec/noir-contracts.js'; import { type PXEService } from '@aztec/pxe'; // TODO(#7373): Deploy honk solidity verifier -// // @ts-expect-error solc-js doesn't publish its types https://github.com/ethereum/solc-js/issues/689 -// import solc from 'solc'; -// import { getContract } from 'viem'; +// @ts-expect-error solc-js doesn't publish its types https://github.com/ethereum/solc-js/issues/689 +import solc from 'solc'; +import { getContract } from 'viem'; + import { waitRegisteredAccountSynced } from '../benchmarks/utils.js'; import { getACVMConfig } from '../fixtures/get_acvm_config.js'; import { getBBConfig } from '../fixtures/get_bb_config.js'; @@ -287,58 +288,56 @@ export class FullProverTest { ); } - deployVerifier() { + async deployVerifier() { if (!this.circuitProofVerifier) { throw new Error('No verifier'); } - // TODO(#7373): Deploy honk solidity verifier - return Promise.resolve(); - // const { walletClient, publicClient, l1ContractAddresses } = this.context.deployL1ContractsValues; - - // const contract = await this.circuitProofVerifier.generateSolidityContract( - // 'RootRollupArtifact', - // 'UltraVerifier.sol', - // ); - - // const input = { - // language: 'Solidity', - // sources: { - // 'UltraVerifier.sol': { - // content: contract, - // }, - // }, - // settings: { - // // we require the optimizer - // optimizer: { - // enabled: true, - // runs: 200, - // }, - // evmVersion: 'paris', - // outputSelection: { - // '*': { - // '*': ['evm.bytecode.object', 'abi'], - // }, - // }, - // }, - // }; - - // const output = JSON.parse(solc.compile(JSON.stringify(input))); - - // const abi = output.contracts['UltraVerifier.sol']['UltraVerifier'].abi; - // const bytecode: string = output.contracts['UltraVerifier.sol']['UltraVerifier'].evm.bytecode.object; - - // const verifierAddress = await deployL1Contract(walletClient, publicClient, abi, `0x${bytecode}`); - - // this.logger.info(`Deployed Real verifier at ${verifierAddress}`); - - // const rollup = getContract({ - // abi: RollupAbi, - // address: l1ContractAddresses.rollupAddress.toString(), - // client: walletClient, - // }); - - // await rollup.write.setVerifier([verifierAddress.toString()]); - // this.logger.info('Rollup only accepts valid proofs now'); + const { walletClient, publicClient, l1ContractAddresses } = this.context.deployL1ContractsValues; + + const contract = await this.circuitProofVerifier.generateSolidityContract( + 'RootRollupArtifact', + 'UltraHonkVerifier.sol', + ); + + const input = { + language: 'Solidity', + sources: { + 'UltraHonkVerifier.sol': { + content: contract, + }, + }, + settings: { + // we require the optimizer + optimizer: { + enabled: true, + runs: 200, + }, + evmVersion: 'paris', + outputSelection: { + '*': { + '*': ['evm.bytecode.object', 'abi'], + }, + }, + }, + }; + + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + const abi = output.contracts['UltraVerifier.sol']['UltraVerifier'].abi; + const bytecode: string = output.contracts['UltraVerifier.sol']['UltraVerifier'].evm.bytecode.object; + + const verifierAddress = await deployL1Contract(walletClient, publicClient, abi, `0x${bytecode}`); + + this.logger.info(`Deployed Real verifier at ${verifierAddress}`); + + const rollup = getContract({ + abi: RollupAbi, + address: l1ContractAddresses.rollupAddress.toString(), + client: walletClient, + }); + + await rollup.write.setVerifier([verifierAddress.toString()]); + this.logger.info('Rollup only accepts valid proofs now'); } } From 8aef04368616795cbcfb59541f1c043a63e2bb76 Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Tue, 13 Aug 2024 09:31:54 +0000 Subject: [PATCH 2/4] fix: correct contract name --- .../cli/src/cmds/l1/deploy_l1_verifier.ts | 16 ++++++++-------- yarn-project/cli/src/cmds/l1/index.ts | 4 ++-- .../integration_proof_verification.test.ts | 10 +++++----- .../end-to-end/src/e2e_prover/e2e_prover_test.ts | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts b/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts index 39d10398c99..a338352d21e 100644 --- a/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts +++ b/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts @@ -8,7 +8,7 @@ import solc from 'solc'; import { getContract } from 'viem'; import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts'; -export async function deployUltraVerifier( +export async function deployUltraHonkVerifier( ethRpcUrl: string, privateKey: string, mnemonic: string, @@ -26,13 +26,13 @@ export async function deployUltraVerifier( const { BBCircuitVerifier } = await import('@aztec/bb-prover'); const circuitVerifier = await BBCircuitVerifier.new({ bbBinaryPath, bbWorkingDirectory }); - const contractSrc = await circuitVerifier.generateSolidityContract('RootRollupArtifact', 'UltraVerifier.sol'); - log('Generated UltraVerifier contract'); + const contractSrc = await circuitVerifier.generateSolidityContract('RootRollupArtifact', 'UltraHonkVerifier.sol'); + log('Generated UltraHonkVerifier contract'); const input = { language: 'Solidity', sources: { - 'UltraVerifier.sol': { + 'UltraHonkVerifier.sol': { content: contractSrc, }, }, @@ -52,10 +52,10 @@ export async function deployUltraVerifier( }; const output = JSON.parse(solc.compile(JSON.stringify(input))); - log('Compiled UltraVerifier'); + log('Compiled UltraHonkVerifier'); - const abi = output.contracts['UltraVerifier.sol']['UltraVerifier'].abi; - const bytecode: string = output.contracts['UltraVerifier.sol']['UltraVerifier'].evm.bytecode.object; + const abi = output.contracts['UltraHonkVerifier.sol']['UltraHonkVerifier'].abi; + const bytecode: string = output.contracts['UltraHonkVerifier.sol']['HonkVerifier'].evm.bytecode.object; const account = !privateKey ? mnemonicToAccount(mnemonic!) @@ -63,7 +63,7 @@ export async function deployUltraVerifier( const { publicClient, walletClient } = createL1Clients(ethRpcUrl, account); const verifierAddress = await deployL1Contract(walletClient, publicClient, abi, `0x${bytecode}`); - log(`Deployed UltraVerifier at ${verifierAddress.toString()}`); + log(`Deployed HonkVerifier at ${verifierAddress.toString()}`); const pxe = await createCompatibleClient(pxeRpcUrl, debugLogger); const { l1ContractAddresses } = await pxe.getNodeInfo(); diff --git a/yarn-project/cli/src/cmds/l1/index.ts b/yarn-project/cli/src/cmds/l1/index.ts index 21457b31d5f..3653949339c 100644 --- a/yarn-project/cli/src/cmds/l1/index.ts +++ b/yarn-project/cli/src/cmds/l1/index.ts @@ -61,7 +61,7 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL .option('--bb ', 'Path to bb binary') .option('--bb-working-dir ', 'Path to bb working directory') .action(async options => { - const { deployMockVerifier, deployUltraVerifier } = await import('./deploy_l1_verifier.js'); + const { deployMockVerifier, deployUltraHonkVerifier } = await import('./deploy_l1_verifier.js'); if (options.verifier === 'mock') { await deployMockVerifier( options.ethRpcUrl, @@ -72,7 +72,7 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL debugLogger, ); } else { - await deployUltraVerifier( + await deployUltraHonkVerifier( options.ethRpcUrl, options.privateKey, options.mnemonic, diff --git a/yarn-project/end-to-end/src/composed/integration_proof_verification.test.ts b/yarn-project/end-to-end/src/composed/integration_proof_verification.test.ts index 641bb5faded..522e295d58f 100644 --- a/yarn-project/end-to-end/src/composed/integration_proof_verification.test.ts +++ b/yarn-project/end-to-end/src/composed/integration_proof_verification.test.ts @@ -74,8 +74,8 @@ describe('proof_verification', () => { const input = { language: 'Solidity', sources: { - 'UltraVerifier.sol': { - content: await circuitVerifier.generateSolidityContract('RootRollupArtifact', 'UltraVerifier.sol'), + 'UltraHonkVerifier.sol': { + content: await circuitVerifier.generateSolidityContract('RootRollupArtifact', 'UltraHonkVerifier.sol'), }, }, settings: { @@ -95,8 +95,8 @@ describe('proof_verification', () => { const output = JSON.parse(solc.compile(JSON.stringify(input))); - const abi = output.contracts['UltraVerifier.sol']['UltraVerifier'].abi; - const bytecode: string = output.contracts['UltraVerifier.sol']['UltraVerifier'].evm.bytecode.object; + const abi = output.contracts['UltraHonkVerifier.sol']['HonkVerifier'].abi; + const bytecode: string = output.contracts['UltraHonkVerifier.sol']['HonkVerifier'].evm.bytecode.object; const verifierAddress = await deployL1Contract(walletClient, publicClient, abi, `0x${bytecode}`); verifierContract = getContract({ @@ -132,7 +132,7 @@ describe('proof_verification', () => { }); }); - describe('UltraVerifier', () => { + describe('HonkVerifier', () => { it('verifies full proof', async () => { const reader = BufferReader.asReader(proof.buffer); // +2 fields for archive diff --git a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts index 8dd6605f764..65bc3b987a6 100644 --- a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts @@ -324,8 +324,8 @@ export class FullProverTest { const output = JSON.parse(solc.compile(JSON.stringify(input))); - const abi = output.contracts['UltraVerifier.sol']['UltraVerifier'].abi; - const bytecode: string = output.contracts['UltraVerifier.sol']['UltraVerifier'].evm.bytecode.object; + const abi = output.contracts['UltraHonkVerifier.sol']['HonkVerifier'].abi; + const bytecode: string = output.contracts['UltraHonkVerifier.sol']['HonkVerifier'].evm.bytecode.object; const verifierAddress = await deployL1Contract(walletClient, publicClient, abi, `0x${bytecode}`); From 326b7052863c35271a2a0fed5136eb13e4d6a2b7 Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Tue, 13 Aug 2024 10:29:17 +0000 Subject: [PATCH 3/4] feat: enable verifier on the networks --- .github/workflows/devnet-deploys.yml | 10 ++++++ .../cli/src/cmds/l1/deploy_l1_verifier.ts | 31 ++++++++++--------- yarn-project/cli/src/cmds/l1/index.ts | 21 ++++++++----- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/.github/workflows/devnet-deploys.yml b/.github/workflows/devnet-deploys.yml index 789de886ba5..11a39129498 100644 --- a/.github/workflows/devnet-deploys.yml +++ b/.github/workflows/devnet-deploys.yml @@ -592,6 +592,16 @@ jobs: run: | ./.github/scripts/wait_for_infra.sh pxe ${{ env.DEPLOY_TAG }} ${{ env.API_KEY }} + - name: Deploy verifier + working-directory: ./yarn-project/aztec/terraform/pxe + run: | + set -eo pipefail + docker run aztecprotocol/aztec:${{ env.DEPLOY_TAG }} deploy-verifier \ + --rpc-url https://api.aztec.network/${{ env.DEPLOY_TAG }}/aztec-pxe/${{ env.API_KEY }} \ + --l1-rpc-url https://${{ env.DEPLOY_TAG }}-mainnet-fork.aztec.network:8545/${{ env.API_KEY }} \ + --l1-chain-id ${{ env.L1_CHAIN_ID }} \ + --l1-private-key ${{ env.CONTRACT_PUBLISHER_PRIVATE_KEY }} + - name: Enable transactions bot working-directory: ./yarn-project/aztec/terraform/bot run: | diff --git a/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts b/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts index a338352d21e..6c09d4d2b16 100644 --- a/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts +++ b/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts @@ -1,20 +1,20 @@ import { createCompatibleClient } from '@aztec/aztec.js'; -import { createL1Clients, deployL1Contract } from '@aztec/ethereum'; +import { createEthereumChain, createL1Clients, deployL1Contract } from '@aztec/ethereum'; import { type DebugLogger, type LogFn } from '@aztec/foundation/log'; import { InvalidOptionArgumentError } from 'commander'; // @ts-expect-error solc-js doesn't publish its types https://github.com/ethereum/solc-js/issues/689 import solc from 'solc'; import { getContract } from 'viem'; -import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts'; export async function deployUltraHonkVerifier( ethRpcUrl: string, - privateKey: string, + l1ChainId: string, + privateKey: string | undefined, mnemonic: string, pxeRpcUrl: string, - bbBinaryPath = process.env.BB_BINARY_PATH, - bbWorkingDirectory = process.env.BB_WORKING_DIRECTORY, + bbBinaryPath: string, + bbWorkingDirectory: string, log: LogFn, debugLogger: DebugLogger, ) { @@ -57,10 +57,11 @@ export async function deployUltraHonkVerifier( const abi = output.contracts['UltraHonkVerifier.sol']['UltraHonkVerifier'].abi; const bytecode: string = output.contracts['UltraHonkVerifier.sol']['HonkVerifier'].evm.bytecode.object; - const account = !privateKey - ? mnemonicToAccount(mnemonic!) - : privateKeyToAccount(`${privateKey.startsWith('0x') ? '' : '0x'}${privateKey}` as `0x${string}`); - const { publicClient, walletClient } = createL1Clients(ethRpcUrl, account); + const { publicClient, walletClient } = createL1Clients( + ethRpcUrl, + privateKey ?? mnemonic, + createEthereumChain(ethRpcUrl, l1ChainId).chainInfo, + ); const verifierAddress = await deployL1Contract(walletClient, publicClient, abi, `0x${bytecode}`); log(`Deployed HonkVerifier at ${verifierAddress.toString()}`); @@ -82,16 +83,18 @@ export async function deployUltraHonkVerifier( export async function deployMockVerifier( ethRpcUrl: string, - privateKey: string, + l1ChainId: string, + privateKey: string | undefined, mnemonic: string, pxeRpcUrl: string, log: LogFn, debugLogger: DebugLogger, ) { - const account = !privateKey - ? mnemonicToAccount(mnemonic!) - : privateKeyToAccount(`${privateKey.startsWith('0x') ? '' : '0x'}${privateKey}` as `0x${string}`); - const { publicClient, walletClient } = createL1Clients(ethRpcUrl, account); + const { publicClient, walletClient } = createL1Clients( + ethRpcUrl, + privateKey ?? mnemonic, + createEthereumChain(ethRpcUrl, l1ChainId).chainInfo, + ); const { MockVerifierAbi, MockVerifierBytecode, RollupAbi } = await import('@aztec/l1-artifacts'); const mockVerifierAddress = await deployL1Contract(walletClient, publicClient, MockVerifierAbi, MockVerifierBytecode); diff --git a/yarn-project/cli/src/cmds/l1/index.ts b/yarn-project/cli/src/cmds/l1/index.ts index 3653949339c..197d999da91 100644 --- a/yarn-project/cli/src/cmds/l1/index.ts +++ b/yarn-project/cli/src/cmds/l1/index.ts @@ -13,6 +13,8 @@ import { } from '../../utils/commands.js'; export function injectCommands(program: Command, log: LogFn, debugLogger: DebugLogger) { + const { BB_BINARY_PATH, BB_WORKING_DIRECTORY } = process.env; + program .command('deploy-l1-contracts') .description('Deploys all necessary Ethereum contracts for Aztec.') @@ -46,26 +48,28 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL .command('deploy-l1-verifier') .description('Deploys the rollup verifier contract') .requiredOption( - '--eth-rpc-url ', + '--l1-rpc-url ', 'Url of the ethereum host. Chain identifiers localhost and testnet can be used', ETHEREUM_HOST, ) + .requiredOption('--l1-chain-id ', 'The chain id of the L1 network', '31337') .addOption(pxeOption) - .requiredOption('-pk, --private-key ', 'The private key to use for deployment', PRIVATE_KEY) + .option('--l1-private-key ', 'The L1 private key to use for deployment', PRIVATE_KEY) .option( '-m, --mnemonic ', 'The mnemonic to use in deployment', 'test test test test test test test test test test test junk', ) .requiredOption('--verifier ', 'Either mock or real', 'real') - .option('--bb ', 'Path to bb binary') - .option('--bb-working-dir ', 'Path to bb working directory') + .option('--bb ', 'Path to bb binary', BB_BINARY_PATH) + .option('--bb-working-dir ', 'Path to bb working directory', BB_WORKING_DIRECTORY) .action(async options => { const { deployMockVerifier, deployUltraHonkVerifier } = await import('./deploy_l1_verifier.js'); if (options.verifier === 'mock') { await deployMockVerifier( - options.ethRpcUrl, - options.privateKey, + options.l1RpcUrl, + options.l1ChainId, + options.l1PrivateKey, options.mnemonic, options.rpcUrl, log, @@ -73,8 +77,9 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL ); } else { await deployUltraHonkVerifier( - options.ethRpcUrl, - options.privateKey, + options.l1RpcUrl, + options.l1ChainId, + options.l1PrivateKey, options.mnemonic, options.rpcUrl, options.bb, From ca20af2e92581317e4495c04b0693a2c96abbc9e Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Tue, 13 Aug 2024 10:33:36 +0000 Subject: [PATCH 4/4] fix: update contract name in docker images --- yarn-project/Dockerfile | 2 +- yarn-project/Earthfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/Dockerfile b/yarn-project/Dockerfile index 6ecc7e2039e..aab2df6860e 100644 --- a/yarn-project/Dockerfile +++ b/yarn-project/Dockerfile @@ -42,7 +42,7 @@ ENV ACVM_WORKING_DIRECTORY=/usr/src/yarn-project/acvm RUN mkdir -p $BB_WORKING_DIRECTORY $ACVM_WORKING_DIRECTORY && \ test $(arch) = "x86_64" && \ echo -n RootRollupArtifact PrivateKernelTailArtifact PrivateKernelTailToPublicArtifact | xargs -d ' ' -P 3 -I {} node bb-prover/dest/bb/index.js write-vk -c {} && \ - node bb-prover/dest/bb/index.js write-contract -c RootRollupArtifact -n UltraVerifier.sol || \ + node bb-prover/dest/bb/index.js write-contract -c RootRollupArtifact -n UltraHonkVerifier.sol || \ echo "Skipping VK generation arch=$(arch)" RUN yarn workspaces focus @aztec/aztec @aztec/cli-wallet --production && yarn cache clean diff --git a/yarn-project/Earthfile b/yarn-project/Earthfile index 4a74e6bea92..6a918d6abb7 100644 --- a/yarn-project/Earthfile +++ b/yarn-project/Earthfile @@ -116,7 +116,7 @@ protocol-verification-keys: rollup-verifier-contract: FROM +bb-cli COPY --dir +protocol-verification-keys/usr/src/bb /usr/src - RUN --entrypoint write-contract -c RootRollupArtifact -n UltraVerifier.sol + RUN --entrypoint write-contract -c RootRollupArtifact -n UltraHonkVerifier.sol SAVE ARTIFACT /usr/src/bb /usr/src/bb txe: