@aztec/simulator 0.45.1 → 0.46.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +2 -2
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +8 -8
  4. package/dest/acvm/serialize.d.ts.map +1 -1
  5. package/dest/acvm/serialize.js +2 -1
  6. package/dest/avm/opcodes/ec_add.js +3 -3
  7. package/dest/avm/opcodes/multi_scalar_mul.js +3 -3
  8. package/dest/client/client_execution_context.d.ts +0 -1
  9. package/dest/client/client_execution_context.d.ts.map +1 -1
  10. package/dest/client/client_execution_context.js +6 -6
  11. package/dest/client/execution_result.js +2 -2
  12. package/dest/client/simulator.d.ts.map +1 -1
  13. package/dest/client/simulator.js +2 -2
  14. package/dest/mocks/fixtures.js +2 -2
  15. package/dest/public/abstract_phase_manager.d.ts +8 -3
  16. package/dest/public/abstract_phase_manager.d.ts.map +1 -1
  17. package/dest/public/abstract_phase_manager.js +29 -16
  18. package/dest/public/app_logic_phase_manager.d.ts +3 -1
  19. package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
  20. package/dest/public/app_logic_phase_manager.js +11 -4
  21. package/dest/public/executor.d.ts.map +1 -1
  22. package/dest/public/executor.js +2 -3
  23. package/dest/public/public_kernel.d.ts.map +1 -1
  24. package/dest/public/public_kernel.js +6 -6
  25. package/dest/public/public_processor.d.ts.map +1 -1
  26. package/dest/public/public_processor.js +4 -2
  27. package/dest/public/setup_phase_manager.d.ts +3 -1
  28. package/dest/public/setup_phase_manager.d.ts.map +1 -1
  29. package/dest/public/setup_phase_manager.js +11 -4
  30. package/dest/public/side_effect_trace.d.ts +1 -3
  31. package/dest/public/side_effect_trace.d.ts.map +1 -1
  32. package/dest/public/side_effect_trace.js +4 -7
  33. package/dest/public/tail_phase_manager.d.ts +3 -1
  34. package/dest/public/tail_phase_manager.d.ts.map +1 -1
  35. package/dest/public/tail_phase_manager.js +8 -7
  36. package/dest/public/teardown_phase_manager.d.ts +3 -1
  37. package/dest/public/teardown_phase_manager.d.ts.map +1 -1
  38. package/dest/public/teardown_phase_manager.js +11 -4
  39. package/dest/rollup/rollup.d.ts.map +1 -1
  40. package/dest/rollup/rollup.js +7 -7
  41. package/package.json +9 -9
  42. package/src/acvm/oracle/oracle.ts +9 -5
  43. package/src/acvm/serialize.ts +1 -0
  44. package/src/avm/opcodes/ec_add.ts +2 -2
  45. package/src/avm/opcodes/multi_scalar_mul.ts +2 -2
  46. package/src/client/client_execution_context.ts +1 -5
  47. package/src/client/execution_result.ts +1 -1
  48. package/src/client/simulator.ts +0 -1
  49. package/src/mocks/fixtures.ts +1 -1
  50. package/src/public/abstract_phase_manager.ts +54 -17
  51. package/src/public/app_logic_phase_manager.ts +29 -10
  52. package/src/public/executor.ts +0 -3
  53. package/src/public/public_kernel.ts +5 -8
  54. package/src/public/public_processor.ts +4 -1
  55. package/src/public/setup_phase_manager.ts +16 -4
  56. package/src/public/side_effect_trace.ts +2 -8
  57. package/src/public/tail_phase_manager.ts +15 -5
  58. package/src/public/teardown_phase_manager.ts +16 -4
  59. package/src/rollup/rollup.ts +20 -10
