-
Notifications
You must be signed in to change notification settings - Fork 295
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Further modularises `noir-protocol-circuits-types`, exposing a `client/lazy` API that allow browser bundles to not import every single JSON artifact at once, but rather pull them on demand. `/server` and `/vks` entrypoints are also provided to aid in startup CLI times, jest cache and general cleanup. This is very important due to the sheer amount of different reset variants we currently have. However, a regular `/client/bundle` is still exposed in case dynamic imports are not supported in the target platform. This takes our bundle sizes in the example vite box (with PXE in the browser and proving) from 50MB (30 compressed) to ~3MB before meaningful content is displayed. After that, `bb.js` is an additional 8-9 and each circuit hovers around 0.3-1, but only the ones used in the transactions are pulled when required. Also removed the `TestPrivateKernelProver`, and replaced it by each of our prover implementations providing a cleaner simulation vs. witgen+proving interface. This way, the prover is now 100% a PXE plugin (which will allow us to even delegate proving!)
- Loading branch information
Showing
69 changed files
with
870 additions
and
973 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,35 @@ | ||
import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; | ||
import { type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/server'; | ||
|
||
export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_rollup_honk'; | ||
|
||
const UltraKeccakHonkCircuits = ['RootRollupArtifact'] as const satisfies ProtocolArtifact[]; | ||
const UltraKeccakHonkCircuits = ['RootRollupArtifact'] as const satisfies ServerProtocolArtifact[]; | ||
const UltraHonkCircuits = [ | ||
// 'EmptyNestedArtifact', | ||
// 'PrivateKernelEmptyArtifact', | ||
'BaseParityArtifact', | ||
'RootParityArtifact', | ||
] as const satisfies ProtocolArtifact[]; | ||
] as const satisfies ServerProtocolArtifact[]; | ||
|
||
export type UltraKeccakHonkProtocolArtifact = (typeof UltraKeccakHonkCircuits)[number]; | ||
export type UltraHonkProtocolArtifact = (typeof UltraHonkCircuits)[number]; | ||
export type UltraRollupHonkProtocolArtifact = Exclude< | ||
Exclude<ProtocolArtifact, UltraKeccakHonkProtocolArtifact>, | ||
UltraHonkProtocolArtifact | ||
export type UltraKeccakHonkServerProtocolArtifact = (typeof UltraKeccakHonkCircuits)[number]; | ||
export type UltraHonkServerProtocolArtifact = (typeof UltraHonkCircuits)[number]; | ||
export type UltraRollupHonkServerProtocolArtifact = Exclude< | ||
Exclude<ServerProtocolArtifact, UltraKeccakHonkServerProtocolArtifact>, | ||
UltraHonkServerProtocolArtifact | ||
>; | ||
|
||
export function getUltraHonkFlavorForCircuit(artifact: UltraKeccakHonkProtocolArtifact): 'ultra_keccak_honk'; | ||
export function getUltraHonkFlavorForCircuit(artifact: UltraHonkProtocolArtifact): 'ultra_honk'; | ||
export function getUltraHonkFlavorForCircuit(artifact: UltraRollupHonkProtocolArtifact): 'ultra_rollup_honk'; | ||
export function getUltraHonkFlavorForCircuit(artifact: ProtocolArtifact): UltraHonkFlavor; | ||
export function getUltraHonkFlavorForCircuit(artifact: ProtocolArtifact): UltraHonkFlavor { | ||
export function getUltraHonkFlavorForCircuit(artifact: UltraKeccakHonkServerProtocolArtifact): 'ultra_keccak_honk'; | ||
export function getUltraHonkFlavorForCircuit(artifact: UltraHonkServerProtocolArtifact): 'ultra_honk'; | ||
export function getUltraHonkFlavorForCircuit(artifact: UltraRollupHonkServerProtocolArtifact): 'ultra_rollup_honk'; | ||
export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor; | ||
export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor { | ||
if (isUltraKeccakHonkCircuit(artifact)) { | ||
return 'ultra_keccak_honk'; | ||
} else if (UltraHonkCircuits.includes(artifact as UltraHonkProtocolArtifact)) { | ||
} else if (UltraHonkCircuits.includes(artifact as UltraHonkServerProtocolArtifact)) { | ||
return 'ultra_honk'; | ||
} | ||
return 'ultra_rollup_honk'; | ||
} | ||
|
||
function isUltraKeccakHonkCircuit(artifact: ProtocolArtifact): artifact is UltraKeccakHonkProtocolArtifact { | ||
return UltraKeccakHonkCircuits.includes(artifact as UltraKeccakHonkProtocolArtifact); | ||
function isUltraKeccakHonkCircuit(artifact: ServerProtocolArtifact): artifact is UltraKeccakHonkServerProtocolArtifact { | ||
return UltraKeccakHonkCircuits.includes(artifact as UltraKeccakHonkServerProtocolArtifact); | ||
} |
110 changes: 110 additions & 0 deletions
110
yarn-project/bb-prover/src/prover/bb_native_private_kernel_prover.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { type ClientIvcProof } from '@aztec/circuits.js'; | ||
import { runInDirectory } from '@aztec/foundation/fs'; | ||
import { type Logger, createLogger } from '@aztec/foundation/log'; | ||
import { BundleArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/bundle'; | ||
|
||
import { encode } from '@msgpack/msgpack'; | ||
import { serializeWitness } from '@noir-lang/noirc_abi'; | ||
import { type WitnessMap } from '@noir-lang/types'; | ||
import { promises as fs } from 'fs'; | ||
import path from 'path'; | ||
|
||
import { BB_RESULT, computeGateCountForCircuit, executeBbClientIvcProof } from '../bb/execute.js'; | ||
import { type BBConfig } from '../config.js'; | ||
import { BBPrivateKernelProver } from './bb_private_kernel_prover.js'; | ||
import { readFromOutputDirectory } from './client_ivc_proof_utils.js'; | ||
|
||
/** | ||
* This proof creator implementation uses the native bb binary. | ||
*/ | ||
export class BBNativePrivateKernelProver extends BBPrivateKernelProver { | ||
private constructor( | ||
private bbBinaryPath: string, | ||
private bbWorkingDirectory: string, | ||
private skipCleanup: boolean, | ||
protected override log = createLogger('bb-prover:native'), | ||
) { | ||
super(new BundleArtifactProvider(), log); | ||
} | ||
|
||
public static async new(config: BBConfig, log?: Logger) { | ||
await fs.mkdir(config.bbWorkingDirectory, { recursive: true }); | ||
return new BBNativePrivateKernelProver(config.bbBinaryPath, config.bbWorkingDirectory, !!config.bbSkipCleanup, log); | ||
} | ||
|
||
private async _createClientIvcProof( | ||
directory: string, | ||
acirs: Buffer[], | ||
witnessStack: WitnessMap[], | ||
): Promise<ClientIvcProof> { | ||
// TODO(#7371): Longer term we won't use this hacked together msgpack format | ||
// and instead properly create the bincode serialization from rust | ||
await fs.writeFile(path.join(directory, 'acir.msgpack'), encode(acirs)); | ||
await fs.writeFile( | ||
path.join(directory, 'witnesses.msgpack'), | ||
encode(witnessStack.map(map => serializeWitness(map))), | ||
); | ||
const provingResult = await executeBbClientIvcProof( | ||
this.bbBinaryPath, | ||
directory, | ||
path.join(directory, 'acir.msgpack'), | ||
path.join(directory, 'witnesses.msgpack'), | ||
this.log.info, | ||
); | ||
|
||
if (provingResult.status === BB_RESULT.FAILURE) { | ||
this.log.error(`Failed to generate client ivc proof`); | ||
throw new Error(provingResult.reason); | ||
} | ||
|
||
const proof = await readFromOutputDirectory(directory); | ||
|
||
this.log.info(`Generated IVC proof`, { | ||
duration: provingResult.durationMs, | ||
eventName: 'circuit-proving', | ||
}); | ||
|
||
return proof; | ||
} | ||
|
||
public override async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise<ClientIvcProof> { | ||
this.log.info(`Generating Client IVC proof`); | ||
const operation = async (directory: string) => { | ||
return await this._createClientIvcProof(directory, acirs, witnessStack); | ||
}; | ||
return await this.runInDirectory(operation); | ||
} | ||
|
||
public override async computeGateCountForCircuit(bytecode: Buffer, circuitName: string): Promise<number> { | ||
const logFunction = (message: string) => { | ||
this.log.debug(`$bb gates ${circuitName} - ${message}`); | ||
}; | ||
|
||
const result = await computeGateCountForCircuit( | ||
this.bbBinaryPath, | ||
this.bbWorkingDirectory, | ||
circuitName, | ||
bytecode, | ||
'mega_honk', | ||
logFunction, | ||
); | ||
if (result.status === BB_RESULT.FAILURE) { | ||
throw new Error(result.reason); | ||
} | ||
|
||
return result.circuitSize as number; | ||
} | ||
|
||
private runInDirectory<T>(fn: (dir: string) => Promise<T>) { | ||
const log = this.log; | ||
return runInDirectory( | ||
this.bbWorkingDirectory, | ||
(dir: string) => | ||
fn(dir).catch(err => { | ||
log.error(`Error running operation at ${dir}: ${err}`); | ||
throw err; | ||
}), | ||
this.skipCleanup, | ||
); | ||
} | ||
} |
Oops, something went wrong.