Skip to content

Commit

Permalink
refactor(sol): generate & compile verifier contract in bootstrap (#11364
Browse files Browse the repository at this point in the history
)

This was an ad-hoc step in yarn-project, and write-contract was only
called in the Earthfile's. This brings it to the bootstrap scripts where
it can be a normal dependency of l1-contracts.
  • Loading branch information
ludamad authored Jan 23, 2025
1 parent c3c04a4 commit bf3b12a
Show file tree
Hide file tree
Showing 25 changed files with 230 additions and 785 deletions.
63 changes: 3 additions & 60 deletions Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,21 @@ 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.
# 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"

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
Expand All @@ -92,7 +84,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
Expand Down Expand Up @@ -261,19 +253,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
Expand All @@ -287,42 +266,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
########################################################################################################################
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ void contract_honk(const std::string& output_path, const std::string& vk_path)
auto vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(read_file(vk_path)));
vk->pcs_verification_key = std::make_shared<VerifierCommitmentKey>();

std::string contract = get_honk_solidity_verifier(std::move(vk));
std::string contract = get_honk_solidity_verifier(vk);

if (output_path == "-") {
writeStringToStdout(contract);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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));
{
Expand Down Expand Up @@ -1801,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;
}
}
1 change: 1 addition & 0 deletions l1-contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ out/
# Dotenv file
.env

generated
lcov.info

# Local foundry env
Expand Down
23 changes: 20 additions & 3 deletions l1-contracts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,40 @@ 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"
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

# Ensure libraries are at the correct version
git submodule update --init --recursive ./lib

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" 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
forge build
# Step 1: Build everything in src.
forge build $(find src test -name '*.sol')

# Step 2: Build the the generated verifier contract with optimization.
forge build $(find generated -name '*.sol') \
--optimize \
--optimizer-runs 200

cache_upload $artifact out
fi
Expand Down
3 changes: 1 addition & 2 deletions l1-contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion noir-projects/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ case "$cmd" in
exit
;;
*)
echo_stderr "Unknown command: $CMD"
echo_stderr "Unknown command: $cmd"
exit 1
esac
28 changes: 24 additions & 4 deletions noir-projects/noir-protocol-circuits/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ rollup_honk_patterns=(
"rollup_merge"
)


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

function on_exit() {
rm -rf $tmp_dir
Expand All @@ -55,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
Expand Down Expand Up @@ -87,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"
Expand All @@ -113,9 +122,20 @@ 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")

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
if echo "$name" | grep -qE "${verifier_generate_regex}"; then
local verifier_path="$key_dir/${name}_verifier.sol"
SECONDS=0
# Generate solidity verifier for this contract.
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
else
cache_upload vk-$hash.tar.gz $key_path &> /dev/null
fi
fi
}

Expand Down Expand Up @@ -162,7 +182,7 @@ case "$CMD" in
git clean -fdx
;;
"clean-keys")
rm -rf target/keys
rm -rf $key_dir
;;
""|"fast"|"full")
build
Expand Down
67 changes: 0 additions & 67 deletions yarn-project/Dockerfile

This file was deleted.

39 changes: 0 additions & 39 deletions yarn-project/Dockerfile.test

This file was deleted.

Loading

1 comment on commit bf3b12a

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: bf3b12a Previous: c3c04a4 Ratio
wasmconstruct_proof_ultrahonk_power_of_2/20 14745.195283000001 ms/iter 13476.218786999998 ms/iter 1.09

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ludamad @codygunton

Please sign in to comment.