-
Notifications
You must be signed in to change notification settings - Fork 303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: UH recursion in the browser #11049
Changes from all commits
c6af0b9
b88f1e9
2c26d15
690f340
0e1b7a0
11669fa
ea9651e
8a59f35
16b3197
09f6351
dbc2ab4
442f0f4
6e48a72
27a9301
267930e
7fa849b
20b7590
1d552d2
8c50726
d9948e4
4c77ef3
a488849
e0a50a8
07d8753
e45f474
9c4c968
9ab78e0
0a05309
a593246
8ffa5b7
dfe906f
aa04873
163886e
8b9bc55
d70791d
57a50f8
11cf033
ab813b1
7a03ddf
4a29e15
0f1ca8d
0a89b4d
80b0a5a
d34bb9a
b7fb5fe
5079044
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('@aztec/foundation/eslint'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
artifacts/ | ||
circuits/**/proofs/* | ||
circuits/**/Prover.toml | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
crates | ||
artifacts |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Noir + Bb benchmarking suite | ||
|
||
The goal of this module is to provide a simple place for people to construct benchmarks of witness generation and proving. At the moment it only pertains to UltraHonk recursion in the browser, but we have a similar module in ivc-integration that shows prover performance of our ClientIVC suite. | ||
|
||
## Building | ||
|
||
The package assumes that bb.js has been built, but it is easy to rebuild, as we show below. | ||
|
||
The full build command `yarn build` deletes all circuit artifacts and generated code, compiles the circuits, computes their verification keys, generates declarations and types for parsing circuit bytecode and verification keys in typescript, generates additional type information for noir.js and bb.js, and builds the typescript. With all of this, `yarn test` will run whatever jest tests are present, and `yarn serve:app` will serve a simple app with proving for execution in a web browser. but we can build more incrementally as well. | ||
|
||
Scenario: I have made changes to bb.js and now I want to rebuild and run the browser app with multithreaded proving and symbols for the meaningful WASM stack traces. Command: | ||
``` | ||
cd ../../barretenberg/ts && SKIP_ST_BUILD=1 NO_STRIP=1 yarn build && cd - && yarn build:app && yarn serve:app | ||
``` | ||
|
||
Scenario: bb.js is unchanged, but I have changed one of my test circuits, and I want to run all tests. Command: | ||
``` | ||
yarn generate && yarn build:ts && yarn test | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[package] | ||
name = "circuit_1" | ||
type = "bin" | ||
|
||
[dependencies] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
fn main(x: Field, y: pub Field) { | ||
assert(x != y); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[package] | ||
name = "circuit_2" | ||
type = "bin" | ||
|
||
[dependencies] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use std::hash::poseidon; | ||
|
||
// This circuit aggregates a single Honk proof from `assert_statement`. | ||
global ULTRA_VK_SIZE: u32 = 128; | ||
global ULTRA_PROOF_SIZE: u32 = 459; | ||
global NUM_NON_ACCUMULATOR_PUBLIC_INPUTS: u32 = 1; | ||
global HONK_IDENTIFIER: u32 = 1; | ||
fn main( | ||
verification_key: [Field; ULTRA_VK_SIZE], | ||
proof: [Field; ULTRA_PROOF_SIZE], | ||
public_inputs: pub [Field; NUM_NON_ACCUMULATOR_PUBLIC_INPUTS], | ||
key_hash: Field, | ||
mut z: Field | ||
) { | ||
std::verify_proof_with_type( | ||
verification_key, | ||
proof, | ||
public_inputs, | ||
key_hash, | ||
HONK_IDENTIFIER, | ||
); | ||
|
||
for _ in 0..250 { | ||
z += poseidon::bn254::hash_1([z]); | ||
} | ||
|
||
// Make sure the hash value is used so it's not optimized away. | ||
assert(z != 0); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#!/usr/bin/env bash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you have to call this before serving? what's the flow of commands you call? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, you need to generate the artifacts before you build, otherwise you will hit a build error because you are generating types that are imported in the app. |
||
set -eu | ||
source $(git rev-parse --show-toplevel)/ci3/source_bootstrap | ||
|
||
export BB=${BB:-../../barretenberg/cpp/build/bin/bb} | ||
export NARGO=${NARGO:-$(realpath ../../noir/noir-repo/target/release/nargo)} | ||
|
||
key_dir=artifacts/keys | ||
|
||
function compile { | ||
set -euo pipefail | ||
local dir=$1 | ||
local name=${dir//-/_} | ||
local circuit_path="./circuits/$name" | ||
|
||
echo_stderr "Generating bytecode for circuit: $name..." | ||
cd $circuit_path | ||
$NARGO compile | ||
cd - | ||
local filename="$name.json" | ||
mv $circuit_path/target/$filename artifacts/ | ||
|
||
local json_path="./artifacts/$filename" | ||
local write_vk_cmd="write_vk_ultra_honk -h 1" | ||
local vk_as_fields_cmd="vk_as_fields_ultra_honk" | ||
local key_path="$key_dir/$name.vk.data.json" | ||
echo_stderr "Generating vk for circuit: $name..." | ||
SECONDS=0 | ||
local vk_cmd="jq -r '.bytecode' $json_path | base64 -d | gunzip | $BB $write_vk_cmd -b - -o - --recursive | xxd -p -c 0" | ||
vk=$(dump_fail "$vk_cmd") | ||
local vkf_cmd="echo '$vk' | xxd -r -p | $BB $vk_as_fields_cmd -k - -o -" | ||
vk_fields=$(dump_fail "$vkf_cmd") | ||
jq -n --arg vk "$vk" --argjson vkf "$vk_fields" '{keyAsBytes: $vk, keyAsFields: $vkf}' > $key_path | ||
echo "Key output at: $key_path (${SECONDS}s)" | ||
} | ||
|
||
compile $1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
{ | ||
"name": "@aztec/bb-bench", | ||
"version": "0.1.0", | ||
"type": "module", | ||
"exports": { | ||
".": "./dest/index.js", | ||
"./types": "./dest/types/index.js" | ||
}, | ||
"inherits": [ | ||
"../package.common.json", | ||
"./package.local.json" | ||
], | ||
"scripts": { | ||
"build": "yarn clean && yarn generate && yarn build:app", | ||
"clean": "rm -rf ./dest .tsbuildinfo src/types artifacts", | ||
"generate": "yarn generate:artifacts && yarn generate:code", | ||
"generate:artifacts": "mkdir -p artifacts/keys && ls circuits | xargs -n 1 ./generate_artifacts.sh", | ||
"generate:code": "node --no-warnings --loader ts-node/esm src/scripts/generate_declaration_files.ts && node --no-warnings --loader ts-node/esm src/scripts/generate_ts_from_abi.ts && run -T prettier -w ./src/types", | ||
"build:ts": "tsc -b", | ||
"build:app": "tsc -b && rm -rf dest && webpack && cp ../../barretenberg/favicon.ico dest", | ||
"build:dev": "tsc -b --watch", | ||
"serve:app": "./serve.sh", | ||
"formatting": "run -T prettier --check ./src && run -T eslint ./src", | ||
"formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src", | ||
"formatting:fix:types": "NODE_OPTIONS='--max-old-space-size=8096' run -T eslint --fix ./src/types && run -T prettier -w ./src/types", | ||
"test": "HARDWARE_CONCURRENCY=${HARDWARE_CONCURRENCY:-16} RAYON_NUM_THREADS=${RAYON_NUM_THREADS:-4} NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}" | ||
}, | ||
"dependencies": { | ||
"@aztec/bb.js": "../../ts", | ||
"@aztec/foundation": "workspace:^", | ||
"@noir-lang/noir_codegen": "portal:../../noir/packages/noir_codegen", | ||
"@noir-lang/noir_js": "file:../../noir/packages/noir_js" | ||
}, | ||
"devDependencies": { | ||
"@aztec/bb-prover": "workspace:^", | ||
"@jest/globals": "^29.5.0", | ||
"@types/jest": "^29.5.0", | ||
"@types/node": "^22.8.1", | ||
"copy-webpack-plugin": "^12.0.2", | ||
"debug": "^4.3.4", | ||
"favicon-emoji": "2.3.1", | ||
"html-webpack-plugin": "^5.6.0", | ||
"jest": "^29.5.0", | ||
"resolve-typescript-plugin": "^2.0.1", | ||
"serve": "^14.2.1", | ||
"ts-loader": "^9.5.1", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.0.4", | ||
"webpack": "^5.90.3", | ||
"webpack-cli": "^5.1.4", | ||
"webpack-dev-server": "^5.0.3" | ||
}, | ||
"files": [ | ||
"dest", | ||
"src", | ||
"!*.test.*", | ||
"artifacts" | ||
], | ||
"types": "./dest/index.d.ts", | ||
"engines": { | ||
"node": ">=18" | ||
}, | ||
"jest": { | ||
"extensionsToTreatAsEsm": [ | ||
".ts" | ||
], | ||
"transform": { | ||
"^.+\\.tsx?$": [ | ||
"@swc/jest", | ||
{ | ||
"jsc": { | ||
"parser": { | ||
"syntax": "typescript", | ||
"decorators": true | ||
}, | ||
"transform": { | ||
"decoratorVersion": "2022-03" | ||
} | ||
} | ||
} | ||
] | ||
}, | ||
"moduleNameMapper": { | ||
"^(\\.{1,2}/.*)\\.[cm]?js$": "$1" | ||
}, | ||
"reporters": [ | ||
"default" | ||
], | ||
"testTimeout": 30000, | ||
"testRegex": "./src/.*\\.test\\.(js|mjs|ts)$", | ||
"rootDir": "./src", | ||
"setupFiles": [ | ||
"../../foundation/src/jest/setup.mjs" | ||
] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"scripts": { | ||
"build": "yarn clean && yarn generate && yarn build:app", | ||
"clean": "rm -rf ./dest .tsbuildinfo src/types artifacts", | ||
"build:app": "tsc -b && rm -rf dest && webpack && cp ../../barretenberg/favicon.ico dest" | ||
}, | ||
"files": ["dest", "src", "artifacts", "!*.test.*"] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why ignore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't track large files that will potentially change a lot because it causes the repo to grow in terms of disk space used, slows down
git clone
s etc.