1+ import { uniqueBy } from '@aztec/foundation/collection' ;
12import { vkAsFieldsMegaHonk } from '@aztec/foundation/crypto/keys' ;
23import { Fr } from '@aztec/foundation/curves/bn254' ;
34import { type Logger , type LoggerBindings , createLogger } from '@aztec/foundation/log' ;
@@ -22,12 +23,14 @@ import {
2223 PrivateKernelTailCircuitPrivateInputs ,
2324 type PrivateKernelTailCircuitPublicInputs ,
2425 PrivateVerificationKeyHints ,
26+ type UpdatedClassIdHints ,
2527} from '@aztec/stdlib/kernel' ;
2628import { ChonkProof , ChonkProofWithPublicInputs } from '@aztec/stdlib/proofs' ;
2729import {
2830 type PrivateCallExecutionResult ,
2931 type PrivateExecutionResult ,
3032 TxRequest ,
33+ collectNested ,
3134 collectNoteHashNullifierCounterMap ,
3235 getFinalMinRevertibleSideEffectCounter ,
3336} from '@aztec/stdlib/tx' ;
@@ -108,6 +111,8 @@ export class PrivateKernelExecutionProver {
108111 const minRevertibleSideEffectCounter = getFinalMinRevertibleSideEffectCounter ( executionResult ) ;
109112 const splitCounter = isPrivateOnlyTx ? 0 : minRevertibleSideEffectCounter ;
110113
114+ const updatedClassIdHintsMap = await this . prefetchUpdatedClassIdHints ( executionResult ) ;
115+
111116 while ( executionStack . length ) {
112117 if ( ! firstIteration ) {
113118 let resetBuilder = new PrivateKernelResetPrivateInputsBuilder (
@@ -161,7 +166,7 @@ export class PrivateKernelExecutionProver {
161166 } ,
162167 } ) ;
163168
164- const privateCallData = await this . createPrivateCallData ( currentExecution ) ;
169+ const privateCallData = await this . createPrivateCallData ( currentExecution , updatedClassIdHintsMap ) ;
165170
166171 if ( firstIteration ) {
167172 const witgenTimer = new Timer ( ) ;
@@ -401,7 +406,28 @@ export class PrivateKernelExecutionProver {
401406 ) ;
402407 }
403408
404- private async createPrivateCallData ( { publicInputs, vk : vkAsBuffer } : PrivateCallExecutionResult ) {
409+ /** Prefetches updated class id hints for all unique contracts in the execution tree in parallel. */
410+ private async prefetchUpdatedClassIdHints (
411+ executionResult : PrivateExecutionResult ,
412+ ) : Promise < Map < string , UpdatedClassIdHints > > {
413+ const allAddresses = collectNested ( [ executionResult . entrypoint ] , exec => [
414+ exec . publicInputs . callContext . contractAddress ,
415+ ] ) ;
416+ const uniqueAddresses = uniqueBy ( allAddresses , a => a . toString ( ) ) ;
417+ return new Map < string , UpdatedClassIdHints > (
418+ await Promise . all (
419+ uniqueAddresses . map (
420+ async addr =>
421+ [ addr . toString ( ) , await this . oracle . getUpdatedClassIdHints ( addr ) ] as [ string , UpdatedClassIdHints ] ,
422+ ) ,
423+ ) ,
424+ ) ;
425+ }
426+
427+ private async createPrivateCallData (
428+ { publicInputs, vk : vkAsBuffer } : PrivateCallExecutionResult ,
429+ updatedClassIdHintsMap : Map < string , UpdatedClassIdHints > ,
430+ ) {
405431 const { contractAddress, functionSelector } = publicInputs . callContext ;
406432
407433 const vkAsFields = await vkAsFieldsMegaHonk ( vkAsBuffer ) ;
@@ -417,7 +443,7 @@ export class PrivateKernelExecutionProver {
417443 const { artifactHash : contractClassArtifactHash , publicBytecodeCommitment : contractClassPublicBytecodeCommitment } =
418444 await this . oracle . getContractClassIdPreimage ( currentContractClassId ) ;
419445
420- const updatedClassIdHints = await this . oracle . getUpdatedClassIdHints ( contractAddress ) ;
446+ const updatedClassIdHints = updatedClassIdHintsMap . get ( contractAddress . toString ( ) ) ! ;
421447
422448 return PrivateCallData . from ( {
423449 publicInputs,
0 commit comments