From 46da3cc8a9c1c407a8ad2857695eea794e334efd Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Tue, 17 Dec 2024 08:29:32 +0100 Subject: [PATCH] feat: PXE browser proving (#10704) Closes: https://github.com/AztecProtocol/aztec-packages/issues/10587 - Imports `bb.js` as a prover for PXE, both in the browser and in the `cli-wallet` (if PXE_PROVER_ENABLED=1 but BB_WORKING_DIRECTORY and BB_BINARY_PATH are unset) - Splits `noir-protocol-circuits-types` so a `/client` bundle can be imported without all the public artifacts - Reenables vite box with proving since it doesn't run out of memory anymore --------- Co-authored-by: Cody Co-authored-by: ledwards2225 Co-authored-by: ludamad --- barretenberg/ts/package.json | 2 +- barretenberg/ts/src/barretenberg/index.ts | 2 +- barretenberg/ts/yarn.lock | 9 +- boxes/boxes/vite/.env | 1 + boxes/boxes/vite/package.json | 15 +- boxes/boxes/vite/src/config.ts | 17 +- boxes/boxes/vite/src/contracts/src/main.nr | 30 +- boxes/boxes/vite/vite.config.ts | 17 +- boxes/package.json | 6 +- boxes/yarn.lock | 647 +++++++++++-- noir/noir-repo/yarn.lock | 9 +- yarn-project/bb-prover/package.json | 3 + .../src/prover/bb_private_kernel_prover.ts | 138 +-- .../bb-prover/src/prover/bb_prover.ts | 3 +- .../src/prover/client_ivc_proof_utils.ts | 39 + yarn-project/bb-prover/src/prover/index.ts | 1 + .../bb-prover/src/verifier/bb_verifier.ts | 3 +- yarn-project/bb-prover/src/wasm/index.ts | 155 +++ .../src/interfaces/private_kernel_prover.ts | 9 - .../l1_payload/encrypted_log_payload.test.ts | 2 +- yarn-project/circuits.js/package.json | 3 +- .../circuits.js/src/hash/hash.test.ts | 3 +- .../circuits.js/src/hash/map_slot.test.ts | 2 +- .../circuits.js/src/keys/derivation.test.ts | 2 +- .../src/structs/block_header.test.ts | 3 +- .../src/structs/client_ivc_proof.ts | 38 - .../src/structs/tx_request.test.ts | 3 +- .../circuits.js/src/types/public_keys.test.ts | 2 +- yarn-project/circuits.js/tsconfig.json | 3 +- .../composed/integration_l1_publisher.test.ts | 7 +- .../contract_class_registration.test.ts | 2 +- .../end-to-end/src/e2e_p2p/p2p_network.ts | 5 +- .../end-to-end/src/e2e_prover/full.test.ts | 3 +- .../src/fixtures/snapshot_manager.ts | 13 +- yarn-project/end-to-end/src/fixtures/utils.ts | 7 +- .../end-to-end/src/spartan/4epochs.test.ts | 5 +- .../src/spartan/gating-passive.test.ts | 5 +- .../end-to-end/src/spartan/reorg.test.ts | 5 +- yarn-project/ethereum/src/eth_cheat_codes.ts | 28 - .../src/test/eth_cheat_codes_with_state.ts | 36 + yarn-project/ethereum/src/test/index.ts | 1 + yarn-project/foundation/.eslintrc.cjs | 2 +- yarn-project/foundation/package.json | 1 + .../foundation/src/fields/point.test.ts | 2 +- .../foundation/src/testing/files/index.ts | 76 ++ yarn-project/foundation/src/testing/index.ts | 2 +- .../foundation/src/testing/test_data.ts | 75 -- .../src/native_client_ivc_integration.test.ts | 16 +- yarn-project/noir-contracts.js/package.json | 2 +- .../noir-protocol-circuits-types/package.json | 4 +- .../src/artifacts.ts | 103 -- .../src/artifacts/client.ts | 38 + .../src/artifacts/index.ts | 14 + .../src/artifacts/server.ts | 60 ++ .../src/client.ts | 24 + .../src/execution/client.ts | 438 +++++++++ .../src/execution/index.ts | 2 + .../src/execution/server.ts | 397 ++++++++ .../noir-protocol-circuits-types/src/index.ts | 881 +----------------- .../src/utils/decoded_inputs.ts | 14 + .../src/utils/foreign_call_handler.ts | 66 ++ .../noir-protocol-circuits-types/src/vks.ts | 2 +- .../tsconfig.json | 3 +- yarn-project/protocol-contracts/package.json | 3 +- yarn-project/protocol-contracts/tsconfig.json | 3 +- .../src/test/bb_prover_full_rollup.test.ts | 3 +- yarn-project/pxe/src/kernel_oracle/index.ts | 2 +- ...ild_private_kernel_reset_private_inputs.ts | 2 +- .../src/kernel_prover/kernel_prover.test.ts | 7 - .../pxe/src/kernel_prover/kernel_prover.ts | 12 +- .../kernel_prover/test/test_circuit_prover.ts | 28 +- .../pxe/src/pxe_service/pxe_service.ts | 6 +- .../pxe/src/utils/create_pxe_service.ts | 11 +- yarn-project/simulator/src/client/index.ts | 1 + .../simulator/src/providers/acvm_wasm.ts | 2 +- yarn-project/simulator/src/providers/index.ts | 1 - yarn-project/yarn.lock | 4 +- 77 files changed, 2097 insertions(+), 1494 deletions(-) create mode 100644 boxes/boxes/vite/.env create mode 100644 yarn-project/bb-prover/src/prover/client_ivc_proof_utils.ts create mode 100644 yarn-project/bb-prover/src/wasm/index.ts create mode 100644 yarn-project/ethereum/src/test/eth_cheat_codes_with_state.ts create mode 100644 yarn-project/foundation/src/testing/files/index.ts delete mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/client.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/execution/client.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/execution/index.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/execution/server.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/utils/decoded_inputs.ts create mode 100644 yarn-project/noir-protocol-circuits-types/src/utils/foreign_call_handler.ts diff --git a/barretenberg/ts/package.json b/barretenberg/ts/package.json index 994d286a07d..8ccaf5540dc 100644 --- a/barretenberg/ts/package.json +++ b/barretenberg/ts/package.json @@ -53,7 +53,7 @@ }, "dependencies": { "comlink": "^4.4.1", - "commander": "^10.0.1", + "commander": "^12.1.0", "debug": "^4.3.4", "fflate": "^0.8.0", "pako": "^2.1.0", diff --git a/barretenberg/ts/src/barretenberg/index.ts b/barretenberg/ts/src/barretenberg/index.ts index 4c8097bb89b..688759c18bb 100644 --- a/barretenberg/ts/src/barretenberg/index.ts +++ b/barretenberg/ts/src/barretenberg/index.ts @@ -69,7 +69,7 @@ export class Barretenberg extends BarretenbergApi { async initSRSClientIVC(): Promise { // crsPath can be undefined const crs = await Crs.new(2 ** 20 + 1, this.options.crsPath); - const grumpkinCrs = await GrumpkinCrs.new(2 ** 14 + 1, this.options.crsPath); + const grumpkinCrs = await GrumpkinCrs.new(2 ** 15 + 1, this.options.crsPath); // Load CRS into wasm global CRS state. // TODO: Make RawBuffer be default behavior, and have a specific Vector type for when wanting length prefixed. diff --git a/barretenberg/ts/yarn.lock b/barretenberg/ts/yarn.lock index d375496453c..22aafa7eec4 100644 --- a/barretenberg/ts/yarn.lock +++ b/barretenberg/ts/yarn.lock @@ -38,7 +38,7 @@ __metadata: "@typescript-eslint/parser": ^5.54.1 buffer: ^6.0.3 comlink: ^4.4.1 - commander: ^10.0.1 + commander: ^12.1.0 copy-webpack-plugin: ^11.0.0 debug: ^4.3.4 eslint: ^8.35.0 @@ -2434,6 +2434,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^12.1.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 68e9818b00fc1ed9cdab9eb16905551c2b768a317ae69a5e3c43924c2b20ac9bb65b27e1cab36aeda7b6496376d4da908996ba2c0b5d79463e0fb1e77935d514 + languageName: node + linkType: hard + "commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" diff --git a/boxes/boxes/vite/.env b/boxes/boxes/vite/.env new file mode 100644 index 00000000000..6f73ed0c33b --- /dev/null +++ b/boxes/boxes/vite/.env @@ -0,0 +1 @@ +VITE_AZTEC_NODE_URL=http://localhost:8080 \ No newline at end of file diff --git a/boxes/boxes/vite/package.json b/boxes/boxes/vite/package.json index 2107b6c79ad..5d127569aef 100644 --- a/boxes/boxes/vite/package.json +++ b/boxes/boxes/vite/package.json @@ -16,6 +16,7 @@ "dependencies": { "@aztec/accounts": "portal:../../../yarn-project/accounts", "@aztec/aztec.js": "portal:../../../yarn-project/aztec.js", + "@aztec/bb-prover": "link:../../../yarn-project/bb-prover", "@aztec/circuit-types": "portal:../../../yarn-project/circuit-types", "@aztec/key-store": "link:../../../yarn-project/key-store", "@aztec/kv-store": "portal:../../../yarn-project/kv-store", @@ -31,18 +32,16 @@ "@eslint/js": "^9.13.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", - "@vitejs/plugin-react-swc": "^3.5.0", + "@vitejs/plugin-react-swc": "^3.7.2", "eslint": "^9.13.0", - "eslint-plugin-react-hooks": "^5.0.0", - "eslint-plugin-react-refresh": "^0.4.14", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.16", "globals": "^15.11.0", - "memfs": "^4.14.0", - "node-stdlib-browser": "^1.3.0", "typescript": "~5.6.2", "typescript-eslint": "^8.11.0", - "vite": "^5.4.10", - "vite-plugin-externalize-deps": "^0.8.0", + "vite": "^6.0.3", "vite-plugin-node-polyfills": "^0.22.0", + "vite-plugin-strip-block": "^1.0.1", "vite-plugin-top-level-await": "^1.4.4" } -} \ No newline at end of file +} diff --git a/boxes/boxes/vite/src/config.ts b/boxes/boxes/vite/src/config.ts index bced26cc094..734f450c80a 100644 --- a/boxes/boxes/vite/src/config.ts +++ b/boxes/boxes/vite/src/config.ts @@ -6,16 +6,21 @@ import { } from "@aztec/aztec.js"; import { BoxReactContractArtifact } from "../artifacts/BoxReact"; import { AccountManager } from "@aztec/aztec.js/account"; -import { SingleKeyAccountContract } from "@aztec/accounts/single_key"; +import { SchnorrAccountContract } from "@aztec/accounts/schnorr"; import { createAztecNodeClient } from "@aztec/aztec.js"; import { PXEService } from "@aztec/pxe/service"; import { PXEServiceConfig, getPXEServiceConfig } from "@aztec/pxe/config"; import { KVPxeDatabase } from "@aztec/pxe/database"; -import { TestPrivateKernelProver } from "@aztec/pxe/kernel_prover"; import { KeyStore } from "@aztec/key-store"; import { PrivateKernelProver } from "@aztec/circuit-types"; import { L2TipsStore } from "@aztec/kv-store/stores"; import { createStore } from "@aztec/kv-store/indexeddb"; +import { BBWasmPrivateKernelProver } from "@aztec/bb-prover/wasm"; + +process.env = Object.keys(import.meta.env).reduce((acc, key) => { + acc[key.replace("VITE_", "")] = import.meta.env[key]; + return acc; +}, {}); const SECRET_KEY = Fr.random(); @@ -33,17 +38,18 @@ export class PrivateEnv { const config = getPXEServiceConfig(); config.dataDirectory = "pxe"; const aztecNode = await createAztecNodeClient(this.nodeURL); - const proofCreator = new TestPrivateKernelProver(); + const proofCreator = new BBWasmPrivateKernelProver(16); this.pxe = await this.createPXEService(aztecNode, config, proofCreator); const encryptionPrivateKey = deriveMasterIncomingViewingSecretKey( this.secretKey, ); - this.accountContract = new SingleKeyAccountContract(encryptionPrivateKey); + this.accountContract = new SchnorrAccountContract(encryptionPrivateKey); this.account = new AccountManager( this.pxe, this.secretKey, this.accountContract, ); + await this.account.deploy().wait(); } async createPXEService( @@ -81,14 +87,13 @@ export class PrivateEnv { } async getWallet() { - // taking advantage that register is no-op if already registered return await this.account.register(); } } export const deployerEnv = new PrivateEnv( SECRET_KEY, - process.env.PXE_URL || "http://localhost:8080", + process.env.AZTEC_NODE_URL, ); const IGNORE_FUNCTIONS = [ diff --git a/boxes/boxes/vite/src/contracts/src/main.nr b/boxes/boxes/vite/src/contracts/src/main.nr index f4924981e8e..6955a87ecb4 100644 --- a/boxes/boxes/vite/src/contracts/src/main.nr +++ b/boxes/boxes/vite/src/contracts/src/main.nr @@ -3,11 +3,9 @@ use dep::aztec::macros::aztec; #[aztec] contract BoxReact { use dep::aztec::{ - protocol_types::public_keys::OvpkM, - keys::getters::get_public_keys, - prelude::{AztecAddress, PrivateMutable, Map, NoteInterface, NoteHeader, Point}, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, - macros::{storage::storage, functions::{private, public, initializer}} + macros::{functions::{initializer, private}, storage::storage}, + prelude::{AztecAddress, Map, PrivateMutable}, }; use dep::value_note::value_note::ValueNote; @@ -18,27 +16,27 @@ contract BoxReact { #[private] #[initializer] - fn constructor( - number: Field, - owner: AztecAddress - ) { + fn constructor(number: Field, owner: AztecAddress) { let numbers = storage.numbers; let mut new_number = ValueNote::new(number, owner); - let owner_ovpk_m = get_public_keys(owner).ovpk_m; - numbers.at(owner).initialize(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner_ovpk_m, owner, context.msg_sender())); + numbers.at(owner).initialize(&mut new_number).emit(encode_and_encrypt_note( + &mut context, + owner, + context.msg_sender(), + )); } #[private] - fn setNumber( - number: Field, - owner: AztecAddress - ) { + fn setNumber(number: Field, owner: AztecAddress) { let numbers = storage.numbers; let mut new_number = ValueNote::new(number, owner); - let owner_ovpk_m = get_public_keys(owner).ovpk_m; - numbers.at(owner).replace(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner_ovpk_m, owner, context.msg_sender())); + numbers.at(owner).replace(&mut new_number).emit(encode_and_encrypt_note( + &mut context, + owner, + context.msg_sender(), + )); } unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote { diff --git a/boxes/boxes/vite/vite.config.ts b/boxes/boxes/vite/vite.config.ts index eb101d8e821..ef09a7d9e67 100644 --- a/boxes/boxes/vite/vite.config.ts +++ b/boxes/boxes/vite/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; import { PolyfillOptions, nodePolyfills } from "vite-plugin-node-polyfills"; import topLevelAwait from "vite-plugin-top-level-await"; +import stripBlock from "vite-plugin-strip-block"; // Unfortunate, but needed due to https://github.com/davidmyersdev/vite-plugin-node-polyfills/issues/81 // Suspected to be because of the yarn workspace setup, but not sure @@ -23,17 +24,19 @@ const nodePolyfillsFix = (options?: PolyfillOptions | undefined): Plugin => { // https://vite.dev/config/ export default defineConfig({ + server: { + headers: { + "Cross-Origin-Opener-Policy": "same-origin", + "Cross-Origin-Embedder-Policy": "require-corp", + }, + }, plugins: [ + stripBlock({ start: "testing-only-start", end: "testing-only-end" }), react(), - nodePolyfillsFix({ - overrides: { - fs: "memfs", - buffer: "buffer/", - }, - }), + nodePolyfillsFix({ include: ["buffer", "process", "path"] }), topLevelAwait(), ], optimizeDeps: { - exclude: ["@noir-lang/acvm_js", "@noir-lang/noirc_abi"], + exclude: ["@noir-lang/acvm_js", "@noir-lang/noirc_abi", "@aztec/bb-prover"], }, }); diff --git a/boxes/package.json b/boxes/package.json index a904d9b967b..7cd31f064ca 100644 --- a/boxes/package.json +++ b/boxes/package.json @@ -4,8 +4,8 @@ "version": "0.5.0", "type": "module", "scripts": { - "compile": "yarn workspaces foreach --exclude vite -A -v run compile", - "build": "yarn workspaces foreach --exclude vite -A -v run build", + "compile": "yarn workspaces foreach -A -v run compile", + "build": "yarn workspaces foreach -A -v run build", "install-browsers": "playwright install --with-deps", "publish": "yarn npm publish", "test": "vitest bin.test.js", @@ -43,4 +43,4 @@ "devDependencies": { "@playwright/test": "1.46.1" } -} \ No newline at end of file +} diff --git a/boxes/yarn.lock b/boxes/yarn.lock index 5be00301898..69d40a3842c 100644 --- a/boxes/yarn.lock +++ b/boxes/yarn.lock @@ -27,6 +27,12 @@ __metadata: languageName: node linkType: soft +"@aztec/bb-prover@link:../../../yarn-project/bb-prover::locator=vite%40workspace%3Aboxes%2Fvite": + version: 0.0.0-use.local + resolution: "@aztec/bb-prover@link:../../../yarn-project/bb-prover::locator=vite%40workspace%3Aboxes%2Fvite" + languageName: node + linkType: soft + "@aztec/builder@npm:latest": version: 0.63.1 resolution: "@aztec/builder@npm:0.63.1" @@ -553,6 +559,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/aix-ppc64@npm:0.24.0" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm64@npm:0.21.5" @@ -560,6 +573,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/android-arm64@npm:0.24.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm@npm:0.21.5" @@ -567,6 +587,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/android-arm@npm:0.24.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-x64@npm:0.21.5" @@ -574,6 +601,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/android-x64@npm:0.24.0" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-arm64@npm:0.21.5" @@ -581,6 +615,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/darwin-arm64@npm:0.24.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-x64@npm:0.21.5" @@ -588,6 +629,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/darwin-x64@npm:0.24.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-arm64@npm:0.21.5" @@ -595,6 +643,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/freebsd-arm64@npm:0.24.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-x64@npm:0.21.5" @@ -602,6 +657,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/freebsd-x64@npm:0.24.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm64@npm:0.21.5" @@ -609,6 +671,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-arm64@npm:0.24.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm@npm:0.21.5" @@ -616,6 +685,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-arm@npm:0.24.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ia32@npm:0.21.5" @@ -623,6 +699,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-ia32@npm:0.24.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-loong64@npm:0.21.5" @@ -630,6 +713,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-loong64@npm:0.24.0" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-mips64el@npm:0.21.5" @@ -637,6 +727,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-mips64el@npm:0.24.0" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ppc64@npm:0.21.5" @@ -644,6 +741,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-ppc64@npm:0.24.0" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-riscv64@npm:0.21.5" @@ -651,6 +755,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-riscv64@npm:0.24.0" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-s390x@npm:0.21.5" @@ -658,6 +769,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-s390x@npm:0.24.0" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-x64@npm:0.21.5" @@ -665,6 +783,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/linux-x64@npm:0.24.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/netbsd-x64@npm:0.21.5" @@ -672,6 +797,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/netbsd-x64@npm:0.24.0" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/openbsd-arm64@npm:0.24.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/openbsd-x64@npm:0.21.5" @@ -679,6 +818,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/openbsd-x64@npm:0.24.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/sunos-x64@npm:0.21.5" @@ -686,6 +832,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/sunos-x64@npm:0.24.0" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-arm64@npm:0.21.5" @@ -693,6 +846,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/win32-arm64@npm:0.24.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-ia32@npm:0.21.5" @@ -700,6 +860,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/win32-ia32@npm:0.24.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-x64@npm:0.21.5" @@ -707,6 +874,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.24.0": + version: 0.24.0 + resolution: "@esbuild/win32-x64@npm:0.24.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.1 resolution: "@eslint-community/eslint-utils@npm:4.4.1" @@ -1274,38 +1448,6 @@ __metadata: languageName: node linkType: hard -"@jsonjoy.com/base64@npm:^1.1.1": - version: 1.1.2 - resolution: "@jsonjoy.com/base64@npm:1.1.2" - peerDependencies: - tslib: 2 - checksum: 88717945f66dc89bf58ce75624c99fe6a5c9a0c8614e26d03e406447b28abff80c69fb37dabe5aafef1862cf315071ae66e5c85f6018b437d95f8d13d235e6eb - languageName: node - linkType: hard - -"@jsonjoy.com/json-pack@npm:^1.0.3": - version: 1.1.0 - resolution: "@jsonjoy.com/json-pack@npm:1.1.0" - dependencies: - "@jsonjoy.com/base64": "npm:^1.1.1" - "@jsonjoy.com/util": "npm:^1.1.2" - hyperdyperid: "npm:^1.2.0" - thingies: "npm:^1.20.0" - peerDependencies: - tslib: 2 - checksum: cdf5cb567a7f2e703d4966a3e3a5f7f7b54ee40a2102aa0ede5c79bcf2060c8465d82f39de8583db4cf1d8415bec8e57dfb1156ef663567b846cdea45813d9d1 - languageName: node - linkType: hard - -"@jsonjoy.com/util@npm:^1.1.2, @jsonjoy.com/util@npm:^1.3.0": - version: 1.5.0 - resolution: "@jsonjoy.com/util@npm:1.5.0" - peerDependencies: - tslib: 2 - checksum: 0065ae12c4108d8aede01a479c8d2b5a39bce99e9a449d235befc753f57e8385d9c1115720529f26597840b7398d512898155423d9859fd638319fb0c827365d - languageName: node - linkType: hard - "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.5 resolution: "@leichtgewicht/ip-codec@npm:2.0.5" @@ -1541,6 +1683,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.28.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-android-arm64@npm:4.27.3" @@ -1548,6 +1697,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-android-arm64@npm:4.28.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-darwin-arm64@npm:4.27.3" @@ -1555,6 +1711,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.28.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-darwin-x64@npm:4.27.3" @@ -1562,6 +1725,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.28.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-freebsd-arm64@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-freebsd-arm64@npm:4.27.3" @@ -1569,6 +1739,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-arm64@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.28.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-freebsd-x64@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-freebsd-x64@npm:4.27.3" @@ -1576,6 +1753,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-x64@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-freebsd-x64@npm:4.28.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.27.3" @@ -1583,6 +1767,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.28.1" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-musleabihf@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.27.3" @@ -1590,6 +1781,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-musleabihf@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.28.1" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.27.3" @@ -1597,6 +1795,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.28.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.27.3" @@ -1604,6 +1809,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.28.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loongarch64-gnu@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.28.1" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-powerpc64le-gnu@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.27.3" @@ -1611,6 +1830,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.28.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.27.3" @@ -1618,6 +1844,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.28.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-s390x-gnu@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.27.3" @@ -1625,6 +1858,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-s390x-gnu@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.28.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.27.3" @@ -1632,6 +1872,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.28.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-linux-x64-musl@npm:4.27.3" @@ -1639,6 +1886,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.28.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.27.3" @@ -1646,6 +1900,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.28.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.27.3" @@ -1653,6 +1914,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.28.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.27.3": version: 4.27.3 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.27.3" @@ -1660,6 +1928,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.28.1": + version: 4.28.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.28.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -2523,14 +2798,14 @@ __metadata: languageName: node linkType: hard -"@vitejs/plugin-react-swc@npm:^3.5.0": - version: 3.7.1 - resolution: "@vitejs/plugin-react-swc@npm:3.7.1" +"@vitejs/plugin-react-swc@npm:^3.7.2": + version: 3.7.2 + resolution: "@vitejs/plugin-react-swc@npm:3.7.2" dependencies: "@swc/core": "npm:^1.7.26" peerDependencies: - vite: ^4 || ^5 - checksum: 2d613e69c0d0b809c94df80ca2b0caf39c50f0b98aa1f8599fd086bc37dac1449898eb6572000e1c133313137cac93440c4cb0861e05820c78bd2c07a52e64a8 + vite: ^4 || ^5 || ^6 + checksum: 9b9a5e0540791ba96a9fe4e8b8146ab274edcc730315535705f20126d6dfaffe72ae474bac9904ce841976e1959b6ecffd047bb2f0b7abf4d85aae7fbfdd00ab languageName: node linkType: hard @@ -5052,6 +5327,89 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.24.0": + version: 0.24.0 + resolution: "esbuild@npm:0.24.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.24.0" + "@esbuild/android-arm": "npm:0.24.0" + "@esbuild/android-arm64": "npm:0.24.0" + "@esbuild/android-x64": "npm:0.24.0" + "@esbuild/darwin-arm64": "npm:0.24.0" + "@esbuild/darwin-x64": "npm:0.24.0" + "@esbuild/freebsd-arm64": "npm:0.24.0" + "@esbuild/freebsd-x64": "npm:0.24.0" + "@esbuild/linux-arm": "npm:0.24.0" + "@esbuild/linux-arm64": "npm:0.24.0" + "@esbuild/linux-ia32": "npm:0.24.0" + "@esbuild/linux-loong64": "npm:0.24.0" + "@esbuild/linux-mips64el": "npm:0.24.0" + "@esbuild/linux-ppc64": "npm:0.24.0" + "@esbuild/linux-riscv64": "npm:0.24.0" + "@esbuild/linux-s390x": "npm:0.24.0" + "@esbuild/linux-x64": "npm:0.24.0" + "@esbuild/netbsd-x64": "npm:0.24.0" + "@esbuild/openbsd-arm64": "npm:0.24.0" + "@esbuild/openbsd-x64": "npm:0.24.0" + "@esbuild/sunos-x64": "npm:0.24.0" + "@esbuild/win32-arm64": "npm:0.24.0" + "@esbuild/win32-ia32": "npm:0.24.0" + "@esbuild/win32-x64": "npm:0.24.0" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 9f1aadd8d64f3bff422ae78387e66e51a5e09de6935a6f987b6e4e189ed00fdc2d1bc03d2e33633b094008529c8b6e06c7ad1a9782fb09fec223bf95998c0683 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -5197,16 +5555,25 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^5.0.0": - version: 5.0.0 - resolution: "eslint-plugin-react-hooks@npm:5.0.0" +"eslint-plugin-react-hooks@npm:^5.1.0": + version: 5.1.0 + resolution: "eslint-plugin-react-hooks@npm:5.1.0" peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - checksum: bcb74b421f32e4203a7100405b57aab85526be4461e5a1da01bc537969a30012d2ee209a2c2a6cac543833a27188ce1e6ad71e4628d0bb4a2e5365cad86c5002 + checksum: 37ef76e1d916d46ab8e93a596078efcf2162e2c653614437e0c54e31d02a5dadabec22802fab717effe257aeb4bdc20c2a710666a89ab1cf07e01e614dde75d8 languageName: node linkType: hard -"eslint-plugin-react-refresh@npm:^0.4.14, eslint-plugin-react-refresh@npm:^0.4.3": +"eslint-plugin-react-refresh@npm:^0.4.16": + version: 0.4.16 + resolution: "eslint-plugin-react-refresh@npm:0.4.16" + peerDependencies: + eslint: ">=8.40" + checksum: 0628d54b6cc6773a89252e2a7c82c7905a00dc8dc99a6ae2885a64f3b45bd3012a40cf9791ee24aa5dcf75665d8c8be4699845bbbf205cd0ef652702701a7865 + languageName: node + linkType: hard + +"eslint-plugin-react-refresh@npm:^0.4.3": version: 0.4.14 resolution: "eslint-plugin-react-refresh@npm:0.4.14" peerDependencies: @@ -6527,13 +6894,6 @@ __metadata: languageName: node linkType: hard -"hyperdyperid@npm:^1.2.0": - version: 1.2.0 - resolution: "hyperdyperid@npm:1.2.0" - checksum: 885ba3177c7181d315a856ee9c0005ff8eb5dcb1ce9e9d61be70987895d934d84686c37c981cceeb53216d4c9c15c1cc25f1804e84cc6a74a16993c5d7fd0893 - languageName: node - linkType: hard - "iconv-lite@npm:0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" @@ -8041,18 +8401,6 @@ __metadata: languageName: node linkType: hard -"memfs@npm:^4.14.0": - version: 4.14.0 - resolution: "memfs@npm:4.14.0" - dependencies: - "@jsonjoy.com/json-pack": "npm:^1.0.3" - "@jsonjoy.com/util": "npm:^1.3.0" - tree-dump: "npm:^1.0.1" - tslib: "npm:^2.0.0" - checksum: d1de2e4b3c269f5b5f27b63f60bb8ea9ae5800843776e0bed4548f2957dcd55237ac5eab3a5ffe0d561a6be53e42c055a7bc79efc1613563b14e14c287ef3b0a - languageName: node - linkType: hard - "merge-descriptors@npm:1.0.3": version: 1.0.3 resolution: "merge-descriptors@npm:1.0.3" @@ -8508,7 +8856,7 @@ __metadata: languageName: node linkType: hard -"node-stdlib-browser@npm:^1.2.0, node-stdlib-browser@npm:^1.3.0": +"node-stdlib-browser@npm:^1.2.0": version: 1.3.0 resolution: "node-stdlib-browser@npm:1.3.0" dependencies: @@ -9221,7 +9569,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.29, postcss@npm:^8.4.33, postcss@npm:^8.4.43": +"postcss@npm:^8.4.29, postcss@npm:^8.4.33, postcss@npm:^8.4.43, postcss@npm:^8.4.49": version: 8.4.49 resolution: "postcss@npm:8.4.49" dependencies: @@ -9893,6 +10241,78 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.23.0": + version: 4.28.1 + resolution: "rollup@npm:4.28.1" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.28.1" + "@rollup/rollup-android-arm64": "npm:4.28.1" + "@rollup/rollup-darwin-arm64": "npm:4.28.1" + "@rollup/rollup-darwin-x64": "npm:4.28.1" + "@rollup/rollup-freebsd-arm64": "npm:4.28.1" + "@rollup/rollup-freebsd-x64": "npm:4.28.1" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.28.1" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.28.1" + "@rollup/rollup-linux-arm64-gnu": "npm:4.28.1" + "@rollup/rollup-linux-arm64-musl": "npm:4.28.1" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.28.1" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.28.1" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.28.1" + "@rollup/rollup-linux-s390x-gnu": "npm:4.28.1" + "@rollup/rollup-linux-x64-gnu": "npm:4.28.1" + "@rollup/rollup-linux-x64-musl": "npm:4.28.1" + "@rollup/rollup-win32-arm64-msvc": "npm:4.28.1" + "@rollup/rollup-win32-ia32-msvc": "npm:4.28.1" + "@rollup/rollup-win32-x64-msvc": "npm:4.28.1" + "@types/estree": "npm:1.0.6" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 2d2d0433b7cb53153a04c7b406f342f31517608dc57510e49177941b9e68c30071674b83a0292ef1d87184e5f7c6d0f2945c8b3c74963074de10c75366fe2c14 + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -10744,15 +11164,6 @@ __metadata: languageName: node linkType: hard -"thingies@npm:^1.20.0": - version: 1.21.0 - resolution: "thingies@npm:1.21.0" - peerDependencies: - tslib: ^2 - checksum: 7570ee855aecb73185a672ecf3eb1c287a6512bf5476449388433b2d4debcf78100bc8bfd439b0edd38d2bc3bfb8341de5ce85b8557dec66d0f27b962c9a8bc1 - languageName: node - linkType: hard - "thread-stream@npm:^2.6.0": version: 2.7.0 resolution: "thread-stream@npm:2.7.0" @@ -10887,15 +11298,6 @@ __metadata: languageName: node linkType: hard -"tree-dump@npm:^1.0.1": - version: 1.0.2 - resolution: "tree-dump@npm:1.0.2" - peerDependencies: - tslib: 2 - checksum: d1d180764e9c691b28332dbd74226c6b6af361dfb1e134bb11e60e17cb11c215894adee50ffc578da5dcf546006693947be8b6665eb1269b56e2f534926f1c1f - languageName: node - linkType: hard - "ts-api-utils@npm:^1.0.1, ts-api-utils@npm:^1.3.0": version: 1.4.0 resolution: "ts-api-utils@npm:1.4.0" @@ -11351,15 +11753,6 @@ __metadata: languageName: node linkType: hard -"vite-plugin-externalize-deps@npm:^0.8.0": - version: 0.8.0 - resolution: "vite-plugin-externalize-deps@npm:0.8.0" - peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: 0ed0d2a85f96e6470b700c1a598de9e3b189b186f7a3d05e4e945c0381bb2717dce5a40de5d6b485ec8e30f31ff33b17d56d487f618395d7b55ad7ef74d35ca3 - languageName: node - linkType: hard - "vite-plugin-node-polyfills@npm:^0.22.0": version: 0.22.0 resolution: "vite-plugin-node-polyfills@npm:0.22.0" @@ -11372,6 +11765,13 @@ __metadata: languageName: node linkType: hard +"vite-plugin-strip-block@npm:^1.0.1": + version: 1.0.1 + resolution: "vite-plugin-strip-block@npm:1.0.1" + checksum: 4302a035fbcaff8c5cfdffeedfd7c61d9b7198aeac1123cdadc00770db1d4828e7b780ce3a84106c786e771eb47c60289a694283c95702819f6f909c21bc3bbe + languageName: node + linkType: hard + "vite-plugin-top-level-await@npm:^1.4.4": version: 1.4.4 resolution: "vite-plugin-top-level-await@npm:1.4.4" @@ -11385,7 +11785,7 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.0, vite@npm:^5.4.10": +"vite@npm:^5.0.0": version: 5.4.11 resolution: "vite@npm:5.4.11" dependencies: @@ -11428,12 +11828,65 @@ __metadata: languageName: node linkType: hard +"vite@npm:^6.0.3": + version: 6.0.3 + resolution: "vite@npm:6.0.3" + dependencies: + esbuild: "npm:^0.24.0" + fsevents: "npm:~2.3.3" + postcss: "npm:^8.4.49" + rollup: "npm:^4.23.0" + peerDependencies: + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: ">=1.21.0" + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 764ebed14770426a638575b23a51127c630ace873999ab896b0184484d8107e7255cdf64cfb36c65c1ef1d583e44b70a1d14c0f05b89612e834a5806e3964475 + languageName: node + linkType: hard + "vite@workspace:boxes/vite": version: 0.0.0-use.local resolution: "vite@workspace:boxes/vite" dependencies: "@aztec/accounts": "portal:../../../yarn-project/accounts" "@aztec/aztec.js": "portal:../../../yarn-project/aztec.js" + "@aztec/bb-prover": "link:../../../yarn-project/bb-prover" "@aztec/circuit-types": "portal:../../../yarn-project/circuit-types" "@aztec/key-store": "link:../../../yarn-project/key-store" "@aztec/kv-store": "portal:../../../yarn-project/kv-store" @@ -11443,22 +11896,20 @@ __metadata: "@noir-lang/noirc_abi": "link:../../../noir/packages/noirc_abi" "@types/react": "npm:^18.3.12" "@types/react-dom": "npm:^18.3.1" - "@vitejs/plugin-react-swc": "npm:^3.5.0" + "@vitejs/plugin-react-swc": "npm:^3.7.2" buffer: "npm:^6.0.3" eslint: "npm:^9.13.0" - eslint-plugin-react-hooks: "npm:^5.0.0" - eslint-plugin-react-refresh: "npm:^0.4.14" + eslint-plugin-react-hooks: "npm:^5.1.0" + eslint-plugin-react-refresh: "npm:^0.4.16" globals: "npm:^15.11.0" - memfs: "npm:^4.14.0" - node-stdlib-browser: "npm:^1.3.0" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" react-toastify: "npm:^10.0.6" typescript: "npm:~5.6.2" typescript-eslint: "npm:^8.11.0" - vite: "npm:^5.4.10" - vite-plugin-externalize-deps: "npm:^0.8.0" + vite: "npm:^6.0.3" vite-plugin-node-polyfills: "npm:^0.22.0" + vite-plugin-strip-block: "npm:^1.0.1" vite-plugin-top-level-await: "npm:^1.4.4" languageName: unknown linkType: soft diff --git a/noir/noir-repo/yarn.lock b/noir/noir-repo/yarn.lock index 3c8df2b1772..07b6b677b62 100644 --- a/noir/noir-repo/yarn.lock +++ b/noir/noir-repo/yarn.lock @@ -226,7 +226,7 @@ __metadata: resolution: "@aztec/bb.js@portal:../../../../barretenberg/ts::locator=integration-tests%40workspace%3Acompiler%2Fintegration-tests" dependencies: comlink: ^4.4.1 - commander: ^10.0.1 + commander: ^12.1.0 debug: ^4.3.4 fflate: ^0.8.0 pako: ^2.1.0 @@ -9822,6 +9822,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^12.1.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 68e9818b00fc1ed9cdab9eb16905551c2b768a317ae69a5e3c43924c2b20ac9bb65b27e1cab36aeda7b6496376d4da908996ba2c0b5d79463e0fb1e77935d514 + languageName: node + linkType: hard + "commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" diff --git a/yarn-project/bb-prover/package.json b/yarn-project/bb-prover/package.json index 9dff8dc8a80..82b623c73a9 100644 --- a/yarn-project/bb-prover/package.json +++ b/yarn-project/bb-prover/package.json @@ -4,6 +4,7 @@ "type": "module", "exports": { ".": "./dest/index.js", + "./wasm": "./dest/wasm/index.js", "./prover": "./dest/prover/index.js", "./verifier": "./dest/verifier/index.js", "./test": "./dest/test/index.js" @@ -69,6 +70,7 @@ ] }, "dependencies": { + "@aztec/bb.js": "portal:../../barretenberg/ts", "@aztec/circuit-types": "workspace:^", "@aztec/circuits.js": "workspace:^", "@aztec/foundation": "workspace:^", @@ -80,6 +82,7 @@ "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi", "@noir-lang/types": "portal:../../noir/packages/types", "commander": "^12.1.0", + "pako": "^2.1.0", "source-map-support": "^0.5.21", "tslib": "^2.4.0" }, diff --git a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts index 3925723b351..2d70f5726eb 100644 --- a/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts @@ -1,22 +1,14 @@ +import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types'; +import { type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; import { - type AppCircuitSimulateOutput, - type PrivateKernelProver, - type PrivateKernelSimulateOutput, -} from '@aztec/circuit-types'; -import { type CircuitSimulationStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats'; -import { - AGGREGATION_OBJECT_LENGTH, - ClientIvcProof, - Fr, + type ClientIvcProof, type PrivateKernelCircuitPublicInputs, type PrivateKernelInitCircuitPrivateInputs, type PrivateKernelInnerCircuitPrivateInputs, type PrivateKernelResetCircuitPrivateInputs, type PrivateKernelTailCircuitPrivateInputs, type PrivateKernelTailCircuitPublicInputs, - Proof, - RecursiveProof, - type VerificationKeyAsFields, + type Proof, type VerificationKeyData, } from '@aztec/circuits.js'; import { runInDirectory } from '@aztec/foundation/fs'; @@ -48,19 +40,12 @@ import { type WitnessMap } from '@noir-lang/types'; import { promises as fs } from 'fs'; import path from 'path'; -import { - BB_RESULT, - PROOF_FIELDS_FILENAME, - PROOF_FILENAME, - computeGateCountForCircuit, - computeVerificationKey, - executeBbClientIvcProof, - verifyProof, -} from '../bb/execute.js'; +import { BB_RESULT, computeGateCountForCircuit, executeBbClientIvcProof, verifyProof } from '../bb/execute.js'; import { type BBConfig } from '../config.js'; import { type UltraHonkFlavor, getUltraHonkFlavorForCircuit } from '../honk.js'; import { mapProtocolArtifactNameToCircuitName } from '../stats.js'; import { extractVkData } from '../verification_key/verification_key_data.js'; +import { readFromOutputDirectory } from './client_ivc_proof_utils.js'; /** * This proof creator implementation uses the native bb binary. @@ -112,7 +97,7 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver { throw new Error(provingResult.reason); } - const proof = await ClientIvcProof.readFromOutputDirectory(directory); + const proof = await readFromOutputDirectory(directory); this.log.info(`Generated IVC proof`, { duration: provingResult.durationMs, @@ -184,22 +169,6 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver { ); } - public async computeAppCircuitVerificationKey( - bytecode: Buffer, - appCircuitName?: string, - ): Promise { - const operation = async (directory: string) => { - this.log.debug(`Proving app circuit`); - // App circuits are always recursive; the #[recursive] attribute used to be applied automatically - // by the `private` comptime macro in noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr - // Yet, inside `computeVerificationKey` the `mega_honk` flavor is used, which doesn't use the recursive flag. - const recursive = true; - return await this.computeVerificationKey(directory, bytecode, recursive, 'App', appCircuitName); - }; - - return await this.runInDirectory(operation); - } - /** * Verifies a proof, will generate the verification key if one is not cached internally * @param circuitType - The type of circuit whose proof is to be verified @@ -313,99 +282,6 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver { return kernelOutput; } - private async computeVerificationKey( - directory: string, - bytecode: Buffer, - recursive: boolean, - circuitType: ClientProtocolArtifact | 'App', - appCircuitName?: string, - ): Promise<{ - verificationKey: VerificationKeyAsFields; - }> { - const dbgCircuitName = appCircuitName ? `(${appCircuitName})` : ''; - this.log.info(`Computing VK of ${circuitType}${dbgCircuitName} circuit...`); - - const timer = new Timer(); - - const vkResult = await computeVerificationKey( - this.bbBinaryPath, - directory, - circuitType, - bytecode, - recursive, - circuitType === 'App' ? 'mega_honk' : getUltraHonkFlavorForCircuit(circuitType), - this.log.debug, - ); - - if (vkResult.status === BB_RESULT.FAILURE) { - this.log.error(`Failed to generate verification key for ${circuitType}${dbgCircuitName}: ${vkResult.reason}`); - throw new Error(vkResult.reason); - } - - this.log.info(`Generated ${circuitType}${dbgCircuitName} VK in ${Math.ceil(timer.ms())} ms`); - - if (circuitType === 'App') { - const vkData = await extractVkData(directory); - - this.log.debug(`Computed verification key`, { - circuitName: 'app-circuit', - duration: vkResult.durationMs, - eventName: 'circuit-simulation', - inputSize: bytecode.length, - outputSize: vkData.keyAsBytes.length, - circuitSize: vkData.circuitSize, - numPublicInputs: vkData.numPublicInputs, - } as CircuitSimulationStats); - - return { verificationKey: vkData.keyAsFields }; - } - - const vkData = await this.updateVerificationKeyAfterSimulation(directory, circuitType); - - this.log.debug(`Computed verification key`, { - circuitName: mapProtocolArtifactNameToCircuitName(circuitType), - duration: vkResult.durationMs, - eventName: 'circuit-simulation', - inputSize: bytecode.length, - outputSize: vkData.keyAsBytes.length, - circuitSize: vkData.circuitSize, - numPublicInputs: vkData.numPublicInputs, - } as CircuitSimulationStats); - - return { verificationKey: vkData.keyAsFields }; - } - - /** - * Parses and returns the proof data stored at the specified directory - * @param filePath - The directory containing the proof data - * @param circuitType - The type of circuit proven - * @returns The proof - */ - private async readProofAsFields( - filePath: string, - circuitType: ClientProtocolArtifact | 'App', - vkData: VerificationKeyData, - ): Promise> { - const [binaryProof, proofString] = await Promise.all([ - fs.readFile(`${filePath}/${PROOF_FILENAME}`), - fs.readFile(`${filePath}/${PROOF_FIELDS_FILENAME}`, { encoding: 'utf-8' }), - ]); - const json = JSON.parse(proofString); - const fields = json.map(Fr.fromHexString); - const numPublicInputs = vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH; - const fieldsWithoutPublicInputs = fields.slice(numPublicInputs); - this.log.info( - `Circuit type: ${circuitType}, complete proof length: ${fields.length}, without public inputs: ${fieldsWithoutPublicInputs.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}, is recursive: ${vkData.isRecursive}, raw length: ${binaryProof.length}`, - ); - const proof = new RecursiveProof( - fieldsWithoutPublicInputs, - new Proof(binaryProof, vkData.numPublicInputs), - true, - fieldsWithoutPublicInputs.length, - ); - return proof; - } - private runInDirectory(fn: (dir: string) => Promise) { const log = this.log; return runInDirectory( diff --git a/yarn-project/bb-prover/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts index 7deae9e16ff..62391579ed8 100644 --- a/yarn-project/bb-prover/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -99,6 +99,7 @@ import { type UltraHonkFlavor, getUltraHonkFlavorForCircuit } from '../honk.js'; import { ProverInstrumentation } from '../instrumentation.js'; import { mapProtocolArtifactNameToCircuitName } from '../stats.js'; import { extractAvmVkData, extractVkData } from '../verification_key/verification_key_data.js'; +import { writeToOutputDirectory } from './client_ivc_proof_utils.js'; const logger = createLogger('bb-prover'); @@ -551,7 +552,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { const hasher = crypto.createHash('sha256'); hasher.update(input.toBuffer()); - await input.clientIVCData.writeToOutputDirectory(bbWorkingDirectory); + await writeToOutputDirectory(input.clientIVCData, bbWorkingDirectory); const provingResult = await generateTubeProof(this.config.bbBinaryPath, bbWorkingDirectory, logger.verbose); if (provingResult.status === BB_RESULT.FAILURE) { diff --git a/yarn-project/bb-prover/src/prover/client_ivc_proof_utils.ts b/yarn-project/bb-prover/src/prover/client_ivc_proof_utils.ts new file mode 100644 index 00000000000..ba604dc6866 --- /dev/null +++ b/yarn-project/bb-prover/src/prover/client_ivc_proof_utils.ts @@ -0,0 +1,39 @@ +import { ClientIvcProof } from '@aztec/circuits.js'; + +import { promises as fs } from 'fs'; +import { join } from 'path'; + +/** + * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs + * Create a ClientIvcProof from the result of client_ivc_prove_output_all or client_ivc_prove_output_all_msgpack + * @param directory the directory of results + * @returns the encapsulated client ivc proof + */ +export async function readFromOutputDirectory(directory: string) { + const [clientIvcVkBuffer, clientIvcProofBuffer] = await Promise.all( + ['client_ivc_vk', 'client_ivc_proof'].map(fileName => fs.readFile(join(directory, fileName))), + ); + return new ClientIvcProof(clientIvcProofBuffer, clientIvcVkBuffer); +} + +/** + * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs + * Serialize a ClientIvcProof to the files expected by prove_tube + * + * Example usage: + * await runInDirectory(bbWorkingDirectory, async (dir: string) => { + * await privateTx.clientIvcProof!.writeToOutputDirectory(bbWorkingDirectory); + * const result = await generateTubeProof(bbPath, dir, logger.info) + * expect(result.status).toBe(BB_RESULT.SUCCESS) + * }); + * @param proof the ClientIvcProof from readFromOutputDirectory + * @param directory the directory of results + */ +export async function writeToOutputDirectory(clientIvcProof: ClientIvcProof, directory: string) { + const { clientIvcProofBuffer, clientIvcVkBuffer } = clientIvcProof; + const fileData = [ + ['client_ivc_proof', clientIvcProofBuffer], + ['client_ivc_vk', clientIvcVkBuffer], + ] as const; + await Promise.all(fileData.map(([fileName, buffer]) => fs.writeFile(join(directory, fileName), buffer))); +} diff --git a/yarn-project/bb-prover/src/prover/index.ts b/yarn-project/bb-prover/src/prover/index.ts index 61453485089..4079e27943c 100644 --- a/yarn-project/bb-prover/src/prover/index.ts +++ b/yarn-project/bb-prover/src/prover/index.ts @@ -1,2 +1,3 @@ export * from './bb_prover.js'; export * from './bb_private_kernel_prover.js'; +export * from './client_ivc_proof_utils.js'; diff --git a/yarn-project/bb-prover/src/verifier/bb_verifier.ts b/yarn-project/bb-prover/src/verifier/bb_verifier.ts index e99102f074e..e1f5b17def2 100644 --- a/yarn-project/bb-prover/src/verifier/bb_verifier.ts +++ b/yarn-project/bb-prover/src/verifier/bb_verifier.ts @@ -23,6 +23,7 @@ import { } from '../bb/execute.js'; import { type BBConfig } from '../config.js'; import { type UltraKeccakHonkProtocolArtifact, 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'; @@ -162,7 +163,7 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier { this.logger.debug(`${circuit} BB out - ${message}`); }; - await tx.clientIvcProof.writeToOutputDirectory(bbWorkingDirectory); + await writeToOutputDirectory(tx.clientIvcProof, bbWorkingDirectory); const result = await verifyClientIvcProof(this.config.bbBinaryPath, bbWorkingDirectory, logFunction); if (result.status === BB_RESULT.FAILURE) { diff --git a/yarn-project/bb-prover/src/wasm/index.ts b/yarn-project/bb-prover/src/wasm/index.ts new file mode 100644 index 00000000000..9163848db9e --- /dev/null +++ b/yarn-project/bb-prover/src/wasm/index.ts @@ -0,0 +1,155 @@ +import { AztecClientBackend } from '@aztec/bb.js'; +import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types'; +import { + ClientIvcProof, + type PrivateKernelCircuitPublicInputs, + type PrivateKernelInitCircuitPrivateInputs, + type PrivateKernelInnerCircuitPrivateInputs, + type PrivateKernelResetCircuitPrivateInputs, + type PrivateKernelTailCircuitPrivateInputs, + type PrivateKernelTailCircuitPublicInputs, +} from '@aztec/circuits.js'; +import { createLogger } from '@aztec/foundation/log'; +import { Timer } from '@aztec/foundation/timer'; +import { + ClientCircuitArtifacts, + ClientCircuitVks, + type ClientProtocolArtifact, + convertPrivateKernelInitInputsToWitnessMap, + convertPrivateKernelInitOutputsFromWitnessMap, + convertPrivateKernelInnerInputsToWitnessMap, + convertPrivateKernelInnerOutputsFromWitnessMap, + convertPrivateKernelResetInputsToWitnessMap, + convertPrivateKernelResetOutputsFromWitnessMap, + convertPrivateKernelTailForPublicOutputsFromWitnessMap, + convertPrivateKernelTailInputsToWitnessMap, + convertPrivateKernelTailOutputsFromWitnessMap, + convertPrivateKernelTailToPublicInputsToWitnessMap, + getPrivateKernelResetArtifactName, +} from '@aztec/noir-protocol-circuits-types/client'; +import { WASMSimulator } from '@aztec/simulator/client'; +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import { type WitnessMap } from '@noir-lang/noir_js'; +import { serializeWitness } from '@noir-lang/noirc_abi'; +import { ungzip } from 'pako'; + +export class BBWasmPrivateKernelProver implements PrivateKernelProver { + private simulator = new WASMSimulator(); + + constructor(private threads: number = 1, private log = createLogger('bb-prover:wasm')) {} + + public async simulateProofInit( + inputs: PrivateKernelInitCircuitPrivateInputs, + ): Promise> { + return await this.simulate( + inputs, + 'PrivateKernelInitArtifact', + convertPrivateKernelInitInputsToWitnessMap, + convertPrivateKernelInitOutputsFromWitnessMap, + ); + } + + public async simulateProofInner( + inputs: PrivateKernelInnerCircuitPrivateInputs, + ): Promise> { + return await this.simulate( + inputs, + 'PrivateKernelInnerArtifact', + convertPrivateKernelInnerInputsToWitnessMap, + convertPrivateKernelInnerOutputsFromWitnessMap, + ); + } + + public async simulateProofReset( + inputs: PrivateKernelResetCircuitPrivateInputs, + ): Promise> { + const variantInputs = inputs.trimToSizes(); + const artifactName = getPrivateKernelResetArtifactName(inputs.dimensions); + return await this.simulate( + variantInputs, + artifactName, + variantInputs => convertPrivateKernelResetInputsToWitnessMap(variantInputs, artifactName), + output => convertPrivateKernelResetOutputsFromWitnessMap(output, artifactName), + ); + } + + public async simulateProofTail( + inputs: PrivateKernelTailCircuitPrivateInputs, + ): Promise> { + if (!inputs.isForPublic()) { + return await this.simulate( + inputs, + 'PrivateKernelTailArtifact', + convertPrivateKernelTailInputsToWitnessMap, + convertPrivateKernelTailOutputsFromWitnessMap, + ); + } + return await this.simulate( + inputs, + 'PrivateKernelTailToPublicArtifact', + convertPrivateKernelTailToPublicInputsToWitnessMap, + convertPrivateKernelTailForPublicOutputsFromWitnessMap, + ); + } + + private async simulate< + I extends { toBuffer: () => Buffer }, + O extends PrivateKernelCircuitPublicInputs | PrivateKernelTailCircuitPublicInputs, + >( + inputs: I, + circuitType: ClientProtocolArtifact, + convertInputs: (inputs: I) => WitnessMap, + convertOutputs: (outputs: WitnessMap) => O, + ): Promise> { + this.log.debug(`Generating witness for ${circuitType}`); + const compiledCircuit: NoirCompiledCircuit = ClientCircuitArtifacts[circuitType]; + + const witnessMap = convertInputs(inputs); + const timer = new Timer(); + const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit); + const output = convertOutputs(outputWitness); + + this.log.debug(`Generated witness for ${circuitType}`, { + eventName: 'circuit-witness-generation', + circuitName: circuitType, + duration: timer.ms(), + inputSize: inputs.toBuffer().length, + outputSize: output.toBuffer().length, + }); + + const verificationKey = ClientCircuitVks[circuitType].keyAsFields; + const bytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); + + const kernelOutput: PrivateKernelSimulateOutput = { + publicInputs: output, + verificationKey, + outputWitness, + bytecode, + }; + return kernelOutput; + } + + async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise { + const timer = new Timer(); + this.log.info(`Generating ClientIVC proof...`); + const backend = new AztecClientBackend( + acirs.map(acir => ungzip(acir)), + { threads: this.threads }, + ); + + const [proof, vk] = await backend.prove(witnessStack.map(witnessMap => ungzip(serializeWitness(witnessMap)))); + await backend.destroy(); + this.log.info(`Generated ClientIVC proof`, { + eventName: 'client-ivc-proof-generation', + duration: timer.ms(), + proofSize: proof.length, + vkSize: vk.length, + }); + return new ClientIvcProof(Buffer.from(proof), Buffer.from(vk)); + } + + computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise { + return Promise.resolve(0); + } +} diff --git a/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts b/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts index 9dd399919ce..f1ca3b8c0c6 100644 --- a/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts +++ b/yarn-project/circuit-types/src/interfaces/private_kernel_prover.ts @@ -98,15 +98,6 @@ export interface PrivateKernelProver { */ createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise; - /** - * Creates a proof for an app circuit. - * - * @param bytecode - The circuit bytecode in gzipped bincode format - * @param appCircuitName - Optionally specify the name of the app circuit - * @returns A Promise resolving to a Proof object - */ - computeAppCircuitVerificationKey(bytecode: Buffer, appCircuitName?: string): Promise; - /** * Compute the gate count for a given circuit. * @param bytecode - The circuit bytecode in gzipped bincode format diff --git a/yarn-project/circuit-types/src/logs/l1_payload/encrypted_log_payload.test.ts b/yarn-project/circuit-types/src/logs/l1_payload/encrypted_log_payload.test.ts index 93879b71d62..8fa34784694 100644 --- a/yarn-project/circuit-types/src/logs/l1_payload/encrypted_log_payload.test.ts +++ b/yarn-project/circuit-types/src/logs/l1_payload/encrypted_log_payload.test.ts @@ -8,7 +8,7 @@ import { } from '@aztec/circuits.js'; import { randomBytes } from '@aztec/foundation/crypto'; import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; -import { updateInlineTestData } from '@aztec/foundation/testing'; +import { updateInlineTestData } from '@aztec/foundation/testing/files'; import { EncryptedLogPayload } from './encrypted_log_payload.js'; diff --git a/yarn-project/circuits.js/package.json b/yarn-project/circuits.js/package.json index 66d4573bdb0..3006bd8fc8b 100644 --- a/yarn-project/circuits.js/package.json +++ b/yarn-project/circuits.js/package.json @@ -59,7 +59,8 @@ "files": [ "dest", "src", - "!*.test.*" + "!*.test.*", + "!src/scripts/*" ], "types": "./dest/index.d.ts", "engines": { diff --git a/yarn-project/circuits.js/src/hash/hash.test.ts b/yarn-project/circuits.js/src/hash/hash.test.ts index fc1f0bc9018..39fa210a6f3 100644 --- a/yarn-project/circuits.js/src/hash/hash.test.ts +++ b/yarn-project/circuits.js/src/hash/hash.test.ts @@ -1,5 +1,6 @@ import { times } from '@aztec/foundation/collection'; -import { setupCustomSnapshotSerializers, updateInlineTestData } from '@aztec/foundation/testing'; +import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; +import { updateInlineTestData } from '@aztec/foundation/testing/files'; import { AztecAddress, EthAddress, Fr, L2ToL1Message, ScopedL2ToL1Message } from '../index.js'; import { makeAztecAddress } from '../tests/factories.js'; diff --git a/yarn-project/circuits.js/src/hash/map_slot.test.ts b/yarn-project/circuits.js/src/hash/map_slot.test.ts index f21df688f33..b120c496ea5 100644 --- a/yarn-project/circuits.js/src/hash/map_slot.test.ts +++ b/yarn-project/circuits.js/src/hash/map_slot.test.ts @@ -1,6 +1,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; -import { updateInlineTestData } from '@aztec/foundation/testing'; +import { updateInlineTestData } from '@aztec/foundation/testing/files'; import { deriveStorageSlotInMap } from './index.js'; diff --git a/yarn-project/circuits.js/src/keys/derivation.test.ts b/yarn-project/circuits.js/src/keys/derivation.test.ts index 6f67df60ea4..e2fec80baf5 100644 --- a/yarn-project/circuits.js/src/keys/derivation.test.ts +++ b/yarn-project/circuits.js/src/keys/derivation.test.ts @@ -1,5 +1,5 @@ import { Fr, Point } from '@aztec/foundation/fields'; -import { updateInlineTestData } from '@aztec/foundation/testing'; +import { updateInlineTestData } from '@aztec/foundation/testing/files'; import { PublicKeys } from '../types/public_keys.js'; import { computeAddress, computePreaddress } from './derivation.js'; diff --git a/yarn-project/circuits.js/src/structs/block_header.test.ts b/yarn-project/circuits.js/src/structs/block_header.test.ts index 053bf0d2639..40c7e3eec96 100644 --- a/yarn-project/circuits.js/src/structs/block_header.test.ts +++ b/yarn-project/circuits.js/src/structs/block_header.test.ts @@ -1,5 +1,6 @@ import { randomInt } from '@aztec/foundation/crypto'; -import { setupCustomSnapshotSerializers, updateInlineTestData } from '@aztec/foundation/testing'; +import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; +import { updateInlineTestData } from '@aztec/foundation/testing/files'; import { BLOCK_HEADER_LENGTH } from '../constants.gen.js'; import { makeHeader } from '../tests/factories.js'; diff --git a/yarn-project/circuits.js/src/structs/client_ivc_proof.ts b/yarn-project/circuits.js/src/structs/client_ivc_proof.ts index 3ce4169c2f8..f8c2bf1b59e 100644 --- a/yarn-project/circuits.js/src/structs/client_ivc_proof.ts +++ b/yarn-project/circuits.js/src/structs/client_ivc_proof.ts @@ -1,9 +1,6 @@ import { bufferSchemaFor } from '@aztec/foundation/schemas'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { promises as fs } from 'fs'; -import path from 'path'; - /** * TODO(https://github.com/AztecProtocol/aztec-packages/issues/7370) refactory this to * eventually we read all these VKs from the data tree instead of passing them @@ -25,41 +22,6 @@ export class ClientIvcProof { return new ClientIvcProof(Buffer.from(''), Buffer.from('')); } - /** - * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs - * Create a ClientIvcProof from the result of client_ivc_prove_output_all or client_ivc_prove_output_all_msgpack - * @param directory the directory of results - * @returns the encapsulated client ivc proof - */ - static async readFromOutputDirectory(directory: string) { - const [clientIvcVkBuffer, clientIvcProofBuffer] = await Promise.all( - ['client_ivc_vk', 'client_ivc_proof'].map(fileName => fs.readFile(path.join(directory, fileName))), - ); - return new ClientIvcProof(clientIvcProofBuffer, clientIvcVkBuffer); - } - - /** - * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs - * Serialize a ClientIvcProof to the files expected by prove_tube - * - * Example usage: - * await runInDirectory(bbWorkingDirectory, async (dir: string) => { - * await privateTx.clientIvcProof!.writeToOutputDirectory(bbWorkingDirectory); - * const result = await generateTubeProof(bbPath, dir, logger.info) - * expect(result.status).toBe(BB_RESULT.SUCCESS) - * }); - * @param proof the ClientIvcProof from readFromOutputDirectory - * @param directory the directory of results - */ - async writeToOutputDirectory(directory: string) { - const { clientIvcProofBuffer, clientIvcVkBuffer } = this; - const fileData = [ - ['client_ivc_proof', clientIvcProofBuffer], - ['client_ivc_vk', clientIvcVkBuffer], - ] as const; - await Promise.all(fileData.map(([fileName, buffer]) => fs.writeFile(path.join(directory, fileName), buffer))); - } - static get schema() { return bufferSchemaFor(ClientIvcProof); } diff --git a/yarn-project/circuits.js/src/structs/tx_request.test.ts b/yarn-project/circuits.js/src/structs/tx_request.test.ts index 8c97cd8e0f4..723e322817e 100644 --- a/yarn-project/circuits.js/src/structs/tx_request.test.ts +++ b/yarn-project/circuits.js/src/structs/tx_request.test.ts @@ -2,7 +2,8 @@ import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { randomInt } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; -import { setupCustomSnapshotSerializers, updateInlineTestData } from '@aztec/foundation/testing'; +import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; +import { updateInlineTestData } from '@aztec/foundation/testing/files'; import { TX_REQUEST_LENGTH } from '../constants.gen.js'; import { makeTxRequest } from '../tests/factories.js'; diff --git a/yarn-project/circuits.js/src/types/public_keys.test.ts b/yarn-project/circuits.js/src/types/public_keys.test.ts index b4a21a9e2c0..e8068ff6c31 100644 --- a/yarn-project/circuits.js/src/types/public_keys.test.ts +++ b/yarn-project/circuits.js/src/types/public_keys.test.ts @@ -1,5 +1,5 @@ import { Fr, Point } from '@aztec/foundation/fields'; -import { updateInlineTestData } from '@aztec/foundation/testing'; +import { updateInlineTestData } from '@aztec/foundation/testing/files'; import { PublicKeys } from './public_keys.js'; diff --git a/yarn-project/circuits.js/tsconfig.json b/yarn-project/circuits.js/tsconfig.json index fb67f66550e..f37d6d829a8 100644 --- a/yarn-project/circuits.js/tsconfig.json +++ b/yarn-project/circuits.js/tsconfig.json @@ -16,5 +16,6 @@ "path": "../types" } ], - "include": ["src"] + "include": ["src"], + "exclude": ["src/scripts"] } diff --git a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts index d8030191abb..f03231342b9 100644 --- a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts @@ -1,6 +1,6 @@ import { type ArchiveSource } from '@aztec/archiver'; import { getConfigEnvVars } from '@aztec/aztec-node'; -import { AztecAddress, EthCheatCodes, Fr, GlobalVariables, type L2Block, createLogger } from '@aztec/aztec.js'; +import { AztecAddress, Fr, GlobalVariables, type L2Block, createLogger } from '@aztec/aztec.js'; // eslint-disable-next-line no-restricted-imports import { type L2Tips, @@ -20,6 +20,7 @@ import { } from '@aztec/circuits.js'; import { fr } from '@aztec/circuits.js/testing'; import { type L1ContractAddresses, createEthereumChain } from '@aztec/ethereum'; +import { EthCheatCodesWithState } from '@aztec/ethereum/test'; import { range } from '@aztec/foundation/array'; import { Blob } from '@aztec/foundation/blob'; import { sha256, sha256ToField } from '@aztec/foundation/crypto'; @@ -99,7 +100,7 @@ describe('L1Publisher integration', () => { let coinbase: EthAddress; let feeRecipient: AztecAddress; - let ethCheatCodes: EthCheatCodes; + let ethCheatCodes: EthCheatCodesWithState; let worldStateSynchronizer: ServerWorldStateSynchronizer; // To update the test data, run "export AZTEC_GENERATE_TEST_DATA=1" in shell and run the tests again @@ -125,7 +126,7 @@ describe('L1Publisher integration', () => { { assumeProvenThrough: undefined }, )); - ethCheatCodes = new EthCheatCodes(config.l1RpcUrl); + ethCheatCodes = new EthCheatCodesWithState(config.l1RpcUrl); rollupAddress = getAddress(l1ContractAddresses.rollupAddress.toString()); outboxAddress = getAddress(l1ContractAddresses.outboxAddress.toString()); diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts index 3cb28f8d7f2..1223bcf3958 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts @@ -22,7 +22,7 @@ import { } from '@aztec/aztec.js/deployment'; import { type ContractClassIdPreimage, PublicKeys, computeContractClassId } from '@aztec/circuits.js'; import { FunctionSelector, FunctionType } from '@aztec/foundation/abi'; -import { writeTestData } from '@aztec/foundation/testing'; +import { writeTestData } from '@aztec/foundation/testing/files'; import { StatefulTestContract } from '@aztec/noir-contracts.js/StatefulTest'; import { TestContract } from '@aztec/noir-contracts.js/Test'; import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token'; diff --git a/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts b/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts index c033061b6d9..2d55474e7c8 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts @@ -1,7 +1,8 @@ import { getSchnorrAccount } from '@aztec/accounts/schnorr'; import { type AztecNodeConfig, type AztecNodeService } from '@aztec/aztec-node'; import { type AccountWalletWithSecretKey } from '@aztec/aztec.js'; -import { EthCheatCodes, MINIMUM_STAKE, getL1ContractsConfigEnvVars } from '@aztec/ethereum'; +import { MINIMUM_STAKE, getL1ContractsConfigEnvVars } from '@aztec/ethereum'; +import { EthCheatCodesWithState } from '@aztec/ethereum/test'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { RollupAbi, TestERC20Abi } from '@aztec/l1-artifacts'; import { SpamContract } from '@aztec/noir-contracts.js/Spam'; @@ -184,7 +185,7 @@ export class P2PNetworkTest { const slotsInEpoch = await rollup.read.EPOCH_DURATION(); const timestamp = await rollup.read.getTimestampForSlot([slotsInEpoch]); - const cheatCodes = new EthCheatCodes(aztecNodeConfig.l1RpcUrl); + const cheatCodes = new EthCheatCodesWithState(aztecNodeConfig.l1RpcUrl); try { await cheatCodes.warp(Number(timestamp)); } catch (err) { diff --git a/yarn-project/end-to-end/src/e2e_prover/full.test.ts b/yarn-project/end-to-end/src/e2e_prover/full.test.ts index a3672413d00..8d9566d48ff 100644 --- a/yarn-project/end-to-end/src/e2e_prover/full.test.ts +++ b/yarn-project/end-to-end/src/e2e_prover/full.test.ts @@ -1,5 +1,6 @@ import { type AztecAddress, EthAddress, retryUntil } from '@aztec/aztec.js'; -import { isGenerateTestDataEnabled, switchGenerateProtocolCircuitTestData } from '@aztec/foundation/testing'; +import { isGenerateTestDataEnabled } from '@aztec/foundation/testing'; +import { switchGenerateProtocolCircuitTestData } from '@aztec/foundation/testing/files'; import { RewardDistributorAbi, RollupAbi, TestERC20Abi } from '@aztec/l1-artifacts'; import '@jest/globals'; diff --git a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts index 5581397e60c..58252091655 100644 --- a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts +++ b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts @@ -7,7 +7,6 @@ import { CheatCodes, type CompleteAddress, type DeployL1Contracts, - EthCheatCodes, Fr, GrumpkinScalar, type Logger, @@ -16,7 +15,7 @@ import { } from '@aztec/aztec.js'; import { deployInstance, registerContractClass } from '@aztec/aztec.js/deployment'; import { type DeployL1ContractsArgs, createL1Clients, getL1ContractsConfigEnvVars, l1Artifacts } from '@aztec/ethereum'; -import { startAnvil } from '@aztec/ethereum/test'; +import { EthCheatCodesWithState, startAnvil } from '@aztec/ethereum/test'; import { asyncMap } from '@aztec/foundation/async-map'; import { createLogger } from '@aztec/foundation/log'; import { resolver, reviver } from '@aztec/foundation/serialize'; @@ -178,7 +177,7 @@ class SnapshotManager implements ISnapshotManager { await restore(snapshotData, context); // Save the snapshot data. - const ethCheatCodes = new EthCheatCodes(context.aztecNodeConfig.l1RpcUrl); + const ethCheatCodes = new EthCheatCodesWithState(context.aztecNodeConfig.l1RpcUrl); const anvilStateFile = `${this.livePath}/anvil.dat`; await ethCheatCodes.dumpChainState(anvilStateFile); writeFileSync(`${this.livePath}/${name}.json`, JSON.stringify(snapshotData || {}, resolver)); @@ -294,7 +293,7 @@ async function setupFromFresh( aztecNodeConfig.publisherPrivateKey = `0x${publisherPrivKey!.toString('hex')}`; aztecNodeConfig.validatorPrivateKey = `0x${validatorPrivKey!.toString('hex')}`; - const ethCheatCodes = new EthCheatCodes(aztecNodeConfig.l1RpcUrl); + const ethCheatCodes = new EthCheatCodesWithState(aztecNodeConfig.l1RpcUrl); if (opts.l1StartTime) { await ethCheatCodes.warp(opts.l1StartTime); @@ -333,7 +332,7 @@ async function setupFromFresh( } const watcher = new AnvilTestWatcher( - new EthCheatCodes(aztecNodeConfig.l1RpcUrl), + new EthCheatCodesWithState(aztecNodeConfig.l1RpcUrl), deployL1ContractsValues.l1ContractAddresses.rollupAddress, deployL1ContractsValues.publicClient, ); @@ -411,7 +410,7 @@ async function setupFromState(statePath: string, logger: Logger): Promise { }); it('transfer tokens for 4 epochs', async () => { - const ethCheatCodes = new EthCheatCodes(ETHEREUM_HOST); + const ethCheatCodes = new EthCheatCodesWithState(ETHEREUM_HOST); // Get 4 epochs const rollupCheatCodes = new RollupCheatCodes( ethCheatCodes, diff --git a/yarn-project/end-to-end/src/spartan/gating-passive.test.ts b/yarn-project/end-to-end/src/spartan/gating-passive.test.ts index 99d5b06dc2c..99c8394b5f1 100644 --- a/yarn-project/end-to-end/src/spartan/gating-passive.test.ts +++ b/yarn-project/end-to-end/src/spartan/gating-passive.test.ts @@ -1,4 +1,5 @@ -import { EthCheatCodes, createCompatibleClient, sleep } from '@aztec/aztec.js'; +import { createCompatibleClient, sleep } from '@aztec/aztec.js'; +import { EthCheatCodesWithState } from '@aztec/ethereum/test'; import { createLogger } from '@aztec/foundation/log'; import { expect, jest } from '@jest/globals'; @@ -84,7 +85,7 @@ describe('a test that passively observes the network in the presence of network }); const client = await createCompatibleClient(PXE_URL, debugLogger); - const ethCheatCodes = new EthCheatCodes(ETHEREUM_HOST); + const ethCheatCodes = new EthCheatCodesWithState(ETHEREUM_HOST); const rollupCheatCodes = new RollupCheatCodes( ethCheatCodes, await client.getNodeInfo().then(n => n.l1ContractAddresses), diff --git a/yarn-project/end-to-end/src/spartan/reorg.test.ts b/yarn-project/end-to-end/src/spartan/reorg.test.ts index f524503a4cf..ad221bbade7 100644 --- a/yarn-project/end-to-end/src/spartan/reorg.test.ts +++ b/yarn-project/end-to-end/src/spartan/reorg.test.ts @@ -1,4 +1,5 @@ -import { EthCheatCodes, sleep } from '@aztec/aztec.js'; +import { sleep } from '@aztec/aztec.js'; +import { EthCheatCodesWithState } from '@aztec/ethereum/test'; import { createLogger } from '@aztec/foundation/log'; import { expect, jest } from '@jest/globals'; @@ -59,7 +60,7 @@ describe('reorg test', () => { hostPort: HOST_ETHEREUM_PORT, }); testWallets = await setupTestWalletsWithTokens(PXE_URL, MINT_AMOUNT, debugLogger); - const ethCheatCodes = new EthCheatCodes(ETHEREUM_HOST); + const ethCheatCodes = new EthCheatCodesWithState(ETHEREUM_HOST); const rollupCheatCodes = new RollupCheatCodes( ethCheatCodes, await testWallets.pxe.getNodeInfo().then(n => n.l1ContractAddresses), diff --git a/yarn-project/ethereum/src/eth_cheat_codes.ts b/yarn-project/ethereum/src/eth_cheat_codes.ts index a68646c17ab..2ec0706619f 100644 --- a/yarn-project/ethereum/src/eth_cheat_codes.ts +++ b/yarn-project/ethereum/src/eth_cheat_codes.ts @@ -3,7 +3,6 @@ import { keccak256 } from '@aztec/foundation/crypto'; import { type EthAddress } from '@aztec/foundation/eth-address'; import { createLogger } from '@aztec/foundation/log'; -import fs from 'fs'; import { type Hex } from 'viem'; /** @@ -196,33 +195,6 @@ export class EthCheatCodes { this.logger.verbose(`Warped L1 timestamp to ${timestamp}`); } - /** - * Dumps the current chain state to a file. - * @param fileName - The file name to dump state into - */ - public async dumpChainState(fileName: string): Promise { - const res = await this.rpcCall('hardhat_dumpState', []); - if (res.error) { - throw new Error(`Error dumping state: ${res.error.message}`); - } - const jsonContent = JSON.stringify(res.result); - fs.writeFileSync(`${fileName}.json`, jsonContent, 'utf8'); - this.logger.verbose(`Dumped state to ${fileName}`); - } - - /** - * Loads the chain state from a file. - * @param fileName - The file name to load state from - */ - public async loadChainState(fileName: string): Promise { - const data = JSON.parse(fs.readFileSync(`${fileName}.json`, 'utf8')); - const res = await this.rpcCall('hardhat_loadState', [data]); - if (res.error) { - throw new Error(`Error loading state: ${res.error.message}`); - } - this.logger.verbose(`Loaded state from ${fileName}`); - } - /** * Load the value at a storage slot of a contract address on eth * @param contract - The contract address diff --git a/yarn-project/ethereum/src/test/eth_cheat_codes_with_state.ts b/yarn-project/ethereum/src/test/eth_cheat_codes_with_state.ts new file mode 100644 index 00000000000..8f28d8961b0 --- /dev/null +++ b/yarn-project/ethereum/src/test/eth_cheat_codes_with_state.ts @@ -0,0 +1,36 @@ +import fs from 'fs'; + +import { EthCheatCodes } from '../eth_cheat_codes.js'; + +/** + * A class that provides utility functions for interacting with ethereum (L1) dumping/loading state to/from a file. + * It is separated to avoid importing fs in the main EthCheatCodes class, which might be used in the browser. + */ +export class EthCheatCodesWithState extends EthCheatCodes { + /** + * Dumps the current chain state to a file. + * @param fileName - The file name to dump state into + */ + public async dumpChainState(fileName: string): Promise { + const res = await this.rpcCall('hardhat_dumpState', []); + if (res.error) { + throw new Error(`Error dumping state: ${res.error.message}`); + } + const jsonContent = JSON.stringify(res.result); + fs.writeFileSync(`${fileName}.json`, jsonContent, 'utf8'); + this.logger.verbose(`Dumped state to ${fileName}`); + } + + /** + * Loads the chain state from a file. + * @param fileName - The file name to load state from + */ + public async loadChainState(fileName: string): Promise { + const data = JSON.parse(fs.readFileSync(`${fileName}.json`, 'utf8')); + const res = await this.rpcCall('hardhat_loadState', [data]); + if (res.error) { + throw new Error(`Error loading state: ${res.error.message}`); + } + this.logger.verbose(`Loaded state from ${fileName}`); + } +} diff --git a/yarn-project/ethereum/src/test/index.ts b/yarn-project/ethereum/src/test/index.ts index e6e7d745ad6..cdb11e52589 100644 --- a/yarn-project/ethereum/src/test/index.ts +++ b/yarn-project/ethereum/src/test/index.ts @@ -1,2 +1,3 @@ export * from './start_anvil.js'; export * from './tx_delayer.js'; +export * from './eth_cheat_codes_with_state.js'; diff --git a/yarn-project/foundation/.eslintrc.cjs b/yarn-project/foundation/.eslintrc.cjs index ec3bcb348b7..6388fe800a8 100644 --- a/yarn-project/foundation/.eslintrc.cjs +++ b/yarn-project/foundation/.eslintrc.cjs @@ -78,5 +78,5 @@ module.exports = { // this unfortunately doesn't block `fit` and `fdescribe` 'no-only-tests/no-only-tests': ['error'], }, - ignorePatterns: ['node_modules', 'dest*', 'dist', '*.js', '.eslintrc.cjs', '.eslintrc.*.cjs'], + ignorePatterns: ['node_modules', 'dest*', 'dist', '*.js', 'scripts*', '.eslintrc.cjs', '.eslintrc.*.cjs'], }; diff --git a/yarn-project/foundation/package.json b/yarn-project/foundation/package.json index 263ccdb0c92..f6c94248bba 100644 --- a/yarn-project/foundation/package.json +++ b/yarn-project/foundation/package.json @@ -48,6 +48,7 @@ "./committable": "./dest/committable/index.js", "./noir": "./dest/noir/index.js", "./testing": "./dest/testing/index.js", + "./testing/files": "./dest/testing/files/index.js", "./array": "./dest/array/index.js", "./validation": "./dest/validation/index.js", "./promise": "./dest/promise/index.js", diff --git a/yarn-project/foundation/src/fields/point.test.ts b/yarn-project/foundation/src/fields/point.test.ts index f98771fb5c0..f7650b38da0 100644 --- a/yarn-project/foundation/src/fields/point.test.ts +++ b/yarn-project/foundation/src/fields/point.test.ts @@ -1,6 +1,6 @@ import { jsonParseWithSchema, jsonStringify } from '../json-rpc/convert.js'; import { schemas } from '../schemas/schemas.js'; -import { updateInlineTestData } from '../testing/test_data.js'; +import { updateInlineTestData } from '../testing/files/index.js'; import { Fr } from './fields.js'; import { Point } from './point.js'; diff --git a/yarn-project/foundation/src/testing/files/index.ts b/yarn-project/foundation/src/testing/files/index.ts new file mode 100644 index 00000000000..a45f40f8203 --- /dev/null +++ b/yarn-project/foundation/src/testing/files/index.ts @@ -0,0 +1,76 @@ +import { existsSync, readFileSync, writeFileSync } from 'fs'; +import { dirname, join, resolve } from 'path'; + +import { createConsoleLogger } from '../../log/console.js'; +import { fileURLToPath } from '../../url/index.js'; +import { isGenerateTestDataEnabled } from '../test_data.js'; + +let generateProtocolCircuitTestData = false; + +/** + * This is separate so Prover.tomls don't get edited everytime any test is run, + * Only full.test updates prover tomls, then switches this off. + */ +export function switchGenerateProtocolCircuitTestData() { + generateProtocolCircuitTestData = !generateProtocolCircuitTestData; +} + +/** Writes the contents specified to the target file if test data generation is enabled. */ +export function writeTestData(targetFileFromRepoRoot: string, contents: string | Buffer) { + if (!isGenerateTestDataEnabled()) { + return; + } + const targetFile = getPathToFile(targetFileFromRepoRoot); + const toWrite = typeof contents === 'string' ? contents : contents.toString('hex'); + writeFileSync(targetFile, toWrite); + const logger = createConsoleLogger('aztec:testing:test_data'); + logger(`Wrote test data to ${targetFile}`); +} + +/** + * Looks for a variable assignment in the target file and updates the value, only if test data generation is enabled. + * Note that a magic inline comment would be a cleaner approach, like `/* TEST-DATA-START *\/` and `/* TEST-DATA-END *\/`, + * but running nargo fmt on it panics since the comment would be erased, so we roll with this for now. + * @remarks Requires AZTEC_GENERATE_TEST_DATA=1 to be set + */ +export function updateInlineTestData(targetFileFromRepoRoot: string, itemName: string, value: string) { + if (!isGenerateTestDataEnabled()) { + return; + } + const logger = createConsoleLogger('aztec:testing:test_data'); + const targetFile = getPathToFile(targetFileFromRepoRoot); + const contents = readFileSync(targetFile, 'utf8').toString(); + const regex = new RegExp(`let ${itemName} =[\\s\\S]*?;`, 'g'); + if (!regex.exec(contents)) { + throw new Error(`Test data marker for ${itemName} not found in ${targetFile}`); + } + + const updatedContents = contents.replaceAll(regex, `let ${itemName} = ${value};`); + writeFileSync(targetFile, updatedContents); + logger(`Updated test data in ${targetFile} for ${itemName} to ${value}`); +} + +/** + * Updates the sample Prover.toml files in noir-projects/noir-protocol-circuits/crates/. + * @remarks Requires AZTEC_GENERATE_TEST_DATA=1 & generateProtocolCircuitTestData=true to be set + * To re-gen, run 'AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn workspace @aztec/end-to-end test full.test' + */ +export function updateProtocolCircuitSampleInputs(circuitName: string, value: string) { + if (!isGenerateTestDataEnabled() || !generateProtocolCircuitTestData) { + return; + } + const logger = createConsoleLogger('aztec:testing:test_data'); + const targetFileFromRepoRoot = `noir-projects/noir-protocol-circuits/crates/${circuitName}/Prover.toml`; + const targetFile = getPathToFile(targetFileFromRepoRoot); + writeFileSync(targetFile, value); + logger(`Updated test data in ${targetFile} for ${circuitName}`); +} + +function getPathToFile(targetFileFromRepoRoot: string) { + const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../../'); + if (!existsSync(join(repoRoot, 'CODEOWNERS'))) { + throw new Error(`Path to repo root is incorrect (got ${repoRoot})`); + } + + return join(repoRoot, targetFileFromRepoRoot); +} diff --git a/yarn-project/foundation/src/testing/index.ts b/yarn-project/foundation/src/testing/index.ts index b39430dd6f0..5d2ecb37c2b 100644 --- a/yarn-project/foundation/src/testing/index.ts +++ b/yarn-project/foundation/src/testing/index.ts @@ -1,3 +1,3 @@ -export * from './test_data.js'; export * from './snapshot_serializer.js'; export * from './port_allocator.js'; +export * from './test_data.js'; diff --git a/yarn-project/foundation/src/testing/test_data.ts b/yarn-project/foundation/src/testing/test_data.ts index e1575d01ebb..7e16b0e6be5 100644 --- a/yarn-project/foundation/src/testing/test_data.ts +++ b/yarn-project/foundation/src/testing/test_data.ts @@ -1,25 +1,10 @@ -import { existsSync, readFileSync, writeFileSync } from 'fs'; -import { dirname, join, resolve } from 'path'; - -import { createConsoleLogger } from '../log/console.js'; -import { fileURLToPath } from '../url/index.js'; - const testData: { [key: string]: unknown[] } = {}; -let generateProtocolCircuitTestData = false; /** Returns whether test data generation is enabled */ export function isGenerateTestDataEnabled() { return ['1', 'true'].includes(process.env.AZTEC_GENERATE_TEST_DATA ?? '') && typeof expect !== 'undefined'; } -/** - * This is separate so Prover.tomls don't get edited everytime any test is run, - * Only full.test updates prover tomls, then switches this off. - */ -export function switchGenerateProtocolCircuitTestData() { - generateProtocolCircuitTestData = !generateProtocolCircuitTestData; -} - /** Pushes test data with the given name, only if test data generation is enabled. */ export function pushTestData(itemName: string, data: T) { if (!isGenerateTestDataEnabled()) { @@ -49,63 +34,3 @@ export function getTestData(itemName: string): unknown[] { const fullItemName = `${testName} ${itemName}`; return testData[fullItemName]; } - -/** Writes the contents specified to the target file if test data generation is enabled. */ -export function writeTestData(targetFileFromRepoRoot: string, contents: string | Buffer) { - if (!isGenerateTestDataEnabled()) { - return; - } - const targetFile = getPathToFile(targetFileFromRepoRoot); - const toWrite = typeof contents === 'string' ? contents : contents.toString('hex'); - writeFileSync(targetFile, toWrite); - const logger = createConsoleLogger('aztec:testing:test_data'); - logger(`Wrote test data to ${targetFile}`); -} - -/** - * Looks for a variable assignment in the target file and updates the value, only if test data generation is enabled. - * Note that a magic inline comment would be a cleaner approach, like `/* TEST-DATA-START *\/` and `/* TEST-DATA-END *\/`, - * but running nargo fmt on it panics since the comment would be erased, so we roll with this for now. - * @remarks Requires AZTEC_GENERATE_TEST_DATA=1 to be set - */ -export function updateInlineTestData(targetFileFromRepoRoot: string, itemName: string, value: string) { - if (!isGenerateTestDataEnabled()) { - return; - } - const logger = createConsoleLogger('aztec:testing:test_data'); - const targetFile = getPathToFile(targetFileFromRepoRoot); - const contents = readFileSync(targetFile, 'utf8').toString(); - const regex = new RegExp(`let ${itemName} =[\\s\\S]*?;`, 'g'); - if (!regex.exec(contents)) { - throw new Error(`Test data marker for ${itemName} not found in ${targetFile}`); - } - - const updatedContents = contents.replaceAll(regex, `let ${itemName} = ${value};`); - writeFileSync(targetFile, updatedContents); - logger(`Updated test data in ${targetFile} for ${itemName} to ${value}`); -} - -/** - * Updates the sample Prover.toml files in noir-projects/noir-protocol-circuits/crates/. - * @remarks Requires AZTEC_GENERATE_TEST_DATA=1 & generateProtocolCircuitTestData=true to be set - * To re-gen, run 'AZTEC_GENERATE_TEST_DATA=1 FAKE_PROOFS=1 yarn workspace @aztec/end-to-end test full.test' - */ -export function updateProtocolCircuitSampleInputs(circuitName: string, value: string) { - if (!isGenerateTestDataEnabled() || !generateProtocolCircuitTestData) { - return; - } - const logger = createConsoleLogger('aztec:testing:test_data'); - const targetFileFromRepoRoot = `noir-projects/noir-protocol-circuits/crates/${circuitName}/Prover.toml`; - const targetFile = getPathToFile(targetFileFromRepoRoot); - writeFileSync(targetFile, value); - logger(`Updated test data in ${targetFile} for ${circuitName}`); -} - -function getPathToFile(targetFileFromRepoRoot: string) { - const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../../'); - if (!existsSync(join(repoRoot, 'CODEOWNERS'))) { - throw new Error(`Path to repo root is incorrect (got ${repoRoot})`); - } - - return join(repoRoot, targetFileFromRepoRoot); -} diff --git a/yarn-project/ivc-integration/src/native_client_ivc_integration.test.ts b/yarn-project/ivc-integration/src/native_client_ivc_integration.test.ts index 9572a436fb2..076e4518b75 100644 --- a/yarn-project/ivc-integration/src/native_client_ivc_integration.test.ts +++ b/yarn-project/ivc-integration/src/native_client_ivc_integration.test.ts @@ -1,5 +1,11 @@ -import { BB_RESULT, executeBbClientIvcProof, verifyClientIvcProof } from '@aztec/bb-prover'; -import { ClientIvcProof } from '@aztec/circuits.js'; +import { + BB_RESULT, + executeBbClientIvcProof, + readFromOutputDirectory, + verifyClientIvcProof, + writeToOutputDirectory, +} from '@aztec/bb-prover'; +import { type ClientIvcProof } from '@aztec/circuits.js'; import { createLogger } from '@aztec/foundation/log'; import { jest } from '@jest/globals'; @@ -46,7 +52,7 @@ describe('Client IVC Integration', () => { throw new Error(provingResult.reason); } - return ClientIvcProof.readFromOutputDirectory(bbWorkingDirectory); + return readFromOutputDirectory(bbWorkingDirectory); } // This test will verify a client IVC proof of a simple tx: @@ -57,7 +63,7 @@ describe('Client IVC Integration', () => { const [bytecodes, witnessStack] = await generate3FunctionTestingIVCStack(); const proof = await createClientIvcProof(witnessStack, bytecodes); - await proof.writeToOutputDirectory(bbWorkingDirectory); + await writeToOutputDirectory(proof, bbWorkingDirectory); const verifyResult = await verifyClientIvcProof(bbBinaryPath, bbWorkingDirectory, logger.info); expect(verifyResult.status).toEqual(BB_RESULT.SUCCESS); @@ -74,7 +80,7 @@ describe('Client IVC Integration', () => { const [bytecodes, witnessStack] = await generate6FunctionTestingIVCStack(); const proof = await createClientIvcProof(witnessStack, bytecodes); - await proof.writeToOutputDirectory(bbWorkingDirectory); + await writeToOutputDirectory(proof, bbWorkingDirectory); const verifyResult = await verifyClientIvcProof(bbBinaryPath, bbWorkingDirectory, logger.info); expect(verifyResult.status).toEqual(BB_RESULT.SUCCESS); diff --git a/yarn-project/noir-contracts.js/package.json b/yarn-project/noir-contracts.js/package.json index 3eed2ad6ae2..c54eb0a5965 100644 --- a/yarn-project/noir-contracts.js/package.json +++ b/yarn-project/noir-contracts.js/package.json @@ -81,4 +81,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/noir-protocol-circuits-types/package.json b/yarn-project/noir-protocol-circuits-types/package.json index 461cd3ede1a..3a16ad9a69e 100644 --- a/yarn-project/noir-protocol-circuits-types/package.json +++ b/yarn-project/noir-protocol-circuits-types/package.json @@ -4,6 +4,7 @@ "type": "module", "exports": { ".": "./dest/index.js", + "./client": "./dest/client.js", "./types": "./dest/types/index.js" }, "inherits": [ @@ -92,7 +93,8 @@ "dest", "src", "!*.test.*", - "artifacts" + "artifacts", + "!src/scripts/*" ], "types": "./dest/index.d.ts", "engines": { diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts.ts deleted file mode 100644 index f4a12718405..00000000000 --- a/yarn-project/noir-protocol-circuits-types/src/artifacts.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { type NoirCompiledCircuit } from '@aztec/types/noir'; - -import EmptyNestedJson from '../artifacts/empty_nested.json' assert { type: 'json' }; -import EmptyNestedSimulatedJson from '../artifacts/empty_nested_simulated.json' assert { type: 'json' }; -import BaseParityJson from '../artifacts/parity_base.json' assert { type: 'json' }; -import RootParityJson from '../artifacts/parity_root.json' assert { type: 'json' }; -import PrivateKernelEmptyJson from '../artifacts/private_kernel_empty.json' assert { type: 'json' }; -import PrivateKernelEmptySimulatedJson from '../artifacts/private_kernel_empty_simulated.json' assert { type: 'json' }; -import PrivateKernelInitJson from '../artifacts/private_kernel_init.json' assert { type: 'json' }; -import PrivateKernelInitSimulatedJson from '../artifacts/private_kernel_init_simulated.json' assert { type: 'json' }; -import PrivateKernelInnerJson from '../artifacts/private_kernel_inner.json' assert { type: 'json' }; -import PrivateKernelInnerSimulatedJson from '../artifacts/private_kernel_inner_simulated.json' assert { type: 'json' }; -import PrivateKernelTailJson from '../artifacts/private_kernel_tail.json' assert { type: 'json' }; -import PrivateKernelTailSimulatedJson from '../artifacts/private_kernel_tail_simulated.json' assert { type: 'json' }; -import PrivateKernelTailToPublicJson from '../artifacts/private_kernel_tail_to_public.json' assert { type: 'json' }; -import PrivateKernelTailToPublicSimulatedJson from '../artifacts/private_kernel_tail_to_public_simulated.json' assert { type: 'json' }; -import PrivateBaseRollupJson from '../artifacts/rollup_base_private.json' assert { type: 'json' }; -import PrivateBaseRollupSimulatedJson from '../artifacts/rollup_base_private_simulated.json' assert { type: 'json' }; -import PublicBaseRollupJson from '../artifacts/rollup_base_public.json' assert { type: 'json' }; -import PublicBaseRollupSimulatedJson from '../artifacts/rollup_base_public_simulated.json' assert { type: 'json' }; -import BlockMergeRollupJson from '../artifacts/rollup_block_merge.json' assert { type: 'json' }; -import BlockRootRollupJson from '../artifacts/rollup_block_root.json' assert { type: 'json' }; -import EmptyBlockRootRollupJson from '../artifacts/rollup_block_root_empty.json' assert { type: 'json' }; -import BlockRootRollupSimulatedJson from '../artifacts/rollup_block_root_simulated.json' assert { type: 'json' }; -import MergeRollupJson from '../artifacts/rollup_merge.json' assert { type: 'json' }; -import RootRollupJson from '../artifacts/rollup_root.json' assert { type: 'json' }; -import { - PrivateKernelResetArtifacts, - PrivateKernelResetSimulatedArtifacts, - type PrivateResetArtifact, -} from './private_kernel_reset_data.js'; - -// These are all circuits that should generate proofs with the `recursive` flag. -export type ServerProtocolArtifact = - | 'EmptyNestedArtifact' - | 'PrivateKernelEmptyArtifact' - | 'BaseParityArtifact' - | 'RootParityArtifact' - | 'PrivateBaseRollupArtifact' - | 'PublicBaseRollupArtifact' - | 'MergeRollupArtifact' - | 'BlockRootRollupArtifact' - | 'EmptyBlockRootRollupArtifact' - | 'BlockMergeRollupArtifact' - | 'RootRollupArtifact'; - -export type ClientProtocolArtifact = - | 'PrivateKernelInitArtifact' - | 'PrivateKernelInnerArtifact' - | 'PrivateKernelTailArtifact' - | 'PrivateKernelTailToPublicArtifact' - | PrivateResetArtifact; - -export type ProtocolArtifact = ServerProtocolArtifact | ClientProtocolArtifact; - -export const ServerCircuitArtifacts: Record = { - EmptyNestedArtifact: EmptyNestedJson as NoirCompiledCircuit, - PrivateKernelEmptyArtifact: PrivateKernelEmptyJson as NoirCompiledCircuit, - BaseParityArtifact: BaseParityJson as NoirCompiledCircuit, - RootParityArtifact: RootParityJson as NoirCompiledCircuit, - PrivateBaseRollupArtifact: PrivateBaseRollupJson as NoirCompiledCircuit, - PublicBaseRollupArtifact: PublicBaseRollupJson as NoirCompiledCircuit, - MergeRollupArtifact: MergeRollupJson as NoirCompiledCircuit, - BlockRootRollupArtifact: BlockRootRollupJson as NoirCompiledCircuit, - EmptyBlockRootRollupArtifact: EmptyBlockRootRollupJson as NoirCompiledCircuit, - BlockMergeRollupArtifact: BlockMergeRollupJson as NoirCompiledCircuit, - RootRollupArtifact: RootRollupJson as NoirCompiledCircuit, -}; - -export const SimulatedServerCircuitArtifacts: Record = { - EmptyNestedArtifact: EmptyNestedSimulatedJson as NoirCompiledCircuit, - PrivateKernelEmptyArtifact: PrivateKernelEmptySimulatedJson as NoirCompiledCircuit, - BaseParityArtifact: BaseParityJson as NoirCompiledCircuit, - RootParityArtifact: RootParityJson as NoirCompiledCircuit, - PrivateBaseRollupArtifact: PrivateBaseRollupSimulatedJson as NoirCompiledCircuit, - PublicBaseRollupArtifact: PublicBaseRollupSimulatedJson as NoirCompiledCircuit, - MergeRollupArtifact: MergeRollupJson as NoirCompiledCircuit, - BlockRootRollupArtifact: BlockRootRollupSimulatedJson as NoirCompiledCircuit, - EmptyBlockRootRollupArtifact: EmptyBlockRootRollupJson as NoirCompiledCircuit, - BlockMergeRollupArtifact: BlockMergeRollupJson as NoirCompiledCircuit, - RootRollupArtifact: RootRollupJson as NoirCompiledCircuit, -}; - -export const ClientCircuitArtifacts: Record = { - PrivateKernelInitArtifact: PrivateKernelInitJson as NoirCompiledCircuit, - PrivateKernelInnerArtifact: PrivateKernelInnerJson as NoirCompiledCircuit, - PrivateKernelTailArtifact: PrivateKernelTailJson as NoirCompiledCircuit, - PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicJson as NoirCompiledCircuit, - ...PrivateKernelResetArtifacts, -}; - -export const SimulatedClientCircuitArtifacts: Record = { - PrivateKernelInitArtifact: PrivateKernelInitSimulatedJson as NoirCompiledCircuit, - PrivateKernelInnerArtifact: PrivateKernelInnerSimulatedJson as NoirCompiledCircuit, - PrivateKernelTailArtifact: PrivateKernelTailSimulatedJson as NoirCompiledCircuit, - PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicSimulatedJson as NoirCompiledCircuit, - ...PrivateKernelResetSimulatedArtifacts, -}; - -export const ProtocolCircuitArtifacts: Record = { - ...ClientCircuitArtifacts, - ...ServerCircuitArtifacts, -}; diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts new file mode 100644 index 00000000000..256ac0405dd --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/client.ts @@ -0,0 +1,38 @@ +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import PrivateKernelInitJson from '../../artifacts/private_kernel_init.json' assert { type: 'json' }; +import PrivateKernelInitSimulatedJson from '../../artifacts/private_kernel_init_simulated.json' assert { type: 'json' }; +import PrivateKernelInnerJson from '../../artifacts/private_kernel_inner.json' assert { type: 'json' }; +import PrivateKernelInnerSimulatedJson from '../../artifacts/private_kernel_inner_simulated.json' assert { type: 'json' }; +import PrivateKernelTailJson from '../../artifacts/private_kernel_tail.json' assert { type: 'json' }; +import PrivateKernelTailSimulatedJson from '../../artifacts/private_kernel_tail_simulated.json' assert { type: 'json' }; +import PrivateKernelTailToPublicJson from '../../artifacts/private_kernel_tail_to_public.json' assert { type: 'json' }; +import PrivateKernelTailToPublicSimulatedJson from '../../artifacts/private_kernel_tail_to_public_simulated.json' assert { type: 'json' }; +import { + PrivateKernelResetArtifacts, + PrivateKernelResetSimulatedArtifacts, + type PrivateResetArtifact, +} from '../private_kernel_reset_data.js'; + +export type ClientProtocolArtifact = + | 'PrivateKernelInitArtifact' + | 'PrivateKernelInnerArtifact' + | 'PrivateKernelTailArtifact' + | 'PrivateKernelTailToPublicArtifact' + | PrivateResetArtifact; + +export const ClientCircuitArtifacts: Record = { + PrivateKernelInitArtifact: PrivateKernelInitJson as NoirCompiledCircuit, + PrivateKernelInnerArtifact: PrivateKernelInnerJson as NoirCompiledCircuit, + PrivateKernelTailArtifact: PrivateKernelTailJson as NoirCompiledCircuit, + PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicJson as NoirCompiledCircuit, + ...PrivateKernelResetArtifacts, +}; + +export const SimulatedClientCircuitArtifacts: Record = { + PrivateKernelInitArtifact: PrivateKernelInitSimulatedJson as NoirCompiledCircuit, + PrivateKernelInnerArtifact: PrivateKernelInnerSimulatedJson as NoirCompiledCircuit, + PrivateKernelTailArtifact: PrivateKernelTailSimulatedJson as NoirCompiledCircuit, + PrivateKernelTailToPublicArtifact: PrivateKernelTailToPublicSimulatedJson as NoirCompiledCircuit, + ...PrivateKernelResetSimulatedArtifacts, +}; diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts new file mode 100644 index 00000000000..acf23c28593 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/index.ts @@ -0,0 +1,14 @@ +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import { ClientCircuitArtifacts, type ClientProtocolArtifact } from './client.js'; +import { ServerCircuitArtifacts, type ServerProtocolArtifact } from './server.js'; + +export * from './client.js'; +export * from './server.js'; + +export type ProtocolArtifact = ServerProtocolArtifact | ClientProtocolArtifact; + +export const ProtocolCircuitArtifacts: Record = { + ...ClientCircuitArtifacts, + ...ServerCircuitArtifacts, +}; diff --git a/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts b/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts new file mode 100644 index 00000000000..4952f994f19 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/artifacts/server.ts @@ -0,0 +1,60 @@ +import { type NoirCompiledCircuit } from '@aztec/types/noir'; + +import EmptyNestedJson from '../../artifacts/empty_nested.json' assert { type: 'json' }; +import EmptyNestedSimulatedJson from '../../artifacts/empty_nested_simulated.json' assert { type: 'json' }; +import BaseParityJson from '../../artifacts/parity_base.json' assert { type: 'json' }; +import RootParityJson from '../../artifacts/parity_root.json' assert { type: 'json' }; +import PrivateKernelEmptyJson from '../../artifacts/private_kernel_empty.json' assert { type: 'json' }; +import PrivateKernelEmptySimulatedJson from '../../artifacts/private_kernel_empty_simulated.json' assert { type: 'json' }; +import PrivateBaseRollupJson from '../../artifacts/rollup_base_private.json' assert { type: 'json' }; +import PrivateBaseRollupSimulatedJson from '../../artifacts/rollup_base_private_simulated.json' assert { type: 'json' }; +import PublicBaseRollupJson from '../../artifacts/rollup_base_public.json' assert { type: 'json' }; +import PublicBaseRollupSimulatedJson from '../../artifacts/rollup_base_public_simulated.json' assert { type: 'json' }; +import BlockMergeRollupJson from '../../artifacts/rollup_block_merge.json' assert { type: 'json' }; +import BlockRootRollupJson from '../../artifacts/rollup_block_root.json' assert { type: 'json' }; +import EmptyBlockRootRollupJson from '../../artifacts/rollup_block_root_empty.json' assert { type: 'json' }; +import BlockRootRollupSimulatedJson from '../../artifacts/rollup_block_root_simulated.json' assert { type: 'json' }; +import MergeRollupJson from '../../artifacts/rollup_merge.json' assert { type: 'json' }; +import RootRollupJson from '../../artifacts/rollup_root.json' assert { type: 'json' }; + +// These are all circuits that should generate proofs with the `recursive` flag. +export type ServerProtocolArtifact = + | 'EmptyNestedArtifact' + | 'PrivateKernelEmptyArtifact' + | 'BaseParityArtifact' + | 'RootParityArtifact' + | 'PrivateBaseRollupArtifact' + | 'PublicBaseRollupArtifact' + | 'MergeRollupArtifact' + | 'BlockRootRollupArtifact' + | 'EmptyBlockRootRollupArtifact' + | 'BlockMergeRollupArtifact' + | 'RootRollupArtifact'; + +export const ServerCircuitArtifacts: Record = { + EmptyNestedArtifact: EmptyNestedJson as NoirCompiledCircuit, + PrivateKernelEmptyArtifact: PrivateKernelEmptyJson as NoirCompiledCircuit, + BaseParityArtifact: BaseParityJson as NoirCompiledCircuit, + RootParityArtifact: RootParityJson as NoirCompiledCircuit, + PrivateBaseRollupArtifact: PrivateBaseRollupJson as NoirCompiledCircuit, + PublicBaseRollupArtifact: PublicBaseRollupJson as NoirCompiledCircuit, + MergeRollupArtifact: MergeRollupJson as NoirCompiledCircuit, + BlockRootRollupArtifact: BlockRootRollupJson as NoirCompiledCircuit, + EmptyBlockRootRollupArtifact: EmptyBlockRootRollupJson as NoirCompiledCircuit, + BlockMergeRollupArtifact: BlockMergeRollupJson as NoirCompiledCircuit, + RootRollupArtifact: RootRollupJson as NoirCompiledCircuit, +}; + +export const SimulatedServerCircuitArtifacts: Record = { + EmptyNestedArtifact: EmptyNestedSimulatedJson as NoirCompiledCircuit, + PrivateKernelEmptyArtifact: PrivateKernelEmptySimulatedJson as NoirCompiledCircuit, + BaseParityArtifact: BaseParityJson as NoirCompiledCircuit, + RootParityArtifact: RootParityJson as NoirCompiledCircuit, + PrivateBaseRollupArtifact: PrivateBaseRollupSimulatedJson as NoirCompiledCircuit, + PublicBaseRollupArtifact: PublicBaseRollupSimulatedJson as NoirCompiledCircuit, + MergeRollupArtifact: MergeRollupJson as NoirCompiledCircuit, + BlockRootRollupArtifact: BlockRootRollupSimulatedJson as NoirCompiledCircuit, + EmptyBlockRootRollupArtifact: EmptyBlockRootRollupJson as NoirCompiledCircuit, + BlockMergeRollupArtifact: BlockMergeRollupJson as NoirCompiledCircuit, + RootRollupArtifact: RootRollupJson as NoirCompiledCircuit, +}; diff --git a/yarn-project/noir-protocol-circuits-types/src/client.ts b/yarn-project/noir-protocol-circuits-types/src/client.ts new file mode 100644 index 00000000000..db2b21ae601 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/client.ts @@ -0,0 +1,24 @@ +export { + convertPrivateKernelInitInputsToWitnessMap, + convertPrivateKernelInitOutputsFromWitnessMap, + convertPrivateKernelInnerInputsToWitnessMap, + convertPrivateKernelInnerOutputsFromWitnessMap, + convertPrivateKernelResetInputsToWitnessMap, + convertPrivateKernelResetOutputsFromWitnessMap, + convertPrivateKernelTailForPublicOutputsFromWitnessMap, + convertPrivateKernelTailInputsToWitnessMap, + convertPrivateKernelTailOutputsFromWitnessMap, + convertPrivateKernelTailToPublicInputsToWitnessMap, + executeInit, + executeInner, + executeReset, + executeTail, + executeTailForPublic, +} from './execution/client.js'; + +export { ClientCircuitArtifacts, type ClientProtocolArtifact } from './artifacts/client.js'; + +export { getPrivateKernelResetArtifactName } from './utils/private_kernel_reset.js'; +export { maxPrivateKernelResetDimensions, privateKernelResetDimensionsConfig } from './private_kernel_reset_data.js'; +export { foreignCallHandler } from './utils/foreign_call_handler.js'; +export { ClientCircuitVks, getVKIndex, getVKTreeRoot, getVKSiblingPath } from './vks.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/execution/client.ts b/yarn-project/noir-protocol-circuits-types/src/execution/client.ts new file mode 100644 index 00000000000..cfa768c1742 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/execution/client.ts @@ -0,0 +1,438 @@ +import { + type PrivateKernelCircuitPublicInputs, + type PrivateKernelInitCircuitPrivateInputs, + type PrivateKernelInnerCircuitPrivateInputs, + type PrivateKernelResetCircuitPrivateInputs, + type PrivateKernelResetCircuitPrivateInputsVariants, + type PrivateKernelResetDimensions, + type PrivateKernelTailCircuitPrivateInputs, + type PrivateKernelTailCircuitPublicInputs, +} from '@aztec/circuits.js'; + +import { type CompiledCircuit, type InputMap, Noir, type WitnessMap } from '@noir-lang/noir_js'; +import { type Abi, abiDecode, abiEncode } from '@noir-lang/noirc_abi'; + +import { ClientCircuitArtifacts, SimulatedClientCircuitArtifacts } from '../artifacts/client.js'; +import { type PrivateResetArtifact } from '../private_kernel_reset_data.js'; +import { + mapFieldToNoir, + mapPrivateCallDataToNoir, + mapPrivateCircuitPublicInputsToNoir, + mapPrivateKernelCircuitPublicInputsFromNoir, + mapPrivateKernelCircuitPublicInputsToNoir, + mapPrivateKernelDataToNoir, + mapPrivateKernelResetHintsToNoir, + mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir, + mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir, + mapTxRequestToNoir, +} from '../type_conversion.js'; +import { + type PrivateKernelInitReturnType, + type PrivateKernelInnerReturnType, + type PrivateKernelResetReturnType, + type PrivateKernelTailReturnType, + type PrivateKernelTailToPublicReturnType, + PrivateKernelInit as executePrivateKernelInitWithACVM, + PrivateKernelInner as executePrivateKernelInnerWithACVM, + PrivateKernelTailToPublic as executePrivateKernelTailToPublicWithACVM, + PrivateKernelTail as executePrivateKernelTailWithACVM, +} from '../types/index.js'; +import { type DecodedInputs } from '../utils/decoded_inputs.js'; +import { foreignCallHandler } from '../utils/foreign_call_handler.js'; +import { getPrivateKernelResetArtifactName } from '../utils/private_kernel_reset.js'; + +/* eslint-disable camelcase */ + +// Utility function with self-contained dynamic imports, so it can be stripped from browser bundles +// This is only ever used in testing, so it's safe to do so +/* testing-only-start */ +async function updateProtocolCircuitSampleInputs(circuitName: string, inputs: any) { + const { updateProtocolCircuitSampleInputs } = await import('@aztec/foundation/testing/files'); + const TOML = await import('@iarna/toml'); + updateProtocolCircuitSampleInputs(circuitName, TOML.stringify(inputs)); +} +/* testing-only-end */ + +/** + * Executes the init private kernel. + * @param privateKernelInitCircuitPrivateInputs - The private inputs to the initial private kernel. + * @returns The public inputs. + */ +export async function executeInit( + privateKernelInitCircuitPrivateInputs: PrivateKernelInitCircuitPrivateInputs, +): Promise { + const inputs = { + tx_request: mapTxRequestToNoir(privateKernelInitCircuitPrivateInputs.txRequest), + vk_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.vkTreeRoot), + protocol_contract_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), + private_call: mapPrivateCallDataToNoir(privateKernelInitCircuitPrivateInputs.privateCall), + is_private_only: privateKernelInitCircuitPrivateInputs.isPrivateOnly, + app_public_inputs: mapPrivateCircuitPublicInputsToNoir( + privateKernelInitCircuitPrivateInputs.privateCall.publicInputs, + ), + }; + + // Allow bundlers to remove this code + /* testing-only-start */ + await updateProtocolCircuitSampleInputs('private-kernel-init', inputs); + /* testing-only-end */ + + const returnType = await executePrivateKernelInitWithACVM( + inputs.tx_request, + inputs.vk_tree_root, + inputs.protocol_contract_tree_root, + inputs.private_call, + inputs.is_private_only, + inputs.app_public_inputs, + SimulatedClientCircuitArtifacts.PrivateKernelInitArtifact as CompiledCircuit, + foreignCallHandler, + ); + + return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); +} + +/** + * Executes the inner private kernel. + * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the inner private kernel. + * @returns The public inputs. + */ +export async function executeInner( + privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, +): Promise { + const inputs = { + previous_kernel: mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( + privateKernelInnerCircuitPrivateInputs.previousKernel.publicInputs, + ), + private_call: mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), + app_public_inputs: mapPrivateCircuitPublicInputsToNoir( + privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs, + ), + }; + + // Allow bundlers to remove this code + /* testing-only-start */ + await updateProtocolCircuitSampleInputs('private-kernel-inner', inputs); + /* testing-only-end */ + + const returnType = await executePrivateKernelInnerWithACVM( + inputs.previous_kernel, + inputs.previous_kernel_public_inputs, + inputs.private_call, + inputs.app_public_inputs, + SimulatedClientCircuitArtifacts.PrivateKernelInnerArtifact as CompiledCircuit, + foreignCallHandler, + ); + + return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); +} + +/** + * Executes the inner private kernel. + * @param privateKernelResetCircuitPrivateInputs - The private inputs to the reset private kernel. + * @returns The public inputs. + */ +export async function executeReset< + NH_RR_PENDING extends number, + NH_RR_SETTLED extends number, + NLL_RR_PENDING extends number, + NLL_RR_SETTLED extends number, + KEY_VALIDATION_REQUESTS extends number, + NUM_TRANSIENT_DATA_HINTS extends number, +>( + privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputsVariants< + NH_RR_PENDING, + NH_RR_SETTLED, + NLL_RR_PENDING, + NLL_RR_SETTLED, + KEY_VALIDATION_REQUESTS, + NUM_TRANSIENT_DATA_HINTS + >, + dimensions: PrivateKernelResetDimensions, + // TODO: This input is a hack so we can write full reset inputs to a Prover.toml. Ideally we remove it in favour of adding a test that runs a full reset. + untrimmedPrivateKernelResetCircuitPrivateInputs?: PrivateKernelResetCircuitPrivateInputs, +): Promise { + const artifact = SimulatedClientCircuitArtifacts[getPrivateKernelResetArtifactName(dimensions)]; + const program = new Noir(artifact as CompiledCircuit); + if (untrimmedPrivateKernelResetCircuitPrivateInputs) { + await updateResetCircuitSampleInputs(untrimmedPrivateKernelResetCircuitPrivateInputs); + } + const args: InputMap = { + previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( + privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, + ), + hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), + }; + const { returnValue } = await program.execute(args, foreignCallHandler); + return mapPrivateKernelCircuitPublicInputsFromNoir(returnValue as any); +} + +/** + * Executes the tail private kernel. + * @param privateKernelCircuitPrivateInputs - The private inputs to the tail private kernel. + * @returns The public inputs. + */ +export async function executeTail( + privateInputs: PrivateKernelTailCircuitPrivateInputs, +): Promise { + const inputs = { + previous_kernel: mapPrivateKernelDataToNoir(privateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir(privateInputs.previousKernel.publicInputs), + }; + + // Allow bundlers to remove this code + /* testing-only-start */ + await updateProtocolCircuitSampleInputs('private-kernel-tail', inputs); + /* testing-only-end */ + + const returnType = await executePrivateKernelTailWithACVM( + inputs.previous_kernel, + inputs.previous_kernel_public_inputs, + SimulatedClientCircuitArtifacts.PrivateKernelTailArtifact as CompiledCircuit, + foreignCallHandler, + ); + + return mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir(returnType); +} + +/** + * Executes the tail private kernel. + * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the tail private kernel. + * @returns The public inputs. + */ +export async function executeTailForPublic( + privateInputs: PrivateKernelTailCircuitPrivateInputs, +): Promise { + const inputs = { + previous_kernel: mapPrivateKernelDataToNoir(privateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir(privateInputs.previousKernel.publicInputs), + }; + + // Allow bundlers to remove this code + /* testing-only-start */ + await updateProtocolCircuitSampleInputs('private-kernel-tail-to-public', inputs); + /* testing-only-end */ + + const returnType = await executePrivateKernelTailToPublicWithACVM( + inputs.previous_kernel, + inputs.previous_kernel_public_inputs, + SimulatedClientCircuitArtifacts.PrivateKernelTailToPublicArtifact as CompiledCircuit, + foreignCallHandler, + ); + + return mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir(returnType); +} + +/** + * Converts the inputs of the private kernel init circuit into a witness map + * @param inputs - The private kernel inputs. + * @returns The witness map + */ +export function convertPrivateKernelInitInputsToWitnessMap( + privateKernelInitCircuitPrivateInputs: PrivateKernelInitCircuitPrivateInputs, +): WitnessMap { + const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelInitArtifact.abi, { + tx_request: mapTxRequestToNoir(privateKernelInitCircuitPrivateInputs.txRequest), + vk_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.vkTreeRoot), + protocol_contract_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), + private_call: mapPrivateCallDataToNoir(privateKernelInitCircuitPrivateInputs.privateCall), + is_private_only: privateKernelInitCircuitPrivateInputs.isPrivateOnly, + app_public_inputs: mapPrivateCircuitPublicInputsToNoir( + privateKernelInitCircuitPrivateInputs.privateCall.publicInputs, + ), + }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the private kernel inner circuit into a witness map + * @param inputs - The private kernel inputs. + * @returns The witness map + */ +export function convertPrivateKernelInnerInputsToWitnessMap( + privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, +): WitnessMap { + const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelInnerArtifact.abi, { + previous_kernel: mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( + privateKernelInnerCircuitPrivateInputs.previousKernel.publicInputs, + ), + private_call: mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), + app_public_inputs: mapPrivateCircuitPublicInputsToNoir( + privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs, + ), + }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the private kernel reset circuit into a witness map + * @param inputs - The private kernel inputs. + * @returns The witness map + */ +export function convertPrivateKernelResetInputsToWitnessMap< + NH_RR_PENDING extends number, + NH_RR_SETTLED extends number, + NLL_RR_PENDING extends number, + NLL_RR_SETTLED extends number, + KEY_VALIDATION_REQUESTS extends number, + NUM_TRANSIENT_DATA_HINTS extends number, +>( + privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputsVariants< + NH_RR_PENDING, + NH_RR_SETTLED, + NLL_RR_PENDING, + NLL_RR_SETTLED, + KEY_VALIDATION_REQUESTS, + NUM_TRANSIENT_DATA_HINTS + >, + artifactName: PrivateResetArtifact, +): WitnessMap { + const args: InputMap = { + previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( + privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, + ), + hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), + }; + const artifact = ClientCircuitArtifacts[artifactName]; + const initialWitnessMap = abiEncode(artifact.abi as Abi, args); + return initialWitnessMap; +} + +/** + * Converts the inputs of the private kernel tail circuit into a witness map + * @param inputs - The private kernel inputs. + * @returns The witness map + */ +export function convertPrivateKernelTailInputsToWitnessMap( + privateKernelTailCircuitPrivateInputs: PrivateKernelTailCircuitPrivateInputs, +): WitnessMap { + const args: InputMap = { + previous_kernel: mapPrivateKernelDataToNoir(privateKernelTailCircuitPrivateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( + privateKernelTailCircuitPrivateInputs.previousKernel.publicInputs, + ), + }; + const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelTailArtifact.abi, args); + return initialWitnessMap; +} + +/** + * Converts the inputs of the private kernel tail to public circuit into a witness map + * @param inputs - The private kernel inputs. + * @returns The witness map + */ +export function convertPrivateKernelTailToPublicInputsToWitnessMap( + privateKernelTailToPublicCircuitPrivateInputs: PrivateKernelTailCircuitPrivateInputs, +): WitnessMap { + const args: InputMap = { + previous_kernel: mapPrivateKernelDataToNoir(privateKernelTailToPublicCircuitPrivateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( + privateKernelTailToPublicCircuitPrivateInputs.previousKernel.publicInputs, + ), + }; + const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelTailToPublicArtifact.abi, args); + return initialWitnessMap; +} + +/** + * Converts the outputs of the private kernel init circuit from a witness map. + * @param outputs - The private kernel outputs as a witness map. + * @returns The public inputs. + */ +export function convertPrivateKernelInitOutputsFromWitnessMap(outputs: WitnessMap): PrivateKernelCircuitPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelInitArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as PrivateKernelInitReturnType; + + return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the private kernel inner circuit from a witness map. + * @param outputs - The private kernel outputs as a witness map. + * @returns The public inputs. + */ +export function convertPrivateKernelInnerOutputsFromWitnessMap(outputs: WitnessMap): PrivateKernelCircuitPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelInnerArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as PrivateKernelInnerReturnType; + + return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the private kernel reset circuit from a witness map. + * @param outputs - The private kernel outputs as a witness map. + * @returns The public inputs. + */ +export function convertPrivateKernelResetOutputsFromWitnessMap( + outputs: WitnessMap, + artifactName: PrivateResetArtifact, +): PrivateKernelCircuitPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const artifact = ClientCircuitArtifacts[artifactName]; + const decodedInputs: DecodedInputs = abiDecode(artifact.abi as Abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as PrivateKernelResetReturnType; + + return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the private kernel tail circuit from a witness map. + * @param outputs - The private kernel outputs as a witness map. + * @returns The public inputs. + */ +export function convertPrivateKernelTailOutputsFromWitnessMap( + outputs: WitnessMap, +): PrivateKernelTailCircuitPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelTailArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as PrivateKernelTailReturnType; + + return mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir(returnType); +} + +/** + * Converts the outputs of the private kernel tail for public circuit from a witness map. + * @param outputs - The private kernel outputs as a witness map. + * @returns The public inputs. + */ +export function convertPrivateKernelTailForPublicOutputsFromWitnessMap( + outputs: WitnessMap, +): PrivateKernelTailCircuitPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelTailToPublicArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as PrivateKernelTailToPublicReturnType; + + return mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir(returnType); +} + +async function updateResetCircuitSampleInputs( + privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputs, +) { + const inputs = { + previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), + previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( + privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, + ), + hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), + }; + + // Allow bundlers to remove this code + /* testing-only-start */ + await updateProtocolCircuitSampleInputs('private-kernel-reset', inputs); + /* testing-only-end */ +} diff --git a/yarn-project/noir-protocol-circuits-types/src/execution/index.ts b/yarn-project/noir-protocol-circuits-types/src/execution/index.ts new file mode 100644 index 00000000000..9ab6d0fec4c --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/execution/index.ts @@ -0,0 +1,2 @@ +export * from './client.js'; +export * from './server.js'; diff --git a/yarn-project/noir-protocol-circuits-types/src/execution/server.ts b/yarn-project/noir-protocol-circuits-types/src/execution/server.ts new file mode 100644 index 00000000000..5396265eea0 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/execution/server.ts @@ -0,0 +1,397 @@ +import { + type BaseOrMergeRollupPublicInputs, + type BaseParityInputs, + type BlockMergeRollupInputs, + type BlockRootOrBlockMergePublicInputs, + type BlockRootRollupInputs, + type EmptyBlockRootRollupInputs, + type KernelCircuitPublicInputs, + type MergeRollupInputs, + type ParityPublicInputs, + type PrivateBaseRollupInputs, + type PrivateKernelEmptyInputs, + type PublicBaseRollupInputs, + type RootParityInputs, + type RootRollupInputs, + type RootRollupPublicInputs, +} from '@aztec/circuits.js'; +import { updateProtocolCircuitSampleInputs } from '@aztec/foundation/testing/files'; + +import TOML from '@iarna/toml'; +import { type WitnessMap } from '@noir-lang/acvm_js'; +import { abiDecode, abiEncode } from '@noir-lang/noirc_abi'; + +import { ServerCircuitArtifacts, SimulatedServerCircuitArtifacts } from '../artifacts/server.js'; +import { + mapBaseOrMergeRollupPublicInputsFromNoir, + mapBaseParityInputsToNoir, + mapBlockMergeRollupInputsToNoir, + mapBlockRootOrBlockMergePublicInputsFromNoir, + mapBlockRootRollupInputsToNoir, + mapEmptyBlockRootRollupInputsToNoir, + mapEmptyKernelInputsToNoir, + mapKernelCircuitPublicInputsFromNoir, + mapMergeRollupInputsToNoir, + mapParityPublicInputsFromNoir, + mapPrivateBaseRollupInputsToNoir, + mapPublicBaseRollupInputsToNoir, + mapRootParityInputsToNoir, + mapRootRollupInputsToNoir, + mapRootRollupPublicInputsFromNoir, +} from '../type_conversion.js'; +import { + type ParityBaseReturnType, + type ParityRootReturnType, + type PrivateKernelEmptyReturnType, + type RollupBasePrivateReturnType, + type RollupBasePublicReturnType, + type RollupBlockMergeReturnType, + type RollupBlockRootEmptyReturnType, + type RollupBlockRootReturnType, + type RollupMergeReturnType, + type RollupRootReturnType, +} from '../types/index.js'; +import { type DecodedInputs } from '../utils/decoded_inputs.js'; + +/** + * Converts the inputs of the base parity circuit into a witness map. + * @param inputs - The base parity inputs. + * @returns The witness map + */ +export function convertBaseParityInputsToWitnessMap(inputs: BaseParityInputs): WitnessMap { + const mapped = mapBaseParityInputsToNoir(inputs); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.BaseParityArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the root parity circuit into a witness map. + * @param inputs - The root parity inputs. + * @returns The witness map + */ +export function convertRootParityInputsToWitnessMap(inputs: RootParityInputs): WitnessMap { + const mapped = mapRootParityInputsToNoir(inputs); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.RootParityArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +export function convertPrivateKernelEmptyInputsToWitnessMap(inputs: PrivateKernelEmptyInputs): WitnessMap { + const mapped = mapEmptyKernelInputsToNoir(inputs); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.PrivateKernelEmptyArtifact.abi, { input: mapped as any }); + return initialWitnessMap; +} + +export function convertPrivateBaseRollupInputsToWitnessMap(inputs: PrivateBaseRollupInputs): WitnessMap { + const mapped = mapPrivateBaseRollupInputsToNoir(inputs); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +export function convertSimulatedPrivateBaseRollupInputsToWitnessMap(inputs: PrivateBaseRollupInputs): WitnessMap { + const mapped = mapPrivateBaseRollupInputsToNoir(inputs); + updateProtocolCircuitSampleInputs('rollup-base-private', TOML.stringify({ inputs: mapped })); + const initialWitnessMap = abiEncode(SimulatedServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, { + inputs: mapped as any, + }); + return initialWitnessMap; +} + +export function convertPublicBaseRollupInputsToWitnessMap(inputs: PublicBaseRollupInputs): WitnessMap { + const mapped = mapPublicBaseRollupInputsToNoir(inputs); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.PublicBaseRollupArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +export function convertSimulatedPublicBaseRollupInputsToWitnessMap(inputs: PublicBaseRollupInputs): WitnessMap { + const mapped = mapPublicBaseRollupInputsToNoir(inputs); + updateProtocolCircuitSampleInputs('rollup-base-public', TOML.stringify({ inputs: mapped })); + const initialWitnessMap = abiEncode(SimulatedServerCircuitArtifacts.PublicBaseRollupArtifact.abi, { + inputs: mapped as any, + }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the merge rollup circuit into a witness map. + * @param inputs - The merge rollup inputs. + * @returns The witness map + */ +export function convertMergeRollupInputsToWitnessMap(inputs: MergeRollupInputs): WitnessMap { + const mapped = mapMergeRollupInputsToNoir(inputs); + updateProtocolCircuitSampleInputs('rollup-merge', TOML.stringify({ inputs: mapped })); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.MergeRollupArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the block root rollup circuit into a witness map. + * @param inputs - The block root rollup inputs. + * @returns The witness map + */ +export function convertBlockRootRollupInputsToWitnessMap(inputs: BlockRootRollupInputs): WitnessMap { + const mapped = mapBlockRootRollupInputsToNoir(inputs); + updateProtocolCircuitSampleInputs('rollup-block-root', TOML.stringify({ inputs: mapped })); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.BlockRootRollupArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the simulated block root rollup circuit into a witness map. + * @param inputs - The block root rollup inputs. + * @returns The witness map + */ +export function convertSimulatedBlockRootRollupInputsToWitnessMap(inputs: BlockRootRollupInputs): WitnessMap { + const mapped = mapBlockRootRollupInputsToNoir(inputs); + updateProtocolCircuitSampleInputs('rollup-block-root', TOML.stringify({ inputs: mapped })); + const initialWitnessMap = abiEncode(SimulatedServerCircuitArtifacts.BlockRootRollupArtifact.abi, { + inputs: mapped as any, + }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the empty block root rollup circuit into a witness map. + * @param inputs - The empty block root rollup inputs. + * @returns The witness map + */ +export function convertEmptyBlockRootRollupInputsToWitnessMap(inputs: EmptyBlockRootRollupInputs): WitnessMap { + const mapped = mapEmptyBlockRootRollupInputsToNoir(inputs); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.EmptyBlockRootRollupArtifact.abi, { + inputs: mapped as any, + }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the block merge rollup circuit into a witness map. + * @param inputs - The block merge rollup inputs. + * @returns The witness map + */ +export function convertBlockMergeRollupInputsToWitnessMap(inputs: BlockMergeRollupInputs): WitnessMap { + const mapped = mapBlockMergeRollupInputsToNoir(inputs); + updateProtocolCircuitSampleInputs('rollup-block-merge', TOML.stringify({ inputs: mapped })); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.BlockMergeRollupArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +/** + * Converts the inputs of the root rollup circuit into a witness map. + * @param inputs - The root rollup inputs. + * @returns The witness map + */ +export function convertRootRollupInputsToWitnessMap(inputs: RootRollupInputs): WitnessMap { + const mapped = mapRootRollupInputsToNoir(inputs); + updateProtocolCircuitSampleInputs('rollup-root', TOML.stringify({ inputs: mapped })); + const initialWitnessMap = abiEncode(ServerCircuitArtifacts.RootRollupArtifact.abi, { inputs: mapped as any }); + return initialWitnessMap; +} + +export function convertPrivateKernelEmptyOutputsFromWitnessMap(outputs: WitnessMap): KernelCircuitPublicInputs { + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.PrivateKernelEmptyArtifact.abi, outputs); + const returnType = decodedInputs.return_value as PrivateKernelEmptyReturnType; + + return mapKernelCircuitPublicInputsFromNoir(returnType); +} + +export function convertSimulatedPrivateKernelEmptyOutputsFromWitnessMap( + outputs: WitnessMap, +): KernelCircuitPublicInputs { + const decodedInputs: DecodedInputs = abiDecode( + SimulatedServerCircuitArtifacts.PrivateKernelEmptyArtifact.abi, + outputs, + ); + const returnType = decodedInputs.return_value as PrivateKernelEmptyReturnType; + + return mapKernelCircuitPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the simulated base rollup circuit from a witness map. + * @param outputs - The base rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertSimulatedPrivateBaseRollupOutputsFromWitnessMap( + outputs: WitnessMap, +): BaseOrMergeRollupPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode( + SimulatedServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, + outputs, + ); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBasePrivateReturnType; + + return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the base rollup circuit from a witness map. + * @param outputs - The base rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertPrivateBaseRollupOutputsFromWitnessMap(outputs: WitnessMap): BaseOrMergeRollupPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBasePrivateReturnType; + + return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the simulated base rollup circuit from a witness map. + * @param outputs - The base rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertSimulatedPublicBaseRollupOutputsFromWitnessMap( + outputs: WitnessMap, +): BaseOrMergeRollupPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(SimulatedServerCircuitArtifacts.PublicBaseRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBasePublicReturnType; + + return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the base rollup circuit from a witness map. + * @param outputs - The base rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertPublicBaseRollupOutputsFromWitnessMap(outputs: WitnessMap): BaseOrMergeRollupPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.PublicBaseRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBasePublicReturnType; + + return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the merge rollup circuit from a witness map. + * @param outputs - The merge rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertMergeRollupOutputsFromWitnessMap(outputs: WitnessMap): BaseOrMergeRollupPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.MergeRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupMergeReturnType; + + return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the empty block root rollup circuit from a witness map. + * @param outputs - The block root rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertEmptyBlockRootRollupOutputsFromWitnessMap( + outputs: WitnessMap, +): BlockRootOrBlockMergePublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.EmptyBlockRootRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBlockRootEmptyReturnType; + + return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the simulated block root rollup circuit from a witness map. + * @param outputs - The block root rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertSimulatedBlockRootRollupOutputsFromWitnessMap( + outputs: WitnessMap, +): BlockRootOrBlockMergePublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(SimulatedServerCircuitArtifacts.BlockRootRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBlockRootReturnType; + + return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the block root rollup circuit from a witness map. + * @param outputs - The block root rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertBlockRootRollupOutputsFromWitnessMap(outputs: WitnessMap): BlockRootOrBlockMergePublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.BlockRootRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBlockRootReturnType; + + return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the block merge rollup circuit from a witness map. + * @param outputs - The block merge rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertBlockMergeRollupOutputsFromWitnessMap(outputs: WitnessMap): BlockRootOrBlockMergePublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.BlockMergeRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupBlockMergeReturnType; + + return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the root rollup circuit from a witness map. + * @param outputs - The root rollup outputs as a witness map. + * @returns The public inputs. + */ +export function convertRootRollupOutputsFromWitnessMap(outputs: WitnessMap): RootRollupPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.RootRollupArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as RollupRootReturnType; + + return mapRootRollupPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the base parity circuit from a witness map. + * @param outputs - The base parity outputs as a witness map. + * @returns The public inputs. + */ +export function convertBaseParityOutputsFromWitnessMap(outputs: WitnessMap): ParityPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.BaseParityArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as ParityBaseReturnType; + + return mapParityPublicInputsFromNoir(returnType); +} + +/** + * Converts the outputs of the root parity circuit from a witness map. + * @param outputs - The root parity outputs as a witness map. + * @returns The public inputs. + */ +export function convertRootParityOutputsFromWitnessMap(outputs: WitnessMap): ParityPublicInputs { + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.RootParityArtifact.abi, outputs); + + // Cast the inputs as the return type + const returnType = decodedInputs.return_value as ParityRootReturnType; + + return mapParityPublicInputsFromNoir(returnType); +} diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts index 1955e7bfbd1..22bb7a5a041 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -1,880 +1,7 @@ -import { - type BaseOrMergeRollupPublicInputs, - type BaseParityInputs, - BlockBlobPublicInputs, - type BlockMergeRollupInputs, - type BlockRootOrBlockMergePublicInputs, - type BlockRootRollupInputs, - type EmptyBlockRootRollupInputs, - Fr, - type KernelCircuitPublicInputs, - type MergeRollupInputs, - type ParityPublicInputs, - type PrivateBaseRollupInputs, - type PrivateKernelCircuitPublicInputs, - type PrivateKernelEmptyInputs, - type PrivateKernelInitCircuitPrivateInputs, - type PrivateKernelInnerCircuitPrivateInputs, - type PrivateKernelResetCircuitPrivateInputs, - type PrivateKernelResetCircuitPrivateInputsVariants, - type PrivateKernelResetDimensions, - type PrivateKernelTailCircuitPrivateInputs, - type PrivateKernelTailCircuitPublicInputs, - type PublicBaseRollupInputs, - type RootParityInputs, - type RootRollupInputs, - type RootRollupPublicInputs, - SpongeBlob, -} from '@aztec/circuits.js'; -import { Blob } from '@aztec/foundation/blob'; -import { applyStringFormatting, createLogger } from '@aztec/foundation/log'; -import { updateProtocolCircuitSampleInputs } from '@aztec/foundation/testing'; +export * from './artifacts/index.js'; +export * from './execution/index.js'; -import TOML from '@iarna/toml'; -import { type ForeignCallInput, type ForeignCallOutput } from '@noir-lang/acvm_js'; -import { type CompiledCircuit, type InputMap, Noir } from '@noir-lang/noir_js'; -import { type Abi, abiDecode, abiEncode } from '@noir-lang/noirc_abi'; -import { type WitnessMap } from '@noir-lang/types'; -import { strict as assert } from 'assert'; - -import { - ClientCircuitArtifacts, - ServerCircuitArtifacts, - SimulatedClientCircuitArtifacts, - SimulatedServerCircuitArtifacts, -} from './artifacts.js'; -import { type PrivateResetArtifact } from './private_kernel_reset_data.js'; -import { - mapBaseOrMergeRollupPublicInputsFromNoir, - mapBaseParityInputsToNoir, - mapBlockMergeRollupInputsToNoir, - mapBlockRootOrBlockMergePublicInputsFromNoir, - mapBlockRootRollupInputsToNoir, - mapEmptyBlockRootRollupInputsToNoir, - mapEmptyKernelInputsToNoir, - mapFieldToNoir, - mapKernelCircuitPublicInputsFromNoir, - mapMergeRollupInputsToNoir, - mapParityPublicInputsFromNoir, - mapPrivateBaseRollupInputsToNoir, - mapPrivateCallDataToNoir, - mapPrivateCircuitPublicInputsToNoir, - mapPrivateKernelCircuitPublicInputsFromNoir, - mapPrivateKernelCircuitPublicInputsToNoir, - mapPrivateKernelDataToNoir, - mapPrivateKernelResetHintsToNoir, - mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir, - mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir, - mapPublicBaseRollupInputsToNoir, - mapRootParityInputsToNoir, - mapRootRollupInputsToNoir, - mapRootRollupPublicInputsFromNoir, - mapTxRequestToNoir, -} from './type_conversion.js'; -import { - type ParityBaseReturnType, - type ParityRootReturnType, - type PrivateKernelEmptyReturnType, - type PrivateKernelInitReturnType, - type PrivateKernelInnerReturnType, - type PrivateKernelResetReturnType, - type PrivateKernelTailReturnType, - type PrivateKernelTailToPublicReturnType, - type RollupBasePrivateReturnType, - type RollupBasePublicReturnType, - type RollupBlockMergeReturnType, - type RollupBlockRootEmptyReturnType, - type RollupBlockRootReturnType, - type RollupMergeReturnType, - type RollupRootReturnType, - PrivateKernelInit as executePrivateKernelInitWithACVM, - PrivateKernelInner as executePrivateKernelInnerWithACVM, - PrivateKernelTailToPublic as executePrivateKernelTailToPublicWithACVM, - PrivateKernelTail as executePrivateKernelTailWithACVM, -} from './types/index.js'; -import { getPrivateKernelResetArtifactName } from './utils/private_kernel_reset.js'; - -export * from './artifacts.js'; +export { getPrivateKernelResetArtifactName } from './utils/private_kernel_reset.js'; export { maxPrivateKernelResetDimensions, privateKernelResetDimensionsConfig } from './private_kernel_reset_data.js'; -export * from './utils/private_kernel_reset.js'; +export { foreignCallHandler } from './utils/foreign_call_handler.js'; export * from './vks.js'; - -/* eslint-disable camelcase */ - -// TODO(Tom): This should be exported from noirc_abi -/** - * The decoded inputs from the circuit. - */ -export type DecodedInputs = { - /** - * The inputs to the circuit - */ - inputs: Record; - /** - * The return value of the circuit - */ - return_value: any; -}; - -/** - * Executes the init private kernel. - * @param privateKernelInitCircuitPrivateInputs - The private inputs to the initial private kernel. - * @returns The public inputs. - */ -export async function executeInit( - privateKernelInitCircuitPrivateInputs: PrivateKernelInitCircuitPrivateInputs, -): Promise { - const inputs = { - tx_request: mapTxRequestToNoir(privateKernelInitCircuitPrivateInputs.txRequest), - vk_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.vkTreeRoot), - protocol_contract_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), - private_call: mapPrivateCallDataToNoir(privateKernelInitCircuitPrivateInputs.privateCall), - is_private_only: privateKernelInitCircuitPrivateInputs.isPrivateOnly, - app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInitCircuitPrivateInputs.privateCall.publicInputs, - ), - }; - updateProtocolCircuitSampleInputs('private-kernel-init', TOML.stringify(inputs)); - const returnType = await executePrivateKernelInitWithACVM( - inputs.tx_request, - inputs.vk_tree_root, - inputs.protocol_contract_tree_root, - inputs.private_call, - inputs.is_private_only, - inputs.app_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelInitArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Executes the inner private kernel. - * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the inner private kernel. - * @returns The public inputs. - */ -export async function executeInner( - privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, -): Promise { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelInnerCircuitPrivateInputs.previousKernel.publicInputs, - ), - private_call: mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), - app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs, - ), - }; - updateProtocolCircuitSampleInputs('private-kernel-inner', TOML.stringify(inputs)); - const returnType = await executePrivateKernelInnerWithACVM( - inputs.previous_kernel, - inputs.previous_kernel_public_inputs, - inputs.private_call, - inputs.app_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelInnerArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Executes the inner private kernel. - * @param privateKernelResetCircuitPrivateInputs - The private inputs to the reset private kernel. - * @returns The public inputs. - */ -export async function executeReset< - NH_RR_PENDING extends number, - NH_RR_SETTLED extends number, - NLL_RR_PENDING extends number, - NLL_RR_SETTLED extends number, - KEY_VALIDATION_REQUESTS extends number, - NUM_TRANSIENT_DATA_HINTS extends number, ->( - privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputsVariants< - NH_RR_PENDING, - NH_RR_SETTLED, - NLL_RR_PENDING, - NLL_RR_SETTLED, - KEY_VALIDATION_REQUESTS, - NUM_TRANSIENT_DATA_HINTS - >, - dimensions: PrivateKernelResetDimensions, - // TODO: This input is a hack so we can write full reset inputs to a Prover.toml. Ideally we remove it in favour of adding a test that runs a full reset. - untrimmedPrivateKernelResetCircuitPrivateInputs?: PrivateKernelResetCircuitPrivateInputs, -): Promise { - const artifact = SimulatedClientCircuitArtifacts[getPrivateKernelResetArtifactName(dimensions)]; - const program = new Noir(artifact as CompiledCircuit); - if (untrimmedPrivateKernelResetCircuitPrivateInputs) { - updateResetCircuitSampleInputs(untrimmedPrivateKernelResetCircuitPrivateInputs); - } - const args: InputMap = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, - ), - hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), - }; - const { returnValue } = await program.execute(args, foreignCallHandler); - return mapPrivateKernelCircuitPublicInputsFromNoir(returnValue as any); -} - -/** - * Executes the tail private kernel. - * @param privateKernelCircuitPrivateInputs - The private inputs to the tail private kernel. - * @returns The public inputs. - */ -export async function executeTail( - privateInputs: PrivateKernelTailCircuitPrivateInputs, -): Promise { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir(privateInputs.previousKernel.publicInputs), - }; - updateProtocolCircuitSampleInputs('private-kernel-tail', TOML.stringify(inputs)); - const returnType = await executePrivateKernelTailWithACVM( - inputs.previous_kernel, - inputs.previous_kernel_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelTailArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir(returnType); -} - -/** - * Executes the tail private kernel. - * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the tail private kernel. - * @returns The public inputs. - */ -export async function executeTailForPublic( - privateInputs: PrivateKernelTailCircuitPrivateInputs, -): Promise { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir(privateInputs.previousKernel.publicInputs), - }; - updateProtocolCircuitSampleInputs('private-kernel-tail-to-public', TOML.stringify(inputs)); - const returnType = await executePrivateKernelTailToPublicWithACVM( - inputs.previous_kernel, - inputs.previous_kernel_public_inputs, - SimulatedClientCircuitArtifacts.PrivateKernelTailToPublicArtifact as CompiledCircuit, - foreignCallHandler, - ); - - return mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir(returnType); -} - -/** - * Converts the inputs of the private kernel init circuit into a witness map - * @param inputs - The private kernel inputs. - * @returns The witness map - */ -export function convertPrivateKernelInitInputsToWitnessMap( - privateKernelInitCircuitPrivateInputs: PrivateKernelInitCircuitPrivateInputs, -): WitnessMap { - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelInitArtifact.abi, { - tx_request: mapTxRequestToNoir(privateKernelInitCircuitPrivateInputs.txRequest), - vk_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.vkTreeRoot), - protocol_contract_tree_root: mapFieldToNoir(privateKernelInitCircuitPrivateInputs.protocolContractTreeRoot), - private_call: mapPrivateCallDataToNoir(privateKernelInitCircuitPrivateInputs.privateCall), - is_private_only: privateKernelInitCircuitPrivateInputs.isPrivateOnly, - app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInitCircuitPrivateInputs.privateCall.publicInputs, - ), - }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the private kernel inner circuit into a witness map - * @param inputs - The private kernel inputs. - * @returns The witness map - */ -export function convertPrivateKernelInnerInputsToWitnessMap( - privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, -): WitnessMap { - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelInnerArtifact.abi, { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelInnerCircuitPrivateInputs.previousKernel.publicInputs, - ), - private_call: mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), - app_public_inputs: mapPrivateCircuitPublicInputsToNoir( - privateKernelInnerCircuitPrivateInputs.privateCall.publicInputs, - ), - }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the private kernel reset circuit into a witness map - * @param inputs - The private kernel inputs. - * @returns The witness map - */ -export function convertPrivateKernelResetInputsToWitnessMap< - NH_RR_PENDING extends number, - NH_RR_SETTLED extends number, - NLL_RR_PENDING extends number, - NLL_RR_SETTLED extends number, - KEY_VALIDATION_REQUESTS extends number, - NUM_TRANSIENT_DATA_HINTS extends number, ->( - privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputsVariants< - NH_RR_PENDING, - NH_RR_SETTLED, - NLL_RR_PENDING, - NLL_RR_SETTLED, - KEY_VALIDATION_REQUESTS, - NUM_TRANSIENT_DATA_HINTS - >, - artifactName: PrivateResetArtifact, -): WitnessMap { - const args: InputMap = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, - ), - hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), - }; - const artifact = ClientCircuitArtifacts[artifactName]; - const initialWitnessMap = abiEncode(artifact.abi as Abi, args); - return initialWitnessMap; -} - -/** - * Converts the inputs of the private kernel tail circuit into a witness map - * @param inputs - The private kernel inputs. - * @returns The witness map - */ -export function convertPrivateKernelTailInputsToWitnessMap( - privateKernelTailCircuitPrivateInputs: PrivateKernelTailCircuitPrivateInputs, -): WitnessMap { - const args: InputMap = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelTailCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelTailCircuitPrivateInputs.previousKernel.publicInputs, - ), - }; - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelTailArtifact.abi, args); - return initialWitnessMap; -} - -/** - * Converts the inputs of the private kernel tail to public circuit into a witness map - * @param inputs - The private kernel inputs. - * @returns The witness map - */ -export function convertPrivateKernelTailToPublicInputsToWitnessMap( - privateKernelTailToPublicCircuitPrivateInputs: PrivateKernelTailCircuitPrivateInputs, -): WitnessMap { - const args: InputMap = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelTailToPublicCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelTailToPublicCircuitPrivateInputs.previousKernel.publicInputs, - ), - }; - const initialWitnessMap = abiEncode(ClientCircuitArtifacts.PrivateKernelTailToPublicArtifact.abi, args); - return initialWitnessMap; -} - -/** - * Converts the outputs of the private kernel init circuit from a witness map. - * @param outputs - The private kernel outputs as a witness map. - * @returns The public inputs. - */ -export function convertPrivateKernelInitOutputsFromWitnessMap(outputs: WitnessMap): PrivateKernelCircuitPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelInitArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as PrivateKernelInitReturnType; - - return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the private kernel inner circuit from a witness map. - * @param outputs - The private kernel outputs as a witness map. - * @returns The public inputs. - */ -export function convertPrivateKernelInnerOutputsFromWitnessMap(outputs: WitnessMap): PrivateKernelCircuitPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelInnerArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as PrivateKernelInnerReturnType; - - return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the private kernel reset circuit from a witness map. - * @param outputs - The private kernel outputs as a witness map. - * @returns The public inputs. - */ -export function convertPrivateKernelResetOutputsFromWitnessMap( - outputs: WitnessMap, - artifactName: PrivateResetArtifact, -): PrivateKernelCircuitPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const artifact = ClientCircuitArtifacts[artifactName]; - const decodedInputs: DecodedInputs = abiDecode(artifact.abi as Abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as PrivateKernelResetReturnType; - - return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the private kernel tail circuit from a witness map. - * @param outputs - The private kernel outputs as a witness map. - * @returns The public inputs. - */ -export function convertPrivateKernelTailOutputsFromWitnessMap( - outputs: WitnessMap, -): PrivateKernelTailCircuitPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelTailArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as PrivateKernelTailReturnType; - - return mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir(returnType); -} - -/** - * Converts the outputs of the private kernel tail for public circuit from a witness map. - * @param outputs - The private kernel outputs as a witness map. - * @returns The public inputs. - */ -export function convertPrivateKernelTailForPublicOutputsFromWitnessMap( - outputs: WitnessMap, -): PrivateKernelTailCircuitPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ClientCircuitArtifacts.PrivateKernelTailToPublicArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as PrivateKernelTailToPublicReturnType; - - return mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir(returnType); -} - -/** - * Converts the inputs of the base parity circuit into a witness map. - * @param inputs - The base parity inputs. - * @returns The witness map - */ -export function convertBaseParityInputsToWitnessMap(inputs: BaseParityInputs): WitnessMap { - const mapped = mapBaseParityInputsToNoir(inputs); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.BaseParityArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the root parity circuit into a witness map. - * @param inputs - The root parity inputs. - * @returns The witness map - */ -export function convertRootParityInputsToWitnessMap(inputs: RootParityInputs): WitnessMap { - const mapped = mapRootParityInputsToNoir(inputs); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.RootParityArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -export function convertPrivateKernelEmptyInputsToWitnessMap(inputs: PrivateKernelEmptyInputs): WitnessMap { - const mapped = mapEmptyKernelInputsToNoir(inputs); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.PrivateKernelEmptyArtifact.abi, { input: mapped as any }); - return initialWitnessMap; -} - -export function convertPrivateBaseRollupInputsToWitnessMap(inputs: PrivateBaseRollupInputs): WitnessMap { - const mapped = mapPrivateBaseRollupInputsToNoir(inputs); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -export function convertSimulatedPrivateBaseRollupInputsToWitnessMap(inputs: PrivateBaseRollupInputs): WitnessMap { - const mapped = mapPrivateBaseRollupInputsToNoir(inputs); - updateProtocolCircuitSampleInputs('rollup-base-private', TOML.stringify({ inputs: mapped })); - const initialWitnessMap = abiEncode(SimulatedServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, { - inputs: mapped as any, - }); - return initialWitnessMap; -} - -export function convertPublicBaseRollupInputsToWitnessMap(inputs: PublicBaseRollupInputs): WitnessMap { - const mapped = mapPublicBaseRollupInputsToNoir(inputs); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.PublicBaseRollupArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -export function convertSimulatedPublicBaseRollupInputsToWitnessMap(inputs: PublicBaseRollupInputs): WitnessMap { - const mapped = mapPublicBaseRollupInputsToNoir(inputs); - updateProtocolCircuitSampleInputs('rollup-base-public', TOML.stringify({ inputs: mapped })); - const initialWitnessMap = abiEncode(SimulatedServerCircuitArtifacts.PublicBaseRollupArtifact.abi, { - inputs: mapped as any, - }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the merge rollup circuit into a witness map. - * @param inputs - The merge rollup inputs. - * @returns The witness map - */ -export function convertMergeRollupInputsToWitnessMap(inputs: MergeRollupInputs): WitnessMap { - const mapped = mapMergeRollupInputsToNoir(inputs); - updateProtocolCircuitSampleInputs('rollup-merge', TOML.stringify({ inputs: mapped })); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.MergeRollupArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the block root rollup circuit into a witness map. - * @param inputs - The block root rollup inputs. - * @returns The witness map - */ -export function convertBlockRootRollupInputsToWitnessMap(inputs: BlockRootRollupInputs): WitnessMap { - const mapped = mapBlockRootRollupInputsToNoir(inputs); - updateProtocolCircuitSampleInputs('rollup-block-root', TOML.stringify({ inputs: mapped })); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.BlockRootRollupArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the simulated block root rollup circuit into a witness map. - * @param inputs - The block root rollup inputs. - * @returns The witness map - */ -export function convertSimulatedBlockRootRollupInputsToWitnessMap(inputs: BlockRootRollupInputs): WitnessMap { - const mapped = mapBlockRootRollupInputsToNoir(inputs); - updateProtocolCircuitSampleInputs('rollup-block-root', TOML.stringify({ inputs: mapped })); - const initialWitnessMap = abiEncode(SimulatedServerCircuitArtifacts.BlockRootRollupArtifact.abi, { - inputs: mapped as any, - }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the empty block root rollup circuit into a witness map. - * @param inputs - The empty block root rollup inputs. - * @returns The witness map - */ -export function convertEmptyBlockRootRollupInputsToWitnessMap(inputs: EmptyBlockRootRollupInputs): WitnessMap { - const mapped = mapEmptyBlockRootRollupInputsToNoir(inputs); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.EmptyBlockRootRollupArtifact.abi, { - inputs: mapped as any, - }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the block merge rollup circuit into a witness map. - * @param inputs - The block merge rollup inputs. - * @returns The witness map - */ -export function convertBlockMergeRollupInputsToWitnessMap(inputs: BlockMergeRollupInputs): WitnessMap { - const mapped = mapBlockMergeRollupInputsToNoir(inputs); - updateProtocolCircuitSampleInputs('rollup-block-merge', TOML.stringify({ inputs: mapped })); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.BlockMergeRollupArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -/** - * Converts the inputs of the root rollup circuit into a witness map. - * @param inputs - The root rollup inputs. - * @returns The witness map - */ -export function convertRootRollupInputsToWitnessMap(inputs: RootRollupInputs): WitnessMap { - const mapped = mapRootRollupInputsToNoir(inputs); - updateProtocolCircuitSampleInputs('rollup-root', TOML.stringify({ inputs: mapped })); - const initialWitnessMap = abiEncode(ServerCircuitArtifacts.RootRollupArtifact.abi, { inputs: mapped as any }); - return initialWitnessMap; -} - -export function convertPrivateKernelEmptyOutputsFromWitnessMap(outputs: WitnessMap): KernelCircuitPublicInputs { - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.PrivateKernelEmptyArtifact.abi, outputs); - const returnType = decodedInputs.return_value as PrivateKernelEmptyReturnType; - - return mapKernelCircuitPublicInputsFromNoir(returnType); -} - -export function convertSimulatedPrivateKernelEmptyOutputsFromWitnessMap( - outputs: WitnessMap, -): KernelCircuitPublicInputs { - const decodedInputs: DecodedInputs = abiDecode( - SimulatedServerCircuitArtifacts.PrivateKernelEmptyArtifact.abi, - outputs, - ); - const returnType = decodedInputs.return_value as PrivateKernelEmptyReturnType; - - return mapKernelCircuitPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the simulated base rollup circuit from a witness map. - * @param outputs - The base rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertSimulatedPrivateBaseRollupOutputsFromWitnessMap( - outputs: WitnessMap, -): BaseOrMergeRollupPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode( - SimulatedServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, - outputs, - ); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBasePrivateReturnType; - - return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the base rollup circuit from a witness map. - * @param outputs - The base rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertPrivateBaseRollupOutputsFromWitnessMap(outputs: WitnessMap): BaseOrMergeRollupPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.PrivateBaseRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBasePrivateReturnType; - - return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the simulated base rollup circuit from a witness map. - * @param outputs - The base rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertSimulatedPublicBaseRollupOutputsFromWitnessMap( - outputs: WitnessMap, -): BaseOrMergeRollupPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(SimulatedServerCircuitArtifacts.PublicBaseRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBasePublicReturnType; - - return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the base rollup circuit from a witness map. - * @param outputs - The base rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertPublicBaseRollupOutputsFromWitnessMap(outputs: WitnessMap): BaseOrMergeRollupPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.PublicBaseRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBasePublicReturnType; - - return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the merge rollup circuit from a witness map. - * @param outputs - The merge rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertMergeRollupOutputsFromWitnessMap(outputs: WitnessMap): BaseOrMergeRollupPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.MergeRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupMergeReturnType; - - return mapBaseOrMergeRollupPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the empty block root rollup circuit from a witness map. - * @param outputs - The block root rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertEmptyBlockRootRollupOutputsFromWitnessMap( - outputs: WitnessMap, -): BlockRootOrBlockMergePublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.EmptyBlockRootRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBlockRootEmptyReturnType; - - return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the block root rollup circuit from a witness map. - * @param outputs - The block root rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertBlockRootRollupOutputsFromWitnessMap(outputs: WitnessMap): BlockRootOrBlockMergePublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.BlockRootRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBlockRootReturnType; - - return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the simulated block root rollup circuit from a witness map. - * @param outputs - The block root rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertSimulatedBlockRootRollupOutputsFromWitnessMap( - outputs: WitnessMap, -): BlockRootOrBlockMergePublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(SimulatedServerCircuitArtifacts.BlockRootRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBlockRootReturnType; - - return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the block merge rollup circuit from a witness map. - * @param outputs - The block merge rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertBlockMergeRollupOutputsFromWitnessMap(outputs: WitnessMap): BlockRootOrBlockMergePublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.BlockMergeRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupBlockMergeReturnType; - - return mapBlockRootOrBlockMergePublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the root rollup circuit from a witness map. - * @param outputs - The root rollup outputs as a witness map. - * @returns The public inputs. - */ -export function convertRootRollupOutputsFromWitnessMap(outputs: WitnessMap): RootRollupPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.RootRollupArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as RollupRootReturnType; - - return mapRootRollupPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the base parity circuit from a witness map. - * @param outputs - The base parity outputs as a witness map. - * @returns The public inputs. - */ -export function convertBaseParityOutputsFromWitnessMap(outputs: WitnessMap): ParityPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.BaseParityArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as ParityBaseReturnType; - - return mapParityPublicInputsFromNoir(returnType); -} - -/** - * Converts the outputs of the root parity circuit from a witness map. - * @param outputs - The root parity outputs as a witness map. - * @returns The public inputs. - */ -export function convertRootParityOutputsFromWitnessMap(outputs: WitnessMap): ParityPublicInputs { - // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(ServerCircuitArtifacts.RootParityArtifact.abi, outputs); - - // Cast the inputs as the return type - const returnType = decodedInputs.return_value as ParityRootReturnType; - - return mapParityPublicInputsFromNoir(returnType); -} - -function updateResetCircuitSampleInputs( - privateKernelResetCircuitPrivateInputs: PrivateKernelResetCircuitPrivateInputs, -) { - const inputs = { - previous_kernel: mapPrivateKernelDataToNoir(privateKernelResetCircuitPrivateInputs.previousKernel), - previous_kernel_public_inputs: mapPrivateKernelCircuitPublicInputsToNoir( - privateKernelResetCircuitPrivateInputs.previousKernel.publicInputs, - ), - hints: mapPrivateKernelResetHintsToNoir(privateKernelResetCircuitPrivateInputs.hints), - }; - updateProtocolCircuitSampleInputs('private-kernel-reset', TOML.stringify(inputs)); -} - -function fromACVMField(field: string): Fr { - return Fr.fromBuffer(Buffer.from(field.slice(2), 'hex')); -} - -function toACVMField(field: Fr): string { - return `0x${field.toBuffer().toString('hex')}`; -} - -export function foreignCallHandler(name: string, args: ForeignCallInput[]): Promise { - // ForeignCallInput is actually a string[], so the args are string[][]. - const log = createLogger('noir-protocol-circuits:oracle'); - - if (name === 'debugLog') { - assert(args.length === 3, 'expected 3 arguments for debugLog: msg, fields_length, fields'); - const [msgRaw, _ignoredFieldsSize, fields] = args; - const msg: string = msgRaw.map(acvmField => String.fromCharCode(fromACVMField(acvmField).toNumber())).join(''); - const fieldsFr: Fr[] = fields.map((field: string) => fromACVMField(field)); - log.verbose('debug_log ' + applyStringFormatting(msg, fieldsFr)); - } else if (name === 'evaluateBlobs') { - // TODO(#10323): this was added to save simulation time (~1min in ACVM, ~3mins in wasm -> 500ms). - // The use of bignum adds a lot of unconstrained code which overloads limits when simulating. - // If/when simulation times of unconstrained are improved, remove this. - // Create and evaulate our blobs: - const paddedBlobsAsFr: Fr[] = args[0].map((field: string) => fromACVMField(field)); - const kzgCommitments = args[1].map((field: string) => fromACVMField(field)); - const spongeBlob = SpongeBlob.fromFields( - args - .slice(2) - .flat() - .map((field: string) => fromACVMField(field)), - ); - const blobsAsFr = paddedBlobsAsFr.slice(0, spongeBlob.expectedFields); - // NB: the above used to be: - // const blobsAsFr: Fr[] = args[0].map((field: string) => fromACVMField(field)).filter(field => !field.isZero()); - // ...but we now have private logs which have a fixed number of fields and may have 0 values. - // TODO(Miranda): trim 0 fields from private logs - const blobs = Blob.getBlobs(blobsAsFr); - const blobPublicInputs = BlockBlobPublicInputs.fromBlobs(blobs); - // Checks on injected values: - const hash = spongeBlob.squeeze(); - blobs.forEach((blob, i) => { - const injected = kzgCommitments.slice(2 * i, 2 * i + 2); - const calculated = blob.commitmentToFields(); - if (!calculated[0].equals(injected[0]) || !calculated[1].equals(injected[1])) { - throw new Error(`Blob commitment mismatch. Real: ${calculated}, Injected: ${injected}`); - } - if (!hash.equals(blob.fieldsHash)) { - throw new Error( - `Injected blob fields do not match rolled up fields. Real hash: ${hash}, Injected hash: ${blob.fieldsHash}`, - ); - } - }); - return Promise.resolve([blobPublicInputs.toFields().map(toACVMField)]); - } else { - throw Error(`unexpected oracle during execution: ${name}`); - } - - return Promise.resolve([]); -} diff --git a/yarn-project/noir-protocol-circuits-types/src/utils/decoded_inputs.ts b/yarn-project/noir-protocol-circuits-types/src/utils/decoded_inputs.ts new file mode 100644 index 00000000000..631b1a48f30 --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/utils/decoded_inputs.ts @@ -0,0 +1,14 @@ +// TODO(Tom): This should be exported from noirc_abi +/** + * The decoded inputs from the circuit. + */ +export type DecodedInputs = { + /** + * The inputs to the circuit + */ + inputs: Record; + /** + * The return value of the circuit + */ + return_value: any; +}; diff --git a/yarn-project/noir-protocol-circuits-types/src/utils/foreign_call_handler.ts b/yarn-project/noir-protocol-circuits-types/src/utils/foreign_call_handler.ts new file mode 100644 index 00000000000..5cf86ef55eb --- /dev/null +++ b/yarn-project/noir-protocol-circuits-types/src/utils/foreign_call_handler.ts @@ -0,0 +1,66 @@ +import { BlockBlobPublicInputs, Fr, SpongeBlob } from '@aztec/circuits.js'; +import { Blob } from '@aztec/foundation/blob'; +import { applyStringFormatting, createLogger } from '@aztec/foundation/log'; + +import { type ForeignCallInput, type ForeignCallOutput } from '@noir-lang/acvm_js'; +import { strict as assert } from 'assert'; + +function fromACVMField(field: string): Fr { + return Fr.fromBuffer(Buffer.from(field.slice(2), 'hex')); +} + +function toACVMField(field: Fr): string { + return `0x${field.toBuffer().toString('hex')}`; +} + +export function foreignCallHandler(name: string, args: ForeignCallInput[]): Promise { + // ForeignCallInput is actually a string[], so the args are string[][]. + const log = createLogger('noir-protocol-circuits:oracle'); + + if (name === 'debugLog') { + assert(args.length === 3, 'expected 3 arguments for debugLog: msg, fields_length, fields'); + const [msgRaw, _ignoredFieldsSize, fields] = args; + const msg: string = msgRaw.map(acvmField => String.fromCharCode(fromACVMField(acvmField).toNumber())).join(''); + const fieldsFr: Fr[] = fields.map((field: string) => fromACVMField(field)); + log.verbose('debug_log ' + applyStringFormatting(msg, fieldsFr)); + } else if (name === 'evaluateBlobs') { + // TODO(#10323): this was added to save simulation time (~1min in ACVM, ~3mins in wasm -> 500ms). + // The use of bignum adds a lot of unconstrained code which overloads limits when simulating. + // If/when simulation times of unconstrained are improved, remove this. + // Create and evaulate our blobs: + const paddedBlobsAsFr: Fr[] = args[0].map((field: string) => fromACVMField(field)); + const kzgCommitments = args[1].map((field: string) => fromACVMField(field)); + const spongeBlob = SpongeBlob.fromFields( + args + .slice(2) + .flat() + .map((field: string) => fromACVMField(field)), + ); + const blobsAsFr = paddedBlobsAsFr.slice(0, spongeBlob.expectedFields); + // NB: the above used to be: + // const blobsAsFr: Fr[] = args[0].map((field: string) => fromACVMField(field)).filter(field => !field.isZero()); + // ...but we now have private logs which have a fixed number of fields and may have 0 values. + // TODO(Miranda): trim 0 fields from private logs + const blobs = Blob.getBlobs(blobsAsFr); + const blobPublicInputs = BlockBlobPublicInputs.fromBlobs(blobs); + // Checks on injected values: + const hash = spongeBlob.squeeze(); + blobs.forEach((blob, i) => { + const injected = kzgCommitments.slice(2 * i, 2 * i + 2); + const calculated = blob.commitmentToFields(); + if (!calculated[0].equals(injected[0]) || !calculated[1].equals(injected[1])) { + throw new Error(`Blob commitment mismatch. Real: ${calculated}, Injected: ${injected}`); + } + if (!hash.equals(blob.fieldsHash)) { + throw new Error( + `Injected blob fields do not match rolled up fields. Real hash: ${hash}, Injected hash: ${blob.fieldsHash}`, + ); + } + }); + return Promise.resolve([blobPublicInputs.toFields().map(toACVMField)]); + } else { + throw Error(`unexpected oracle during execution: ${name}`); + } + + return Promise.resolve([]); +} diff --git a/yarn-project/noir-protocol-circuits-types/src/vks.ts b/yarn-project/noir-protocol-circuits-types/src/vks.ts index ca1675d32ad..dbf31a3a6e3 100644 --- a/yarn-project/noir-protocol-circuits-types/src/vks.ts +++ b/yarn-project/noir-protocol-circuits-types/src/vks.ts @@ -41,7 +41,7 @@ import EmptyBlockRootRollupVkJson from '../artifacts/keys/rollup_block_root_empt import MergeRollupVkJson from '../artifacts/keys/rollup_merge.vk.data.json' assert { type: 'json' }; import RootRollupVkJson from '../artifacts/keys/rollup_root.vk.data.json' assert { type: 'json' }; import TubeVkJson from '../artifacts/keys/tube.vk.data.json' assert { type: 'json' }; -import { type ClientProtocolArtifact, type ProtocolArtifact, type ServerProtocolArtifact } from './artifacts.js'; +import { type ClientProtocolArtifact, type ProtocolArtifact, type ServerProtocolArtifact } from './artifacts/index.js'; import { PrivateKernelResetVkIndexes, PrivateKernelResetVks } from './private_kernel_reset_data.js'; import { keyJsonToVKData } from './utils/vk_json.js'; diff --git a/yarn-project/noir-protocol-circuits-types/tsconfig.json b/yarn-project/noir-protocol-circuits-types/tsconfig.json index 4544ee09c62..99be5d0c203 100644 --- a/yarn-project/noir-protocol-circuits-types/tsconfig.json +++ b/yarn-project/noir-protocol-circuits-types/tsconfig.json @@ -23,5 +23,6 @@ "path": "../merkle-tree" } ], - "include": ["src", "artifacts/*.d.json.ts", "artifacts/**/*.d.json.ts"] + "include": ["src", "artifacts/*.d.json.ts", "artifacts/**/*.d.json.ts"], + "exclude": ["src/scripts"] } diff --git a/yarn-project/protocol-contracts/package.json b/yarn-project/protocol-contracts/package.json index d12d967b95e..a83311f5f46 100644 --- a/yarn-project/protocol-contracts/package.json +++ b/yarn-project/protocol-contracts/package.json @@ -94,7 +94,8 @@ "dest", "src", "!*.test.*", - "artifacts" + "artifacts", + "!src/scripts/*" ], "engines": { "node": ">=18" diff --git a/yarn-project/protocol-contracts/tsconfig.json b/yarn-project/protocol-contracts/tsconfig.json index 96ab4e32557..db070c81cb1 100644 --- a/yarn-project/protocol-contracts/tsconfig.json +++ b/yarn-project/protocol-contracts/tsconfig.json @@ -16,5 +16,6 @@ "path": "../types" } ], - "include": ["src", "artifacts/*.d.json.ts"] + "include": ["src", "artifacts/*.d.json.ts"], + "exclude": ["src/scripts"] } diff --git a/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts index 2f23c94e278..fcd971b41e5 100644 --- a/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts +++ b/yarn-project/prover-client/src/test/bb_prover_full_rollup.test.ts @@ -4,7 +4,8 @@ import { Fr, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js'; import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; -import { getTestData, isGenerateTestDataEnabled, writeTestData } from '@aztec/foundation/testing'; +import { getTestData, isGenerateTestDataEnabled } from '@aztec/foundation/testing'; +import { writeTestData } from '@aztec/foundation/testing/files'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; diff --git a/yarn-project/pxe/src/kernel_oracle/index.ts b/yarn-project/pxe/src/kernel_oracle/index.ts index 7a5648ed7c3..030f8d4cf0f 100644 --- a/yarn-project/pxe/src/kernel_oracle/index.ts +++ b/yarn-project/pxe/src/kernel_oracle/index.ts @@ -15,7 +15,7 @@ import { import { createLogger } from '@aztec/foundation/log'; import { type Tuple } from '@aztec/foundation/serialize'; import { type KeyStore } from '@aztec/key-store'; -import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types'; +import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/client'; import { type ContractDataOracle } from '../contract_data_oracle/index.js'; import { type ProvingDataOracle } from './../kernel_prover/proving_data_oracle.js'; diff --git a/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts b/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts index 438506677df..b7435a4483b 100644 --- a/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +++ b/yarn-project/pxe/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts @@ -37,7 +37,7 @@ import { import { makeTuple } from '@aztec/foundation/array'; import { padArrayEnd } from '@aztec/foundation/collection'; import { type Tuple, assertLength } from '@aztec/foundation/serialize'; -import { privateKernelResetDimensionsConfig } from '@aztec/noir-protocol-circuits-types'; +import { privateKernelResetDimensionsConfig } from '@aztec/noir-protocol-circuits-types/client'; import { type ProvingDataOracle } from '../proving_data_oracle.js'; diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index d7ae9401a9b..7795a069f7e 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -111,12 +111,6 @@ describe('Kernel Prover', () => { }; }; - const computeAppCircuitVerificationKeyOutput = () => { - return { - verificationKey: VerificationKeyAsFields.makeEmpty(CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS), - }; - }; - const expectExecution = (fns: string[]) => { const callStackItemsInit = proofCreator.simulateProofInit.mock.calls.map(args => String.fromCharCode(args[0].privateCall.publicInputs.callContext.functionSelector.value), @@ -157,7 +151,6 @@ describe('Kernel Prover', () => { proofCreator.simulateProofInner.mockResolvedValue(simulateProofOutput([])); proofCreator.simulateProofReset.mockResolvedValue(simulateProofOutput([])); proofCreator.simulateProofTail.mockResolvedValue(simulateProofOutputFinal([])); - proofCreator.computeAppCircuitVerificationKey.mockResolvedValue(computeAppCircuitVerificationKeyOutput()); prover = new KernelProver(oracle, proofCreator); }); diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index eb7b9b7a841..a43676a6bbe 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -31,7 +31,8 @@ import { vkAsFieldsMegaHonk } from '@aztec/foundation/crypto'; import { createLogger } from '@aztec/foundation/log'; import { assertLength } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; -import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { Timer } from '@aztec/foundation/timer'; +import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/client'; import { getProtocolContractSiblingPath, isProtocolContract, @@ -118,6 +119,8 @@ export class KernelProver { profile: boolean = false, dryRun: boolean = false, ): Promise> { + const timer = new Timer(); + const isPrivateOnlyTx = this.isPrivateOnly(executionResult); const executionStack = [executionResult]; @@ -197,7 +200,9 @@ export class KernelProver { privateCallData, isPrivateOnlyTx, ); + pushTestData('private-kernel-inputs-init', proofInput); + output = await this.proofCreator.simulateProofInit(proofInput); acirs.push(output.bytecode); @@ -214,7 +219,9 @@ export class KernelProver { assertLength(previousVkMembershipWitness.siblingPath, VK_TREE_HEIGHT), ); const proofInput = new PrivateKernelInnerCircuitPrivateInputs(previousKernelData, privateCallData); + pushTestData('private-kernel-inputs-inner', proofInput); + output = await this.proofCreator.simulateProofInner(proofInput); acirs.push(output.bytecode); @@ -267,6 +274,7 @@ export class KernelProver { const privateInputs = new PrivateKernelTailCircuitPrivateInputs(previousKernelData); pushTestData('private-kernel-inputs-ordering', privateInputs); + const tailOutput = await this.proofCreator.simulateProofTail(privateInputs); if (tailOutput.publicInputs.forPublic) { const privateLogs = privateInputs.previousKernel.publicInputs.end.privateLogs; @@ -282,6 +290,8 @@ export class KernelProver { tailOutput.profileResult = { gateCounts }; } + this.log.info(`Witness generation took ${timer.ms()}ms`); + // TODO(#7368) how do we 'bincode' encode these inputs? if (!dryRun) { const ivcProof = await this.proofCreator.createClientIvcProof(acirs, witnessStack); diff --git a/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts b/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts index 6b16e34b13e..b6e4e918077 100644 --- a/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/test/test_circuit_prover.ts @@ -1,11 +1,6 @@ -import { - type AppCircuitSimulateOutput, - type PrivateKernelProver, - type PrivateKernelSimulateOutput, -} from '@aztec/circuit-types'; +import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types'; import type { CircuitSimulationStats } from '@aztec/circuit-types/stats'; import { - CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, ClientIvcProof, type PrivateKernelCircuitPublicInputs, type PrivateKernelInitCircuitPrivateInputs, @@ -13,13 +8,12 @@ import { type PrivateKernelResetCircuitPrivateInputs, type PrivateKernelTailCircuitPrivateInputs, type PrivateKernelTailCircuitPublicInputs, - VerificationKeyAsFields, } from '@aztec/circuits.js'; import { createLogger } from '@aztec/foundation/log'; import { elapsed } from '@aztec/foundation/timer'; import { - type ProtocolArtifact, - ProtocolCircuitVks, + ClientCircuitVks, + type ClientProtocolArtifact, executeInit, executeInner, executeReset, @@ -27,7 +21,7 @@ import { executeTailForPublic, getPrivateKernelResetArtifactName, maxPrivateKernelResetDimensions, -} from '@aztec/noir-protocol-circuits-types'; +} from '@aztec/noir-protocol-circuits-types/client'; import { type WitnessMap } from '@noir-lang/types'; @@ -114,22 +108,12 @@ export class TestPrivateKernelProver implements PrivateKernelProver { return Promise.resolve(0); } - computeAppCircuitVerificationKey( - _bytecode: Buffer, - _appCircuitName?: string | undefined, - ): Promise { - const appCircuitProofOutput: AppCircuitSimulateOutput = { - verificationKey: VerificationKeyAsFields.makeEmpty(CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS), - }; - return Promise.resolve(appCircuitProofOutput); - } - private makeEmptyKernelSimulateOutput< PublicInputsType extends PrivateKernelTailCircuitPublicInputs | PrivateKernelCircuitPublicInputs, - >(publicInputs: PublicInputsType, circuitType: ProtocolArtifact) { + >(publicInputs: PublicInputsType, circuitType: ClientProtocolArtifact) { const kernelProofOutput: PrivateKernelSimulateOutput = { publicInputs, - verificationKey: ProtocolCircuitVks[circuitType].keyAsFields, + verificationKey: ClientCircuitVks[circuitType].keyAsFields, outputWitness: new Map(), bytecode: Buffer.from([]), }; diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index f2b1f419909..b7110ae1a99 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -56,6 +56,7 @@ import { } from '@aztec/foundation/abi'; import { Fr, type Point } from '@aztec/foundation/fields'; import { type Logger, createLogger } from '@aztec/foundation/log'; +import { Timer } from '@aztec/foundation/timer'; import { type KeyStore } from '@aztec/key-store'; import { type L2TipsStore } from '@aztec/kv-store/stores'; import { @@ -494,10 +495,11 @@ export class PXEService implements PXE { version: txRequest.txContext.version, authWitnesses: txRequest.authWitnesses.map(w => w.requestHash), }; - this.log.verbose( + this.log.info( `Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`, txInfo, ); + const timer = new Timer(); await this.synchronizer.sync(); const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes); @@ -526,7 +528,7 @@ export class PXEService implements PXE { } } - this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()}`, { + this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()} in ${timer.ms()}ms`, { txHash: simulatedTx.tryGetTxHash(), ...txInfo, ...(profileResult ? { gateCounts: profileResult.gateCounts } : {}), diff --git a/yarn-project/pxe/src/utils/create_pxe_service.ts b/yarn-project/pxe/src/utils/create_pxe_service.ts index 773c7fa08aa..18783887ffb 100644 --- a/yarn-project/pxe/src/utils/create_pxe_service.ts +++ b/yarn-project/pxe/src/utils/create_pxe_service.ts @@ -1,4 +1,5 @@ import { BBNativePrivateKernelProver } from '@aztec/bb-prover'; +import { BBWasmPrivateKernelProver } from '@aztec/bb-prover/wasm'; import { type AztecNode, type PrivateKernelProver } from '@aztec/circuit-types'; import { randomBytes } from '@aztec/foundation/crypto'; import { createLogger } from '@aztec/foundation/log'; @@ -59,9 +60,11 @@ function createProver(config: PXEServiceConfig, logSuffix?: string) { // (@PhilWindle) Temporary validation until WASM is implemented if (!config.bbBinaryPath || !config.bbWorkingDirectory) { - throw new Error(`Prover must be configured with binary path and working directory`); + return new BBWasmPrivateKernelProver(16); + } else { + const bbConfig = config as Required> & + PXEServiceConfig; + const log = createLogger('pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : '')); + return BBNativePrivateKernelProver.new({ bbSkipCleanup: false, ...bbConfig }, log); } - const bbConfig = config as Required> & PXEServiceConfig; - const log = createLogger('pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : '')); - return BBNativePrivateKernelProver.new({ bbSkipCleanup: false, ...bbConfig }, log); } diff --git a/yarn-project/simulator/src/client/index.ts b/yarn-project/simulator/src/client/index.ts index 123138b079f..3bff1cb6ec7 100644 --- a/yarn-project/simulator/src/client/index.ts +++ b/yarn-project/simulator/src/client/index.ts @@ -3,3 +3,4 @@ export * from './db_oracle.js'; export * from './pick_notes.js'; export * from './execution_note_cache.js'; export { extractPrivateCircuitPublicInputs } from './private_execution.js'; +export { WASMSimulator } from '../providers/acvm_wasm.js'; diff --git a/yarn-project/simulator/src/providers/acvm_wasm.ts b/yarn-project/simulator/src/providers/acvm_wasm.ts index ffbfed5fc58..bed021be5be 100644 --- a/yarn-project/simulator/src/providers/acvm_wasm.ts +++ b/yarn-project/simulator/src/providers/acvm_wasm.ts @@ -1,4 +1,4 @@ -import { foreignCallHandler } from '@aztec/noir-protocol-circuits-types'; +import { foreignCallHandler } from '@aztec/noir-protocol-circuits-types/client'; import { type NoirCompiledCircuit } from '@aztec/types/noir'; import { executeCircuit } from '@noir-lang/acvm_js'; diff --git a/yarn-project/simulator/src/providers/index.ts b/yarn-project/simulator/src/providers/index.ts index 15902dc2b65..634f163865d 100644 --- a/yarn-project/simulator/src/providers/index.ts +++ b/yarn-project/simulator/src/providers/index.ts @@ -1,4 +1,3 @@ export * from './acvm_native.js'; -export * from './acvm_wasm.js'; export * from './simulation_provider.js'; export * from './factory.js'; diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 5d3e2c5a5f3..3bc9084e506 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -285,6 +285,7 @@ __metadata: version: 0.0.0-use.local resolution: "@aztec/bb-prover@workspace:bb-prover" dependencies: + "@aztec/bb.js": "portal:../../barretenberg/ts" "@aztec/circuit-types": "workspace:^" "@aztec/circuits.js": "workspace:^" "@aztec/ethereum": "workspace:^" @@ -306,6 +307,7 @@ __metadata: commander: ^12.1.0 jest: ^29.5.0 jest-mock-extended: ^3.0.3 + pako: ^2.1.0 source-map-support: ^0.5.21 ts-node: ^10.9.1 tslib: ^2.4.0 @@ -321,7 +323,7 @@ __metadata: resolution: "@aztec/bb.js@portal:../barretenberg/ts::locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: comlink: ^4.4.1 - commander: ^10.0.1 + commander: ^12.1.0 debug: ^4.3.4 fflate: ^0.8.0 pako: ^2.1.0