Skip to content

Commit

Permalink
feat: Proving the rollup circuits (#5599)
Browse files Browse the repository at this point in the history
This PR implements a first stage of proving the rollup circuits. We
introduce the bb binary and use it to produce verification keys,
generate proofs and later verify those proofs for all of the rollup
circuits, currently demonstrated in a unit test.
  • Loading branch information
PhilWindle committed Apr 12, 2024
1 parent 30a2edd commit 145cbcd
Show file tree
Hide file tree
Showing 50 changed files with 2,595 additions and 1,060 deletions.
14 changes: 14 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,18 @@ jobs:
command: cond_spot_run_build yarn-project-test 64
aztec_manifest_key: yarn-project-test

prover-client-test:
docker:
- image: aztecprotocol/alpine-build-image
resource_class: small
steps:
- *checkout
- *setup_env
- run:
name: "Build and test"
command: cond_spot_run_build prover-client-test 128
aztec_manifest_key: prover-client-test

aztec-package:
machine:
image: default
Expand Down Expand Up @@ -1429,6 +1441,7 @@ workflows:
- end-to-end: *defaults_yarn_project
- aztec-faucet: *defaults_yarn_project_pre_join
- build-docs: *defaults_yarn_project_pre_join
- prover-client-test: *defaults_yarn_project
- yarn-project-test: *defaults_yarn_project
- yarn-project-x86_64: *defaults_yarn_project_pre_join
- yarn-project-arm64: *defaults_yarn_project_pre_join
Expand Down Expand Up @@ -1581,6 +1594,7 @@ workflows:
- yellow-paper
- noir-packages-tests
- yarn-project-test
- prover-client-test
<<: *defaults

# Benchmark jobs.
Expand Down
17 changes: 17 additions & 0 deletions build_manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ yarn-project-test:
- l1-contracts
- noir-projects
- barretenberg-x86_64-linux-clang
- noir

# Runs all prover-client checks and tests.
prover-client-test:
buildDir: yarn-project
projectDir: yarn-project/prover-client
dockerfile: Dockerfile.test
rebuildPatterns:
- ^yarn-project/.*\.(ts|tsx|js|cjs|mjs|json|html|md|sh|nr|toml|snap)$
- ^yarn-project/Dockerfile$
dependencies:
- bb.js
- noir-packages
- l1-contracts
- noir-projects
- barretenberg-x86_64-linux-clang
- noir

# Builds all of yarn-project, with all developer dependencies.
# Creates a runnable container used to run tests and formatting checks.
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"bbfree",
"bbmalloc",
"benesjan",
"Bincode",
"bleurgh",
"bodyparser",
"bootnode",
Expand Down
7 changes: 3 additions & 4 deletions noir/noir-repo/tooling/acvm_cli/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ use bn254_blackbox_solver::Bn254BlackBoxSolver;
use clap::Args;

use crate::cli::fs::inputs::{read_bytecode_from_file, read_inputs_from_file};
use crate::cli::fs::witness::save_witness_to_dir;
use crate::errors::CliError;
use nargo::ops::{execute_program, DefaultForeignCallExecutor};

use super::fs::witness::create_output_witness_string;
use super::fs::witness::{create_output_witness_string, save_witness_to_dir};

/// Executes a circuit to calculate its return value
#[derive(Debug, Clone, Args)]
Expand Down Expand Up @@ -46,9 +45,9 @@ fn run_command(args: ExecuteCommand) -> Result<String, CliError> {
)?;
if args.output_witness.is_some() {
save_witness_to_dir(
&output_witness_string,
&args.working_directory,
output_witness,
&args.output_witness.unwrap(),
&args.working_directory,
)?;
}
Ok(output_witness_string)
Expand Down
47 changes: 34 additions & 13 deletions noir/noir-repo/tooling/acvm_cli/src/cli/fs/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@ use std::{
path::{Path, PathBuf},
};

use acvm::acir::native_types::WitnessMap;
use acvm::acir::native_types::{WitnessMap, WitnessStack};

use crate::errors::{CliError, FilesystemError};

/// Saves the provided output witnesses to a toml file created at the given location
pub(crate) fn save_witness_to_dir<P: AsRef<Path>>(
output_witness: &String,
witness_dir: P,
file_name: &String,
) -> Result<PathBuf, FilesystemError> {
let witness_path = witness_dir.as_ref().join(file_name);
fn create_named_dir(named_dir: &Path, name: &str) -> PathBuf {
std::fs::create_dir_all(named_dir)
.unwrap_or_else(|_| panic!("could not create the `{name}` directory"));

PathBuf::from(named_dir)
}

let mut file = File::create(&witness_path)
.map_err(|_| FilesystemError::OutputWitnessCreationFailed(file_name.clone()))?;
write!(file, "{}", output_witness)
.map_err(|_| FilesystemError::OutputWitnessWriteFailed(file_name.clone()))?;
fn write_to_file(bytes: &[u8], path: &Path) -> String {
let display = path.display();

Ok(witness_path)
let mut file = match File::create(path) {
Err(why) => panic!("couldn't create {display}: {why}"),
Ok(file) => file,
};

match file.write_all(bytes) {
Err(why) => panic!("couldn't write to {display}: {why}"),
Ok(_) => display.to_string(),
}
}

/// Creates a toml representation of the provided witness map
Expand All @@ -34,3 +39,19 @@ pub(crate) fn create_output_witness_string(witnesses: &WitnessMap) -> Result<Str

toml::to_string(&witness_map).map_err(|_| CliError::OutputWitnessSerializationFailed())
}

pub(crate) fn save_witness_to_dir<P: AsRef<Path>>(
witnesses: WitnessStack,
witness_name: &str,
witness_dir: P,
) -> Result<PathBuf, FilesystemError> {
create_named_dir(witness_dir.as_ref(), "witness");
let witness_path = witness_dir.as_ref().join(witness_name).with_extension("gz");

let buf: Vec<u8> = witnesses
.try_into()
.map_err(|_op| FilesystemError::OutputWitnessCreationFailed(witness_name.to_string()))?;
write_to_file(buf.as_slice(), &witness_path);

Ok(witness_path)
}
3 changes: 0 additions & 3 deletions noir/noir-repo/tooling/acvm_cli/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ pub(crate) enum FilesystemError {

#[error(" Error: failed to create output witness file {0}.")]
OutputWitnessCreationFailed(String),

#[error(" Error: failed to write output witness file {0}.")]
OutputWitnessWriteFailed(String),
}

#[derive(Debug, Error)]
Expand Down
11 changes: 10 additions & 1 deletion noir/noir-repo/tooling/noirc_abi_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// See Cargo.toml for explanation.
use getrandom as _;

use acvm::acir::native_types::WitnessMap;
use acvm::acir::native_types::{WitnessMap, WitnessStack};
use iter_extended::try_btree_map;
use noirc_abi::{
errors::InputParserError,
Expand Down Expand Up @@ -113,3 +113,12 @@ pub fn abi_decode(abi: JsAbi, witness_map: JsWitnessMap) -> Result<JsValue, JsAb
<wasm_bindgen::JsValue as JsValueSerdeExt>::from_serde(&return_struct)
.map_err(|err| err.to_string().into())
}

#[wasm_bindgen(js_name = serializeWitness)]
pub fn serialise_witness(witness_map: JsWitnessMap) -> Result<Vec<u8>, JsAbiError> {
console_error_panic_hook::set_once();
let converted_witness: WitnessMap = witness_map.into();
let witness_stack: WitnessStack = converted_witness.into();
let output = witness_stack.try_into();
output.map_err(|_| JsAbiError::new("Failed to convert to Vec<u8>".to_string()))
}
2 changes: 1 addition & 1 deletion yarn-project/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ COPY --from=bb.js /usr/src/barretenberg/ts /usr/src/barretenberg/ts
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
# We want the native ACVM binary
# We want the native ACVM and BB binaries
COPY --from=noir /usr/src/noir/noir-repo/target/release/acvm /usr/src/noir/noir-repo/target/release/acvm
COPY --from=barretenberg /usr/src/barretenberg/cpp/build/bin/bb /usr/src/barretenberg/cpp/build/bin/bb

Expand Down
3 changes: 3 additions & 0 deletions yarn-project/Dockerfile.test
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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 barretenberg
FROM aztecprotocol/noir as noir

FROM node:18.19.0 as builder
RUN apt update && apt install -y jq curl perl && rm -rf /var/lib/apt/lists/* && apt-get clean
Expand All @@ -12,6 +13,8 @@ COPY --from=bb.js /usr/src/barretenberg/ts /usr/src/barretenberg/ts
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
# We want the native ACVM and BB binaries
COPY --from=noir /usr/src/noir/noir-repo/target/release/acvm /usr/src/noir/noir-repo/target/release/acvm
COPY --from=barretenberg /usr/src/barretenberg/cpp/build/bin/bb /usr/src/barretenberg/cpp/build/bin/bb

WORKDIR /usr/src/yarn-project
Expand Down
32 changes: 32 additions & 0 deletions yarn-project/circuit-types/src/tx/processed_tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,34 @@ import {
type Header,
KernelCircuitPublicInputs,
type Proof,
type PublicKernelCircuitPrivateInputs,
type PublicKernelCircuitPublicInputs,
type PublicKernelTailCircuitPrivateInputs,
makeEmptyProof,
} from '@aztec/circuits.js';

/**
* Used to communicate to the prover which type of circuit to prove
*/
export enum PublicKernelType {
SETUP,
APP_LOGIC,
TEARDOWN,
TAIL,
}

export type PublicKernelTailRequest = {
type: PublicKernelType.TAIL;
inputs: PublicKernelTailCircuitPrivateInputs;
};

export type PublicKernelNonTailRequest = {
type: PublicKernelType.SETUP | PublicKernelType.APP_LOGIC | PublicKernelType.TEARDOWN;
inputs: PublicKernelCircuitPrivateInputs;
};

export type PublicKernelRequest = PublicKernelTailRequest | PublicKernelNonTailRequest;

/**
* Represents a tx that has been processed by the sequencer public processor,
* so its kernel circuit public inputs are filled in.
Expand All @@ -38,6 +62,11 @@ export type ProcessedTx = Pick<Tx, 'proof' | 'encryptedLogs' | 'unencryptedLogs'
* Reason the tx was reverted.
*/
revertReason: SimulationError | undefined;

/**
* The collection of public kernel circuit inputs for simulation/proving
*/
publicKernelRequests: PublicKernelRequest[];
};

