Skip to content

Commit

Permalink
feat: enable UltraHonk verifier (#7923)
Browse files Browse the repository at this point in the history
Fix #7373
  • Loading branch information
alexghr authored Aug 13, 2024
1 parent 3f145b3 commit 5e8b4a8
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 95 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/devnet-deploys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/bb-prover/src/bb/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
47 changes: 25 additions & 22 deletions yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts
Original file line number Diff line number Diff line change
@@ -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 deployUltraVerifier(
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,
) {
Expand All @@ -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,
},
},
Expand All @@ -52,18 +52,19 @@ 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!)
: 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 UltraVerifier at ${verifierAddress.toString()}`);
log(`Deployed HonkVerifier at ${verifierAddress.toString()}`);

const pxe = await createCompatibleClient(pxeRpcUrl, debugLogger);
const { l1ContractAddresses } = await pxe.getNodeInfo();
Expand All @@ -82,16 +83,18 @@ export async function deployUltraVerifier(

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);
Expand Down
25 changes: 15 additions & 10 deletions yarn-project/cli/src/cmds/l1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.')
Expand Down Expand Up @@ -46,35 +48,38 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL
.command('deploy-l1-verifier')
.description('Deploys the rollup verifier contract')
.requiredOption(
'--eth-rpc-url <string>',
'--l1-rpc-url <string>',
'Url of the ethereum host. Chain identifiers localhost and testnet can be used',
ETHEREUM_HOST,
)
.requiredOption('--l1-chain-id <string>', 'The chain id of the L1 network', '31337')
.addOption(pxeOption)
.requiredOption('-pk, --private-key <string>', 'The private key to use for deployment', PRIVATE_KEY)
.option('--l1-private-key <string>', 'The L1 private key to use for deployment', PRIVATE_KEY)
.option(
'-m, --mnemonic <string>',
'The mnemonic to use in deployment',
'test test test test test test test test test test test junk',
)
.requiredOption('--verifier <verifier>', 'Either mock or real', 'real')
.option('--bb <path>', 'Path to bb binary')
.option('--bb-working-dir <path>', 'Path to bb working directory')
.option('--bb <path>', 'Path to bb binary', BB_BINARY_PATH)
.option('--bb-working-dir <path>', 'Path to bb working directory', 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,
options.privateKey,
options.l1RpcUrl,
options.l1ChainId,
options.l1PrivateKey,
options.mnemonic,
options.rpcUrl,
log,
debugLogger,
);
} else {
await deployUltraVerifier(
options.ethRpcUrl,
options.privateKey,
await deployUltraHonkVerifier(
options.l1RpcUrl,
options.l1ChainId,
options.l1PrivateKey,
options.mnemonic,
options.rpcUrl,
options.bb,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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({
Expand Down Expand Up @@ -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
Expand Down
109 changes: 54 additions & 55 deletions yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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['UltraHonkVerifier.sol']['HonkVerifier'].abi;
const bytecode: string = output.contracts['UltraHonkVerifier.sol']['HonkVerifier'].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');
}
}

0 comments on commit 5e8b4a8

Please sign in to comment.