@aztec/simulator 0.42.0 → 0.43.0

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 (145) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +3 -2
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +17 -6
  4. package/dest/acvm/oracle/typed_oracle.d.ts +3 -2
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +8 -5
  7. package/dest/avm/avm_gas.d.ts.map +1 -1
  8. package/dest/avm/avm_gas.js +3 -1
  9. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  10. package/dest/avm/avm_memory_types.js +2 -4
  11. package/dest/avm/fixtures/index.d.ts +4 -1
  12. package/dest/avm/fixtures/index.d.ts.map +1 -1
  13. package/dest/avm/fixtures/index.js +11 -6
  14. package/dest/avm/journal/journal.d.ts +3 -3
  15. package/dest/avm/journal/journal.d.ts.map +1 -1
  16. package/dest/avm/journal/journal.js +18 -13
  17. package/dest/avm/journal/trace.d.ts +3 -3
  18. package/dest/avm/journal/trace.d.ts.map +1 -1
  19. package/dest/avm/journal/trace.js +7 -6
  20. package/dest/avm/journal/trace_types.d.ts +4 -0
  21. package/dest/avm/journal/trace_types.d.ts.map +1 -1
  22. package/dest/avm/journal/trace_types.js +1 -5
  23. package/dest/avm/opcodes/accrued_substate.d.ts +2 -2
  24. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  25. package/dest/avm/opcodes/accrued_substate.js +36 -21
  26. package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
  27. package/dest/avm/opcodes/arithmetic.js +12 -9
  28. package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
  29. package/dest/avm/opcodes/bitwise.js +11 -8
  30. package/dest/avm/opcodes/comparators.d.ts.map +1 -1
  31. package/dest/avm/opcodes/comparators.js +7 -5
  32. package/dest/avm/opcodes/contract.d.ts.map +1 -1
  33. package/dest/avm/opcodes/contract.js +20 -24
  34. package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
  35. package/dest/avm/opcodes/control_flow.js +4 -2
  36. package/dest/avm/opcodes/ec_add.d.ts +19 -0
  37. package/dest/avm/opcodes/ec_add.d.ts.map +1 -0
  38. package/dest/avm/opcodes/ec_add.js +78 -0
  39. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  40. package/dest/avm/opcodes/external_calls.js +8 -3
  41. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  42. package/dest/avm/opcodes/hashing.js +10 -2
  43. package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
  44. package/dest/avm/opcodes/instruction_impl.js +4 -2
  45. package/dest/avm/opcodes/memory.d.ts +1 -1
  46. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  47. package/dest/avm/opcodes/memory.js +14 -12
  48. package/dest/avm/opcodes/multi_scalar_mul.d.ts +16 -0
  49. package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -0
  50. package/dest/avm/opcodes/multi_scalar_mul.js +95 -0
  51. package/dest/avm/opcodes/storage.d.ts +1 -1
  52. package/dest/avm/opcodes/storage.d.ts.map +1 -1
  53. package/dest/avm/opcodes/storage.js +11 -8
  54. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  55. package/dest/avm/serialization/bytecode_serialization.js +5 -1
  56. package/dest/avm/serialization/instruction_serialization.d.ts +3 -1
  57. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  58. package/dest/avm/serialization/instruction_serialization.js +4 -2
  59. package/dest/client/client_execution_context.d.ts +15 -3
  60. package/dest/client/client_execution_context.d.ts.map +1 -1
  61. package/dest/client/client_execution_context.js +31 -17
  62. package/dest/client/simulator.d.ts +2 -1
  63. package/dest/client/simulator.d.ts.map +1 -1
  64. package/dest/client/simulator.js +17 -9
  65. package/dest/public/abstract_phase_manager.d.ts +10 -11
  66. package/dest/public/abstract_phase_manager.d.ts.map +1 -1
  67. package/dest/public/abstract_phase_manager.js +75 -53
  68. package/dest/public/app_logic_phase_manager.d.ts +3 -3
  69. package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
  70. package/dest/public/app_logic_phase_manager.js +3 -3
  71. package/dest/public/db_interfaces.d.ts +1 -0
  72. package/dest/public/db_interfaces.d.ts.map +1 -1
  73. package/dest/public/execution.d.ts +1 -15
  74. package/dest/public/execution.d.ts.map +1 -1
  75. package/dest/public/execution.js +1 -51
  76. package/dest/public/executor.d.ts +1 -1
  77. package/dest/public/executor.d.ts.map +1 -1
  78. package/dest/public/executor.js +15 -8
  79. package/dest/public/hints_builder.d.ts +1 -1
  80. package/dest/public/index.d.ts +6 -6
  81. package/dest/public/index.d.ts.map +1 -1
  82. package/dest/public/index.js +7 -7
  83. package/dest/public/phase_manager_factory.d.ts +3 -3
  84. package/dest/public/phase_manager_factory.d.ts.map +1 -1
  85. package/dest/public/phase_manager_factory.js +5 -5
  86. package/dest/public/public_db_sources.d.ts +3 -1
  87. package/dest/public/public_db_sources.d.ts.map +1 -1
  88. package/dest/public/public_db_sources.js +54 -8
  89. package/dest/public/public_processor.d.ts.map +1 -1
  90. package/dest/public/public_processor.js +4 -5
  91. package/dest/public/setup_phase_manager.d.ts +3 -3
  92. package/dest/public/setup_phase_manager.d.ts.map +1 -1
  93. package/dest/public/setup_phase_manager.js +3 -3
  94. package/dest/public/tail_phase_manager.d.ts +3 -3
  95. package/dest/public/tail_phase_manager.d.ts.map +1 -1
  96. package/dest/public/tail_phase_manager.js +3 -3
  97. package/dest/public/teardown_phase_manager.d.ts +3 -3
  98. package/dest/public/teardown_phase_manager.d.ts.map +1 -1
  99. package/dest/public/teardown_phase_manager.js +3 -3
  100. package/dest/public/transitional_adaptors.d.ts +1 -1
  101. package/dest/public/transitional_adaptors.d.ts.map +1 -1
  102. package/dest/public/transitional_adaptors.js +9 -3
  103. package/package.json +8 -8
  104. package/src/acvm/oracle/oracle.ts +35 -6
  105. package/src/acvm/oracle/typed_oracle.ts +20 -4
  106. package/src/avm/avm_gas.ts +2 -0
  107. package/src/avm/avm_memory_types.ts +1 -3
  108. package/src/avm/fixtures/index.ts +12 -8
  109. package/src/avm/journal/journal.ts +26 -21
  110. package/src/avm/journal/trace.ts +8 -11
  111. package/src/avm/journal/trace_types.ts +3 -0
  112. package/src/avm/opcodes/accrued_substate.ts +53 -20
  113. package/src/avm/opcodes/arithmetic.ts +17 -8
  114. package/src/avm/opcodes/bitwise.ts +13 -8
  115. package/src/avm/opcodes/comparators.ts +9 -4
  116. package/src/avm/opcodes/contract.ts +22 -26
  117. package/src/avm/opcodes/control_flow.ts +3 -1
  118. package/src/avm/opcodes/ec_add.ts +92 -0
  119. package/src/avm/opcodes/external_calls.ts +8 -2
  120. package/src/avm/opcodes/hashing.ts +11 -1
  121. package/src/avm/opcodes/instruction_impl.ts +4 -1
  122. package/src/avm/opcodes/memory.ts +18 -11
  123. package/src/avm/opcodes/multi_scalar_mul.ts +114 -0
  124. package/src/avm/opcodes/storage.ts +10 -10
  125. package/src/avm/serialization/bytecode_serialization.ts +4 -0
  126. package/src/avm/serialization/instruction_serialization.ts +2 -0
  127. package/src/client/client_execution_context.ts +46 -18
  128. package/src/client/simulator.ts +18 -8
  129. package/src/public/abstract_phase_manager.ts +77 -59
  130. package/src/public/app_logic_phase_manager.ts +2 -2
  131. package/src/public/db_interfaces.ts +2 -0
  132. package/src/public/execution.ts +0 -69
  133. package/src/public/executor.ts +17 -8
  134. package/src/public/index.ts +6 -12
  135. package/src/public/phase_manager_factory.ts +6 -6
  136. package/src/public/public_db_sources.ts +62 -7
  137. package/src/public/public_processor.ts +4 -7
  138. package/src/public/setup_phase_manager.ts +2 -2
  139. package/src/public/tail_phase_manager.ts +2 -2
  140. package/src/public/teardown_phase_manager.ts +2 -2
  141. package/src/public/transitional_adaptors.ts +42 -2
  142. package/dest/public/utils.d.ts +0 -8
  143. package/dest/public/utils.d.ts.map +0 -1
  144. package/dest/public/utils.js +0 -38
  145. package/src/public/utils.ts +0 -39
