Skip to content

Commit 9693d6e

Browse files
nchamoaztec-bot
authored andcommitted
refactor(pxe): prefetch updated class id hints per unique contract (#23130)
1 parent 5f63954 commit 9693d6e

2 files changed

Lines changed: 56 additions & 7 deletions

File tree

yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.test.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,20 @@ describe('Private Kernel Sequencer', () => {
5454
{
5555
publicInputs,
5656
childPublicInputs = [],
57+
address = contractAddress,
58+
nestedResults,
5759
}: {
5860
publicInputs?: PrivateCircuitPublicInputs;
5961
childPublicInputs?: PrivateCircuitPublicInputs[];
62+
address?: AztecAddress;
63+
nestedResults?: PrivateCallExecutionResult[];
6064
} = {},
6165
): PrivateCallExecutionResult => {
6266
if (!publicInputs) {
6367
publicInputs = PrivateCircuitPublicInputs.empty();
6468
}
6569
publicInputs.callContext.functionSelector = new FunctionSelector(fnName.charCodeAt(0));
66-
publicInputs.callContext.contractAddress = contractAddress;
70+
publicInputs.callContext.contractAddress = address;
6771

6872
return new PrivateCallExecutionResult(
6973
Buffer.alloc(0),
@@ -75,9 +79,10 @@ describe('Private Kernel Sequencer', () => {
7579
[],
7680
[],
7781
[],
78-
(dependencies[fnName] || []).map((name, i) =>
79-
createCallExecutionResult(name, { publicInputs: childPublicInputs[i] }),
80-
),
82+
nestedResults ??
83+
(dependencies[fnName] || []).map((name, i) =>
84+
createCallExecutionResult(name, { publicInputs: childPublicInputs[i] }),
85+
),
8186
[],
8287
);
8388
};
@@ -360,4 +365,22 @@ describe('Private Kernel Sequencer', () => {
360365
expect(proofCreator.simulateReset).toHaveBeenCalledTimes(3);
361366
expect(proofCreator.simulateTail).toHaveBeenCalledTimes(1);
362367
});
368+
369+
it('fetches updated class id hints once per unique contract address', async () => {
370+
const contractAddressB = AztecAddress.fromBigInt(111111n);
371+
372+
// a { b {} c {} }
373+
// a and c use contractAddress, b uses contractAddressB → 2 unique contracts, 3 executions.
374+
dependencies = {};
375+
const bExec = createCallExecutionResult('b', { address: contractAddressB });
376+
const cExec = createCallExecutionResult('c');
377+
const aExec = createCallExecutionResult('a', { nestedResults: [bExec, cExec] });
378+
379+
const executionResult = new PrivateExecutionResult(aExec, Fr.zero(), []);
380+
await prove(executionResult);
381+
382+
expect(oracle.getUpdatedClassIdHints).toHaveBeenCalledTimes(2);
383+
expect(oracle.getUpdatedClassIdHints).toHaveBeenCalledWith(contractAddress);
384+
expect(oracle.getUpdatedClassIdHints).toHaveBeenCalledWith(contractAddressB);
385+
});
363386
});

yarn-project/pxe/src/private_kernel/private_kernel_execution_prover.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { uniqueBy } from '@aztec/foundation/collection';
12
import { vkAsFieldsMegaHonk } from '@aztec/foundation/crypto/keys';
23
import { Fr } from '@aztec/foundation/curves/bn254';
34
import { 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';
2628
import { ChonkProof, ChonkProofWithPublicInputs } from '@aztec/stdlib/proofs';
2729
import {
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

Comments
 (0)