From 8582ef2c3903352d8793a5bc6dc6c3e3a3275d90 Mon Sep 17 00:00:00 2001 From: PhilWindle <60546371+PhilWindle@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:39:00 +0100 Subject: [PATCH] fix: Properly schedule the tube proof and don't prove it twice (#7913) This PR integrates the proving of the tube circuit into the orchestrator state machine. We no longer prove the tube circuit twice for transactions with public functions. --- .../bb-prover/src/prover/bb_prover.ts | 15 +- yarn-project/circuit-types/src/stats/stats.ts | 3 +- .../public_kernel_circuit_private_inputs.ts | 8 +- .../circuits.js/src/tests/factories.ts | 7 +- .../orchestrator/block-building-helpers.ts | 3 +- .../src/orchestrator/orchestrator.ts | 188 +++++++++++------- .../src/orchestrator/tx-proving-state.ts | 40 +++- .../src/public/abstract_phase_manager.ts | 3 +- 8 files changed, 158 insertions(+), 109 deletions(-) diff --git a/yarn-project/bb-prover/src/prover/bb_prover.ts b/yarn-project/bb-prover/src/prover/bb_prover.ts index c050f4cc42c..95378c4ca28 100644 --- a/yarn-project/bb-prover/src/prover/bb_prover.ts +++ b/yarn-project/bb-prover/src/prover/bb_prover.ts @@ -31,7 +31,7 @@ import { type RootRollupInputs, type RootRollupPublicInputs, TUBE_PROOF_LENGTH, - TubeInputs, + type TubeInputs, type VerificationKeyAsFields, type VerificationKeyData, makeRecursiveProofFromBinary, @@ -226,16 +226,6 @@ export class BBNativeRollupProver implements ServerCircuitProver { kernelRequest.inputs.previousKernel.vk, ); - // PUBLIC KERNEL: kernel request should be nonempty at start of public kernel proving but it is not - // TODO(#7369): We should properly enqueue the tube in the public kernel lifetime - if (!kernelRequest.inputs.previousKernel.clientIvcProof.isEmpty()) { - const { tubeVK, tubeProof } = await this.getTubeProof( - new TubeInputs(kernelRequest.inputs.previousKernel.clientIvcProof), - ); - kernelRequest.inputs.previousKernel.vk = tubeVK; - kernelRequest.inputs.previousKernel.proof = tubeProof; - } - await this.verifyWithKey( kernelRequest.inputs.previousKernel.vk, kernelRequest.inputs.previousKernel.proof.binaryProof, @@ -289,8 +279,7 @@ export class BBNativeRollupProver implements ServerCircuitProver { ): Promise> { // We may need to convert the recursive proof into fields format logger.debug(`kernel Data proof: ${baseRollupInput.kernelData.proof}`); - logger.info(`in getBaseRollupProof`); - logger.info(`Number of public inputs in baseRollupInput: ${baseRollupInput.kernelData.vk.numPublicInputs}`); + logger.debug(`Number of public inputs in baseRollupInput: ${baseRollupInput.kernelData.vk.numPublicInputs}`); baseRollupInput.kernelData.proof = await this.ensureValidProof( baseRollupInput.kernelData.proof, 'BaseRollupArtifact', diff --git a/yarn-project/circuit-types/src/stats/stats.ts b/yarn-project/circuit-types/src/stats/stats.ts index 450a6ec8744..a4a79fd0aaa 100644 --- a/yarn-project/circuit-types/src/stats/stats.ts +++ b/yarn-project/circuit-types/src/stats/stats.ts @@ -93,7 +93,8 @@ export type CircuitName = | 'public-kernel-tail' | 'avm-circuit' | 'empty-nested' - | 'private-kernel-empty'; + | 'private-kernel-empty' + | 'tube-circuit'; /** Stats for circuit simulation. */ export type CircuitSimulationStats = { diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts index b55aec38f24..190593832db 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts @@ -1,6 +1,5 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { ClientIvcProof } from '../client_ivc_proof.js'; import { PublicCallData } from './public_call_data.js'; import { PublicKernelData } from './public_kernel_data.js'; @@ -13,8 +12,6 @@ export class PublicKernelCircuitPrivateInputs { * Kernels are recursive and this is the data from the previous kernel. */ public readonly previousKernel: PublicKernelData, - - public readonly clientIvcProof: ClientIvcProof, /** * Public calldata assembled from the execution result and proof. */ @@ -26,7 +23,7 @@ export class PublicKernelCircuitPrivateInputs { * @returns - Buffer representation of the object. */ toBuffer() { - return serializeToBuffer(this.previousKernel, this.clientIvcProof, this.publicCall); + return serializeToBuffer(this.previousKernel, this.publicCall); } /** @@ -45,9 +42,8 @@ export class PublicKernelCircuitPrivateInputs { static fromBuffer(buffer: BufferReader | Buffer) { const reader = BufferReader.asReader(buffer); const previousKernel = reader.readObject(PublicKernelData); - const clientIvcProof = reader.readObject(ClientIvcProof); const publicCall = reader.readObject(PublicCallData); - return new PublicKernelCircuitPrivateInputs(previousKernel, clientIvcProof, publicCall); + return new PublicKernelCircuitPrivateInputs(previousKernel, publicCall); } /** diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 53f54b84bee..4f328cfa0d9 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -24,7 +24,6 @@ import { BaseParityInputs, BaseRollupInputs, CallContext, - ClientIvcProof, CombineHints, CombinedAccumulatedData, CombinedConstantData, @@ -660,11 +659,7 @@ export function makePublicCallData(seed = 1, full = false): PublicCallData { * @returns Public kernel inputs. */ export function makePublicKernelCircuitPrivateInputs(seed = 1): PublicKernelCircuitPrivateInputs { - return new PublicKernelCircuitPrivateInputs( - makePublicKernelData(seed), - ClientIvcProof.empty(), - makePublicCallData(seed + 0x1000), - ); + return new PublicKernelCircuitPrivateInputs(makePublicKernelData(seed), makePublicCallData(seed + 0x1000)); } export function makeCombineHints(seed = 1): CombineHints { diff --git a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts index f1d99085771..c5f1958bbc3 100644 --- a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts +++ b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts @@ -37,7 +37,6 @@ import { type RootRollupPublicInputs, StateDiffHints, type StateReference, - type TUBE_PROOF_LENGTH, VK_TREE_HEIGHT, type VerificationKeyAsFields, type VerificationKeyData, @@ -61,7 +60,7 @@ export type TreeNames = BaseTreeNames | 'L1ToL2MessageTree' | 'Archive'; // Builds the base rollup inputs, updating the contract, nullifier, and data trees in the process export async function buildBaseRollupInput( tx: ProcessedTx, - proof: RecursiveProof, + proof: RecursiveProof, globalVariables: GlobalVariables, db: MerkleTreeOperations, kernelVk: VerificationKeyData, diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index 3061483cba1..1a8f795b39e 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -37,7 +37,7 @@ import { type KernelCircuitPublicInputs, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, - type NESTED_RECURSIVE_PROOF_LENGTH, + NESTED_RECURSIVE_PROOF_LENGTH, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUM_BASE_PARITY_PER_ROOT_PARITY, PrivateKernelEmptyInputData, @@ -47,10 +47,12 @@ import { type RecursiveProof, type RootParityInput, RootParityInputs, + type TUBE_PROOF_LENGTH, TubeInputs, type VerificationKeyAsFields, VerificationKeyData, makeEmptyProof, + makeEmptyRecursiveProof, } from '@aztec/circuits.js'; import { makeTuple } from '@aztec/foundation/array'; import { padArrayEnd } from '@aztec/foundation/collection'; @@ -60,7 +62,7 @@ import { promiseWithResolvers } from '@aztec/foundation/promise'; import { BufferReader, type Tuple } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; import { elapsed } from '@aztec/foundation/timer'; -import { ProtocolCircuitVks, getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; +import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; import { Attributes, type TelemetryClient, type Tracer, trackSpan, wrapCallbackInSpan } from '@aztec/telemetry-client'; import { type MerkleTreeOperations } from '@aztec/world-state'; @@ -78,7 +80,7 @@ import { } from './block-building-helpers.js'; import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js'; import { type MergeRollupInputData, ProvingState, type TreeSnapshots } from './proving-state.js'; -import { TX_PROVING_CODE, TxProvingState } from './tx-proving-state.js'; +import { TX_PROVING_CODE, type TxProvingInstruction, TxProvingState } from './tx-proving-state.js'; const logger = createDebugLogger('aztec:prover:proving-orchestrator'); @@ -250,7 +252,7 @@ export class ProvingOrchestrator implements BlockProver { } const [inputs, treeSnapshots] = await this.prepareTransaction(tx, this.provingState); - this.enqueueFirstProof(inputs, treeSnapshots, tx, this.provingState); + this.enqueueFirstProofs(inputs, treeSnapshots, tx, this.provingState); } /** @@ -365,14 +367,16 @@ export class ProvingOrchestrator implements BlockProver { provingState: ProvingState, ) { // The padding tx contains the proof and vk, generated separately from the base inputs - // Copy these into the base rollup inputs + // Copy these into the base rollup inputs and enqueue the base rollup proof for (let i = 0; i < txInputs.length; i++) { txInputs[i].inputs.kernelData.vk = paddingTx.verificationKey; txInputs[i].inputs.kernelData.proof = paddingTx.recursiveProof; txInputs[i].inputs.kernelData.vkIndex = getVKIndex(paddingTx.verificationKey); txInputs[i].inputs.kernelData.vkPath = getVKSiblingPath(txInputs[i].inputs.kernelData.vkIndex); - this.enqueueFirstProof(txInputs[i].inputs, txInputs[i].snapshot, paddingTx, provingState); + const txProvingState = new TxProvingState(paddingTx, txInputs[i].inputs, txInputs[i].snapshot); + const txIndex = provingState.addNewTx(txProvingState); + this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState); } } @@ -475,32 +479,22 @@ export class ProvingOrchestrator implements BlockProver { const txInputs = await this.prepareBaseRollupInputs(provingState, tx); if (!txInputs) { // This should not be possible - throw new Error(`Unable to add padding transaction, preparing base inputs failed`); + throw new Error(`Unable to add transaction, preparing base inputs failed`); } return txInputs; } - private enqueueFirstProof( + private enqueueFirstProofs( inputs: BaseRollupInputs, treeSnapshots: TreeSnapshots, tx: ProcessedTx, provingState: ProvingState, ) { - const txProvingState = new TxProvingState( - tx, - inputs, - treeSnapshots, - ProtocolCircuitVks.PrivateKernelTailToPublicArtifact, - ); + const txProvingState = new TxProvingState(tx, inputs, treeSnapshots); const txIndex = provingState.addNewTx(txProvingState); + this.enqueueTube(provingState, txIndex); const numPublicKernels = txProvingState.getNumPublicKernels(); - if (!numPublicKernels) { - // no public functions, go straight to the base rollup - logger.debug(`Enqueueing base rollup for tx ${txIndex}`); - this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState); - return; - } - // Enqueue all of the VM/kernel proving requests + // Enqueue all of the VM proving requests // Rather than handle the Kernel Tail as a special case here, we will just handle it inside enqueueVM for (let i = 0; i < numPublicKernels; i++) { logger.debug(`Enqueueing public VM ${i} for tx ${txIndex}`); @@ -583,26 +577,17 @@ export class ProvingOrchestrator implements BlockProver { return; } - const getBaseInputsEmptyTx = async () => { - const inputs = new PrivateKernelEmptyInputData( - this.db.getInitialHeader(), - tx.data.constants.globalVariables.chainId, - tx.data.constants.globalVariables.version, - tx.data.constants.vkTreeRoot, - ); - - const proof = await this.prover.getEmptyTubeProof(inputs); - return await elapsed( - buildBaseRollupInput(tx, proof.proof, provingState.globalVariables, this.db, proof.verificationKey), - ); - }; - const getBaseInputsNonEmptyTx = async () => { - const proof = await this.prover.getTubeProof(new TubeInputs(tx.clientIvcProof)); - return await elapsed( - buildBaseRollupInput(tx, proof.tubeProof, provingState.globalVariables, this.db, proof.tubeVK), - ); - }; - const [ms, inputs] = tx.isEmpty ? await getBaseInputsEmptyTx() : await getBaseInputsNonEmptyTx(); + // We build tha base rollup inputs using a mock proof and verification key. + // These will be overwritten later once we have proven the tube circuit and any public kernels + const [ms, inputs] = await elapsed( + buildBaseRollupInput( + tx, + makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH), + provingState.globalVariables, + this.db, + VerificationKeyData.makeFake(), + ), + ); if (!tx.isEmpty) { this.metrics.recordBaseRollupInputs(ms); @@ -727,6 +712,44 @@ export class ProvingOrchestrator implements BlockProver { ); } + // Enqueues the tub circuit for a given transaction index + // Once completed, will enqueue the next circuit, either a public kernel or the base rollup + private enqueueTube(provingState: ProvingState, txIndex: number) { + if (!provingState?.verifyState()) { + logger.debug('Not running tube circuit, state invalid'); + return; + } + + const txProvingState = provingState.getTxProvingState(txIndex); + logger.debug(`Enqueuing tube circuit for tx index: ${txIndex}`); + + this.deferredProving( + provingState, + wrapCallbackInSpan( + this.tracer, + 'ProvingOrchestrator.prover.getTubeProof', + { + [Attributes.TX_HASH]: txProvingState.processedTx.hash.toString(), + [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server', + [Attributes.PROTOCOL_CIRCUIT_NAME]: 'tube-circuit' as CircuitName, + }, + signal => this.prover.getTubeProof(new TubeInputs(txProvingState.processedTx.clientIvcProof), signal), + ), + result => { + logger.debug(`Completed tube proof for tx index: ${txIndex}`); + const nextKernelRequest = txProvingState.getNextPublicKernelFromTubeProof(result.tubeProof, result.tubeVK); + this.checkAndEnqueueNextTxCircuit( + provingState, + txIndex, + -1, + result.tubeProof, + result.tubeVK, + nextKernelRequest, + ); + }, + ); + } + // Executes the merge rollup circuit and stored the output as intermediate state for the parent merge/root circuit // Enqueues the next level of merge if all inputs are available private enqueueMergeRollup( @@ -953,14 +976,14 @@ export class ProvingOrchestrator implements BlockProver { ); this.deferredProving(provingState, doAvmProving, proofAndVk => { logger.debug(`Proven VM for function index ${functionIndex} of tx index ${txIndex}`); - this.checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, proofAndVk.proof); + this.checkAndEnqueuePublicKernelFromVMProof(provingState, txIndex, functionIndex, proofAndVk.proof); }); } else { - this.checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, /*vmProof=*/ makeEmptyProof()); + this.checkAndEnqueuePublicKernelFromVMProof(provingState, txIndex, functionIndex, /*vmProof=*/ makeEmptyProof()); } } - private checkAndEnqueuePublicKernel( + private checkAndEnqueuePublicKernelFromVMProof( provingState: ProvingState, txIndex: number, functionIndex: number, @@ -978,6 +1001,47 @@ export class ProvingOrchestrator implements BlockProver { } } + // Takes a proof and verification key, passes it to the proving state before enqueueing the next proof + // This could be either a public kernel or the base rollup + // Alternatively, if we are still waiting on a public VM prof then it will continue waiting + private checkAndEnqueueNextTxCircuit( + provingState: ProvingState, + txIndex: number, + completedFunctionIndex: number, + proof: RecursiveProof | RecursiveProof, + verificationKey: VerificationKeyData, + nextKernelRequest: TxProvingInstruction, + ) { + const txProvingState = provingState.getTxProvingState(txIndex); + // What's the status of the next kernel? + if (nextKernelRequest.code === TX_PROVING_CODE.NOT_READY) { + // Must be waiting on a VM proof + return; + } + + if (nextKernelRequest.code === TX_PROVING_CODE.COMPLETED) { + // We must have completed all public function proving, we now move to the base rollup + logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`); + // Take the final proof and assign it to the base rollup inputs + txProvingState.baseRollupInputs.kernelData.proof = proof; + txProvingState.baseRollupInputs.kernelData.vk = verificationKey; + txProvingState.baseRollupInputs.kernelData.vkIndex = getVKIndex(verificationKey); + txProvingState.baseRollupInputs.kernelData.vkPath = getVKSiblingPath( + txProvingState.baseRollupInputs.kernelData.vkIndex, + ); + + this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState); + return; + } + // There must be another kernel ready to be proven + if (nextKernelRequest.function === undefined) { + // Should not be possible + throw new Error(`Error occurred, public function request undefined after kernel proof completed`); + } + + this.enqueuePublicKernel(provingState, txIndex, completedFunctionIndex + 1); + } + /** * Executes the kernel circuit for a public function, will enqueue the next kernel circuit if it's VM is already proven * or the base rollup circuit if there are no more kernels to be proven @@ -1018,37 +1082,17 @@ export class ProvingOrchestrator implements BlockProver { result => { const nextKernelRequest = txProvingState.getNextPublicKernelFromKernelProof( functionIndex, - // PUBLIC KERNEL: I want to pass a client ivc proof into here? result.proof, result.verificationKey, ); - // What's the status of the next kernel? - if (nextKernelRequest.code === TX_PROVING_CODE.NOT_READY) { - // Must be waiting on a VM proof - return; - } - - if (nextKernelRequest.code === TX_PROVING_CODE.COMPLETED) { - // We must have completed all public function proving, we now move to the base rollup - logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`); - // Take the final public tail proof and verification key and pass them to the base rollup - txProvingState.baseRollupInputs.kernelData.proof = result.proof; - txProvingState.baseRollupInputs.kernelData.vk = result.verificationKey; - txProvingState.baseRollupInputs.kernelData.vkIndex = getVKIndex(result.verificationKey); - txProvingState.baseRollupInputs.kernelData.vkPath = getVKSiblingPath( - txProvingState.baseRollupInputs.kernelData.vkIndex, - ); - - this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState); - return; - } - // There must be another kernel ready to be proven - if (nextKernelRequest.function === undefined) { - // Should not be possible - throw new Error(`Error occurred, public function request undefined after kernel proof completed`); - } - - this.enqueuePublicKernel(provingState, txIndex, functionIndex + 1); + this.checkAndEnqueueNextTxCircuit( + provingState, + txIndex, + functionIndex, + result.proof, + result.verificationKey, + nextKernelRequest, + ); }, ); } diff --git a/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts b/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts index 4ef6bd68d02..4f256b8fb7b 100644 --- a/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts +++ b/yarn-project/prover-client/src/orchestrator/tx-proving-state.ts @@ -11,6 +11,7 @@ import { type BaseRollupInputs, type NESTED_RECURSIVE_PROOF_LENGTH, type Proof, + type RECURSIVE_PROOF_LENGTH, type RecursiveProof, type VerificationKeyData, } from '@aztec/circuits.js'; @@ -48,23 +49,17 @@ export class TxProvingState { public readonly processedTx: ProcessedTx, public readonly baseRollupInputs: BaseRollupInputs, public readonly treeSnapshots: Map, - privateKernelVk: VerificationKeyData, ) { let previousProofType = PublicKernelType.NON_PUBLIC; for (let i = 0; i < processedTx.publicProvingRequests.length; i++) { const provingRequest = processedTx.publicProvingRequests[i]; const kernelRequest = provingRequest.type === AVM_REQUEST ? provingRequest.kernelRequest : provingRequest; - // the first circuit has a valid previous proof, it came from private - if (i === 0) { - kernelRequest.inputs.previousKernel.vk = privateKernelVk; - kernelRequest.inputs.previousKernel.clientIvcProof = processedTx.clientIvcProof; - } const vmRequest = provingRequest.type === AVM_REQUEST ? provingRequest : undefined; const publicFunction: PublicFunction = { vmRequest, vmProof: undefined, previousProofType, - previousKernelProven: i === 0, + previousKernelProven: false, publicKernelRequest: kernelRequest, }; this.publicFunctions.push(publicFunction); @@ -105,6 +100,37 @@ export class TxProvingState { return { code: TX_PROVING_CODE.READY, function: nextFunction }; } + // Updates the transaction's proving state after completion of a tube proof + // Returns an instruction as to the next stage of tx proving + public getNextPublicKernelFromTubeProof( + proof: RecursiveProof, + verificationKey: VerificationKeyData, + ): TxProvingInstruction { + const nextKernelIndex = 0; + if (nextKernelIndex >= this.publicFunctions.length) { + // The next kernel index is greater than our set of functions, we are done! + return { code: TX_PROVING_CODE.COMPLETED, function: undefined }; + } + + // There is more work to do, are we ready? + const nextFunction = this.publicFunctions[nextKernelIndex]; + + // pass both the proof and verification key forward to the next circuit + nextFunction.publicKernelRequest.inputs.previousKernel.proof = proof; + nextFunction.publicKernelRequest.inputs.previousKernel.vk = verificationKey; + + // We need to update this so the state machine knows this proof is ready + nextFunction.previousKernelProven = true; + nextFunction.previousProofType = PublicKernelType.NON_PUBLIC; + if (nextFunction.vmProof === undefined) { + // The VM proof for the next function is not ready + return { code: TX_PROVING_CODE.NOT_READY, function: undefined }; + } + + // The VM proof is ready, we can continue + return { code: TX_PROVING_CODE.READY, function: nextFunction }; + } + // Updates the transaction's proving state after completion of a VM proof // Returns an instruction as to the next stage of tx proving public getNextPublicKernelFromVMProof(provenIndex: number, proof: Proof): TxProvingInstruction { diff --git a/yarn-project/simulator/src/public/abstract_phase_manager.ts b/yarn-project/simulator/src/public/abstract_phase_manager.ts index fc89d685bc1..965caab647e 100644 --- a/yarn-project/simulator/src/public/abstract_phase_manager.ts +++ b/yarn-project/simulator/src/public/abstract_phase_manager.ts @@ -14,7 +14,6 @@ import { import { type AvmExecutionHints, AztecAddress, - ClientIvcProof, ContractStorageRead, ContractStorageUpdateRequest, Fr, @@ -361,7 +360,7 @@ export abstract class AbstractPhaseManager { const previousKernel = this.getPreviousKernelData(previousOutput, previousCircuit); // We take a deep copy (clone) of these inputs to be passed to the prover - const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, ClientIvcProof.empty(), callData); + const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData); switch (this.phase) { case PublicKernelType.SETUP: return [inputs.clone(), await this.publicKernel.publicKernelCircuitSetup(inputs), 'PublicKernelSetupArtifact'];