@@ -132,29 +132,31 @@ export class AcirSimulator {
132
132
  * @param nonce - The nonce of the note hash.
133
133
  * @param storageSlot - The storage slot.
134
134
  * @param noteTypeId - The note type identifier.
135
+ * @param computeNullifier - A flag indicating whether to compute the nullifier or just return 0.
135
136
  * @param note - The note.
136
137
  * @returns The nullifier.
137
138
  */
138
- public async computeNoteHashAndNullifier(
139
+ public async computeNoteHashAndOptionallyANullifier(
139
140
  contractAddress: AztecAddress,
140
141
  nonce: Fr,
141
142
  storageSlot: Fr,
142
143
  noteTypeId: Fr,
144
+ computeNullifier: boolean,
143
145
  note: Note,
144
146
  ) {
145
147
  const artifact: FunctionArtifact | undefined = await this.db.getFunctionArtifactByName(
146
148
  contractAddress,
147
- 'compute_note_hash_and_nullifier',
149
+ 'compute_note_hash_and_optionally_a_nullifier',
148
150
  );
149
151
  if (!artifact) {
150
152
  throw new Error(
151
- `Mandatory implementation of "compute_note_hash_and_nullifier" missing in noir contract ${contractAddress.toString()}.`,
153
+ `Mandatory implementation of "compute_note_hash_and_optionally_a_nullifier" missing in noir contract ${contractAddress.toString()}.`,
152
154
  );
153
155
  }
154
156
 
155
- if (artifact.parameters.length != 5) {
157
+ if (artifact.parameters.length != 6) {
156
158
  throw new Error(
157
- `Expected 5 parameters in mandatory implementation of "compute_note_hash_and_nullifier", but found ${
159
+ `Expected 6 parameters in mandatory implementation of "compute_note_hash_and_optionally_a_nullifier", but found ${
158
160
  artifact.parameters.length
159
161
  } in noir contract ${contractAddress.toString()}.`,
160
162
  );
@@ -163,7 +165,7 @@ export class AcirSimulator {
163
165
  const maxNoteFields = (artifact.parameters[artifact.parameters.length - 1].type as ArrayType).length;
164
166
  if (maxNoteFields < note.items.length) {
165
167
  throw new Error(
166
- `The note being processed has ${note.items.length} fields, while "compute_note_hash_and_nullifier" can only handle a maximum of ${maxNoteFields} fields. Please reduce the number of fields in your note.`,
168
+ `The note being processed has ${note.items.length} fields, while "compute_note_hash_and_optionally_a_nullifier" can only handle a maximum of ${maxNoteFields} fields. Please reduce the number of fields in your note.`,
167
169
  );
168
170
  }
169
171
 
@@ -175,7 +177,14 @@ export class AcirSimulator {
175
177
  selector: FunctionSelector.empty(),
176
178
  type: FunctionType.UNCONSTRAINED,
177
179
  isStatic: artifact.isStatic,
178
- args: encodeArguments(artifact, [contractAddress, nonce, storageSlot, noteTypeId, extendedNoteItems]),
180
+ args: encodeArguments(artifact, [
181
+ contractAddress,
182
+ nonce,
183
+ storageSlot,
184
+ noteTypeId,
185
+ computeNullifier,
186
+ extendedNoteItems,
187
+ ]),
179
188
  returnTypes: artifact.returnTypes,
180
189
  };
181
190
 
@@ -202,11 +211,12 @@ export class AcirSimulator {
202
211
  * @returns The note hash.
203
212
  */
204
213
  public async computeInnerNoteHash(contractAddress: AztecAddress, storageSlot: Fr, noteTypeId: Fr, note: Note) {
205
- const { innerNoteHash } = await this.computeNoteHashAndNullifier(
214
+ const { innerNoteHash } = await this.computeNoteHashAndOptionallyANullifier(
206
215
  contractAddress,
207
216
  Fr.ZERO,
208
217
  storageSlot,
209
218
  noteTypeId,
219
+ false,
210
220
  note,
211
221
  );
212
222
  return innerNoteHash;
@@ -67,36 +67,15 @@ import { type MerkleTreeOperations } from '@aztec/world-state';
67
67
 
68
68
  import { HintsBuilder } from './hints_builder.js';
69
69
  import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js';
70
- import { lastSideEffectCounter } from './utils.js';
71
70
 
72
- export enum PublicKernelPhase {
73
- SETUP = 'setup',
74
- APP_LOGIC = 'app-logic',
75
- TEARDOWN = 'teardown',
76
- TAIL = 'tail',
77
- }
78
-
79
- export const PhaseIsRevertible: Record<PublicKernelPhase, boolean> = {
80
- [PublicKernelPhase.SETUP]: false,
81
- [PublicKernelPhase.APP_LOGIC]: true,
82
- [PublicKernelPhase.TEARDOWN]: true,
83
- [PublicKernelPhase.TAIL]: false,
71
+ export const PhaseIsRevertible: Record<PublicKernelType, boolean> = {
72
+ [PublicKernelType.NON_PUBLIC]: false,
73
+ [PublicKernelType.SETUP]: false,
74
+ [PublicKernelType.APP_LOGIC]: true,
75
+ [PublicKernelType.TEARDOWN]: true,
76
+ [PublicKernelType.TAIL]: false,
84
77
  };
85
78
 
86
- // REFACTOR: Unify both enums and move to types or circuit-types.
87
- export function publicKernelPhaseToKernelType(phase: PublicKernelPhase): PublicKernelType {
88
- switch (phase) {
89
- case PublicKernelPhase.SETUP:
90
- return PublicKernelType.SETUP;
91
- case PublicKernelPhase.APP_LOGIC:
92
- return PublicKernelType.APP_LOGIC;
93
- case PublicKernelPhase.TEARDOWN:
94
- return PublicKernelType.TEARDOWN;
95
- case PublicKernelPhase.TAIL:
96
- return PublicKernelType.TAIL;
97
- }
98
- }
99
-
100
79
  export type PublicProvingInformation = {
101
80
  calldata: Fr[];
102
81
  bytecode: Buffer;
@@ -159,7 +138,7 @@ export abstract class AbstractPhaseManager {
159
138
  protected publicKernel: PublicKernelCircuitSimulator,
160
139
  protected globalVariables: GlobalVariables,
161
140
  protected historicalHeader: Header,
162
- public phase: PublicKernelPhase,
141
+ public phase: PublicKernelType,
163
142
  ) {
164
143
  this.hintsBuilder = new HintsBuilder(db);
165
144
  this.log = createDebugLogger(`aztec:sequencer:${phase}`);
@@ -171,14 +150,15 @@ export abstract class AbstractPhaseManager {
171
150
  */
172
151
  abstract handle(tx: Tx, publicKernelPublicInputs: PublicKernelCircuitPublicInputs): Promise<PhaseResult>;
173
152
 
174
- public static extractEnqueuedPublicCallsByPhase(tx: Tx): Record<PublicKernelPhase, PublicCallRequest[]> {
153
+ public static extractEnqueuedPublicCallsByPhase(tx: Tx): Record<PublicKernelType, PublicCallRequest[]> {
175
154
  const data = tx.data.forPublic;
176
155
  if (!data) {
177
156
  return {
178
- [PublicKernelPhase.SETUP]: [],
179
- [PublicKernelPhase.APP_LOGIC]: [],
180
- [PublicKernelPhase.TEARDOWN]: [],
181
- [PublicKernelPhase.TAIL]: [],
157
+ [PublicKernelType.NON_PUBLIC]: [],
158
+ [PublicKernelType.SETUP]: [],
159
+ [PublicKernelType.APP_LOGIC]: [],
160
+ [PublicKernelType.TEARDOWN]: [],
161
+ [PublicKernelType.TAIL]: [],
182
162
  };
183
163
  }
184
164
  const publicCallsStack = tx.enqueuedPublicFunctionCalls.slice().reverse();
@@ -196,10 +176,11 @@ export abstract class AbstractPhaseManager {
196
176
 
197
177
  if (callRequestsStack.length === 0) {
198
178
  return {
199
- [PublicKernelPhase.SETUP]: [],
200
- [PublicKernelPhase.APP_LOGIC]: [],
201
- [PublicKernelPhase.TEARDOWN]: [],
202
- [PublicKernelPhase.TAIL]: [],
179
+ [PublicKernelType.NON_PUBLIC]: [],
180
+ [PublicKernelType.SETUP]: [],
181
+ [PublicKernelType.APP_LOGIC]: [],
182
+ [PublicKernelType.TEARDOWN]: [],
183
+ [PublicKernelType.TAIL]: [],
203
184
  };
204
185
  }
205
186
 
@@ -212,25 +193,28 @@ export abstract class AbstractPhaseManager {
212
193
 
213
194
  if (firstRevertibleCallIndex === 0) {
214
195
  return {
215
- [PublicKernelPhase.SETUP]: [],
216
- [PublicKernelPhase.APP_LOGIC]: publicCallsStack,
217
- [PublicKernelPhase.TEARDOWN]: teardownCallStack,
218
- [PublicKernelPhase.TAIL]: [],
196
+ [PublicKernelType.NON_PUBLIC]: [],
197
+ [PublicKernelType.SETUP]: [],
198
+ [PublicKernelType.APP_LOGIC]: publicCallsStack,
199
+ [PublicKernelType.TEARDOWN]: teardownCallStack,
200
+ [PublicKernelType.TAIL]: [],
219
201
  };
220
202
  } else if (firstRevertibleCallIndex === -1) {
221
203
  // there's no app logic, split the functions between setup (many) and teardown (just one function call)
222
204
  return {
223
- [PublicKernelPhase.SETUP]: publicCallsStack,
224
- [PublicKernelPhase.APP_LOGIC]: [],
225
- [PublicKernelPhase.TEARDOWN]: teardownCallStack,
226
- [PublicKernelPhase.TAIL]: [],
205
+ [PublicKernelType.NON_PUBLIC]: [],
206
+ [PublicKernelType.SETUP]: publicCallsStack,
207
+ [PublicKernelType.APP_LOGIC]: [],
208
+ [PublicKernelType.TEARDOWN]: teardownCallStack,
209
+ [PublicKernelType.TAIL]: [],
227
210
  };
228
211
  } else {
229
212
  return {
230
- [PublicKernelPhase.SETUP]: publicCallsStack.slice(0, firstRevertibleCallIndex),
231
- [PublicKernelPhase.APP_LOGIC]: publicCallsStack.slice(firstRevertibleCallIndex),
232
- [PublicKernelPhase.TEARDOWN]: teardownCallStack,
233
- [PublicKernelPhase.TAIL]: [],
213
+ [PublicKernelType.NON_PUBLIC]: [],
214
+ [PublicKernelType.SETUP]: publicCallsStack.slice(0, firstRevertibleCallIndex),
215
+ [PublicKernelType.APP_LOGIC]: publicCallsStack.slice(firstRevertibleCallIndex),
216
+ [PublicKernelType.TEARDOWN]: teardownCallStack,
217
+ [PublicKernelType.TAIL]: [],
234
218
  };
235
219
  }
236
220
  }
@@ -278,19 +262,15 @@ export abstract class AbstractPhaseManager {
278
262
  while (executionStack.length) {
279
263
  const current = executionStack.pop()!;
280
264
  const isExecutionRequest = !isPublicExecutionResult(current);
281
- const sideEffectCounter = lastSideEffectCounter(kernelPublicOutput) + 1;
282
- const availableGas = this.getAvailableGas(tx, kernelPublicOutput);
283
- const pendingNullifiers = this.getSiloedPendingNullifiers(kernelPublicOutput);
284
-
285
265
  const result = isExecutionRequest
286
266
  ? await this.publicExecutor.simulate(
287
267
  current,
288
268
  this.globalVariables,
289
- availableGas,
269
+ /*availableGas=*/ this.getAvailableGas(tx, kernelPublicOutput),
290
270
  tx.data.constants.txContext,
291
- pendingNullifiers,
271
+ /*pendingNullifiers=*/ this.getSiloedPendingNullifiers(kernelPublicOutput),
292
272
  transactionFee,
293
- sideEffectCounter,
273
+ /*startSideEffectCounter=*/ AbstractPhaseManager.getMaxSideEffectCounter(kernelPublicOutput) + 1,
294
274
  )
295
275
  : current;
296
276
 
@@ -407,11 +387,11 @@ export abstract class AbstractPhaseManager {
407
387
  // We take a deep copy (clone) of these inputs to be passed to the prover
408
388
  const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData);
409
389
  switch (this.phase) {
410
- case PublicKernelPhase.SETUP:
390
+ case PublicKernelType.SETUP:
411
391
  return [inputs.clone(), await this.publicKernel.publicKernelCircuitSetup(inputs)];
412
- case PublicKernelPhase.APP_LOGIC:
392
+ case PublicKernelType.APP_LOGIC:
413
393
  return [inputs.clone(), await this.publicKernel.publicKernelCircuitAppLogic(inputs)];
414
- case PublicKernelPhase.TEARDOWN:
394
+ case PublicKernelType.TEARDOWN:
415
395
  return [inputs.clone(), await this.publicKernel.publicKernelCircuitTeardown(inputs)];
416
396
  default:
417
397
  throw new Error(`No public kernel circuit for inputs`);
@@ -508,6 +488,44 @@ export abstract class AbstractPhaseManager {
508
488
  return await Promise.all(nested.map(n => this.getPublicCallStackItem(n)));
509
489
  }
510
490
 
491
+ /**
492
+ * Looks at the side effects of a transaction and returns the highest counter
493
+ * @param tx - A transaction
494
+ * @returns The highest side effect counter in the transaction so far
495
+ */
496
+ static getMaxSideEffectCounter(inputs: PublicKernelCircuitPublicInputs): number {
497
+ const sideEffectCounters = [
498
+ ...inputs.endNonRevertibleData.newNoteHashes,
499
+ ...inputs.endNonRevertibleData.newNullifiers,
500
+ ...inputs.endNonRevertibleData.noteEncryptedLogsHashes,
501
+ ...inputs.endNonRevertibleData.encryptedLogsHashes,
502
+ ...inputs.endNonRevertibleData.unencryptedLogsHashes,
503
+ ...inputs.endNonRevertibleData.publicCallStack,
504
+ ...inputs.endNonRevertibleData.publicDataUpdateRequests,
505
+ ...inputs.end.newNoteHashes,
506
+ ...inputs.end.newNullifiers,
507
+ ...inputs.end.noteEncryptedLogsHashes,
508
+ ...inputs.end.encryptedLogsHashes,
509
+ ...inputs.end.unencryptedLogsHashes,
510
+ ...inputs.end.publicCallStack,
511
+ ...inputs.end.publicDataUpdateRequests,
512
+ ];
513
+
514
+ let max = 0;
515
+ for (const sideEffect of sideEffectCounters) {
516
+ if ('startSideEffectCounter' in sideEffect) {
517
+ // look at both start and end counters because for enqueued public calls start > 0 while end === 0
518
+ max = Math.max(max, sideEffect.startSideEffectCounter.toNumber(), sideEffect.endSideEffectCounter.toNumber());
519
+ } else if ('counter' in sideEffect) {
520
+ max = Math.max(max, sideEffect.counter);
521
+ } else {
522
+ throw new Error('Unknown side effect type');
523
+ }
524
+ }
525
+
526
+ return max;
527
+ }
528
+
511
529
  protected getBytecodeHash(_result: PublicExecutionResult) {
512
530
  // TODO: Determine how to calculate bytecode hash. Circuits just check it isn't zero for now.
513
531
  // See https://github.com/AztecProtocol/aztec3-packages/issues/378
@@ -3,7 +3,7 @@ import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs
3
3
  import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator';
4
4
  import { type MerkleTreeOperations } from '@aztec/world-state';
5
5
 
6
- import { AbstractPhaseManager, PublicKernelPhase, makeAvmProvingRequest } from './abstract_phase_manager.js';
6
+ import { AbstractPhaseManager, makeAvmProvingRequest } from './abstract_phase_manager.js';
7
7
  import { type ContractsDataSourcePublicDB } from './public_db_sources.js';
8
8
  import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js';
9
9
 
@@ -19,7 +19,7 @@ export class AppLogicPhaseManager extends AbstractPhaseManager {
19
19
  historicalHeader: Header,
20
20
  protected publicContractsDB: ContractsDataSourcePublicDB,
21
21
  protected publicStateDB: PublicStateDB,
22
- phase: PublicKernelPhase = PublicKernelPhase.APP_LOGIC,
22
+ phase: PublicKernelType = PublicKernelType.APP_LOGIC,
23
23
  ) {
24
24
  super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase);
25
25
  }
@@ -67,6 +67,8 @@ export interface PublicContractsDB {
67
67
  * @returns The contract instance or undefined if not found.
68
68
  */
69
69
  getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined>;
70
+
71
+ getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
70
72
  }
71
73
 
72
74
  /** Database interface for providing access to commitment tree, l1 to l2 message tree, and nullifier tree. */
@@ -9,11 +9,8 @@ import {
9
9
  type NoteHash,
10
10
  type Nullifier,
11
11
  type PublicCallRequest,
12
- PublicDataRead,
13
- PublicDataUpdateRequest,
14
12
  type ReadRequest,
15
13
  } from '@aztec/circuits.js';
16
- import { computePublicDataTreeLeafSlot, computePublicDataTreeValue } from '@aztec/circuits.js/hash';
17
14
 
18
15
  import { type Gas } from '../avm/avm_gas.js';
19
16
 
@@ -98,72 +95,6 @@ export function isPublicExecutionResult(
98
95
  return 'execution' in input && input.execution !== undefined;
99
96
  }
100
97
 
101
- /**
102
- * Collect all public storage reads across all nested executions
103
- * and convert them to PublicDataReads (to match kernel output).
104
- * @param execResult - The topmost execution result.
105
- * @returns All public data reads (in execution order).
106
- */
107
- export function collectPublicDataReads(execResult: PublicExecutionResult): PublicDataRead[] {
108
- // HACK(#1622): part of temporary hack - may be able to remove this function after public state ordering is fixed
109
- const thisExecPublicDataReads = execResult.contractStorageReads.map(read =>
110
- contractStorageReadToPublicDataRead(read),
111
- );
112
- const unsorted = [
113
- ...thisExecPublicDataReads,
114
- ...[...execResult.nestedExecutions].flatMap(result => collectPublicDataReads(result)),
115
- ];
116
- return unsorted.sort((a, b) => a.sideEffectCounter! - b.sideEffectCounter!);
117
- }
118
-
119
- /**
120
- * Collect all public storage update requests across all nested executions
121
- * and convert them to PublicDataUpdateRequests (to match kernel output).
122
- * @param execResult - The topmost execution result.
123
- * @returns All public data reads (in execution order).
124
- */
125
- export function collectPublicDataUpdateRequests(execResult: PublicExecutionResult): PublicDataUpdateRequest[] {
126
- // HACK(#1622): part of temporary hack - may be able to remove this function after public state ordering is fixed
127
- const thisExecPublicDataUpdateRequests = execResult.contractStorageUpdateRequests.map(update =>
128
- contractStorageUpdateRequestToPublicDataUpdateRequest(update),
129
- );
130
- const unsorted = [
131
- ...thisExecPublicDataUpdateRequests,
132
- ...[...execResult.nestedExecutions].flatMap(result => collectPublicDataUpdateRequests(result)),
133
- ];
134
- return unsorted.sort((a, b) => a.sideEffectCounter! - b.sideEffectCounter!);
135
- }
136
-
137
- /**
138
- * Convert a Contract Storage Read to a Public Data Read.
139
- * @param read - the contract storage read to convert
140
- * @param contractAddress - the contract address of the read
141
- * @returns The public data read.
142
- */
143
- function contractStorageReadToPublicDataRead(read: ContractStorageRead): PublicDataRead {
144
- return new PublicDataRead(
145
- computePublicDataTreeLeafSlot(read.contractAddress!, read.storageSlot),
146
- computePublicDataTreeValue(read.currentValue),
147
- read.sideEffectCounter!,
148
- );
149
- }
150
-
151
- /**
152
- * Convert a Contract Storage Update Request to a Public Data Update Request.
153
- * @param update - the contract storage update request to convert
154
- * @param contractAddress - the contract address of the data update request.
155
- * @returns The public data update request.
156
- */
157
- function contractStorageUpdateRequestToPublicDataUpdateRequest(
158
- update: ContractStorageUpdateRequest,
159
- ): PublicDataUpdateRequest {
160
- return new PublicDataUpdateRequest(
161
- computePublicDataTreeLeafSlot(update.contractAddress!, update.storageSlot),
162
- computePublicDataTreeValue(update.newValue),
163
- update.sideEffectCounter!,
164
- );
165
- }
166
-
167
98
  /**
168
99
  * Checks whether the child execution result is valid for a static call (no state modifications).
169
100
  * @param executionResult - The execution result of a public function
@@ -1,5 +1,7 @@
1
+ import { type AvmSimulationStats } from '@aztec/circuit-types/stats';
1
2
  import { Fr, type Gas, type GlobalVariables, type Header, type Nullifier, type TxContext } from '@aztec/circuits.js';
2
3
  import { createDebugLogger } from '@aztec/foundation/log';
4
+ import { Timer } from '@aztec/foundation/timer';
3
5
 
4
6
  import { AvmContext } from '../avm/avm_context.js';
5
7
  import { AvmMachineState } from '../avm/avm_machine_state.js';
@@ -36,25 +38,25 @@ export class PublicExecutor {
36
38
  txContext: TxContext,
37
39
  pendingNullifiers: Nullifier[],
38
40
  transactionFee: Fr = Fr.ZERO,
39
- sideEffectCounter: number = 0,
41
+ startSideEffectCounter: number = 0,
40
42
  ): Promise<PublicExecutionResult> {
41
43
  const address = execution.contractAddress;
42
44
  const selector = execution.functionSelector;
43
45
  const startGas = availableGas;
46
+ const fnName = await this.contractsDb.getDebugFunctionName(address, selector);
44
47
 
45
- PublicExecutor.log.verbose(`[AVM] Executing public external function ${address.toString()}:${selector}.`);
48
+ PublicExecutor.log.verbose(`[AVM] Executing public external function ${fnName}.`);
49
+ const timer = new Timer();
46
50
 
47
51
  // Temporary code to construct the AVM context
48
52
  // These data structures will permeate across the simulator when the public executor is phased out
49
53
  const hostStorage = new HostStorage(this.stateDb, this.contractsDb, this.commitmentsDb);
50
54
 
51
- const startSideEffectCounter = sideEffectCounter;
52
55
  const worldStateJournal = new AvmPersistableStateManager(hostStorage);
53
56
  for (const nullifier of pendingNullifiers) {
54
57
  worldStateJournal.nullifiers.cache.appendSiloed(nullifier.value);
55
58
  }
56
- // All the subsequent side effects will have a counter larger than the call's start counter.
57
- worldStateJournal.trace.accessCounter = startSideEffectCounter + 1;
59
+ worldStateJournal.trace.accessCounter = startSideEffectCounter;
58
60
 
59
61
  const executionEnv = createAvmExecutionEnvironment(
60
62
  execution,
@@ -68,6 +70,7 @@ export class PublicExecutor {
68
70
  const avmContext = new AvmContext(worldStateJournal, executionEnv, machineState);
69
71
  const simulator = new AvmSimulator(avmContext);
70
72
  const avmResult = await simulator.execute();
73
+ const bytecode = simulator.getBytecode();
71
74
 
72
75
  // Commit the journals state to the DBs since this is a top-level execution.
73
76
  // Observe that this will write all the state changes to the DBs, not only the latest for each slot.
@@ -75,9 +78,15 @@ export class PublicExecutor {
75
78
  await avmContext.persistableState.publicStorage.commitToDB();
76
79
 
77
80
  PublicExecutor.log.verbose(
78
- `[AVM] ${address.toString()}:${selector} returned, reverted: ${avmResult.reverted}, reason: ${
79
- avmResult.revertReason
81
+ `[AVM] ${fnName} returned, reverted: ${avmResult.reverted}${
82
+ avmResult.reverted ? ', reason: ' + avmResult.revertReason : ''
80
83
  }.`,
84
+ {
85
+ eventName: 'avm-simulation',
86
+ appCircuitName: fnName ?? 'unknown',
87
+ duration: timer.ms(),
88
+ bytecodeSize: bytecode!.length,
89
+ } satisfies AvmSimulationStats,
81
90
  );
82
91
 
83
92
  const executionResult = convertAvmResultsToPxResult(
@@ -86,7 +95,7 @@ export class PublicExecutor {
86
95
  execution,
87
96
  startGas,
88
97
  avmContext,
89
- simulator.getBytecode(),
98
+ bytecode,
90
99
  );
91
100
 
92
101
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/5818): is this really needed?
@@ -1,16 +1,10 @@
1
+ export * from './abstract_phase_manager.js';
1
2
  export * from './db_interfaces.js';
2
- export {
3
- type PublicExecution,
4
- type PublicExecutionResult,
5
- isPublicExecutionResult,
6
- collectPublicDataReads,
7
- collectPublicDataUpdateRequests,
8
- } from './execution.js';
3
+ export { isPublicExecutionResult, type PublicExecution, type PublicExecutionResult } from './execution.js';
9
4
  export { PublicExecutor } from './executor.js';
10
- export { PublicProcessor, PublicProcessorFactory } from './public_processor.js';
5
+ export * from './fee_payment.js';
6
+ export { HintsBuilder } from './hints_builder.js';
11
7
  export * from './public_db_sources.js';
12
- export * from './abstract_phase_manager.js';
13
- export * from './public_kernel_circuit_simulator.js';
14
8
  export * from './public_kernel.js';
15
- export { HintsBuilder } from './hints_builder.js';
16
- export * from './fee_payment.js';
9
+ export * from './public_kernel_circuit_simulator.js';
10
+ export { PublicProcessor, PublicProcessorFactory } from './public_processor.js';
@@ -1,9 +1,9 @@
1
- import { type Tx } from '@aztec/circuit-types';
1
+ import { PublicKernelType, type Tx } from '@aztec/circuit-types';
2
2
  import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js';
3
3
  import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator';
4
4
  import { type MerkleTreeOperations } from '@aztec/world-state';
5
5
 
6
- import { type AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js';
6
+ import { type AbstractPhaseManager } from './abstract_phase_manager.js';
7
7
  import { AppLogicPhaseManager } from './app_logic_phase_manager.js';
8
8
  import { type ContractsDataSourcePublicDB } from './public_db_sources.js';
9
9
  import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js';
@@ -12,7 +12,7 @@ import { TailPhaseManager } from './tail_phase_manager.js';
12
12
  import { TeardownPhaseManager } from './teardown_phase_manager.js';
13
13
 
14
14
  export class PhaseDidNotChangeError extends Error {
15
- constructor(phase: PublicKernelPhase) {
15
+ constructor(phase: PublicKernelType) {
16
16
  super(`Tried to advance the phase from [${phase}] when the circuit still needs [${phase}]`);
17
17
  }
18
18
  }
@@ -84,7 +84,7 @@ export class PhaseManagerFactory {
84
84
  if (output.needsSetup) {
85
85
  throw new CannotTransitionToSetupError();
86
86
  } else if (output.needsAppLogic) {
87
- if (currentPhaseManager.phase === PublicKernelPhase.APP_LOGIC) {
87
+ if (currentPhaseManager.phase === PublicKernelType.APP_LOGIC) {
88
88
  throw new PhaseDidNotChangeError(currentPhaseManager.phase);
89
89
  }
90
90
  return new AppLogicPhaseManager(
@@ -97,7 +97,7 @@ export class PhaseManagerFactory {
97
97
  publicStateDB,
98
98
  );
99
99
  } else if (output.needsTeardown) {
100
- if (currentPhaseManager.phase === PublicKernelPhase.TEARDOWN) {
100
+ if (currentPhaseManager.phase === PublicKernelType.TEARDOWN) {
101
101
  throw new PhaseDidNotChangeError(currentPhaseManager.phase);
102
102
  }
103
103
  return new TeardownPhaseManager(
@@ -109,7 +109,7 @@ export class PhaseManagerFactory {
109
109
  publicContractsDB,
110
110
  publicStateDB,
111
111
  );
112
- } else if (currentPhaseManager.phase !== PublicKernelPhase.TAIL) {
112
+ } else if (currentPhaseManager.phase !== PublicKernelType.TAIL) {
113
113
  return new TailPhaseManager(
114
114
  db,
115
115
  publicExecutor,