Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable UltraHonk verifier #7923

Merged
merged 4 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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');
}
}
Loading