From b10ab96d8d9133f6dac00f5af46a83830a0e40de Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 14:17:41 +0000 Subject: [PATCH 01/26] stash --- barretenberg/cpp/src/barretenberg/bb/main.cpp | 2 +- noir-projects/noir-protocol-circuits/bootstrap.sh | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index d549d5e1551..abda95b14c6 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -590,7 +590,7 @@ void contract_honk(const std::string& output_path, const std::string& vk_path) auto vk = std::make_shared(from_buffer(read_file(vk_path))); vk->pcs_verification_key = std::make_shared(); - std::string contract = get_honk_solidity_verifier(std::move(vk)); + std::string contract = get_honk_solidity_verifier(vk); if (output_path == "-") { writeStringToStdout(contract); diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index 90b454deb19..df861b37751 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -42,8 +42,11 @@ rollup_honk_patterns=( "rollup_merge" ) + ivc_regex=$(IFS="|"; echo "${ivc_patterns[*]}") rollup_honk_regex=$(IFS="|"; echo "${rollup_honk_patterns[*]}") +# We do this for the rollup root only. +verifier_generate_regex=rollup_root function on_exit() { rm -rf $tmp_dir @@ -115,6 +118,12 @@ function compile { local vkf_cmd="echo '$vk' | xxd -r -p | $BB $vk_as_fields_cmd -k - -o -" # echo_stderrr $vkf_cmd vk_fields=$(dump_fail "$vkf_cmd") + + if echo "$name" | grep -qE "${verifier_generate_regex}"; then + # Generate solidity verifier for this contract. + + fi + $BB contract_ultra_honk -k target/keys/rollup_root.vk.data.json -o UltraHonkVerifier.sol jq -n --arg vk "$vk" --argjson vkf "$vk_fields" '{keyAsBytes: $vk, keyAsFields: $vkf}' > $key_path echo_stderr "Key output at: $key_path (${SECONDS}s)" cache_upload vk-$hash.tar.gz $key_path &> /dev/null @@ -127,7 +136,6 @@ function build { [ -f "package.json" ] && denoise "yarn && node ./scripts/generate_variants.js" - grep -oP '(?<=crates/)[^"]+' Nargo.toml | \ while read -r dir; do toml_file=./crates/$dir/Nargo.toml if grep -q 'type = "bin"' "$toml_file"; then From fe273ffd4e9d1460e28c7f9a6e54ca91b56e9154 Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 14:17:45 +0000 Subject: [PATCH 02/26] Revert "fix(bootstrap): include crates in noir projects hashes (#11344)" This reverts commit 10751139c2f761bfc04fa8cb2fda41b764119bc6. --- noir-projects/noir-protocol-circuits/bootstrap.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index df861b37751..b89940f3822 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -12,7 +12,6 @@ export BB=${BB:-../../barretenberg/cpp/build/bin/bb} export NARGO=${NARGO:-../../noir/noir-repo/target/release/nargo} export BB_HASH=$(cache_content_hash ../../barretenberg/cpp/.rebuild_patterns) export NARGO_HASH=$(cache_content_hash ../../noir/.rebuild_patterns) -export CRATES_HASH=$(cache_content_hash crates) # Set flags for parallel export PARALLELISM=${PARALLELISM:-16} @@ -68,12 +67,10 @@ function compile { local json_path="./target/$filename" local program_hash hash bytecode_hash vk vk_fields local program_hash_cmd="$NARGO check --package $name --silence-warnings --show-program-hash | cut -d' ' -f2" + # echo_stderr $program_hash_cmd program_hash=$(dump_fail "$program_hash_cmd") - echo_stderr "Hash preimage: $NARGO_HASH-$CRATES_HASH-$program_hash" - # We include CRATES_HASH as --show-program-hash does not do a good job at hashing dependencies. - # TODO(ci3) we may need to do a less granular hash if this doesn't work out. - hash=$(hash_str "$NARGO_HASH-$CRATES_HASH-$program_hash") - + echo_stderr "Hash preimage: $NARGO_HASH-$program_hash" + hash=$(hash_str "$NARGO_HASH-$program_hash") if ! cache_download circuit-$hash.tar.gz 1>&2; then SECONDS=0 rm -f $json_path From 477e6bae40862c735acb48f5274e841c67de806a Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 15:22:30 +0000 Subject: [PATCH 03/26] Upload verifier in cache --- noir-projects/noir-protocol-circuits/bootstrap.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index b89940f3822..0222ffbb8a8 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -116,14 +116,17 @@ function compile { # echo_stderrr $vkf_cmd vk_fields=$(dump_fail "$vkf_cmd") + jq -n --arg vk "$vk" --argjson vkf "$vk_fields" '{keyAsBytes: $vk, keyAsFields: $vkf}' > $key_path + echo_stderr "Key output at: $key_path (${SECONDS}s)" if echo "$name" | grep -qE "${verifier_generate_regex}"; then + local verifier_path="$key_dir/$name-verifier.sol" # Generate solidity verifier for this contract. - + echo "$vk_fields" | $BB contract_ultra_honk -k - -o verifier_path + # Include the verifier path if we create it. + cache_upload vk-$hash.tar.gz $key_path $verifier_path &> /dev/null + else + cache_upload vk-$hash.tar.gz $key_path &> /dev/null fi - $BB contract_ultra_honk -k target/keys/rollup_root.vk.data.json -o UltraHonkVerifier.sol - jq -n --arg vk "$vk" --argjson vkf "$vk_fields" '{keyAsBytes: $vk, keyAsFields: $vkf}' > $key_path - echo_stderr "Key output at: $key_path (${SECONDS}s)" - cache_upload vk-$hash.tar.gz $key_path &> /dev/null fi } From 914ac7c1ad0eeaf180a9cb99bfab36d74156b2a7 Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 17:29:26 +0000 Subject: [PATCH 04/26] update --- noir-projects/noir-protocol-circuits/bootstrap.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index 0222ffbb8a8..1f785c4928f 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -119,9 +119,11 @@ function compile { jq -n --arg vk "$vk" --argjson vkf "$vk_fields" '{keyAsBytes: $vk, keyAsFields: $vkf}' > $key_path echo_stderr "Key output at: $key_path (${SECONDS}s)" if echo "$name" | grep -qE "${verifier_generate_regex}"; then - local verifier_path="$key_dir/$name-verifier.sol" + local verifier_path="$key_dir/${name}_verifier.sol" + SECONDS=0 # Generate solidity verifier for this contract. - echo "$vk_fields" | $BB contract_ultra_honk -k - -o verifier_path + echo "$vk" | $BB contract_ultra_honk -k - -o $verifier_path + echo_stderr "VK output at: $verifier_path (${SECONDS}s)" # Include the verifier path if we create it. cache_upload vk-$hash.tar.gz $key_path $verifier_path &> /dev/null else @@ -136,6 +138,7 @@ function build { [ -f "package.json" ] && denoise "yarn && node ./scripts/generate_variants.js" + grep -oP '(?<=crates/)[^"]+' Nargo.toml | \ while read -r dir; do toml_file=./crates/$dir/Nargo.toml if grep -q 'type = "bin"' "$toml_file"; then From bf87a933a16a55148be6f14e88ff2b2f7a64091a Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 18:46:03 +0000 Subject: [PATCH 05/26] fix --- noir-projects/noir-protocol-circuits/bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index 1f785c4928f..b6e3a199175 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -122,7 +122,7 @@ function compile { local verifier_path="$key_dir/${name}_verifier.sol" SECONDS=0 # Generate solidity verifier for this contract. - echo "$vk" | $BB contract_ultra_honk -k - -o $verifier_path + echo "$vk" | xxd -r -p | $BB contract_ultra_honk -k - -o $verifier_path echo_stderr "VK output at: $verifier_path (${SECONDS}s)" # Include the verifier path if we create it. cache_upload vk-$hash.tar.gz $key_path $verifier_path &> /dev/null From 24dbeb94521a4e5dbabdd60f0aeb65b972709917 Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 19:08:11 +0000 Subject: [PATCH 06/26] test --- Earthfile | 60 +------------------ .../noir-protocol-circuits/bootstrap.sh | 1 - 2 files changed, 2 insertions(+), 59 deletions(-) diff --git a/Earthfile b/Earthfile index ba5a728c1fb..8bd3096544b 100644 --- a/Earthfile +++ b/Earthfile @@ -60,16 +60,9 @@ bootstrap: SAVE ARTIFACT /usr/src /usr/src WORKDIR /usr/src -bootstrap-with-verifier: - # TODO(ci3) roll this into normal bootstrap - FROM +bootstrap - WORKDIR /usr/src/yarn-project - ENV DENOISE=1 - COPY --dir +rollup-verifier-contract-with-cache/usr/src/bb /usr/src - # Locally downloaded aztec image contents. bootstrap-aztec: - FROM +bootstrap-with-verifier + FROM +bootstrap WORKDIR /usr/src/yarn-project ENV DENOISE=1 RUN yarn workspaces focus @aztec/aztec --production && yarn cache clean @@ -92,7 +85,7 @@ bootstrap-aztec: # Locally downloaded end-to-end image contents. bootstrap-end-to-end: - FROM +bootstrap-with-verifier + FROM +bootstrap WORKDIR /usr/src/yarn-project RUN yarn workspaces focus @aztec/end-to-end @aztec/cli-wallet --production && yarn cache clean WORKDIR /usr/src @@ -261,19 +254,6 @@ noir-projects-with-cache: RUN ci3/cache_upload_flag $artifact END -rollup-verifier-contract-with-cache: - FROM +bootstrap - ENV CI=1 - ENV USE_CACHE=1 - LET artifact=rollup-verifier-contract-$(./noir-projects/bootstrap.sh hash).tar.gz - # Running this directly in the 'if' means files are not permanent - RUN ci3/cache_download rollup-verifier-contract-3e3a78f9a68f1f1e04240acf0728522d87a313ac-linux-gnu-x86_64 || true - IF ! [ -d /usr/src/bb ] - COPY --dir +rollup-verifier-contract/usr/src/bb /usr/src - RUN ci3/cache_upload $artifact bb - END - SAVE ARTIFACT /usr/src/bb /usr/src/bb - bb-cli: FROM +bootstrap ENV BB_WORKING_DIRECTORY=/usr/src/bb @@ -287,42 +267,6 @@ bb-cli: # yarn symlinks the binary to node_modules/.bin ENTRYPOINT ["/usr/src/yarn-project/node_modules/.bin/bb-cli"] -# helper target to generate vks in parallel -verification-key: - ARG circuit="RootRollupArtifact" - FROM +bb-cli - - # this needs to be exported as an env var for RUN to pick it up - ENV CIRCUIT=$circuit - RUN --entrypoint write-vk -c $CIRCUIT - - SAVE ARTIFACT /usr/src/bb /usr/src/bb - -protocol-verification-keys: - LOCALLY - LET circuits = "RootRollupArtifact PrivateKernelTailArtifact PrivateKernelTailToPublicArtifact" - - FOR circuit IN $circuits - BUILD +verification-key --circuit=$circuit - END - - # this could be FROM scratch - # but FOR doesn't work without /bin/sh - FROM ubuntu:noble - WORKDIR /usr/src/bb - - FOR circuit IN $circuits - COPY (+verification-key/usr/src/bb --circuit=$circuit) . - END - - SAVE ARTIFACT /usr/src/bb /usr/src/bb - -# TODO(ci3): we either don't need this or should be in bootstrap -rollup-verifier-contract: - FROM +bb-cli - COPY --dir +protocol-verification-keys/usr/src/bb /usr/src - RUN --entrypoint write-contract -c RootRollupArtifact -n UltraHonkVerifier.sol - SAVE ARTIFACT /usr/src/bb /usr/src/bb ######################################################################################################################## # File-copying boilerplate ######################################################################################################################## diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index b6e3a199175..7abe078f5f2 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -41,7 +41,6 @@ rollup_honk_patterns=( "rollup_merge" ) - ivc_regex=$(IFS="|"; echo "${ivc_patterns[*]}") rollup_honk_regex=$(IFS="|"; echo "${rollup_honk_patterns[*]}") # We do this for the rollup root only. From abe525b86446d98e3cb898c905730cfd523b4c59 Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 19:45:06 +0000 Subject: [PATCH 07/26] update --- yarn-project/protocol-contracts/src/scripts/generate_data.ts | 2 +- yarn-project/prover-client/src/config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/protocol-contracts/src/scripts/generate_data.ts b/yarn-project/protocol-contracts/src/scripts/generate_data.ts index b803b63f8f0..19eec41a93f 100644 --- a/yarn-project/protocol-contracts/src/scripts/generate_data.ts +++ b/yarn-project/protocol-contracts/src/scripts/generate_data.ts @@ -168,7 +168,7 @@ async function main() { await fs.readFile(path.join(noirContractsRoot, 'protocol_contracts.json'), 'utf8'), ) as string[]; - const leaves = []; + const leaves: Fr[] = []; const destNames = srcNames.map(n => n.split('-')[1]); for (let i = 0; i < srcNames.length; i++) { const srcName = srcNames[i]; diff --git a/yarn-project/prover-client/src/config.ts b/yarn-project/prover-client/src/config.ts index fb8464d639e..a2abb77ef96 100644 --- a/yarn-project/prover-client/src/config.ts +++ b/yarn-project/prover-client/src/config.ts @@ -25,7 +25,7 @@ export const bbConfigMappings: ConfigMappingsType = { }, bbWorkingDirectory: { env: 'BB_WORKING_DIRECTORY', - description: 'The working directory to for proving', + description: 'The working directory to use for proving', }, bbBinaryPath: { env: 'BB_BINARY_PATH', From 3af6d9ea62260ff27896f891dd254021386f308a Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 20 Jan 2025 22:15:15 +0000 Subject: [PATCH 08/26] success compiling solidity contract, avoid warning --- .../dsl/acir_proofs/honk_contract.hpp | 15 +++-- l1-contracts/.gitignore | 1 + l1-contracts/bootstrap.sh | 11 +++- l1-contracts/foundry.toml | 3 +- yarn-project/bb-prover/src/bb/cli.ts | 66 +++++++++---------- 5 files changed, 53 insertions(+), 43 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp index 9929608048d..4395b1e6f11 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp @@ -4,6 +4,7 @@ // Source code for the Ultrahonk Solidity verifier. // It's expected that the AcirComposer will inject a library which will load the verification key into memory. +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) static const char HONK_CONTRACT_SOURCE[] = R"( pragma solidity ^0.8.27; @@ -960,7 +961,7 @@ library RelationsLib { // Contribution 10 point doubling, x-coordinate check // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0 - // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1 + // n.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1 { Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1; Fr y1_sqr_mul_4 = y1_sqr + y1_sqr; @@ -1180,7 +1181,7 @@ library RelationsLib { * The gate boolean check is * (A && B) => C === !(A && B) || C === !A || !B || C * - * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized + * n.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized * with a WRITE operation. */ Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4 @@ -1448,12 +1449,12 @@ interface IVerifier { abstract contract BaseHonkVerifier is IVerifier { using FrLib for Fr; - uint256 immutable N; + uint256 immutable n; uint256 immutable logN; uint256 immutable numPublicInputs; - constructor(uint256 _N, uint256 _logN, uint256 _numPublicInputs) { - N = _N; + constructor(uint256 _n, uint256 _logN, uint256 _numPublicInputs) { + n = _n; logN = _logN; numPublicInputs = _numPublicInputs; } @@ -1498,7 +1499,7 @@ abstract contract BaseHonkVerifier is IVerifier { Fr numerator = Fr.wrap(1); Fr denominator = Fr.wrap(1); - Fr numeratorAcc = gamma + (beta * FrLib.from(N + offset)); + Fr numeratorAcc = gamma + (beta * FrLib.from(n + offset)); Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1)); { @@ -1586,7 +1587,7 @@ abstract contract BaseHonkVerifier is IVerifier { numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i)); } - // Calculate domain size N of inverses + // Calculate domain size n of inverses Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses; for (uint256 i; i < BATCHED_RELATION_PARTIAL_LENGTH; ++i) { Fr inv = BARYCENTRIC_LAGRANGE_DENOMINATORS[i]; diff --git a/l1-contracts/.gitignore b/l1-contracts/.gitignore index 6a702f89970..4523deaa44b 100644 --- a/l1-contracts/.gitignore +++ b/l1-contracts/.gitignore @@ -10,6 +10,7 @@ out/ # Dotenv file .env +src/generated lcov.info # Local foundry env diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index 3f2ee1f6b52..f2732f0d065 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -18,8 +18,17 @@ function build { # Ensure libraries are at the correct version git submodule update --init --recursive ./lib + mkdir -p src/generated + # cp ../noir-projects/noir-protocol-circuits/target/keys/rollup_root_verifier.sol src/generated + # Compile contracts - forge build + # Step 1: Build everything except rollup_root_verifier.sol. + forge build $(find src -name '*.sol' -not -path '*/generated/*') + + # Step 2: Build the generated folder (i.e. the verifier contract) with optimization. + forge build rollup_root_verifier.sol \ + --optimize \ + --optimizer-runs 200 cache_upload $artifact out fi diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index 6576c9bb932..8793b237b17 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -29,5 +29,4 @@ tab_width = 2 variable_override_spacing=false [rpc_endpoints] -mainnet_fork="https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c" - +mainnet_fork="https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c" \ No newline at end of file diff --git a/yarn-project/bb-prover/src/bb/cli.ts b/yarn-project/bb-prover/src/bb/cli.ts index f1bb7547fee..56469458759 100644 --- a/yarn-project/bb-prover/src/bb/cli.ts +++ b/yarn-project/bb-prover/src/bb/cli.ts @@ -69,40 +69,40 @@ export function getProgram(log: LogFn): Command { ); }); - program - .command('write-contract') - .description('Generates the verification contract for the specified circuit') - .requiredOption( - '-w, --working-directory ', - 'A directory to use for storing input/output files', - BB_WORKING_DIRECTORY, - ) - .requiredOption('-b, --bb-path ', 'The path to the BB binary', BB_BINARY_PATH) - .requiredOption('-c, --circuit ', 'The name of a protocol circuit') - .requiredOption('-n --contract-name ', 'The name of the contract to generate', 'contract.sol') - .action(async options => { - const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact]; - if (!compiledCircuit) { - log(`Failed to find circuit ${options.circuit}`); - return; - } - try { - await fs.access(options.workingDirectory, fs.constants.W_OK); - } catch (error) { - log(`Working directory does not exist`); - return; - } + // program + // .command('write-contract') + // .description('Generates the verification contract for the specified circuit') + // .requiredOption( + // '-w, --working-directory ', + // 'A directory to use for storing input/output files', + // BB_WORKING_DIRECTORY, + // ) + // .requiredOption('-b, --bb-path ', 'The path to the BB binary', BB_BINARY_PATH) + // .requiredOption('-c, --circuit ', 'The name of a protocol circuit') + // .requiredOption('-n --contract-name ', 'The name of the contract to generate', 'contract.sol') + // .action(async options => { + // const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact]; + // if (!compiledCircuit) { + // log(`Failed to find circuit ${options.circuit}`); + // return; + // } + // try { + // await fs.access(options.workingDirectory, fs.constants.W_OK); + // } catch (error) { + // log(`Working directory does not exist`); + // return; + // } - await generateContractForCircuit( - options.bbPath, - options.workingDirectory, - options.circuit, - compiledCircuit, - options.contractName, - log, - /*force= */ true, - ); - }); + // await generateContractForCircuit( + // options.bbPath, + // options.workingDirectory, + // options.circuit, + // compiledCircuit, + // options.contractName, + // log, + // /*force= */ true, + // ); + // }); return program; } From 17c3f9e7a7d9086c7b62ea37022b70e08c75cbc1 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 11:26:38 +0000 Subject: [PATCH 09/26] hopefully helpful comment --- l1-contracts/bootstrap.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index f2732f0d065..0ac9d2dba24 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -10,7 +10,7 @@ function build { local artifact=l1-contracts-$hash.tar.gz if ! cache_download $artifact; then # Clean - rm -rf broadcast cache out serve + rm -rf broadcast cache out serve generated # Install forge install --no-commit @@ -19,13 +19,20 @@ function build { git submodule update --init --recursive ./lib mkdir -p src/generated - # cp ../noir-projects/noir-protocol-circuits/target/keys/rollup_root_verifier.sol src/generated + # Copy from noir-projects. Bootstrap must hav + local rollup_verifier_path=../noir-projects/noir-protocol-circuits/target/keys/rollup_root_verifier.sol + if [ -f "$rollup_verifier_path" ]; then + cp "$rollup_verifier_path" src/generated + else + echo_stderr "You likely need to call bootstrap.sh in the noir-projects folder. Could not find the rollup verifier at $rollup_verifier_path." + exit 1 + fi # Compile contracts # Step 1: Build everything except rollup_root_verifier.sol. - forge build $(find src -name '*.sol' -not -path '*/generated/*') + forge build $(find src -name '*.sol' -not -name 'rollup_root_verifier.sol') - # Step 2: Build the generated folder (i.e. the verifier contract) with optimization. + # Step 2: Build the the verifier contract with optimization. forge build rollup_root_verifier.sol \ --optimize \ --optimizer-runs 200 From 6649331c311b2b47d16dbf077495346bacce6648 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 11:39:41 +0000 Subject: [PATCH 10/26] work on ts gen --- l1-contracts/bootstrap.sh | 10 +++++----- yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index 0ac9d2dba24..aa4e5728998 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -22,18 +22,18 @@ function build { # Copy from noir-projects. Bootstrap must hav local rollup_verifier_path=../noir-projects/noir-protocol-circuits/target/keys/rollup_root_verifier.sol if [ -f "$rollup_verifier_path" ]; then - cp "$rollup_verifier_path" src/generated + cp "$rollup_verifier_path" src/generated/RollupVerifier.sol else - echo_stderr "You likely need to call bootstrap.sh in the noir-projects folder. Could not find the rollup verifier at $rollup_verifier_path." + echo_stderr "You may need to run ./bootstrap.sh in the noir-projects folder. Could not find the rollup verifier at $rollup_verifier_path." exit 1 fi # Compile contracts - # Step 1: Build everything except rollup_root_verifier.sol. - forge build $(find src -name '*.sol' -not -name 'rollup_root_verifier.sol') + # Step 1: Build everything except RollupVerifier.sol. + forge build $(find src -name '*.sol' -not -name 'RollupVerifier.sol') # Step 2: Build the the verifier contract with optimization. - forge build rollup_root_verifier.sol \ + forge build RollupVerifier.sol \ --optimize \ --optimizer-runs 200 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 6a587422d5b..4cee415ed06 100644 --- a/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts +++ b/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts @@ -3,8 +3,6 @@ import { compileContract, createEthereumChain, createL1Clients, deployL1Contract import { type LogFn, type Logger } 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 { type Hex, getContract } from 'viem'; export async function deployUltraHonkVerifier( From a78ad2441b8a2913cdb55a2d509378ddf2811cfb Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 12:02:15 +0000 Subject: [PATCH 11/26] better generation --- .../scripts/generate-artifacts.sh | 143 ++++++++++-------- 1 file changed, 80 insertions(+), 63 deletions(-) diff --git a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh index fd3825893f6..088e72f6f18 100755 --- a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh +++ b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh @@ -1,78 +1,95 @@ #!/usr/bin/env bash -set -euo pipefail; +set -euo pipefail -target_dir=./generated +# Contracts name list (all assumed to be in l1-contracts). +# This script writes into the generated/ folder: +# - index.ts: entrypoint +# - {name}Abi.ts: contains the ABI +# - {name}Bytecode.ts: contains the bytecode and link references - -# CONTRACT elements have structure PROJECT_DIR_NAME:CONTRACT_NAME. -# This will generate the following artifacts for the contracts within the target_dir{./generated} directory. -# - a .{CONTRACT_NAME}Bytecode.ts containing the contract bytecode. -# - a .{CONTRACT_NAME}Abi.ts containing the contract ABI. - -CONTRACTS=( - "l1-contracts:Registry" - "l1-contracts:Inbox" - "l1-contracts:Outbox" - "l1-contracts:Rollup" - "l1-contracts:TokenPortal" - "l1-contracts:TestERC20" - "l1-contracts:UniswapPortal" - "l1-contracts:IERC20" - "l1-contracts:FeeJuicePortal" - "l1-contracts:MockVerifier" - "l1-contracts:IVerifier" - "l1-contracts:IProofCommitmentEscrow" - "l1-contracts:ProofCommitmentEscrow" - "l1-contracts:CoinIssuer" - "l1-contracts:RewardDistributor" - "l1-contracts:GovernanceProposer" - "l1-contracts:Governance" - "l1-contracts:NewGovernanceProposerPayload" - "l1-contracts:LeonidasLib" - "l1-contracts:ExtRollupLib" - "l1-contracts:SlashingProposer" - "l1-contracts:Slasher" - "l1-contracts:EmpireBase" - "l1-contracts:SlashFactory" +contracts=( + "Registry" + "Inbox" + "Outbox" + "Rollup" + "TokenPortal" + "TestERC20" + "UniswapPortal" + "IERC20" + "FeeJuicePortal" + "MockVerifier" + "IVerifier" + "IProofCommitmentEscrow" + "ProofCommitmentEscrow" + "CoinIssuer" + "RewardDistributor" + "GovernanceProposer" + "Governance" + "NewGovernanceProposerPayload" + "LeonidasLib" + "ExtRollupLib" + "SlashingProposer" + "Slasher" + "EmpireBase" + "SlashFactory" + "RollupVerifier" ) -# Read the error ABI's once and store it in COMBINED_ERRORS variable -COMBINED_ERRORS=$(jq -s ' - .[0].abi + .[1].abi | - unique_by({type: .type, name: .name}) -' \ - ../../l1-contracts/out/Errors.sol/Errors.json \ - ../../l1-contracts/out/libraries/Errors.sol/Errors.json) - -# create target dir if it doesn't exist -mkdir -p "$target_dir"; +# Combine error ABIs once, removing duplicates by {type, name}. +combined_errors_abi=$( + jq -s ' + .[0].abi + .[1].abi + | unique_by({type: .type, name: .name}) + ' \ + ../../l1-contracts/out/Errors.sol/Errors.json \ + ../../l1-contracts/out/libraries/Errors.sol/Errors.json +) -echo -ne "// Auto generated module\n" > "$target_dir/index.ts"; +# Start from clean. +rm -rf generated && mkdir generated -for E in "${CONTRACTS[@]}"; do - ARR=(${E//:/ }) - ROOT="${ARR[0]}"; - CONTRACT_NAME="${ARR[1]}"; +echo "// Auto-generated module" > "generated/index.ts" - echo -ne "/**\n * $CONTRACT_NAME ABI.\n */\nexport const ${CONTRACT_NAME}Abi = " > "$target_dir/${CONTRACT_NAME}Abi.ts"; +for contract_name in "${contracts[@]}"; do + # Generate Abi.ts + ( + echo "/**" + echo " * ${contract_name} ABI." + echo " */" + echo -n "export const ${contract_name}Abi = " # Merge contract abi and errors abi while removing duplicates based on both type and name # Just merging it into all, it is not the cleanest, but it does the job. - jq -j --argjson errors "$COMBINED_ERRORS" ' - .abi + $errors | - unique_by({type: .type, name: .name}) - ' ../../$ROOT/out/$CONTRACT_NAME.sol/$CONTRACT_NAME.json >> "$target_dir/${CONTRACT_NAME}Abi.ts"; + jq -j --argjson errs "$combined_errors_abi" ' + .abi + $errs + | unique_by({type: .type, name: .name}) + ' \ + "../../l1-contracts/out/${contract_name}.sol/${contract_name}.json" + echo " as const;" + ) > "generated/${contract_name}Abi.ts" - echo " as const;" >> "$target_dir/${CONTRACT_NAME}Abi.ts"; + # Generate Bytecode.ts + ( + echo "/**" + echo " * ${contract_name} bytecode." + echo " */" + echo -n "export const ${contract_name}Bytecode = \"" + jq -j '.bytecode.object' \ + "../../l1-contracts/out/${contract_name}.sol/${contract_name}.json" + echo "\";" - echo -ne "/**\n * $CONTRACT_NAME bytecode.\n */\nexport const ${CONTRACT_NAME}Bytecode = \"" > "$target_dir/${CONTRACT_NAME}Bytecode.ts"; - jq -j '.bytecode.object' ../../$ROOT/out/$CONTRACT_NAME.sol/$CONTRACT_NAME.json >> "$target_dir/${CONTRACT_NAME}Bytecode.ts"; - echo "\";" >> "$target_dir/${CONTRACT_NAME}Bytecode.ts"; - echo -ne "/**\n * $CONTRACT_NAME link references.\n */\nexport const ${CONTRACT_NAME}LinkReferences = " >> "$target_dir/${CONTRACT_NAME}Bytecode.ts"; - jq -j '.bytecode.linkReferences' ../../$ROOT/out/$CONTRACT_NAME.sol/$CONTRACT_NAME.json >> "$target_dir/${CONTRACT_NAME}Bytecode.ts"; - echo " as const;" >> "$target_dir/${CONTRACT_NAME}Bytecode.ts"; + echo "/**" + echo " * ${contract_name} link references." + echo " */" + echo -n "export const ${contract_name}LinkReferences = " + jq -j '.bytecode.linkReferences' \ + "../../l1-contracts/out/${contract_name}.sol/${contract_name}.json" + echo " as const;" + ) > "generated/${contract_name}Bytecode.ts" - echo -ne "export * from './${CONTRACT_NAME}Abi.js';\nexport * from './${CONTRACT_NAME}Bytecode.js';\n" >> "$target_dir/index.ts"; -done; + # Update index.ts exports + echo "export * from './${contract_name}Abi.js';" >> "generated/index.ts" + echo "export * from './${contract_name}Bytecode.js';" >> "generated/index.ts" +done -echo "Successfully generated TS artifacts!"; \ No newline at end of file +echo "Successfully generated TS artifacts!" From a191e2f02b6632393336e3caace160d01d1e7dab Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 12:09:52 +0000 Subject: [PATCH 12/26] path of least resistance: align with HonkVerifier name --- l1-contracts/bootstrap.sh | 8 ++++---- yarn-project/l1-artifacts/scripts/generate-artifacts.sh | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index aa4e5728998..77694b95461 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -22,18 +22,18 @@ function build { # Copy from noir-projects. Bootstrap must hav local rollup_verifier_path=../noir-projects/noir-protocol-circuits/target/keys/rollup_root_verifier.sol if [ -f "$rollup_verifier_path" ]; then - cp "$rollup_verifier_path" src/generated/RollupVerifier.sol + cp "$rollup_verifier_path" src/generated/HonkVerifier.sol else echo_stderr "You may need to run ./bootstrap.sh in the noir-projects folder. Could not find the rollup verifier at $rollup_verifier_path." exit 1 fi # Compile contracts - # Step 1: Build everything except RollupVerifier.sol. - forge build $(find src -name '*.sol' -not -name 'RollupVerifier.sol') + # Step 1: Build everything except HonkVerifier.sol. + forge build $(find src -name '*.sol' -not -name 'HonkVerifier.sol') # Step 2: Build the the verifier contract with optimization. - forge build RollupVerifier.sol \ + forge build HonkVerifier.sol \ --optimize \ --optimizer-runs 200 diff --git a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh index 088e72f6f18..1a933c64329 100755 --- a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh +++ b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -euo pipefail +# Working directory independent. +cd $(git rev-parse --show-toplevel)/yarn-project/l1-artifacts + # Contracts name list (all assumed to be in l1-contracts). # This script writes into the generated/ folder: # - index.ts: entrypoint @@ -32,7 +35,7 @@ contracts=( "Slasher" "EmpireBase" "SlashFactory" - "RollupVerifier" + "HonkVerifier" ) # Combine error ABIs once, removing duplicates by {type, name}. @@ -51,7 +54,6 @@ rm -rf generated && mkdir generated echo "// Auto-generated module" > "generated/index.ts" for contract_name in "${contracts[@]}"; do - # Generate Abi.ts ( echo "/**" From ae1eb115cb0252b60a9042abb4e0dd2678509e56 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 12:13:28 +0000 Subject: [PATCH 13/26] fix generation paths --- l1-contracts/bootstrap.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index 77694b95461..649e9d52c01 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -18,22 +18,22 @@ function build { # Ensure libraries are at the correct version git submodule update --init --recursive ./lib - mkdir -p src/generated + mkdir -p generated # Copy from noir-projects. Bootstrap must hav local rollup_verifier_path=../noir-projects/noir-protocol-circuits/target/keys/rollup_root_verifier.sol if [ -f "$rollup_verifier_path" ]; then - cp "$rollup_verifier_path" src/generated/HonkVerifier.sol + cp "$rollup_verifier_path" generated/HonkVerifier.sol else echo_stderr "You may need to run ./bootstrap.sh in the noir-projects folder. Could not find the rollup verifier at $rollup_verifier_path." exit 1 fi # Compile contracts - # Step 1: Build everything except HonkVerifier.sol. - forge build $(find src -name '*.sol' -not -name 'HonkVerifier.sol') + # Step 1: Build everything in src. + forge build $(find src test -name '*.sol') - # Step 2: Build the the verifier contract with optimization. - forge build HonkVerifier.sol \ + # Step 2: Build the the generated verifier contract with optimization. + forge build $(find generated -name '*.sol') \ --optimize \ --optimizer-runs 200 From bc588e6475b8d13a8f32891bc5909d0ad01c34d2 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 14:16:56 +0000 Subject: [PATCH 14/26] update --- yarn-project/Dockerfile | 67 ---------------- yarn-project/Dockerfile.test | 39 ---------- yarn-project/bb-prover/src/bb/cli.ts | 76 ------------------- yarn-project/bb-prover/src/bb/execute.ts | 37 --------- .../bb-prover/src/verifier/bb_verifier.ts | 20 +---- .../cli/src/cmds/l1/deploy_l1_verifier.ts | 32 +++----- .../integration_proof_verification.test.ts | 18 +++-- .../src/e2e_prover/e2e_prover_test.ts | 33 +++----- .../ethereum/src/deploy_l1_contracts.ts | 44 ----------- 9 files changed, 33 insertions(+), 333 deletions(-) delete mode 100644 yarn-project/Dockerfile delete mode 100644 yarn-project/Dockerfile.test diff --git a/yarn-project/Dockerfile b/yarn-project/Dockerfile deleted file mode 100644 index 60da5d983a7..00000000000 --- a/yarn-project/Dockerfile +++ /dev/null @@ -1,67 +0,0 @@ -FROM --platform=linux/amd64 aztecprotocol/bb.js as bb.js -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 aztecprotocol/noir as noir -# we don't build the bb binary for arm so this will be copied but won't be working on arm images -FROM --platform=linux/amd64 aztecprotocol/barretenberg-x86_64-linux-clang as barretenberg - -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 - -# Copy in portalled packages. -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 -COPY --from=barretenberg /usr/src/barretenberg/cpp/build-pic/lib/world_state_napi.node /usr/src/barretenberg/cpp/build-pic/lib/world_state_napi.node - -WORKDIR /usr/src/yarn-project -COPY . . - -# We install a symlink to yarn-project's node_modules at a location that all portalled packages can find as they -# walk up the tree as part of module resolution. The supposedly idiomatic way of supporting module resolution -# correctly for portalled packages, is to use --preserve-symlinks when running node. -# This does kind of work, but jest doesn't honor it correctly, so this seems like a neat workaround. -# Also, --preserve-symlinks causes duplication of portalled instances such as bb.js, and breaks the singleton logic -# by initialising the module more than once. So at present I don't see a viable alternative. -RUN ln -s /usr/src/yarn-project/node_modules /usr/src/node_modules - -# TODO: Replace puppeteer with puppeteer-core to avoid this. -ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true - -RUN ./bootstrap.sh - -ENV BB_BINARY_PATH=/usr/src/barretenberg/cpp/build/bin/bb -ENV BB_WORKING_DIRECTORY=/usr/src/yarn-project/bb -ENV ACVM_BINARY_PATH=/usr/src/noir/noir-repo/target/release/acvm -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 UltraHonkVerifier.sol || \ - echo "Skipping VK generation arch=$(arch)" - -RUN yarn workspaces focus @aztec/aztec @aztec/cli-wallet --production && yarn cache clean - -# TODO: Use release-please to update package.json directly, and remove this! -# It's here to ensure the image rebuilds if the commit tag changes (as the content hash won't). -# ARG COMMIT_TAG="" -# RUN ./scripts/version_packages.sh - -# We no longer need these. -RUN rm -rf /usr/src/noir-projects /usr/src/l1-contracts - -# Create minimal size image. -FROM node:18.19.1-slim -ARG COMMIT_TAG="" -ENV COMMIT_TAG=$COMMIT_TAG -COPY --from=builder /usr/src /usr/src -WORKDIR /usr/src/yarn-project -# add curl to be able to download CRS file -RUN apt update && apt install -y curl jq -ENTRYPOINT ["yarn"] diff --git a/yarn-project/Dockerfile.test b/yarn-project/Dockerfile.test deleted file mode 100644 index d5999b264ca..00000000000 --- a/yarn-project/Dockerfile.test +++ /dev/null @@ -1,39 +0,0 @@ -FROM --platform=linux/amd64 aztecprotocol/bb.js as bb.js -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 - -# Copy in portalled packages. -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 -COPY . . - -# We install a symlink to yarn-project's node_modules at a location that all portalled packages can find as they -# walk up the tree as part of module resolution. The supposedly idiomatic way of supporting module resolution -# correctly for portalled packages, is to use --preserve-symlinks when running node. -# This does kind of work, but jest doesn't honor it correctly, so this seems like a neat workaround. -# Also, --preserve-symlinks causes duplication of portalled instances such as bb.js, and breaks the singleton logic -# by initialising the module more than once. So at present I don't see a viable alternative. -RUN ln -s /usr/src/yarn-project/node_modules /usr/src/node_modules - -# TODO: Replace puppeteer with puppeteer-core to avoid this. -ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true - -RUN ./bootstrap.sh -RUN yarn prepare:check && yarn formatting && yarn test - -# Avoid pushing some huge container back to ecr. -FROM scratch -COPY --from=builder /usr/src/yarn-project/README.md /usr/src/yarn-project/README.md diff --git a/yarn-project/bb-prover/src/bb/cli.ts b/yarn-project/bb-prover/src/bb/cli.ts index 56469458759..1d382928df8 100644 --- a/yarn-project/bb-prover/src/bb/cli.ts +++ b/yarn-project/bb-prover/src/bb/cli.ts @@ -5,11 +5,6 @@ import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types import { type NoirCompiledCircuit } from '@aztec/types/noir'; import { Command } from 'commander'; -import { promises as fs } from 'fs'; - -import { generateContractForCircuit, generateKeyForNoirCircuit } from './execute.js'; - -const { BB_WORKING_DIRECTORY, BB_BINARY_PATH } = process.env; export const ProtocolCircuitArtifacts: Record = { ...ClientCircuitArtifacts, @@ -33,76 +28,5 @@ export function getProgram(log: LogFn): Command { log(Object.keys(ProtocolCircuitArtifacts).reduce((prev: string, x: string) => prev.concat(`\n${x}`))); }); - program - .command('write-vk') - .description('Generates the verification key for the specified circuit') - .requiredOption( - '-w, --working-directory ', - 'A directory to use for storing input/output files', - BB_WORKING_DIRECTORY, - ) - .requiredOption('-b, --bb-path ', 'The path to the BB binary', BB_BINARY_PATH) - .requiredOption('-c, --circuit ', 'The name of a protocol circuit') - .requiredOption('-f, --flavor ', 'The name of the verification key flavor', 'ultra_honk') - .option('-r, --recursive', 'Whether a SNARK friendly key should be generated', false) - .action(async options => { - const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact]; - if (!compiledCircuit) { - log(`Failed to find circuit ${options.circuit}`); - return; - } - try { - await fs.access(options.workingDirectory, fs.constants.W_OK); - } catch (error) { - log(`Working directory does not exist`); - return; - } - await generateKeyForNoirCircuit( - options.bbPath, - options.workingDirectory, - options.circuit, - compiledCircuit, - options.recursive, - options.flavor, - // (options.circuit as ServerProtocolArtifact) === 'RootRollupArtifact' ? 'ultra_keccak_honk' : 'ultra_honk', - log, - ); - }); - - // program - // .command('write-contract') - // .description('Generates the verification contract for the specified circuit') - // .requiredOption( - // '-w, --working-directory ', - // 'A directory to use for storing input/output files', - // BB_WORKING_DIRECTORY, - // ) - // .requiredOption('-b, --bb-path ', 'The path to the BB binary', BB_BINARY_PATH) - // .requiredOption('-c, --circuit ', 'The name of a protocol circuit') - // .requiredOption('-n --contract-name ', 'The name of the contract to generate', 'contract.sol') - // .action(async options => { - // const compiledCircuit = ProtocolCircuitArtifacts[options.circuit as ProtocolArtifact]; - // if (!compiledCircuit) { - // log(`Failed to find circuit ${options.circuit}`); - // return; - // } - // try { - // await fs.access(options.workingDirectory, fs.constants.W_OK); - // } catch (error) { - // log(`Working directory does not exist`); - // return; - // } - - // await generateContractForCircuit( - // options.bbPath, - // options.workingDirectory, - // options.circuit, - // compiledCircuit, - // options.contractName, - // log, - // /*force= */ true, - // ); - // }); - return program; } diff --git a/yarn-project/bb-prover/src/bb/execute.ts b/yarn-project/bb-prover/src/bb/execute.ts index 7089f888e23..c433142bcff 100644 --- a/yarn-project/bb-prover/src/bb/execute.ts +++ b/yarn-project/bb-prover/src/bb/execute.ts @@ -960,43 +960,6 @@ export async function generateContractForVerificationKey( return res; } -export async function generateContractForCircuit( - pathToBB: string, - workingDirectory: string, - circuitName: string, - compiledCircuit: NoirCompiledCircuit, - contractName: string, - log: LogFn, - force = false, -) { - // Verifier contracts are never recursion friendly, because non-recursive proofs are generated using the keccak256 hash function. - // We need to use the same hash function during verification so proofs generated using keccak256 are cheap to verify on ethereum - // (where the verifier contract would be deployed) whereas if we want to verify the proof within a snark (for recursion) we want - // to use a snark-friendly hash function. - const recursive = false; - - const vkResult = await generateKeyForNoirCircuit( - pathToBB, - workingDirectory, - circuitName, - compiledCircuit, - recursive, - 'ultra_keccak_honk', - log, - force, - ); - if (vkResult.status === BB_RESULT.FAILURE) { - return vkResult; - } - - return generateContractForVerificationKey( - pathToBB, - join(vkResult.vkPath!, VK_FILENAME), - join(workingDirectory, 'contract', circuitName, contractName), - log, - ); -} - /** * Compute bb gate count for a given circuit * @param pathToBB - The full path to the bb binary diff --git a/yarn-project/bb-prover/src/verifier/bb_verifier.ts b/yarn-project/bb-prover/src/verifier/bb_verifier.ts index 09e52c192d6..eceefb2846b 100644 --- a/yarn-project/bb-prover/src/verifier/bb_verifier.ts +++ b/yarn-project/bb-prover/src/verifier/bb_verifier.ts @@ -17,13 +17,12 @@ import { BB_RESULT, PROOF_FILENAME, VK_FILENAME, - generateContractForCircuit, generateKeyForNoirCircuit, verifyClientIvcProof, verifyProof, } from '../bb/execute.js'; import { type BBConfig } from '../config.js'; -import { type UltraKeccakHonkServerProtocolArtifact, getUltraHonkFlavorForCircuit } from '../honk.js'; +import { getUltraHonkFlavorForCircuit } from '../honk.js'; import { writeToOutputDirectory } from '../prover/client_ivc_proof_utils.js'; import { isProtocolArtifactRecursive, mapProtocolArtifactNameToCircuitName } from '../stats.js'; import { extractVkData } from '../verification_key/verification_key_data.js'; @@ -126,23 +125,6 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { await runInDirectory(this.config.bbWorkingDirectory, operation, this.config.bbSkipCleanup); } - public async generateSolidityContract(circuit: UltraKeccakHonkServerProtocolArtifact, contractName: string) { - const result = await generateContractForCircuit( - this.config.bbBinaryPath, - this.config.bbWorkingDirectory, - circuit, - ServerCircuitArtifacts[circuit], - contractName, - this.logger.debug, - ); - - if (result.status === BB_RESULT.FAILURE) { - throw new Error(`Failed to create verifier contract for ${circuit}, ${result.reason}`); - } - - return fs.readFile(result.contractPath!, 'utf-8'); - } - public async verifyProof(tx: Tx): Promise { try { // TODO(#7370) The verification keys should be supplied separately and based on the expectedCircuit 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 4cee415ed06..9f525db385a 100644 --- a/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts +++ b/yarn-project/cli/src/cmds/l1/deploy_l1_verifier.ts @@ -1,6 +1,7 @@ import { createCompatibleClient } from '@aztec/aztec.js'; -import { compileContract, createEthereumChain, createL1Clients, deployL1Contract } from '@aztec/ethereum'; +import { createEthereumChain, createL1Clients, deployL1Contract } from '@aztec/ethereum'; import { type LogFn, type Logger } from '@aztec/foundation/log'; +import { HonkVerifierAbi, HonkVerifierBytecode } from '@aztec/l1-artifacts'; import { InvalidOptionArgumentError } from 'commander'; import { type Hex, getContract } from 'viem'; @@ -20,10 +21,6 @@ export async function deployUltraHonkVerifier( if (!bbBinaryPath || !bbWorkingDirectory) { throw new InvalidOptionArgumentError('Missing path to bb binary and working directory'); } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - Importing bb-prover even in devDeps results in a circular dependency error through @aztec/simulator. Need to ignore because this line doesn't cause an error in a dev environment - const { BBCircuitVerifier } = await import('@aztec/bb-prover'); - const verifier = await BBCircuitVerifier.new({ bbBinaryPath, bbWorkingDirectory, bbSkipCleanup: false }); const { publicClient, walletClient } = createL1Clients( ethRpcUrl, @@ -49,22 +46,15 @@ export async function deployUltraHonkVerifier( client: walletClient, }); - // REFACTOR: Extract this method to a common package. We need a package that deals with L1 - // but also has a reference to L1 artifacts and bb-prover. - const setupVerifier = async ( - artifact: Parameters<(typeof verifier)['generateSolidityContract']>[0], // Cannot properly import the type here due to the hack above - ) => { - const contract = await verifier.generateSolidityContract(artifact, 'UltraHonkVerifier.sol'); - log(`Generated UltraHonkVerifier contract for ${artifact}`); - const { abi, bytecode } = compileContract('UltraHonkVerifier.sol', 'HonkVerifier', contract, solc); - log(`Compiled UltraHonkVerifier contract for ${artifact}`); - const { address: verifierAddress } = await deployL1Contract(walletClient, publicClient, abi, bytecode); - log(`Deployed real ${artifact} verifier at ${verifierAddress}`); - await rollup.write.setEpochVerifier([verifierAddress.toString()]); - log(`Set ${artifact} verifier in ${rollup.address} rollup contract to ${verifierAddress}`); - }; - - await setupVerifier('RootRollupArtifact'); + const { address: verifierAddress } = await deployL1Contract( + walletClient, + publicClient, + HonkVerifierAbi, + HonkVerifierBytecode, + ); + log(`Deployed honk verifier at ${verifierAddress}`); + + await rollup.write.setEpochVerifier([verifierAddress.toString()]); log(`Rollup accepts only real proofs now`); } 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 c910620d366..3d73b87a587 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 @@ -2,15 +2,13 @@ import { deployL1Contract, fileURLToPath } from '@aztec/aztec.js'; import { BBCircuitVerifier } from '@aztec/bb-prover'; import { Proof } from '@aztec/circuits.js'; import { RootRollupPublicInputs } from '@aztec/circuits.js/rollup'; -import { compileContract, createL1Clients } from '@aztec/ethereum'; +import { createL1Clients } from '@aztec/ethereum'; import { type Logger } from '@aztec/foundation/log'; -import { IVerifierAbi } from '@aztec/l1-artifacts'; +import { HonkVerifierAbi, HonkVerifierBytecode, IVerifierAbi } from '@aztec/l1-artifacts'; import { type Anvil } from '@viem/anvil'; import { readFile } from 'fs/promises'; import { join } from 'path'; -// @ts-expect-error solc-js doesn't publish its types https://github.com/ethereum/solc-js/issues/689 -import solc from 'solc'; import { type Account, type Chain, @@ -62,9 +60,15 @@ describe('proof_verification', () => { logger.info('BB and ACVM initialized'); ({ publicClient, walletClient } = createL1Clients(rpcUrl, mnemonicToAccount(MNEMONIC))); - const content = await circuitVerifier.generateSolidityContract('RootRollupArtifact', 'UltraHonkVerifier.sol'); - const { bytecode, abi } = compileContract('UltraHonkVerifier.sol', 'HonkVerifier', content, solc); - const { address: verifierAddress } = await deployL1Contract(walletClient, publicClient, abi, bytecode); + + const { address: verifierAddress } = await deployL1Contract( + walletClient, + publicClient, + HonkVerifierAbi, + HonkVerifierBytecode, + ); + logger.info(`Deployed honk verifier at ${verifierAddress}`); + verifierContract = getContract({ address: verifierAddress.toString(), client: publicClient, abi: IVerifierAbi }); logger.info('Deployed verifier'); }); 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 38fd15d980b..da87e168923 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 @@ -14,24 +14,15 @@ import { createLogger, deployL1Contract, } from '@aztec/aztec.js'; -import { - BBCircuitVerifier, - type ClientProtocolCircuitVerifier, - TestCircuitVerifier, - type UltraKeccakHonkServerProtocolArtifact, -} from '@aztec/bb-prover'; +import { BBCircuitVerifier, type ClientProtocolCircuitVerifier, TestCircuitVerifier } from '@aztec/bb-prover'; import { createBlobSinkClient } from '@aztec/blob-sink/client'; import { type BlobSinkServer } from '@aztec/blob-sink/server'; -import { compileContract } from '@aztec/ethereum'; import { Buffer32 } from '@aztec/foundation/buffer'; -import { RollupAbi, TestERC20Abi } from '@aztec/l1-artifacts'; +import { HonkVerifierAbi, HonkVerifierBytecode, RollupAbi, TestERC20Abi } from '@aztec/l1-artifacts'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { type ProverNode, type ProverNodeConfig, createProverNode } from '@aztec/prover-node'; 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 { type Hex, getContract } from 'viem'; import { privateKeyToAddress } from 'viem/accounts'; @@ -382,7 +373,6 @@ export class FullProverTest { throw new Error('No verifier'); } - const verifier = this.circuitProofVerifier as BBCircuitVerifier; const { walletClient, publicClient, l1ContractAddresses } = this.context.deployL1ContractsValues; const rollup = getContract({ abi: RollupAbi, @@ -390,18 +380,15 @@ export class FullProverTest { client: walletClient, }); - // REFACTOR: Extract this method to a common package. We need a package that deals with L1 - // but also has a reference to L1 artifacts and bb-prover. - const setupVerifier = async (artifact: UltraKeccakHonkServerProtocolArtifact) => { - const contract = await verifier.generateSolidityContract(artifact, 'UltraHonkVerifier.sol'); - const { abi, bytecode } = compileContract('UltraHonkVerifier.sol', 'HonkVerifier', contract, solc); - const { address: verifierAddress } = await deployL1Contract(walletClient, publicClient, abi, bytecode); - this.logger.info(`Deployed real ${artifact} verifier at ${verifierAddress}`); - - await rollup.write.setEpochVerifier([verifierAddress.toString()]); - }; + const { address: verifierAddress } = await deployL1Contract( + walletClient, + publicClient, + HonkVerifierAbi, + HonkVerifierBytecode, + ); + this.logger.info(`Deployed honk verifier at ${verifierAddress}`); - await setupVerifier('RootRollupArtifact'); + await rollup.write.setEpochVerifier([verifierAddress.toString()]); this.logger.info('Rollup only accepts valid proofs now'); } diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index 09e49baf262..fbaa296675a 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -579,50 +579,6 @@ class L1Deployer { } } -/** - * Compiles a contract source code using the provided solc compiler. - * @param fileName - Contract file name (eg UltraHonkVerifier.sol) - * @param contractName - Contract name within the file (eg HonkVerifier) - * @param source - Source code to compile - * @param solc - Solc instance - * @returns ABI and bytecode of the compiled contract - */ -export function compileContract( - fileName: string, - contractName: string, - source: string, - solc: { compile: (source: string) => string }, -): { abi: Narrow; bytecode: Hex } { - const input = { - language: 'Solidity', - sources: { - [fileName]: { - content: source, - }, - }, - settings: { - // we require the optimizer - optimizer: { - enabled: true, - runs: 200, - }, - evmVersion: 'cancun', - outputSelection: { - '*': { - '*': ['evm.bytecode.object', 'abi'], - }, - }, - }, - }; - - const output = JSON.parse(solc.compile(JSON.stringify(input))); - - const abi = output.contracts[fileName][contractName].abi; - const bytecode: `0x${string}` = `0x${output.contracts[fileName][contractName].evm.bytecode.object}`; - - return { abi, bytecode }; -} - // docs:start:deployL1Contract /** * Helper function to deploy ETH contracts. From 47a1bb48827b99bf0f4062067cca8f93b5c19245 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 14:24:30 +0000 Subject: [PATCH 15/26] fix order of dependencies in CI --- Earthfile | 2 +- l1-contracts/.gitignore | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Earthfile b/Earthfile index 8bd3096544b..69d375015ce 100644 --- a/Earthfile +++ b/Earthfile @@ -47,9 +47,9 @@ bootstrap: ARG EARTHLY_GIT_HASH LET bootstrap='rm -rf $(ls -A) && mv $(find /usr/src -mindepth 1 -maxdepth 1) . && - DENOISE=1 CI=1 ./l1-contracts/bootstrap.sh fast && DENOISE=1 CI=1 ./avm-transpiler/bootstrap.sh fast && DENOISE=1 CI=1 ./noir-projects/bootstrap.sh fast && + DENOISE=1 CI=1 ./l1-contracts/bootstrap.sh fast && DENOISE=1 CI=1 ./yarn-project/bootstrap.sh fast && mv $(ls -A) /usr/src' # Use a mounted volume for performance. diff --git a/l1-contracts/.gitignore b/l1-contracts/.gitignore index 4523deaa44b..a61360f0809 100644 --- a/l1-contracts/.gitignore +++ b/l1-contracts/.gitignore @@ -10,7 +10,7 @@ out/ # Dotenv file .env -src/generated +generated lcov.info # Local foundry env From 1a19101569fd8d2c3e86369a9567545b810d9e34 Mon Sep 17 00:00:00 2001 From: ludamad Date: Tue, 21 Jan 2025 17:06:18 +0000 Subject: [PATCH 16/26] fix cache pattern --- Earthfile | 1 - l1-contracts/bootstrap.sh | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Earthfile b/Earthfile index 69d375015ce..f01ebc951e1 100644 --- a/Earthfile +++ b/Earthfile @@ -53,7 +53,6 @@ bootstrap: DENOISE=1 CI=1 ./yarn-project/bootstrap.sh fast && mv $(ls -A) /usr/src' # Use a mounted volume for performance. - # TODO don't retry noir projects. It seems to have been flakey. RUN --raw-output --mount type=cache,id=bootstrap-$EARTHLY_GIT_HASH,target=/build-volume \ bash -c "$bootstrap" diff --git a/l1-contracts/bootstrap.sh b/l1-contracts/bootstrap.sh index 649e9d52c01..cae5c957e58 100755 --- a/l1-contracts/bootstrap.sh +++ b/l1-contracts/bootstrap.sh @@ -3,7 +3,8 @@ source $(git rev-parse --show-toplevel)/ci3/source_bootstrap cmd=${1:-} -export hash=$(cache_content_hash .rebuild_patterns) +# We rely on noir-projects for the verifier contract. +export hash=$(cache_content_hash .rebuild_patterns ../noir-projects/.rebuild_patterns) function build { github_group "l1-contracts build" From ac83c25cd78ac9c4930b85e9b819a57f289bc390 Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 09:59:08 +0000 Subject: [PATCH 17/26] fix cache issue --- barretenberg/acir_tests/sol-test/package.json | 3 +-- noir-projects/bootstrap.sh | 2 +- yarn-project/cli/package.json | 1 - yarn-project/end-to-end/package.json | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/barretenberg/acir_tests/sol-test/package.json b/barretenberg/acir_tests/sol-test/package.json index a13cd369c14..38b5d87ae88 100644 --- a/barretenberg/acir_tests/sol-test/package.json +++ b/barretenberg/acir_tests/sol-test/package.json @@ -8,7 +8,6 @@ "start": "node ./src/index.js" }, "dependencies": { - "ethers": "^6.8.1", - "solc": "^0.8.27" + "ethers": "^6.8.1" } } diff --git a/noir-projects/bootstrap.sh b/noir-projects/bootstrap.sh index 4b98d4fa7fb..f2bc7a47acc 100755 --- a/noir-projects/bootstrap.sh +++ b/noir-projects/bootstrap.sh @@ -50,6 +50,6 @@ case "$cmd" in exit ;; *) - echo_stderr "Unknown command: $CMD" + echo_stderr "Unknown command: $cmd" exit 1 esac diff --git a/yarn-project/cli/package.json b/yarn-project/cli/package.json index 21236b4a1c5..23b4d63d5b5 100644 --- a/yarn-project/cli/package.json +++ b/yarn-project/cli/package.json @@ -79,7 +79,6 @@ "lodash.chunk": "^4.2.0", "lodash.groupby": "^4.6.0", "semver": "^7.5.4", - "solc": "^0.8.27", "source-map-support": "^0.5.21", "tslib": "^2.4.0", "viem": "^2.7.15" diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index 1c496078ba0..0cd19fcc7d3 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -88,7 +88,6 @@ "process": "^0.11.10", "puppeteer-core": "^22.2", "resolve-typescript-plugin": "^2.0.1", - "solc": "^0.8.27", "stream-browserify": "^3.0.0", "string-argv": "^0.3.2", "ts-loader": "^9.4.4", From 15122e492271618f8a250e121f516a031b6167c5 Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 10:30:46 +0000 Subject: [PATCH 18/26] yarn install --- barretenberg/acir_tests/sol-test/package.json | 3 +- yarn-project/yarn.lock | 48 ++----------------- 2 files changed, 6 insertions(+), 45 deletions(-) diff --git a/barretenberg/acir_tests/sol-test/package.json b/barretenberg/acir_tests/sol-test/package.json index 38b5d87ae88..a13cd369c14 100644 --- a/barretenberg/acir_tests/sol-test/package.json +++ b/barretenberg/acir_tests/sol-test/package.json @@ -8,6 +8,7 @@ "start": "node ./src/index.js" }, "dependencies": { - "ethers": "^6.8.1" + "ethers": "^6.8.1", + "solc": "^0.8.27" } } diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 96530873d7b..e3dad76117c 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -524,7 +524,6 @@ __metadata: lodash.chunk: "npm:^4.2.0" lodash.groupby: "npm:^4.6.0" semver: "npm:^7.5.4" - solc: "npm:^0.8.27" source-map-support: "npm:^0.5.21" ts-jest: "npm:^29.1.0" ts-node: "npm:^10.9.1" @@ -620,7 +619,6 @@ __metadata: process: "npm:^0.11.10" puppeteer-core: "npm:^22.2" resolve-typescript-plugin: "npm:^2.0.1" - solc: "npm:^0.8.27" stream-browserify: "npm:^3.0.0" string-argv: "npm:^0.3.2" ts-loader: "npm:^9.4.4" @@ -8563,13 +8561,6 @@ __metadata: languageName: node linkType: hard -"command-exists@npm:^1.2.8": - version: 1.2.9 - resolution: "command-exists@npm:1.2.9" - checksum: 10/46fb3c4d626ca5a9d274f8fe241230817496abc34d12911505370b7411999e183c11adff7078dd8a03ec4cf1391290facda40c6a4faac8203ae38c985eaedd63 - languageName: node - linkType: hard - "command-line-args@npm:^5.1.1": version: 5.2.1 resolution: "command-line-args@npm:5.2.1" @@ -8634,7 +8625,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^8.1.0, commander@npm:^8.3.0": +"commander@npm:^8.3.0": version: 8.3.0 resolution: "commander@npm:8.3.0" checksum: 10/6b7b5d334483ce24bd73c5dac2eab901a7dbb25fd983ea24a1eeac6e7166bb1967f641546e8abf1920afbde86a45fbfe5812fbc69d0dc451bb45ca416a12a3a3 @@ -11324,7 +11315,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.12.1, follow-redirects@npm:^1.15.6": +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.6": version: 1.15.6 resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: @@ -13933,13 +13924,6 @@ __metadata: languageName: node linkType: hard -"js-sha3@npm:0.8.0": - version: 0.8.0 - resolution: "js-sha3@npm:0.8.0" - checksum: 10/a49ac6d3a6bfd7091472a28ab82a94c7fb8544cc584ee1906486536ba1cb4073a166f8c7bb2b0565eade23c5b3a7b8f7816231e0309ab5c549b737632377a20c - languageName: node - linkType: hard - "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -14876,13 +14860,6 @@ __metadata: languageName: node linkType: hard -"memorystream@npm:^0.3.1": - version: 0.3.1 - resolution: "memorystream@npm:0.3.1" - checksum: 10/2e34a1e35e6eb2e342f788f75f96c16f115b81ff6dd39e6c2f48c78b464dbf5b1a4c6ebfae4c573bd0f8dbe8c57d72bb357c60523be184655260d25855c03902 - languageName: node - linkType: hard - "meow@npm:^7.1.1": version: 7.1.1 resolution: "meow@npm:7.1.1" @@ -17851,7 +17828,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.1.0, semver@npm:^5.5.0": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.1.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -18274,23 +18251,6 @@ __metadata: languageName: node linkType: hard -"solc@npm:^0.8.27": - version: 0.8.28 - resolution: "solc@npm:0.8.28" - dependencies: - command-exists: "npm:^1.2.8" - commander: "npm:^8.1.0" - follow-redirects: "npm:^1.12.1" - js-sha3: "npm:0.8.0" - memorystream: "npm:^0.3.1" - semver: "npm:^5.5.0" - tmp: "npm:0.0.33" - bin: - solcjs: solc.js - checksum: 10/2ed06cb9d3507d3da7c5a5a7fb8c8ee08ff4c3a14d863625f9c666ad5f1194ff3f6dad635f67ef1726f197505aefa7038e4930b267d67a3c94d0af155dd08718 - languageName: node - linkType: hard - "sonic-boom@npm:^4.0.1": version: 4.2.0 resolution: "sonic-boom@npm:4.2.0" @@ -19177,7 +19137,7 @@ __metadata: languageName: node linkType: hard -"tmp@npm:0.0.33, tmp@npm:^0.0.33": +"tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33" dependencies: From a51b5e4481083e4cfa223b9dee42ae6bc3079d51 Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 18:35:06 +0000 Subject: [PATCH 19/26] vk flow simplification --- .../noir-protocol-circuits/bootstrap.sh | 2 +- yarn-project/bb-prover/src/bb/execute.ts | 98 ------------------- .../bb-prover/src/prover/bb_prover.ts | 97 ++++-------------- .../bb-prover/src/verifier/bb_verifier.ts | 84 +++------------- 4 files changed, 34 insertions(+), 247 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index 7abe078f5f2..b4246a8331d 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -174,7 +174,7 @@ case "$CMD" in git clean -fdx ;; "clean-keys") - rm -rf target/keys + rm -rf $key_dir ;; ""|"fast"|"full") build diff --git a/yarn-project/bb-prover/src/bb/execute.ts b/yarn-project/bb-prover/src/bb/execute.ts index c433142bcff..94abcd4535e 100644 --- a/yarn-project/bb-prover/src/bb/execute.ts +++ b/yarn-project/bb-prover/src/bb/execute.ts @@ -2,7 +2,6 @@ import { type AvmCircuitInputs, serializeWithMessagePack } from '@aztec/circuits import { sha256 } from '@aztec/foundation/crypto'; import { type LogFn, type Logger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; -import { type NoirCompiledCircuit } from '@aztec/types/noir'; import * as proc from 'child_process'; import { promises as fs } from 'fs'; @@ -97,103 +96,6 @@ export function executeBB( }).catch(_ => ({ status: BB_RESULT.FAILURE, exitCode: -1, signal: undefined })); } -const bytecodeFilename = 'bytecode'; - -/** - * Used for generating either a proving or verification key, will exit early if the key already exists - * It assumes the provided working directory is one where the caller wishes to maintain a permanent set of keys - * It is not considered a temporary directory - * @param pathToBB - The full path to the bb binary - * @param workingDirectory - The directory into which the key should be created - * @param circuitName - An identifier for the circuit - * @param compiledCircuit - The compiled circuit - * @param key - The type of key, either 'pk' or 'vk' - * @param log - A logging function - * @param force - Force the key to be regenerated even if it already exists - * @returns An instance of BBResult - */ -export async function generateKeyForNoirCircuit( - pathToBB: string, - workingDirectory: string, - circuitName: string, - compiledCircuit: NoirCompiledCircuit, - recursive: boolean, - flavor: UltraHonkFlavor, - log: LogFn, - force = false, -): Promise { - const bytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); - - // The key generation is written to e.g. /workingDirectory/pk/BaseParityArtifact/pk - // The bytecode hash file is also written here as /workingDirectory/pk/BaseParityArtifact/bytecode-hash - // The bytecode is written to e.g. /workingDirectory/pk/BaseParityArtifact/bytecode - // The bytecode is removed after the key is generated, leaving just the hash file - const circuitOutputDirectory = `${workingDirectory}/vk/${circuitName}`; - const outputPath = `${circuitOutputDirectory}`; - const bytecodeHash = sha256(bytecode); - - // ensure the directory exists - await fs.mkdir(circuitOutputDirectory, { recursive: true }); - - const res = await fsCache(circuitOutputDirectory, bytecodeHash, log, force, async () => { - const binaryPresent = await fs - .access(pathToBB, fs.constants.R_OK) - .then(_ => true) - .catch(_ => false); - if (!binaryPresent) { - return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` }; - } - - // We are now going to generate the key - try { - const bytecodePath = `${circuitOutputDirectory}/${bytecodeFilename}`; - // Write the bytecode to the working directory - await fs.writeFile(bytecodePath, bytecode); - - // args are the output path and the input bytecode path - const args = ['-o', `${outputPath}/${VK_FILENAME}`, '-b', bytecodePath, recursive ? '--recursive' : '']; - const timer = new Timer(); - let result = await executeBB(pathToBB, `write_vk_${flavor}`, args, log); - - // If we succeeded and the type of key if verification, have bb write the 'fields' version too - if (result.status == BB_RESULT.SUCCESS) { - const asFieldsArgs = ['-k', `${outputPath}/${VK_FILENAME}`, '-o', `${outputPath}/${VK_FIELDS_FILENAME}`, '-v']; - result = await executeBB(pathToBB, `vk_as_fields_${flavor}`, asFieldsArgs, log); - } - const duration = timer.ms(); - - if (result.status == BB_RESULT.SUCCESS) { - return { - status: BB_RESULT.SUCCESS, - durationMs: duration, - pkPath: undefined, - vkPath: outputPath, - proofPath: undefined, - }; - } - // Not a great error message here but it is difficult to decipher what comes from bb - return { - status: BB_RESULT.FAILURE, - reason: `Failed to generate key. Exit code: ${result.exitCode}. Signal ${result.signal}.`, - retry: !!result.signal, - }; - } catch (error) { - return { status: BB_RESULT.FAILURE, reason: `${error}` }; - } - }); - - if (!res) { - return { - status: BB_RESULT.ALREADY_PRESENT, - durationMs: 0, - pkPath: undefined, - vkPath: outputPath, - }; - } - - return res; -} - // TODO(#7369) comment this etc (really just take inspiration from this and rewrite it all O:)) export async function executeBbClientIvcProof( pathToBB: string, diff --git a/yarn-project/bb-prover/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts index ea6b4fe4633..63616abd981 100644 --- a/yarn-project/bb-prover/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -23,7 +23,6 @@ import { RecursiveProof, type RootParityInputs, TUBE_PROOF_LENGTH, - type VerificationKeyAsFields, type VerificationKeyData, makeRecursiveProofFromBinary, } from '@aztec/circuits.js'; @@ -69,6 +68,7 @@ import { convertSingleTxBlockRootRollupInputsToWitnessMap, convertSingleTxBlockRootRollupOutputsFromWitnessMap, } from '@aztec/noir-protocol-circuits-types/server'; +import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/vks'; import { NativeACVMSimulator } from '@aztec/simulator/server'; import { Attributes, type TelemetryClient, getTelemetryClient, trackSpan } from '@aztec/telemetry-client'; @@ -86,7 +86,6 @@ import { PROOF_FILENAME, VK_FILENAME, generateAvmProof, - generateKeyForNoirCircuit, generateProof, generateTubeProof, verifyAvmProof, @@ -114,11 +113,6 @@ export interface BBProverConfig extends BBConfig, ACVMConfig { * Prover implementation that uses barretenberg native proving */ export class BBNativeRollupProver implements ServerCircuitProver { - private verificationKeys = new Map< - `ultra${'_keccak_' | '_' | '_rollup_'}honk_${ServerProtocolArtifact}`, - Promise - >(); - private instrumentation: ProverInstrumentation; constructor(private config: BBProverConfig, telemetry: TelemetryClient) { @@ -157,7 +151,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertBaseParityOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit('BaseParityArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('BaseParityArtifact'); await this.verifyProof('BaseParityArtifact', proof.binaryProof); return makePublicInputsAndRecursiveProof(circuitOutput, proof, verificationKey); @@ -180,7 +174,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertRootParityOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit('RootParityArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('RootParityArtifact'); await this.verifyProof('RootParityArtifact', proof.binaryProof); return makePublicInputsAndRecursiveProof(circuitOutput, proof, verificationKey); @@ -222,7 +216,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertPrivateBaseRollupOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit(artifactName); + const verificationKey = this.getVerificationKeyDataForCircuit(artifactName); await this.verifyProof(artifactName, proof.binaryProof); @@ -249,7 +243,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertPublicBaseRollupOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit(artifactName); + const verificationKey = this.getVerificationKeyDataForCircuit(artifactName); await this.verifyProof(artifactName, proof.binaryProof); @@ -274,7 +268,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertMergeRollupOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit('MergeRollupArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('MergeRollupArtifact'); await this.verifyProof('MergeRollupArtifact', proof.binaryProof); @@ -299,7 +293,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertBlockRootRollupOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit('BlockRootRollupArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('BlockRootRollupArtifact'); await this.verifyProof('BlockRootRollupArtifact', proof.binaryProof); @@ -319,7 +313,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertSingleTxBlockRootRollupOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit('SingleTxBlockRootRollupArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('SingleTxBlockRootRollupArtifact'); await this.verifyProof('SingleTxBlockRootRollupArtifact', proof.binaryProof); @@ -344,7 +338,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertEmptyBlockRootRollupOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit('EmptyBlockRootRollupArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('EmptyBlockRootRollupArtifact'); await this.verifyProof('EmptyBlockRootRollupArtifact', proof.binaryProof); @@ -369,7 +363,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertBlockMergeRollupOutputsFromWitnessMap, ); - const verificationKey = await this.getVerificationKeyDataForCircuit('BlockMergeRollupArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('BlockMergeRollupArtifact'); await this.verifyProof('BlockMergeRollupArtifact', proof.binaryProof); @@ -393,7 +387,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { const recursiveProof = makeRecursiveProofFromBinary(proof, NESTED_RECURSIVE_PROOF_LENGTH); - const verificationKey = await this.getVerificationKeyDataForCircuit('RootRollupArtifact'); + const verificationKey = this.getVerificationKeyDataForCircuit('RootRollupArtifact'); await this.verifyProof('RootRollupArtifact', proof); @@ -462,12 +456,9 @@ export class BBNativeRollupProver implements ServerCircuitProver { throw new ProvingError(provingResult.reason, provingResult, provingResult.retry); } - // Ensure our vk cache is up to date - const vkData = await this.updateVerificationKeyAfterProof(provingResult.vkPath!, circuitType); - return { circuitOutput: output, - vkData, + vkData: this.getVerificationKeyDataForCircuit(circuitType), provingResult, }; } @@ -581,12 +572,12 @@ export class BBNativeRollupProver implements ServerCircuitProver { } public async getTubeProof(input: TubeInputs): Promise> { - // this probably is gonna need to call client ivc const operation = async (bbWorkingDirectory: string) => { logger.debug(`createTubeProof: ${bbWorkingDirectory}`); const provingResult = await this.generateTubeProofWithBB(bbWorkingDirectory, input); // Read the proof as fields + // TODO(AD): this is the only remaining use of extractVkData. const tubeVK = await extractVkData(provingResult.vkPath!); const tubeProof = await this.readProofAsFields(provingResult.proofPath!, tubeVK, TUBE_PROOF_LENGTH); @@ -674,7 +665,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { * @param proof - The proof to be verified */ public async verifyProof(circuitType: ServerProtocolArtifact, proof: Proof) { - const verificationKey = await this.getVerificationKeyDataForCircuit(circuitType); + const verificationKey = this.getVerificationKeyDataForCircuit(circuitType); return await this.verifyWithKey(getUltraHonkFlavorForCircuit(circuitType), verificationKey, proof); } @@ -715,16 +706,6 @@ export class BBNativeRollupProver implements ServerCircuitProver { await this.runInDirectory(operation); } - /** - * Returns the verification key for a circuit, will generate it if not cached internally - * @param circuitType - The type of circuit for which the verification key is required - * @returns The verification key - */ - public async getVerificationKeyForCircuit(circuitType: ServerProtocolArtifact): Promise { - const vkData = await this.getVerificationKeyDataForCircuit(circuitType); - return vkData.clone().keyAsFields; - } - /** * Will check a recursive proof argument for validity of it's 'fields' format of proof and convert if required * @param proof - The input proof that may need converting @@ -789,54 +770,16 @@ export class BBNativeRollupProver implements ServerCircuitProver { } /** - * Returns the verification key data for a circuit, will generate and cache it if not cached internally + * Returns the verification key data for a circuit. * @param circuitType - The type of circuit for which the verification key is required * @returns The verification key data */ - private async getVerificationKeyDataForCircuit(circuitType: ServerProtocolArtifact): Promise { - const flavor = getUltraHonkFlavorForCircuit(circuitType); - let promise = this.verificationKeys.get(`${flavor}_${circuitType}`); - if (!promise) { - promise = generateKeyForNoirCircuit( - this.config.bbBinaryPath, - this.config.bbWorkingDirectory, - circuitType, - ServerCircuitArtifacts[circuitType], - SERVER_CIRCUIT_RECURSIVE, - flavor, - logger.debug, - ).then(result => { - if (result.status === BB_RESULT.FAILURE) { - throw new ProvingError( - `Failed to generate verification key for ${circuitType}, ${result.reason}`, - result, - result.retry, - ); - } - return extractVkData(result.vkPath!); - }); - this.verificationKeys.set(`${flavor}_${circuitType}`, promise); - } - const vk = await promise; - return vk.clone(); - } - - /** - * Ensures our verification key cache includes the key data located at the specified directory - * @param filePath - The directory containing the verification key data files - * @param circuitType - The type of circuit to which the verification key corresponds - */ - private async updateVerificationKeyAfterProof( - filePath: string, - circuitType: ServerProtocolArtifact, - ): Promise { - const flavor = getUltraHonkFlavorForCircuit(circuitType); - let promise = this.verificationKeys.get(`${flavor}_${circuitType}`); - if (!promise) { - promise = extractVkData(filePath); - this.verificationKeys.set(`${flavor}_${circuitType}`, promise); + private getVerificationKeyDataForCircuit(circuitType: ServerProtocolArtifact): VerificationKeyData { + const vk = ServerCircuitVks[circuitType]; + if (vk === undefined) { + throw new Error('Could not find VK for server artifact ' + circuitType); } - return promise; + return vk; } private async readProofAsFields( diff --git a/yarn-project/bb-prover/src/verifier/bb_verifier.ts b/yarn-project/bb-prover/src/verifier/bb_verifier.ts index eceefb2846b..c1b2fa1b852 100644 --- a/yarn-project/bb-prover/src/verifier/bb_verifier.ts +++ b/yarn-project/bb-prover/src/verifier/bb_verifier.ts @@ -4,23 +4,13 @@ import { type Proof, type VerificationKeyData } from '@aztec/circuits.js'; import { runInDirectory } from '@aztec/foundation/fs'; import { type LogFn, type Logger, createLogger } from '@aztec/foundation/log'; import { ServerCircuitArtifacts } from '@aztec/noir-protocol-circuits-types/server'; -import { - type ClientProtocolArtifact, - type ProtocolArtifact, - type ServerProtocolArtifact, -} from '@aztec/noir-protocol-circuits-types/types'; +import { type ClientProtocolArtifact, type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types'; +import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/vks'; import { promises as fs } from 'fs'; import * as path from 'path'; -import { - BB_RESULT, - PROOF_FILENAME, - VK_FILENAME, - generateKeyForNoirCircuit, - verifyClientIvcProof, - verifyProof, -} from '../bb/execute.js'; +import { BB_RESULT, PROOF_FILENAME, VK_FILENAME, verifyClientIvcProof, verifyProof } from '../bb/execute.js'; import { type BBConfig } from '../config.js'; import { getUltraHonkFlavorForCircuit } from '../honk.js'; import { writeToOutputDirectory } from '../prover/client_ivc_proof_utils.js'; @@ -28,74 +18,26 @@ import { isProtocolArtifactRecursive, mapProtocolArtifactNameToCircuitName } fro import { extractVkData } from '../verification_key/verification_key_data.js'; export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { - private constructor( - private config: BBConfig, - private verificationKeys = new Map>(), - private logger: Logger, - ) {} - - public static async new( - config: BBConfig, - initialCircuits: ServerProtocolArtifact[] = [], - logger = createLogger('bb-prover:verifier'), - ) { - await fs.mkdir(config.bbWorkingDirectory, { recursive: true }); - const keys = new Map>(); - for (const circuit of initialCircuits) { - const vkData = await this.generateVerificationKey( - circuit, - config.bbBinaryPath, - config.bbWorkingDirectory, - logger.debug, - ); - keys.set(circuit, Promise.resolve(vkData)); - } - return new BBCircuitVerifier(config, keys, logger); - } - - private static async generateVerificationKey( - circuit: ServerProtocolArtifact, - bbPath: string, - workingDirectory: string, - logFn: LogFn, - ) { - return await generateKeyForNoirCircuit( - bbPath, - workingDirectory, - circuit, - ServerCircuitArtifacts[circuit], - isProtocolArtifactRecursive(circuit), - getUltraHonkFlavorForCircuit(circuit), - logFn, - ).then(result => { - if (result.status === BB_RESULT.FAILURE) { - throw new Error(`Failed to created verification key for ${circuit}, ${result.reason}`); - } + private constructor(private config: BBConfig, private logger: Logger) {} - return extractVkData(result.vkPath!); - }); + public static async new(config: BBConfig, logger = createLogger('bb-prover:verifier')) { + await fs.mkdir(config.bbWorkingDirectory, { recursive: true }); + return new BBCircuitVerifier(config, logger); } - public async getVerificationKeyData(circuit: ServerProtocolArtifact) { - let promise = this.verificationKeys.get(circuit); - if (!promise) { - promise = BBCircuitVerifier.generateVerificationKey( - circuit, - this.config.bbBinaryPath, - this.config.bbWorkingDirectory, - this.logger.debug, - ); + public getVerificationKeyData(circuitType: ServerProtocolArtifact): VerificationKeyData { + const vk = ServerCircuitVks[circuitType]; + if (vk === undefined) { + throw new Error('Could not find VK for server artifact ' + circuitType); } - this.verificationKeys.set(circuit, promise); - const vk = await promise; - return vk.clone(); + return vk; } public async verifyProofForCircuit(circuit: ServerProtocolArtifact, proof: Proof) { const operation = async (bbWorkingDirectory: string) => { const proofFileName = path.join(bbWorkingDirectory, PROOF_FILENAME); const verificationKeyPath = path.join(bbWorkingDirectory, VK_FILENAME); - const verificationKey = await this.getVerificationKeyData(circuit); + const verificationKey = this.getVerificationKeyData(circuit); this.logger.debug(`${circuit} Verifying with key: ${verificationKey.keyAsFields.hash.toString()}`); From fbd1f12ebe9aaf3f581994e390dc7b35fd22c96d Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 19:34:19 +0000 Subject: [PATCH 20/26] fix build --- yarn-project/proof-verifier/src/proof_verifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/proof-verifier/src/proof_verifier.ts b/yarn-project/proof-verifier/src/proof_verifier.ts index 11ba8bfa203..049cd38cd92 100644 --- a/yarn-project/proof-verifier/src/proof_verifier.ts +++ b/yarn-project/proof-verifier/src/proof_verifier.ts @@ -46,7 +46,7 @@ export class ProofVerifier implements Traceable { static async new(config: ProofVerifierConfig, telemetryClient: TelemetryClient): Promise { const logger = createLogger('proof-verifier:block-verifier-bot'); - const verifier = await BBCircuitVerifier.new(config, [], logger); + const verifier = await BBCircuitVerifier.new(config, logger); const client = createPublicClient({ chain: createEthereumChain(config.l1Url, config.l1ChainId).chainInfo, transport: http(config.l1Url), From 9e18c524d17e24e3d83eca1d25c3329adf7c95e8 Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 21:11:15 +0100 Subject: [PATCH 21/26] Update honk_contract.hpp --- .../cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp index 4395b1e6f11..c49748870b6 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp @@ -961,7 +961,7 @@ library RelationsLib { // Contribution 10 point doubling, x-coordinate check // (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0 - // n.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1 + // N.B. we're using the equivalence x1*x1*x1 === y1*y1 - curve_b to reduce degree by 1 { Fr x_pow_4 = (y1_sqr + GRUMPKIN_CURVE_B_PARAMETER_NEGATED) * ep.x_1; Fr y1_sqr_mul_4 = y1_sqr + y1_sqr; @@ -1181,7 +1181,7 @@ library RelationsLib { * The gate boolean check is * (A && B) => C === !(A && B) || C === !A || !B || C * - * n.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized + * N.B. it is the responsibility of the circuit writer to ensure that every RAM cell is initialized * with a WRITE operation. */ Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4 @@ -1802,4 +1802,4 @@ inline std::string get_honk_solidity_verifier(auto const& verification_key) std::ostringstream stream; output_vk_sol_ultra_honk(stream, verification_key, "HonkVerificationKey"); return stream.str() + HONK_CONTRACT_SOURCE; -} \ No newline at end of file +} From 5e8af2c8a4f06ed66f3a8309d2e2c8055414a154 Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 21:11:53 +0100 Subject: [PATCH 22/26] Update honk_contract.hpp --- .../cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp index c49748870b6..b8638c83a84 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp @@ -1587,7 +1587,7 @@ abstract contract BaseHonkVerifier is IVerifier { numeratorValue = numeratorValue * (roundChallenge - Fr.wrap(i)); } - // Calculate domain size n of inverses + // Calculate domain size N of inverses Fr[BATCHED_RELATION_PARTIAL_LENGTH] memory denominatorInverses; for (uint256 i; i < BATCHED_RELATION_PARTIAL_LENGTH; ++i) { Fr inv = BARYCENTRIC_LAGRANGE_DENOMINATORS[i]; From 80561d5a567955492417008ea40185516894d28b Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 21:46:44 +0000 Subject: [PATCH 23/26] disambiguate hash --- noir-projects/noir-protocol-circuits/bootstrap.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index b4246a8331d..58ee09d31e2 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -103,7 +103,8 @@ function compile { # Change this to add verification_key to original json, like contracts does. # Will require changing TS code downstream. bytecode_hash=$(jq -r '.bytecode' $json_path | sha256sum | tr -d ' -') - hash=$(hash_str "$BB_HASH-$bytecode_hash-$proto") + # TODO(AD) remove the -2 after this lands on master, needed to disambiguate + hash=$(hash_str "$BB_HASH-$bytecode_hash-$proto-2") if ! cache_download vk-$hash.tar.gz 1>&2; then local key_path="$key_dir/$name.vk.data.json" echo_stderr "Generating vk for function: $name..." From f7593c9cf99b50f7ecf7700c3795baeef34b0f30 Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 22 Jan 2025 23:22:20 +0000 Subject: [PATCH 24/26] try bump... --- noir-projects/noir-protocol-circuits/bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index 58ee09d31e2..3d6dc56455f 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -104,7 +104,7 @@ function compile { # Will require changing TS code downstream. bytecode_hash=$(jq -r '.bytecode' $json_path | sha256sum | tr -d ' -') # TODO(AD) remove the -2 after this lands on master, needed to disambiguate - hash=$(hash_str "$BB_HASH-$bytecode_hash-$proto-2") + hash=$(hash_str "$BB_HASH-$bytecode_hash-$proto-3") if ! cache_download vk-$hash.tar.gz 1>&2; then local key_path="$key_dir/$name.vk.data.json" echo_stderr "Generating vk for function: $name..." From 7c68a65749f94378b2ac29cfdffcf4b1be92d254 Mon Sep 17 00:00:00 2001 From: ludamad Date: Thu, 23 Jan 2025 18:06:54 +0000 Subject: [PATCH 25/26] fmt --- yarn-project/bb-prover/src/verifier/bb_verifier.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/yarn-project/bb-prover/src/verifier/bb_verifier.ts b/yarn-project/bb-prover/src/verifier/bb_verifier.ts index c1b2fa1b852..7fca42c7c47 100644 --- a/yarn-project/bb-prover/src/verifier/bb_verifier.ts +++ b/yarn-project/bb-prover/src/verifier/bb_verifier.ts @@ -2,8 +2,7 @@ import { type ClientProtocolCircuitVerifier, Tx } from '@aztec/circuit-types'; import { type CircuitVerificationStats } from '@aztec/circuit-types/stats'; import { type Proof, type VerificationKeyData } from '@aztec/circuits.js'; import { runInDirectory } from '@aztec/foundation/fs'; -import { type LogFn, type Logger, createLogger } from '@aztec/foundation/log'; -import { ServerCircuitArtifacts } from '@aztec/noir-protocol-circuits-types/server'; +import { type Logger, createLogger } from '@aztec/foundation/log'; import { type ClientProtocolArtifact, type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types'; import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/vks'; @@ -14,8 +13,7 @@ import { BB_RESULT, PROOF_FILENAME, VK_FILENAME, verifyClientIvcProof, verifyPro import { type BBConfig } from '../config.js'; import { getUltraHonkFlavorForCircuit } from '../honk.js'; import { writeToOutputDirectory } from '../prover/client_ivc_proof_utils.js'; -import { isProtocolArtifactRecursive, mapProtocolArtifactNameToCircuitName } from '../stats.js'; -import { extractVkData } from '../verification_key/verification_key_data.js'; +import { mapProtocolArtifactNameToCircuitName } from '../stats.js'; export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { private constructor(private config: BBConfig, private logger: Logger) {} From 1a310eaba38d09f24f01538d0a0d703624d1f6ef Mon Sep 17 00:00:00 2001 From: ludamad Date: Thu, 23 Jan 2025 20:00:17 +0000 Subject: [PATCH 26/26] perform a fix - which implies things were broken. --- .../noir-protocol-circuits/bootstrap.sh | 13 ++++++-- .../bb-prover/src/prover/bb_prover.ts | 30 +++++++++++-------- yarn-project/noir-contracts.js/package.json | 2 +- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/bootstrap.sh b/noir-projects/noir-protocol-circuits/bootstrap.sh index 3d6dc56455f..566e0418aea 100755 --- a/noir-projects/noir-protocol-circuits/bootstrap.sh +++ b/noir-projects/noir-protocol-circuits/bootstrap.sh @@ -43,6 +43,7 @@ rollup_honk_patterns=( ivc_regex=$(IFS="|"; echo "${ivc_patterns[*]}") rollup_honk_regex=$(IFS="|"; echo "${rollup_honk_patterns[*]}") +keccak_honk_regex=rollup_root # We do this for the rollup root only. verifier_generate_regex=rollup_root @@ -56,7 +57,7 @@ mkdir -p $tmp_dir mkdir -p $key_dir # Export vars needed inside compile. -export tmp_dir key_dir ci3 ivc_regex rollup_honk_regex +export tmp_dir key_dir ci3 ivc_regex rollup_honk_regex keccak_honk_regex verifier_generate_regex function compile { set -euo pipefail @@ -88,8 +89,15 @@ function compile { local vk_as_fields_cmd="vk_as_fields_mega_honk" elif echo "$name" | grep -qE "${rollup_honk_regex}"; then local proto="ultra_rollup_honk" + # -h 2 injects a fake ipa claim local write_vk_cmd="write_vk_ultra_rollup_honk -h 2" local vk_as_fields_cmd="vk_as_fields_ultra_rollup_honk" + elif echo "$name" | grep -qE "${keccak_honk_regex}"; then + local proto="ultra_keccak_honk" + # the root rollup does not need to inject a fake ipa claim + # and does not need to inject a default agg obj, so no -h flag + local write_vk_cmd="write_vk_ultra_keccak_honk" + local vk_as_fields_cmd="vk_as_fields_ultra_keccak_honk" else local proto="ultra_honk" local write_vk_cmd="write_vk_ultra_honk -h 1" @@ -103,8 +111,7 @@ function compile { # Change this to add verification_key to original json, like contracts does. # Will require changing TS code downstream. bytecode_hash=$(jq -r '.bytecode' $json_path | sha256sum | tr -d ' -') - # TODO(AD) remove the -2 after this lands on master, needed to disambiguate - hash=$(hash_str "$BB_HASH-$bytecode_hash-$proto-3") + hash=$(hash_str "$BB_HASH-$bytecode_hash-$proto") if ! cache_download vk-$hash.tar.gz 1>&2; then local key_path="$key_dir/$name.vk.data.json" echo_stderr "Generating vk for function: $name..." diff --git a/yarn-project/bb-prover/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts index 63616abd981..602ba14e358 100644 --- a/yarn-project/bb-prover/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -403,7 +403,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertInput: (input: Input) => WitnessMap, convertOutput: (outputWitness: WitnessMap) => Output, workingDirectory: string, - ): Promise<{ circuitOutput: Output; vkData: VerificationKeyData; provingResult: BBSuccess }> { + ): Promise<{ circuitOutput: Output; provingResult: BBSuccess }> { // Have the ACVM write the partial witness here const outputWitnessFile = path.join(workingDirectory, 'partial-witness.gz'); @@ -458,7 +458,6 @@ export class BBNativeRollupProver implements ServerCircuitProver { return { circuitOutput: output, - vkData: this.getVerificationKeyDataForCircuit(circuitType), provingResult, }; } @@ -470,15 +469,17 @@ export class BBNativeRollupProver implements ServerCircuitProver { convertOutput: (outputWitness: WitnessMap) => Output, ): Promise<{ circuitOutput: Output; proof: Proof }> { const operation = async (bbWorkingDirectory: string) => { - const { - provingResult, - vkData, - circuitOutput: output, - } = await this.generateProofWithBB(input, circuitType, convertInput, convertOutput, bbWorkingDirectory); + const { provingResult, circuitOutput: output } = await this.generateProofWithBB( + input, + circuitType, + convertInput, + convertOutput, + bbWorkingDirectory, + ); // Read the binary proof const rawProof = await fs.readFile(`${provingResult.proofPath!}/${PROOF_FILENAME}`); - + const vkData = this.getVerificationKeyDataForCircuit(circuitType); const proof = new Proof(rawProof, vkData.numPublicInputs); const circuitName = mapProtocolArtifactNameToCircuitName(circuitType); @@ -622,12 +623,15 @@ export class BBNativeRollupProver implements ServerCircuitProver { ): Promise<{ circuitOutput: CircuitOutputType; proof: RecursiveProof }> { // this probably is gonna need to call client ivc const operation = async (bbWorkingDirectory: string) => { - const { - provingResult, - vkData, - circuitOutput: output, - } = await this.generateProofWithBB(input, circuitType, convertInput, convertOutput, bbWorkingDirectory); + const { provingResult, circuitOutput: output } = await this.generateProofWithBB( + input, + circuitType, + convertInput, + convertOutput, + bbWorkingDirectory, + ); + const vkData = this.getVerificationKeyDataForCircuit(circuitType); // Read the proof as fields const proof = await this.readProofAsFields(provingResult.proofPath!, vkData, proofLength); diff --git a/yarn-project/noir-contracts.js/package.json b/yarn-project/noir-contracts.js/package.json index ee504495238..b1cea9b52bf 100644 --- a/yarn-project/noir-contracts.js/package.json +++ b/yarn-project/noir-contracts.js/package.json @@ -76,4 +76,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +}