@aztec/simulator 0.45.0 → 0.46.1

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 (67) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +4 -4
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +13 -13
  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 +9 -9
  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 +5 -5
  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 +37 -24
  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/execution.d.ts +4 -4
  22. package/dest/public/execution.d.ts.map +1 -1
  23. package/dest/public/execution.js +5 -5
  24. package/dest/public/executor.d.ts.map +1 -1
  25. package/dest/public/executor.js +2 -3
  26. package/dest/public/hints_builder.d.ts +3 -3
  27. package/dest/public/hints_builder.d.ts.map +1 -1
  28. package/dest/public/hints_builder.js +1 -1
  29. package/dest/public/public_kernel.d.ts.map +1 -1
  30. package/dest/public/public_kernel.js +6 -6
  31. package/dest/public/public_processor.d.ts.map +1 -1
  32. package/dest/public/public_processor.js +4 -2
  33. package/dest/public/setup_phase_manager.d.ts +3 -1
  34. package/dest/public/setup_phase_manager.d.ts.map +1 -1
  35. package/dest/public/setup_phase_manager.js +11 -4
  36. package/dest/public/side_effect_trace.d.ts +3 -5
  37. package/dest/public/side_effect_trace.d.ts.map +1 -1
  38. package/dest/public/side_effect_trace.js +16 -19
  39. package/dest/public/tail_phase_manager.d.ts +3 -1
  40. package/dest/public/tail_phase_manager.d.ts.map +1 -1
  41. package/dest/public/tail_phase_manager.js +10 -9
  42. package/dest/public/teardown_phase_manager.d.ts +3 -1
  43. package/dest/public/teardown_phase_manager.d.ts.map +1 -1
  44. package/dest/public/teardown_phase_manager.js +11 -4
  45. package/dest/rollup/rollup.d.ts.map +1 -1
  46. package/dest/rollup/rollup.js +7 -7
  47. package/package.json +9 -9
  48. package/src/acvm/oracle/oracle.ts +13 -23
  49. package/src/acvm/serialize.ts +1 -0
  50. package/src/avm/opcodes/ec_add.ts +2 -2
  51. package/src/avm/opcodes/multi_scalar_mul.ts +2 -2
  52. package/src/client/client_execution_context.ts +4 -8
  53. package/src/client/execution_result.ts +1 -1
  54. package/src/client/simulator.ts +0 -1
  55. package/src/mocks/fixtures.ts +4 -4
  56. package/src/public/abstract_phase_manager.ts +65 -28
  57. package/src/public/app_logic_phase_manager.ts +29 -10
  58. package/src/public/execution.ts +9 -9
  59. package/src/public/executor.ts +0 -3
  60. package/src/public/hints_builder.ts +3 -3
  61. package/src/public/public_kernel.ts +5 -8
  62. package/src/public/public_processor.ts +4 -1
  63. package/src/public/setup_phase_manager.ts +16 -4
  64. package/src/public/side_effect_trace.ts +13 -19
  65. package/src/public/tail_phase_manager.ts +19 -9
  66. package/src/public/teardown_phase_manager.ts +16 -4
  67. package/src/rollup/rollup.ts +20 -10
@@ -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
  }