export type RevertedTx = ProcessedTx & {
Expand Down Expand Up @@ -90,6 +119,7 @@ export function makeProcessedTx(
tx: Tx,
kernelOutput: KernelCircuitPublicInputs,
proof: Proof,
publicKernelRequests: PublicKernelRequest[],
revertReason?: SimulationError,
): ProcessedTx {
return {
Expand All @@ -100,6 +130,7 @@ export function makeProcessedTx(
unencryptedLogs: revertReason ? UnencryptedTxL2Logs.empty() : tx.unencryptedLogs,
isEmpty: false,
revertReason,
publicKernelRequests,
};
}

Expand All @@ -123,6 +154,7 @@ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr):
proof: emptyProof,
isEmpty: true,
revertReason: undefined,
publicKernelRequests: [],
};
}

Expand Down
16 changes: 16 additions & 0 deletions yarn-project/circuits.js/src/tests/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ import {
NullifierKeyValidationRequest,
NullifierKeyValidationRequestContext,
NullifierLeafPreimage,
NullifierNonExistentReadRequestHintsBuilder,
NullifierReadRequestHintsBuilder,
PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH,
PUBLIC_DATA_TREE_HEIGHT,
ParityPublicInputs,
Expand Down Expand Up @@ -103,6 +105,7 @@ import {
PublicKernelCircuitPrivateInputs,
PublicKernelCircuitPublicInputs,
PublicKernelData,
PublicKernelTailCircuitPrivateInputs,
ROLLUP_VK_TREE_HEIGHT,
ReadRequest,
ReadRequestContext,
Expand Down Expand Up @@ -790,6 +793,19 @@ export function makePublicKernelCircuitPrivateInputs(seed = 1): PublicKernelCirc
return new PublicKernelCircuitPrivateInputs(makePublicKernelData(seed), makePublicCallData(seed + 0x1000));
}

/**
* Makes arbitrary public kernel tail inputs.
* @param seed - The seed to use for generating the public kernel inputs.
* @returns Public kernel inputs.
*/
export function makePublicKernelTailCircuitPrivateInputs(seed = 1): PublicKernelTailCircuitPrivateInputs {
return new PublicKernelTailCircuitPrivateInputs(
makePublicKernelData(seed),
NullifierReadRequestHintsBuilder.empty(),
NullifierNonExistentReadRequestHintsBuilder.empty(),
);
}

/**
* Makes arbitrary public kernel private inputs.
* @param seed - The seed to use for generating the public kernel inputs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe('L1Publisher integration', () => {
seed + 0x500,
);

const processedTx = makeProcessedTx(tx, kernelOutput, makeProof());
const processedTx = makeProcessedTx(tx, kernelOutput, makeProof(), []);

processedTx.data.end.newNoteHashes = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, fr, seed + 0x100);
processedTx.data.end.newNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, fr, seed + 0x200);
Expand Down
Loading

0 comments on commit 145cbcd

Please sign in to comment.