Skip to content
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
7 changes: 3 additions & 4 deletions yarn-project/ivc-integration/src/avm_integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
import type { ProofAndVerificationKey } from '@aztec/stdlib/interfaces/server';

import { jest } from '@jest/globals';
import { promises as fs } from 'fs';
import os from 'os';
import path from 'path';
import { fileURLToPath } from 'url';

import { getWorkingDirectory } from './bb_working_directory.js';
import {
MockRollupBasePublicCircuit,
generate3FunctionTestingIVCStack,
Expand Down Expand Up @@ -45,7 +44,7 @@ describe('AVM Integration', () => {
let simTester: PublicTxSimulationTester;

beforeAll(async () => {
const clientIVCProofPath = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-avm-integration-client-ivc-'));
const clientIVCProofPath = await getWorkingDirectory('bb-avm-integration-client-ivc-');
bbBinaryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../../barretenberg/cpp/build/bin', 'bb');
const [bytecodes, witnessStack, tailPublicInputs] = await generate3FunctionTestingIVCStack();
clientIVCPublicInputs = tailPublicInputs;
Expand All @@ -63,7 +62,7 @@ describe('AVM Integration', () => {

beforeEach(async () => {
//Create a temp working dir
bbWorkingDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-avm-integration-'));
bbWorkingDirectory = await getWorkingDirectory('bb-avm-integration-');

simTester = await PublicTxSimulationTester.create();
avmTestContractInstance = await simTester.registerAndDeployContract(
Expand Down
9 changes: 9 additions & 0 deletions yarn-project/ivc-integration/src/bb_working_directory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import fs from 'fs/promises';
import os from 'os';
import path from 'path';

export async function getWorkingDirectory(prefix: string): Promise<string> {
const baseFolder = process.env.BB_WORKING_DIRECTORY || os.tmpdir();
await fs.mkdir(baseFolder, { recursive: true });
return await fs.mkdtemp(path.join(baseFolder, prefix));
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import { BB_RESULT, verifyClientIvcProof, writeClientIVCProofToOutputDirectory }
import { createLogger } from '@aztec/foundation/log';

import { jest } from '@jest/globals';
import { promises as fs } from 'fs';
import os from 'os';
import path from 'path';
import { fileURLToPath } from 'url';

import { getWorkingDirectory } from './bb_working_directory.js';
import { generate3FunctionTestingIVCStack, generate6FunctionTestingIVCStack } from './index.js';
import { proveClientIVC } from './prove_native.js';

Expand All @@ -22,7 +21,7 @@ describe('Client IVC Integration', () => {

beforeEach(async () => {
// Create a temp working dir
bbWorkingDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-client-ivc-integration-'));
bbWorkingDirectory = await getWorkingDirectory('bb-client-ivc-integration-');
bbBinaryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../../barretenberg/cpp/build/bin', 'bb');
});

Expand Down
23 changes: 22 additions & 1 deletion yarn-project/ivc-integration/src/prove_wasm.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
import { ClientIvcProof } from '@aztec/stdlib/proofs';

import os from 'os';
import { ungzip } from 'pako';

function base64ToUint8Array(base64: string): Uint8Array {
return Uint8Array.from(atob(base64), c => c.charCodeAt(0));
}

export async function proveClientIVC(
bytecodes: string[],
witnessStack: Uint8Array[],
threads?: number,
): Promise<ClientIvcProof> {
const { AztecClientBackend } = await import('@aztec/bb.js');
const backend = new AztecClientBackend(
bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr)),
{ threads: threads || Math.min(os.cpus().length, 16) },
);
try {
const [proof] = await backend.prove(witnessStack.map((arr: Uint8Array) => ungzip(arr)));
return new ClientIvcProof(Buffer.from(proof));
} finally {
await backend.destroy();
}
}

export async function proveThenVerifyAztecClient(
bytecodes: string[],
witnessStack: Uint8Array[],
Expand All @@ -12,7 +33,7 @@ export async function proveThenVerifyAztecClient(
const { AztecClientBackend } = await import('@aztec/bb.js');
const backend = new AztecClientBackend(
bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr)),
{ threads },
{ threads: threads || Math.min(os.cpus().length, 16) },
);
try {
const [proof, vk] = await backend.prove(witnessStack.map((arr: Uint8Array) => ungzip(arr)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
import type { ProofAndVerificationKey } from '@aztec/stdlib/interfaces/server';

import { jest } from '@jest/globals';
import { promises as fs } from 'fs';
import os from 'os';
import path from 'path';
import { fileURLToPath } from 'url';

import { getWorkingDirectory } from './bb_working_directory.js';
import {
MockRollupBasePrivateCircuit,
MockRollupBasePublicCircuit,
Expand Down Expand Up @@ -54,7 +53,7 @@ describe('Rollup IVC Integration', () => {
bbBinaryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../../barretenberg/cpp/build/bin', 'bb');

// Create a client IVC proof
const clientIVCWorkingDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-rollup-ivc-integration-client-ivc-'));
const clientIVCWorkingDirectory = await getWorkingDirectory('bb-rollup-ivc-integration-client-ivc-');

const [bytecodes, witnessStack, tailPublicInputs] = await generate3FunctionTestingIVCStack();
clientIVCPublicInputs = tailPublicInputs;
Expand All @@ -71,7 +70,7 @@ describe('Rollup IVC Integration', () => {
tubeProof = await proveTube(bbBinaryPath, clientIVCWorkingDirectory, logger);

// Create an AVM proof
const avmWorkingDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-rollup-ivc-integration-avm-'));
const avmWorkingDirectory = await getWorkingDirectory('bb-rollup-ivc-integration-avm-');

const simTester = await PublicTxSimulationTester.create();
const avmTestContractInstance = await simTester.registerAndDeployContract(
Expand All @@ -90,7 +89,7 @@ describe('Rollup IVC Integration', () => {
});

beforeEach(async () => {
workingDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-rollup-ivc-integration-'));
workingDirectory = await getWorkingDirectory('bb-rollup-ivc-integration-');
});

it('Should be able to generate a proof of a 3 transaction rollup', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { BB_RESULT, verifyClientIvcProof, writeClientIVCProofToOutputDirectory } from '@aztec/bb-prover';
import { AztecClientBackend } from '@aztec/bb.js';
import { createLogger } from '@aztec/foundation/log';

import { jest } from '@jest/globals';

/* eslint-disable camelcase */
import createDebug from 'debug';
import { ungzip } from 'pako';
import path from 'path';
import { fileURLToPath } from 'url';

import { getWorkingDirectory } from './bb_working_directory.js';
import {
MOCK_MAX_COMMITMENTS_PER_TX,
MockAppCreatorCircuit,
Expand All @@ -19,6 +24,7 @@ import {
MockPrivateKernelResetCircuit,
MockPrivateKernelResetVk,
MockPrivateKernelTailCircuit,
generate3FunctionTestingIVCStack,
getVkAsFields,
witnessGenCreatorAppMockCircuit,
witnessGenMockPrivateKernelInitCircuit,
Expand All @@ -27,9 +33,11 @@ import {
witnessGenMockPrivateKernelTailCircuit,
witnessGenReaderAppMockCircuit,
} from './index.js';
import { proveThenVerifyAztecClient } from './prove_wasm.js';
import { proveClientIVC as proveClientIVCNative } from './prove_native.js';
import { proveClientIVC as proveClientIVCWasm, proveThenVerifyAztecClient } from './prove_wasm.js';

const logger = createLogger('ivc-integration:test:wasm');

const logger = createDebug('ivc-integration:test:wasm');
createDebug.enable('*');

jest.setTimeout(120_000);
Expand All @@ -41,42 +49,31 @@ describe('Client IVC Integration', () => {
// 1. Run a mock app that creates two commitments
// 2. Run the init kernel to process the app run
// 3. Run the tail kernel to finish the client IVC chain.
it('Should generate a verifiable client IVC proof from a simple mock tx via bb.js', async () => {
const tx = {
number_of_calls: '0x1',
};
// Witness gen app and kernels
const appWitnessGenResult = await witnessGenCreatorAppMockCircuit({ commitments_to_create: ['0x1', '0x2'] });
logger('generated app mock circuit witness');

const initWitnessGenResult = await witnessGenMockPrivateKernelInitCircuit({
app_inputs: appWitnessGenResult.publicInputs,
tx,
app_vk: getVkAsFields(MockAppCreatorVk),
});
logger('generated mock private kernel init witness');

const tailWitnessGenResult = await witnessGenMockPrivateKernelTailCircuit({
prev_kernel_public_inputs: initWitnessGenResult.publicInputs,
kernel_vk: getVkAsFields(MockPrivateKernelInitVk),
});
logger('generated mock private kernel tail witness');

// Create client IVC proof
const bytecodes = [
MockAppCreatorCircuit.bytecode,
MockPrivateKernelInitCircuit.bytecode,
MockPrivateKernelTailCircuit.bytecode,
it('Should generate a verifiable client IVC proof from a simple mock tx via bb.js, verified by bb', async () => {
const [bytecodes, witnessStack] = await generate3FunctionTestingIVCStack();

// We use the bb binary for verification / writing out the VK
const bbBinaryPath = path.join(
path.dirname(fileURLToPath(import.meta.url)),
'../../../barretenberg/cpp/build/bin',
'bb',
);
const clientIVCWorkingDirectory = await getWorkingDirectory('bb-client-ivc-integration-');
const tasks = [
proveClientIVCNative(bbBinaryPath, clientIVCWorkingDirectory, witnessStack, bytecodes, logger),
proveClientIVCWasm(bytecodes, witnessStack),
];

logger('built bytecode array');
const witnessStack = [appWitnessGenResult.witness, initWitnessGenResult.witness, tailWitnessGenResult.witness];
logger('built witness stack');

const verifyResult = await proveThenVerifyAztecClient(bytecodes, witnessStack);
logger(`generated then verified proof. result: ${verifyResult}`);

expect(verifyResult).toEqual(true);
const [_, wasmProof] = await Promise.all(tasks);

// Write the WASM proof over the output directory (the bb cli will have output to this folder, we need the vk to be in place).
await writeClientIVCProofToOutputDirectory(wasmProof, clientIVCWorkingDirectory);
const verifyWasmResultInNative = await verifyClientIvcProof(
bbBinaryPath,
clientIVCWorkingDirectory.concat('/proof'),
clientIVCWorkingDirectory.concat('/vk'),
logger.info,
);
expect(verifyWasmResultInNative.status).toEqual(BB_RESULT.SUCCESS);
});

it('Should generate an array of gate numbers for the stack of programs being proved by ClientIVC', async () => {
Expand All @@ -93,7 +90,7 @@ describe('Client IVC Integration', () => {
// Compute the numbers of gates in each circuit
const gateNumbers = await backend.gates();
await backend.destroy();
logger('Gate numbers for each circuit:', gateNumbers);
logger.info('Gate numbers for each circuit:', gateNumbers);
// STARTER: add a test here instantiate an AztecClientBackend with the above bytecodes, call gates, and check they're correct (maybe just
// eyeball against logs to start... better is to make another test that actually pins the sizes since the mock protocol circuits are
// intended not to change, though for sure there will be some friction, and such test should actually just be located in barretenberg/ts)
Expand Down Expand Up @@ -160,7 +157,7 @@ describe('Client IVC Integration', () => {
];

const verifyResult = await proveThenVerifyAztecClient(bytecodes, witnessStack);
logger(`generated then verified proof. result: ${verifyResult}`);
logger.info(`generated then verified proof. result: ${verifyResult}`);

expect(verifyResult).toEqual(true);
});
Expand Down
1 change: 1 addition & 0 deletions yarn-project/scripts/run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ if [ "${ISOLATE:-0}" -eq 1 ]; then
wait $!
else
export NODE_OPTIONS="--no-warnings --experimental-vm-modules --loader @swc-node/register"
export LOG_LEVEL=${LOG_LEVEL:-info}
cd ../$dir
node ../node_modules/.bin/jest --forceExit --runInBand $test
fi