@@ -48,11 +48,11 @@ export interface PublicExecutionResult {
48
48
  /** The contract storage update requests performed by the function. */
49
49
  contractStorageUpdateRequests: ContractStorageUpdateRequest[];
50
50
  /** The new note hashes to be inserted into the note hashes tree. */
51
- newNoteHashes: NoteHash[];
51
+ noteHashes: NoteHash[];
52
52
  /** The new l2 to l1 messages generated in this call. */
53
- newL2ToL1Messages: L2ToL1Message[];
53
+ l2ToL1Messages: L2ToL1Message[];
54
54
  /** The new nullifiers to be inserted into the nullifier tree. */
55
- newNullifiers: Nullifier[];
55
+ nullifiers: Nullifier[];
56
56
  /** The note hash read requests emitted in this call. */
57
57
  noteHashReadRequests: ReadRequest[];
58
58
  /** The nullifier read requests emitted in this call. */
@@ -115,17 +115,17 @@ export function isPublicExecutionResult(
115
115
  */
116
116
 
117
117
  export function checkValidStaticCall(
118
- newNoteHashes: NoteHash[],
119
- newNullifiers: Nullifier[],
118
+ noteHashes: NoteHash[],
119
+ nullifiers: Nullifier[],
120
120
  contractStorageUpdateRequests: ContractStorageUpdateRequest[],
121
- newL2ToL1Messages: L2ToL1Message[],
121
+ l2ToL1Messages: L2ToL1Message[],
122
122
  unencryptedLogs: UnencryptedFunctionL2Logs,
123
123
  ) {
124
124
  if (
125
125
  contractStorageUpdateRequests.length > 0 ||
126
- newNoteHashes.length > 0 ||
127
- newNullifiers.length > 0 ||
128
- newL2ToL1Messages.length > 0 ||
126
+ noteHashes.length > 0 ||
127
+ nullifiers.length > 0 ||
128
+ l2ToL1Messages.length > 0 ||
129
129
  unencryptedLogs.logs.length > 0
130
130
  ) {
131
131
  throw new Error('Static call cannot update the state, emit L2->L1 messages or generate logs');
@@ -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;
@@ -1,7 +1,7 @@
1
1
  import { MerkleTreeId } from '@aztec/circuit-types';
2
2
  import {
3
3
  type Fr,
4
- type MAX_NEW_NULLIFIERS_PER_TX,
4
+ type MAX_NULLIFIERS_PER_TX,
5
5
  type MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX,
6
6
  MAX_NULLIFIER_READ_REQUESTS_PER_TX,
7
7
  type MAX_PUBLIC_DATA_HINTS,
@@ -30,7 +30,7 @@ export class HintsBuilder {
30
30
 
31
31
  async getNullifierReadRequestHints(
32
32
  nullifierReadRequests: Tuple<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
33
- pendingNullifiers: Tuple<Nullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
33
+ pendingNullifiers: Tuple<Nullifier, typeof MAX_NULLIFIERS_PER_TX>,
34
34
  ) {
35
35
  return (
36
36
  await buildSiloedNullifierReadRequestHints(
@@ -45,7 +45,7 @@ export class HintsBuilder {
45
45
 
46
46
  getNullifierNonExistentReadRequestHints(
47
47
  nullifierNonExistentReadRequests: Tuple<ScopedReadRequest, typeof MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX>,
48
- pendingNullifiers: Tuple<Nullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
48
+ pendingNullifiers: Tuple<Nullifier, typeof MAX_NULLIFIERS_PER_TX>,
49
49
  ) {
50
50
  return buildNullifierNonExistentReadRequestHints(this, nullifierNonExistentReadRequests, pendingNullifiers);
51
51
  }
@@ -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
  }
@@ -16,7 +16,6 @@ import {
16
16
  Nullifier,
17
17
  ReadRequest,
18
18
  } from '@aztec/circuits.js';
19
- import { EventSelector } from '@aztec/foundation/abi';
20
19
  import { Fr } from '@aztec/foundation/fields';
21
20
  import { createDebugLogger } from '@aztec/foundation/log';
22
21
  import { type ContractInstanceWithAddress } from '@aztec/types/contracts';
@@ -39,11 +38,11 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
39
38
  private contractStorageUpdateRequests: ContractStorageUpdateRequest[] = [];
40
39
 
41
40
  private noteHashReadRequests: ReadRequest[] = [];
42
- private newNoteHashes: NoteHash[] = [];
41
+ private noteHashes: NoteHash[] = [];
43
42
 
44
43
  private nullifierReadRequests: ReadRequest[] = [];
45
44
  private nullifierNonExistentReadRequests: ReadRequest[] = [];
46
- private newNullifiers: Nullifier[] = [];
45
+ private nullifiers: Nullifier[] = [];
47
46
 
48
47
  private l1ToL2MsgReadRequests: ReadRequest[] = [];
49
48
  private newL2ToL1Messages: L2ToL1Message[] = [];
@@ -122,7 +121,7 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
122
121
  // IS there, and the AVM circuit should accept THAT noteHash as a hint. The circuit will then compare
123
122
  // the noteHash against the one provided by the user code to determine what to return to the user (exists or not),
124
123
  // and will then propagate the actually-present noteHash to its public inputs.
125
- this.newNoteHashes.push(new NoteHash(noteHash, this.sideEffectCounter));
124
+ this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter));
126
125
  this.logger.debug(`NEW_NOTE_HASH cnt: ${this.sideEffectCounter}`);
127
126
  this.incrementSideEffectCounter();
128
127
  }
@@ -147,7 +146,7 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
147
146
  public traceNewNullifier(_storageAddress: Fr, nullifier: Fr) {
148
147
  // TODO(4805): check if some threshold is reached for max new nullifier
149
148
  // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call
150
- this.newNullifiers.push(new Nullifier(nullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO));
149
+ this.nullifiers.push(new Nullifier(nullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO));
151
150
  this.logger.debug(`NEW_NULLIFIER cnt: ${this.sideEffectCounter}`);
152
151
  this.incrementSideEffectCounter();
153
152
  }
@@ -177,14 +176,15 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
177
176
  // TODO(4805): check if some threshold is reached for max logs
178
177
  const ulog = new UnencryptedL2Log(
179
178
  AztecAddress.fromField(contractAddress),
180
- // TODO(#7198): Remove event selector from UnencryptedL2Log
181
- EventSelector.fromField(new Fr(0)),
182
179
  Buffer.concat(log.map(f => f.toBuffer())),
183
180
  );
184
181
  const basicLogHash = Fr.fromBuffer(ulog.hash());
185
182
  this.unencryptedLogs.push(ulog);
186
183
  this.allUnencryptedLogs.push(ulog);
187
- // TODO(6578): explain magic number 4 here
184
+ // We want the length of the buffer output from function_l2_logs -> toBuffer to equal the stored log length in the kernels.
185
+ // The kernels store the length of the processed log as 4 bytes; thus for this length value to match the log length stored in the kernels,
186
+ // we need to add four to the length here.
187
+ // https://github.com/AztecProtocol/aztec-packages/issues/6578#issuecomment-2125003435
188
188
  this.unencryptedLogsHashes.push(new LogHash(basicLogHash, this.sideEffectCounter, new Fr(ulog.length + 4)));
189
189
  this.logger.debug(`NEW_UNENCRYPTED_LOG cnt: ${this.sideEffectCounter}`);
190
190
  this.incrementSideEffectCounter();
@@ -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),
@@ -294,12 +292,12 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
294
292
  contractStorageReads: this.contractStorageReads,
295
293
  contractStorageUpdateRequests: this.contractStorageUpdateRequests,
296
294
  noteHashReadRequests: this.noteHashReadRequests,
297
- newNoteHashes: this.newNoteHashes,
295
+ noteHashes: this.noteHashes,
298
296
  nullifierReadRequests: this.nullifierReadRequests,
299
297
  nullifierNonExistentReadRequests: this.nullifierNonExistentReadRequests,
300
- newNullifiers: this.newNullifiers,
298
+ nullifiers: this.nullifiers,
301
299
  l1ToL2MsgReadRequests: this.l1ToL2MsgReadRequests,
302
- newL2ToL1Messages: this.newL2ToL1Messages,
300
+ l2ToL1Messages: this.newL2ToL1Messages,
303
301
  // correct the type on these now that they are finalized (lists won't grow)
304
302
  unencryptedLogs: new UnencryptedFunctionL2Logs(this.unencryptedLogs),
305
303
  allUnencryptedLogs: new UnencryptedFunctionL2Logs(this.allUnencryptedLogs),
@@ -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,
@@ -4,12 +4,13 @@ import {
4
4
  type GlobalVariables,
5
5
  type Header,
6
6
  type KernelCircuitPublicInputs,
7
- MAX_NEW_NULLIFIERS_PER_TX,
7
+ MAX_NULLIFIERS_PER_TX,
8
8
  MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
9
9
  type PublicKernelCircuitPublicInputs,
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,21 +63,25 @@ 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
 
71
81
  const pendingNullifiers = mergeAccumulatedData(
72
- nonRevertibleData.newNullifiers,
73
- revertibleData.newNullifiers,
74
- MAX_NEW_NULLIFIERS_PER_TX,
82
+ nonRevertibleData.nullifiers,
83
+ revertibleData.nullifiers,
84
+ MAX_NULLIFIERS_PER_TX,
75
85
  );
76
86
 
77
87
  const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints(
@@ -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