@@ -35,7 +35,6 @@ import {
35
35
  MAX_PUBLIC_DATA_READS_PER_CALL,
36
36
  MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,
37
37
  MAX_UNENCRYPTED_LOGS_PER_CALL,
38
- MembershipWitness,
39
38
  NESTED_RECURSIVE_PROOF_LENGTH,
40
39
  NoteHash,
41
40
  Nullifier,
@@ -48,14 +47,19 @@ import {
48
47
  PublicKernelData,
49
48
  ReadRequest,
50
49
  RevertCode,
51
- VK_TREE_HEIGHT,
52
- VerificationKeyData,
53
50
  makeEmptyProof,
54
51
  makeEmptyRecursiveProof,
55
52
  } from '@aztec/circuits.js';
56
53
  import { computeVarArgsHash } from '@aztec/circuits.js/hash';
57
54
  import { padArrayEnd } from '@aztec/foundation/collection';
58
55
  import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
56
+ import {
57
+ type ProtocolArtifact,
58
+ ProtocolCircuitVkIndexes,
59
+ ProtocolCircuitVks,
60
+ getVKIndex,
61
+ getVKSiblingPath,
62
+ } from '@aztec/noir-protocol-circuits-types';
59
63
  import {
60
64
  type PublicExecutionRequest,
61
65
  type PublicExecutionResult,
@@ -106,6 +110,8 @@ export type TxPublicCallsResult = {
106
110
  publicProvingInformation: PublicProvingInformation[];
107
111
  /** The public kernel output at the end of the Tx */
108
112
  kernelOutput: PublicKernelCircuitPublicInputs;
113
+ /** The last circuit ran by this phase */
114
+ lastKernelArtifact: ProtocolArtifact;
109
115
  /** Unencrypted logs generated during the execution of this Tx */
110
116
  newUnencryptedLogs: UnencryptedFunctionL2Logs[];
111
117
  /** Revert reason, if any */
@@ -121,6 +127,8 @@ export type PhaseResult = {
121
127
  publicProvingRequests: PublicProvingRequest[];
122
128
  /** The output of the public kernel circuit simulation for this phase */
123
129
  publicKernelOutput: PublicKernelCircuitPublicInputs;
130
+ /** The last circuit ran by this phase */
131
+ lastKernelArtifact: ProtocolArtifact;
124
132
  /** The final output of the public kernel circuit for this phase */
125
133
  finalKernelOutput?: KernelCircuitPublicInputs;
126
134
  /** Revert reason, if any */
@@ -150,7 +158,11 @@ export abstract class AbstractPhaseManager {
150
158
  * @param tx - the tx to be processed
151
159
  * @param publicKernelPublicInputs - the output of the public kernel circuit for the previous phase
152
160
  */
153
- abstract handle(tx: Tx, publicKernelPublicInputs: PublicKernelCircuitPublicInputs): Promise<PhaseResult>;
161
+ abstract handle(
162
+ tx: Tx,
163
+ publicKernelPublicInputs: PublicKernelCircuitPublicInputs,
164
+ previousKernelArtifact: ProtocolArtifact,
165
+ ): Promise<PhaseResult>;
154
166
 
155
167
  public static extractEnqueuedPublicCallsByPhase(tx: Tx): Record<PublicKernelType, PublicCallRequest[]> {
156
168
  const data = tx.data.forPublic;
@@ -230,6 +242,7 @@ export abstract class AbstractPhaseManager {
230
242
  protected async processEnqueuedPublicCalls(
231
243
  tx: Tx,
232
244
  previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
245
+ previousKernelArtifact: ProtocolArtifact,
233
246
  ): Promise<TxPublicCallsResult> {
234
247
  const enqueuedCalls = this.extractEnqueuedPublicCalls(tx);
235
248
 
@@ -237,6 +250,7 @@ export abstract class AbstractPhaseManager {
237
250
  return {
238
251
  publicProvingInformation: [],
239
252
  kernelOutput: previousPublicKernelOutput,
253
+ lastKernelArtifact: previousKernelArtifact,
240
254
  newUnencryptedLogs: [],
241
255
  returnValues: [],
242
256
  gasUsed: Gas.empty(),
@@ -253,6 +267,7 @@ export abstract class AbstractPhaseManager {
253
267
  const transactionFee = this.getTransactionFee(tx, previousPublicKernelOutput);
254
268
  let gasUsed = Gas.empty();
255
269
  let kernelPublicOutput: PublicKernelCircuitPublicInputs = previousPublicKernelOutput;
270
+
256
271
  const enqueuedCallResults = [];
257
272
 
258
273
  for (const enqueuedCall of enqueuedCalls) {
@@ -313,8 +328,13 @@ export abstract class AbstractPhaseManager {
313
328
  })`,
314
329
  );
315
330
  const callData = await this.getPublicCallData(result, isExecutionRequest);
316
- const [privateInputs, publicInputs] = await this.runKernelCircuit(kernelPublicOutput, callData);
331
+ const [privateInputs, publicInputs, artifact] = await this.runKernelCircuit(
332
+ kernelPublicOutput,
333
+ previousKernelArtifact,
334
+ callData,
335
+ );
317
336
  kernelPublicOutput = publicInputs;
337
+ previousKernelArtifact = artifact;
318
338
 
319
339
  // Capture the inputs for later proving in the AVM and kernel.
320
340
  const publicProvingInformation: PublicProvingInformation = {
@@ -349,6 +369,7 @@ export abstract class AbstractPhaseManager {
349
369
  return {
350
370
  publicProvingInformation: [],
351
371
  kernelOutput: kernelPublicOutput,
372
+ lastKernelArtifact: previousKernelArtifact,
352
373
  newUnencryptedLogs: [],
353
374
  revertReason: result.revertReason,
354
375
  returnValues: [],
@@ -367,6 +388,7 @@ export abstract class AbstractPhaseManager {
367
388
  return {
368
389
  publicProvingInformation: provingInformationList,
369
390
  kernelOutput: kernelPublicOutput,
391
+ lastKernelArtifact: previousKernelArtifact,
370
392
  newUnencryptedLogs: newUnencryptedFunctionLogs,
371
393
  returnValues: enqueuedCallResults,
372
394
  gasUsed,
@@ -391,31 +413,46 @@ export abstract class AbstractPhaseManager {
391
413
 
392
414
  private async runKernelCircuit(
393
415
  previousOutput: PublicKernelCircuitPublicInputs,
416
+ previousCircuit: ProtocolArtifact,
394
417
  callData: PublicCallData,
395
- ): Promise<[PublicKernelCircuitPrivateInputs, PublicKernelCircuitPublicInputs]> {
396
- const previousKernel = this.getPreviousKernelData(previousOutput);
418
+ ): Promise<[PublicKernelCircuitPrivateInputs, PublicKernelCircuitPublicInputs, ProtocolArtifact]> {
419
+ const previousKernel = this.getPreviousKernelData(previousOutput, previousCircuit);
397
420
 
398
421
  // We take a deep copy (clone) of these inputs to be passed to the prover
399
422
  const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData);
400
423
  switch (this.phase) {
401
424
  case PublicKernelType.SETUP:
402
- return [inputs.clone(), await this.publicKernel.publicKernelCircuitSetup(inputs)];
425
+ return [inputs.clone(), await this.publicKernel.publicKernelCircuitSetup(inputs), 'PublicKernelSetupArtifact'];
403
426
  case PublicKernelType.APP_LOGIC:
404
- return [inputs.clone(), await this.publicKernel.publicKernelCircuitAppLogic(inputs)];
427
+ return [
428
+ inputs.clone(),
429
+ await this.publicKernel.publicKernelCircuitAppLogic(inputs),
430
+ 'PublicKernelAppLogicArtifact',
431
+ ];
405
432
  case PublicKernelType.TEARDOWN:
406
- return [inputs.clone(), await this.publicKernel.publicKernelCircuitTeardown(inputs)];
433
+ return [
434
+ inputs.clone(),
435
+ await this.publicKernel.publicKernelCircuitTeardown(inputs),
436
+ 'PublicKernelTeardownArtifact',
437
+ ];
407
438
  default:
408
439
  throw new Error(`No public kernel circuit for inputs`);
409
440
  }
410
441
  }
411
442
 
412
- protected getPreviousKernelData(previousOutput: PublicKernelCircuitPublicInputs): PublicKernelData {
413
- // The proof and verification key are not used in simulation
414
- const vk = VerificationKeyData.makeFake();
443
+ protected getPreviousKernelData(
444
+ previousOutput: PublicKernelCircuitPublicInputs,
445
+ previousCircuit: ProtocolArtifact,
446
+ ): PublicKernelData {
447
+ // The proof is not used in simulation
415
448
  const proof = makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH);
416
- const vkIndex = 0;
417
- const vkSiblingPath = MembershipWitness.random(VK_TREE_HEIGHT).siblingPath;
418
- return new PublicKernelData(previousOutput, proof, vk, vkIndex, vkSiblingPath);
449
+
450
+ const vk = ProtocolCircuitVks[previousCircuit];
451
+ const vkIndex = ProtocolCircuitVkIndexes[previousCircuit];
452
+
453
+ const leafIndex = getVKIndex(vk);
454
+
455
+ return new PublicKernelData(previousOutput, proof, vk, vkIndex, getVKSiblingPath(leafIndex));
419
456
  }
420
457
 
421
458
  protected async getPublicCallStackItem(result: PublicExecutionResult, isExecutionRequest = false) {
@@ -424,7 +461,7 @@ export abstract class AbstractPhaseManager {
424
461
 
425
462
  const callStackPreimages = await this.getPublicCallStackPreimages(result);
426
463
  const publicCallStackHashes = padArrayEnd(
427
- callStackPreimages.map(c => c.hash()),
464
+ callStackPreimages.map(c => c.getCompressed().hash()),
428
465
  Fr.ZERO,
429
466
  MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
430
467
  );
@@ -1,5 +1,6 @@
1
1
  import { PublicKernelType, type PublicProvingRequest, type Tx } from '@aztec/circuit-types';
2
2
  import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
3
+ import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types';
3
4
  import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator';
4
5
  import { type MerkleTreeOperations } from '@aztec/world-state';
5
6
 
@@ -24,7 +25,11 @@ export class AppLogicPhaseManager extends AbstractPhaseManager {
24
25
  super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase);
25
26
  }
26
27
 
27
- override async handle(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs) {
28
+ override async handle(
29
+ tx: Tx,
30
+ previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
31
+ previousCircuit: ProtocolArtifact,
32
+ ) {
28
33
  this.log.verbose(`Processing tx ${tx.getTxHash()}`);
29
34
  // add new contracts to the contracts db so that their functions may be found and called
30
35
  // TODO(#4073): This is catching only private deployments, when we add public ones, we'll
@@ -33,14 +38,21 @@ export class AppLogicPhaseManager extends AbstractPhaseManager {
33
38
  // TODO(#6464): Should we allow emitting contracts in the private setup phase?
34
39
  // if so, this should only add contracts that were deployed during private app logic.
35
40
  await this.publicContractsDB.addNewContracts(tx);
36
- const { publicProvingInformation, kernelOutput, newUnencryptedLogs, revertReason, returnValues, gasUsed } =
37
- await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput).catch(
38
- // if we throw for any reason other than simulation, we need to rollback and drop the TX
39
- async err => {
40
- await this.publicStateDB.rollbackToCommit();
41
- throw err;
42
- },
43
- );
41
+ const {
42
+ publicProvingInformation,
43
+ kernelOutput,
44
+ lastKernelArtifact,
45
+ newUnencryptedLogs,
46
+ revertReason,
47
+ returnValues,
48
+ gasUsed,
49
+ } = await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousCircuit).catch(
50
+ // if we throw for any reason other than simulation, we need to rollback and drop the TX
51
+ async err => {
52
+ await this.publicStateDB.rollbackToCommit();
53
+ throw err;
54
+ },
55
+ );
44
56
 
45
57
  if (revertReason) {
46
58
  // TODO(#6464): Should we allow emitting contracts in the private setup phase?
@@ -57,6 +69,13 @@ export class AppLogicPhaseManager extends AbstractPhaseManager {
57
69
  const publicProvingRequests: PublicProvingRequest[] = publicProvingInformation.map(info => {
58
70
  return makeAvmProvingRequest(info, PublicKernelType.APP_LOGIC);
59
71
  });
60
- return { publicProvingRequests, publicKernelOutput: kernelOutput, revertReason, returnValues, gasUsed };
72
+ return {
73
+ publicProvingRequests,
74
+ publicKernelOutput: kernelOutput,
75
+ lastKernelArtifact,
76
+ revertReason,
77
+ returnValues,
78
+ gasUsed,
79
+ };
61
80
  }
62
81
  }
@@ -99,9 +99,6 @@ export class PublicExecutor {
99
99
  bytecode,
100
100
  avmResult,
101
101
  fnName,
102
- /*requestSideEffectCounter=*/ executionRequest.callContext.sideEffectCounter,
103
- // NOTE: startSideEffectCounter is not the same as the executionRequest's sideEffectCounter
104
- // (which counts the request itself)
105
102
  );
106
103
 
107
104
  return publicExecutionResult;
@@ -8,10 +8,7 @@ import {
8
8
  import { createDebugLogger } from '@aztec/foundation/log';
9
9
  import { elapsed } from '@aztec/foundation/timer';
10
10
  import {
11
- SimulatedPublicKernelAppLogicArtifact,
12
- SimulatedPublicKernelSetupArtifact,
13
- SimulatedPublicKernelTailArtifact,
14
- SimulatedPublicKernelTeardownArtifact,
11
+ SimulatedServerCircuitArtifacts,
15
12
  convertSimulatedPublicInnerInputsToWitnessMap,
16
13
  convertSimulatedPublicInnerOutputFromWitnessMap,
17
14
  convertSimulatedPublicSetupInputsToWitnessMap,
@@ -50,7 +47,7 @@ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimu
50
47
  }
51
48
  const inputWitness = convertSimulatedPublicSetupInputsToWitnessMap(input);
52
49
  const [duration, witness] = await elapsed(() =>
53
- this.wasmSimulator.simulateCircuit(inputWitness, SimulatedPublicKernelSetupArtifact),
50
+ this.wasmSimulator.simulateCircuit(inputWitness, SimulatedServerCircuitArtifacts.PublicKernelSetupArtifact),
54
51
  );
55
52
  const result = convertSimulatedPublicSetupOutputFromWitnessMap(witness);
56
53
  this.log.debug(`Simulated public kernel setup circuit`, {
@@ -76,7 +73,7 @@ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimu
76
73
  }
77
74
  const inputWitness = convertSimulatedPublicInnerInputsToWitnessMap(input);
78
75
  const [duration, witness] = await elapsed(() =>
79
- this.wasmSimulator.simulateCircuit(inputWitness, SimulatedPublicKernelAppLogicArtifact),
76
+ this.wasmSimulator.simulateCircuit(inputWitness, SimulatedServerCircuitArtifacts.PublicKernelAppLogicArtifact),
80
77
  );
81
78
  const result = convertSimulatedPublicInnerOutputFromWitnessMap(witness);
82
79
  this.log.debug(`Simulated public kernel app logic circuit`, {
@@ -102,7 +99,7 @@ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimu
102
99
  }
103
100
  const inputWitness = convertSimulatedPublicTeardownInputsToWitnessMap(input);
104
101
  const [duration, witness] = await elapsed(() =>
105
- this.wasmSimulator.simulateCircuit(inputWitness, SimulatedPublicKernelTeardownArtifact),
102
+ this.wasmSimulator.simulateCircuit(inputWitness, SimulatedServerCircuitArtifacts.PublicKernelTeardownArtifact),
106
103
  );
107
104
  const result = convertSimulatedPublicTeardownOutputFromWitnessMap(witness);
108
105
  this.log.debug(`Simulated public kernel teardown circuit`, {
@@ -125,7 +122,7 @@ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimu
125
122
  ): Promise<KernelCircuitPublicInputs> {
126
123
  const inputWitness = convertSimulatedPublicTailInputsToWitnessMap(input);
127
124
  const [duration, witness] = await elapsed(() =>
128
- this.wasmSimulator.simulateCircuit(inputWitness, SimulatedPublicKernelTailArtifact),
125
+ this.wasmSimulator.simulateCircuit(inputWitness, SimulatedServerCircuitArtifacts.PublicKernelTailArtifact),
129
126
  );
130
127
  const result = convertSimulatedPublicTailOutputFromWitnessMap(witness);
131
128
  this.log.debug(`Simulated public kernel tail circuit`, {
@@ -23,6 +23,7 @@ import {
23
23
  } from '@aztec/circuits.js';
24
24
  import { times } from '@aztec/foundation/collection';
25
25
  import { createDebugLogger } from '@aztec/foundation/log';
26
+ import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types';
26
27
  import {
27
28
  PublicExecutor,
28
29
  type PublicStateDB,
@@ -232,17 +233,19 @@ export class PublicProcessor {
232
233
  );
233
234
  this.log.debug(`Beginning processing in phase ${phase?.phase} for tx ${tx.getTxHash()}`);
234
235
  let publicKernelPublicInput = tx.data.toPublicKernelCircuitPublicInputs();
236
+ let lastKernelArtifact: ProtocolArtifact = 'PrivateKernelTailToPublicArtifact'; // All txs with public calls must carry tail to public proofs
235
237
  let finalKernelOutput: KernelCircuitPublicInputs | undefined;
236
238
  let revertReason: SimulationError | undefined;
237
239
  const gasUsed: ProcessedTx['gasUsed'] = {};
238
240
  while (phase) {
239
- const output = await phase.handle(tx, publicKernelPublicInput);
241
+ const output = await phase.handle(tx, publicKernelPublicInput, lastKernelArtifact);
240
242
  gasUsed[phase.phase] = output.gasUsed;
241
243
  if (phase.phase === PublicKernelType.APP_LOGIC) {
242
244
  returnValues = output.returnValues;
243
245
  }
244
246
  publicProvingRequests.push(...output.publicProvingRequests);
245
247
  publicKernelPublicInput = output.publicKernelOutput;
248
+ lastKernelArtifact = output.lastKernelArtifact;
246
249
  finalKernelOutput = output.finalKernelOutput;
247
250
  revertReason ??= output.revertReason;
248
251
  phase = PhaseManagerFactory.phaseFromOutput(
@@ -1,5 +1,6 @@
1
1
  import { PublicKernelType, type PublicProvingRequest, type Tx } from '@aztec/circuit-types';
2
2
  import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
3
+ import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types';
3
4
  import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator';
4
5
  import { type MerkleTreeOperations } from '@aztec/world-state';
5
6
 
@@ -24,13 +25,17 @@ export class SetupPhaseManager extends AbstractPhaseManager {
24
25
  super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase);
25
26
  }
26
27
 
27
- override async handle(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs) {
28
+ override async handle(
29
+ tx: Tx,
30
+ previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
31
+ previousCircuit: ProtocolArtifact,
32
+ ) {
28
33
  this.log.verbose(`Processing tx ${tx.getTxHash()}`);
29
34
  // TODO(#6464): Should we allow emitting contracts in the private setup phase?
30
35
  // if so, this should only add contracts that were deployed during private app logic.
31
36
  await this.publicContractsDB.addNewContracts(tx);
32
- const { publicProvingInformation, kernelOutput, newUnencryptedLogs, revertReason, gasUsed } =
33
- await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput).catch(
37
+ const { publicProvingInformation, kernelOutput, lastKernelArtifact, newUnencryptedLogs, revertReason, gasUsed } =
38
+ await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousCircuit).catch(
34
39
  // the abstract phase manager throws if simulation gives error in a non-revertible phase
35
40
  async err => {
36
41
  await this.publicStateDB.rollbackToCommit();
@@ -44,6 +49,13 @@ export class SetupPhaseManager extends AbstractPhaseManager {
44
49
  const publicProvingRequests: PublicProvingRequest[] = publicProvingInformation.map(info => {
45
50
  return makeAvmProvingRequest(info, PublicKernelType.SETUP);
46
51
  });
47
- return { publicProvingRequests, publicKernelOutput: kernelOutput, revertReason, returnValues: [], gasUsed };
52
+ return {
53
+ publicProvingRequests,
54
+ publicKernelOutput: kernelOutput,
55
+ lastKernelArtifact,
56
+ revertReason,
57
+ returnValues: [],
58
+ gasUsed,
59
+ };
48
60
  }
49
61
  }
@@ -273,11 +273,9 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
273
273
  avmCallResults: AvmContractCallResult,
274
274
  /** Function name for logging */
275
275
  functionName: string = 'unknown',
276
- /** The side effect counter of the execution request itself */
277
- requestSideEffectCounter: number = this.startSideEffectCounter,
278
276
  ): PublicExecutionResult {
279
277
  return {
280
- executionRequest: createPublicExecutionRequest(requestSideEffectCounter, avmEnvironment),
278
+ executionRequest: createPublicExecutionRequest(avmEnvironment),
281
279
 
282
280
  startSideEffectCounter: new Fr(this.startSideEffectCounter),
283
281
  endSideEffectCounter: new Fr(this.sideEffectCounter),
@@ -319,17 +317,13 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
319
317
  /**
320
318
  * Helper function to create a public execution request from an AVM execution environment
321
319
  */
322
- function createPublicExecutionRequest(
323
- requestSideEffectCounter: number,
324
- avmEnvironment: AvmExecutionEnvironment,
325
- ): PublicExecutionRequest {
320
+ function createPublicExecutionRequest(avmEnvironment: AvmExecutionEnvironment): PublicExecutionRequest {
326
321
  const callContext = CallContext.from({
327
322
  msgSender: avmEnvironment.sender,
328
323
  storageContractAddress: avmEnvironment.storageAddress,
329
324
  functionSelector: avmEnvironment.functionSelector,
330
325
  isDelegateCall: avmEnvironment.isDelegateCall,
331
326
  isStaticCall: avmEnvironment.isStaticCall,
332
- sideEffectCounter: requestSideEffectCounter,
333
327
  });
334
328
  return {
335
329
  contractAddress: avmEnvironment.address,
@@ -10,6 +10,7 @@ import {
10
10
  PublicKernelTailCircuitPrivateInputs,
11
11
  mergeAccumulatedData,
12
12
  } from '@aztec/circuits.js';
13
+ import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types';
13
14
  import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator';
14
15
  import { type MerkleTreeOperations } from '@aztec/world-state';
15
16
 
@@ -31,9 +32,13 @@ export class TailPhaseManager extends AbstractPhaseManager {
31
32
  super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase);
32
33
  }
33
34
 
34
- override async handle(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs) {
35
+ override async handle(
36
+ tx: Tx,
37
+ previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
38
+ previousKernelArtifact: ProtocolArtifact,
39
+ ) {
35
40
  this.log.verbose(`Processing tx ${tx.getTxHash()}`);
36
- const [inputs, finalKernelOutput] = await this.simulate(previousPublicKernelOutput).catch(
41
+ const [inputs, finalKernelOutput] = await this.simulate(previousPublicKernelOutput, previousKernelArtifact).catch(
37
42
  // the abstract phase manager throws if simulation gives error in non-revertible phase
38
43
  async err => {
39
44
  await this.publicStateDB.rollbackToCommit();
@@ -50,6 +55,7 @@ export class TailPhaseManager extends AbstractPhaseManager {
50
55
  return {
51
56
  publicProvingRequests: [kernelRequest],
52
57
  publicKernelOutput: previousPublicKernelOutput,
58
+ lastKernelArtifact: 'PublicKernelTailArtifact' as ProtocolArtifact,
53
59
  finalKernelOutput,
54
60
  returnValues: [],
55
61
  };
@@ -57,14 +63,18 @@ export class TailPhaseManager extends AbstractPhaseManager {
57
63
 
58
64
  private async simulate(
59
65
  previousOutput: PublicKernelCircuitPublicInputs,
66
+ previousKernelArtifact: ProtocolArtifact,
60
67
  ): Promise<[PublicKernelTailCircuitPrivateInputs, KernelCircuitPublicInputs]> {
61
- const inputs = await this.buildPrivateInputs(previousOutput);
68
+ const inputs = await this.buildPrivateInputs(previousOutput, previousKernelArtifact);
62
69
  // We take a deep copy (clone) of these to pass to the prover
63
70
  return [inputs.clone(), await this.publicKernel.publicKernelCircuitTail(inputs)];
64
71
  }
65
72
 
66
- private async buildPrivateInputs(previousOutput: PublicKernelCircuitPublicInputs) {
67
- const previousKernel = this.getPreviousKernelData(previousOutput);
73
+ private async buildPrivateInputs(
74
+ previousOutput: PublicKernelCircuitPublicInputs,
75
+ previousKernelArtifact: ProtocolArtifact,
76
+ ) {
77
+ const previousKernel = this.getPreviousKernelData(previousOutput, previousKernelArtifact);
68
78
 
69
79
  const { validationRequests, endNonRevertibleData: nonRevertibleData, end: revertibleData } = previousOutput;
70
80
 
@@ -6,6 +6,7 @@ import {
6
6
  type Header,
7
7
  type PublicKernelCircuitPublicInputs,
8
8
  } from '@aztec/circuits.js';
9
+ import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types';
9
10
  import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator';
10
11
  import { type MerkleTreeOperations } from '@aztec/world-state';
11
12
 
@@ -32,10 +33,14 @@ export class TeardownPhaseManager extends AbstractPhaseManager {
32
33
  super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase);
33
34
  }
34
35
 
35
- override async handle(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs) {
36
+ override async handle(
37
+ tx: Tx,
38
+ previousPublicKernelOutput: PublicKernelCircuitPublicInputs,
39
+ previousKernelArtifact: ProtocolArtifact,
40
+ ) {
36
41
  this.log.verbose(`Processing tx ${tx.getTxHash()}`);
37
- const { publicProvingInformation, kernelOutput, newUnencryptedLogs, revertReason, gasUsed } =
38
- await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput).catch(
42
+ const { publicProvingInformation, kernelOutput, lastKernelArtifact, newUnencryptedLogs, revertReason, gasUsed } =
43
+ await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousKernelArtifact).catch(
39
44
  // the abstract phase manager throws if simulation gives error in a non-revertible phase
40
45
  async err => {
41
46
  await this.publicStateDB.rollbackToCommit();
@@ -55,7 +60,14 @@ export class TeardownPhaseManager extends AbstractPhaseManager {
55
60
  const publicProvingRequests: PublicProvingRequest[] = publicProvingInformation.map(info => {
56
61
  return makeAvmProvingRequest(info, PublicKernelType.TEARDOWN);
57
62
  });
58
- return { publicProvingRequests, publicKernelOutput: kernelOutput, revertReason, returnValues: [], gasUsed };
63
+ return {
64
+ publicProvingRequests,
65
+ publicKernelOutput: kernelOutput,
66
+ lastKernelArtifact,
67
+ revertReason,
68
+ returnValues: [],
69
+ gasUsed,
70
+ };
59
71
  }
60
72
 
61
73
  protected override getTransactionFee(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs): Fr {
@@ -12,11 +12,7 @@ import {
12
12
  import { createDebugLogger } from '@aztec/foundation/log';
13
13
  import { elapsed } from '@aztec/foundation/timer';
14
14
  import {
15
- BaseParityArtifact,
16
- MergeRollupArtifact,
17
- RootParityArtifact,
18
- RootRollupArtifact,
19
- SimulatedBaseRollupArtifact,
15
+ SimulatedServerCircuitArtifacts,
20
16
  convertBaseParityInputsToWitnessMap,
21
17
  convertBaseParityOutputsFromWitnessMap,
22
18
  convertMergeRollupInputsToWitnessMap,
@@ -87,7 +83,10 @@ export class RealRollupCircuitSimulator implements RollupSimulator {
87
83
  public async baseParityCircuit(inputs: BaseParityInputs): Promise<ParityPublicInputs> {
88
84
  const witnessMap = convertBaseParityInputsToWitnessMap(inputs);
89
85
 
90
- const witness = await this.simulationProvider.simulateCircuit(witnessMap, BaseParityArtifact);
86
+ const witness = await this.simulationProvider.simulateCircuit(
87
+ witnessMap,
88
+ SimulatedServerCircuitArtifacts.BaseParityArtifact,
89
+ );
91
90
 
92
91
  const result = convertBaseParityOutputsFromWitnessMap(witness);
93
92
 
@@ -102,7 +101,10 @@ export class RealRollupCircuitSimulator implements RollupSimulator {
102
101
  public async rootParityCircuit(inputs: RootParityInputs): Promise<ParityPublicInputs> {
103
102
  const witnessMap = convertRootParityInputsToWitnessMap(inputs);
104
103
 
105
- const witness = await this.simulationProvider.simulateCircuit(witnessMap, RootParityArtifact);
104
+ const witness = await this.simulationProvider.simulateCircuit(
105
+ witnessMap,
106
+ SimulatedServerCircuitArtifacts.RootParityArtifact,
107
+ );
106
108
 
107
109
  const result = convertRootParityOutputsFromWitnessMap(witness);
108
110
 
@@ -117,7 +119,10 @@ export class RealRollupCircuitSimulator implements RollupSimulator {
117
119
  public async baseRollupCircuit(input: BaseRollupInputs): Promise<BaseOrMergeRollupPublicInputs> {
118
120
  const witnessMap = convertSimulatedBaseRollupInputsToWitnessMap(input);
119
121
 
120
- const witness = await this.simulationProvider.simulateCircuit(witnessMap, SimulatedBaseRollupArtifact);
122
+ const witness = await this.simulationProvider.simulateCircuit(
123
+ witnessMap,
124
+ SimulatedServerCircuitArtifacts.BaseRollupArtifact,
125
+ );
121
126
 
122
127
  const result = convertSimulatedBaseRollupOutputsFromWitnessMap(witness);
123
128
 
@@ -131,7 +136,10 @@ export class RealRollupCircuitSimulator implements RollupSimulator {
131
136
  public async mergeRollupCircuit(input: MergeRollupInputs): Promise<BaseOrMergeRollupPublicInputs> {
132
137
  const witnessMap = convertMergeRollupInputsToWitnessMap(input);
133
138
 
134
- const witness = await this.wasmSimulator.simulateCircuit(witnessMap, MergeRollupArtifact);
139
+ const witness = await this.wasmSimulator.simulateCircuit(
140
+ witnessMap,
141
+ SimulatedServerCircuitArtifacts.MergeRollupArtifact,
142
+ );
135
143
 
136
144
  const result = convertMergeRollupOutputsFromWitnessMap(witness);
137
145
 
@@ -146,7 +154,9 @@ export class RealRollupCircuitSimulator implements RollupSimulator {
146
154
  public async rootRollupCircuit(input: RootRollupInputs): Promise<RootRollupPublicInputs> {
147
155
  const witnessMap = convertRootRollupInputsToWitnessMap(input);
148
156
 
149
- const [duration, witness] = await elapsed(() => this.wasmSimulator.simulateCircuit(witnessMap, RootRollupArtifact));
157
+ const [duration, witness] = await elapsed(() =>
158
+ this.wasmSimulator.simulateCircuit(witnessMap, SimulatedServerCircuitArtifacts.RootRollupArtifact),
159
+ );
150
160
 
151
161
  const result = convertRootRollupOutputsFromWitnessMap(witness);
152
162