@aztec/simulator 0.67.1 → 0.68.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 (143) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +1 -1
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +3 -3
  4. package/dest/acvm/oracle/typed_oracle.d.ts +1 -1
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +3 -3
  7. package/dest/avm/avm_memory_types.d.ts +1 -1
  8. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  9. package/dest/avm/avm_memory_types.js +45 -38
  10. package/dest/avm/avm_simulator.d.ts +1 -0
  11. package/dest/avm/avm_simulator.d.ts.map +1 -1
  12. package/dest/avm/avm_simulator.js +38 -18
  13. package/dest/avm/avm_tree.d.ts +2 -23
  14. package/dest/avm/avm_tree.d.ts.map +1 -1
  15. package/dest/avm/avm_tree.js +27 -82
  16. package/dest/avm/errors.d.ts +8 -1
  17. package/dest/avm/errors.d.ts.map +1 -1
  18. package/dest/avm/errors.js +13 -3
  19. package/dest/avm/fixtures/index.d.ts +2 -0
  20. package/dest/avm/fixtures/index.d.ts.map +1 -1
  21. package/dest/avm/fixtures/index.js +4 -4
  22. package/dest/avm/journal/journal.d.ts +15 -7
  23. package/dest/avm/journal/journal.d.ts.map +1 -1
  24. package/dest/avm/journal/journal.js +30 -22
  25. package/dest/avm/journal/nullifiers.d.ts +0 -4
  26. package/dest/avm/journal/nullifiers.d.ts.map +1 -1
  27. package/dest/avm/journal/nullifiers.js +1 -11
  28. package/dest/avm/journal/public_storage.d.ts +1 -49
  29. package/dest/avm/journal/public_storage.d.ts.map +1 -1
  30. package/dest/avm/journal/public_storage.js +1 -19
  31. package/dest/avm/opcodes/addressing_mode.js +3 -3
  32. package/dest/avm/opcodes/conversion.d.ts +4 -4
  33. package/dest/avm/opcodes/conversion.d.ts.map +1 -1
  34. package/dest/avm/opcodes/conversion.js +22 -18
  35. package/dest/avm/opcodes/ec_add.d.ts.map +1 -1
  36. package/dest/avm/opcodes/ec_add.js +5 -4
  37. package/dest/avm/opcodes/external_calls.js +2 -2
  38. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  39. package/dest/avm/opcodes/hashing.js +5 -5
  40. package/dest/avm/opcodes/misc.d.ts.map +1 -1
  41. package/dest/avm/opcodes/misc.js +3 -3
  42. package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
  43. package/dest/avm/opcodes/multi_scalar_mul.js +9 -6
  44. package/dest/avm/test_utils.d.ts +1 -0
  45. package/dest/avm/test_utils.d.ts.map +1 -1
  46. package/dest/avm/test_utils.js +4 -1
  47. package/dest/client/client_execution_context.d.ts.map +1 -1
  48. package/dest/client/client_execution_context.js +2 -1
  49. package/dest/client/db_oracle.d.ts +7 -3
  50. package/dest/client/db_oracle.d.ts.map +1 -1
  51. package/dest/client/index.d.ts +1 -0
  52. package/dest/client/index.d.ts.map +1 -1
  53. package/dest/client/index.js +2 -1
  54. package/dest/client/view_data_oracle.d.ts +2 -2
  55. package/dest/client/view_data_oracle.d.ts.map +1 -1
  56. package/dest/client/view_data_oracle.js +5 -4
  57. package/dest/providers/acvm_wasm.js +2 -2
  58. package/dest/providers/acvm_wasm_with_blobs.d.ts +7 -0
  59. package/dest/providers/acvm_wasm_with_blobs.d.ts.map +1 -0
  60. package/dest/providers/acvm_wasm_with_blobs.js +15 -0
  61. package/dest/providers/index.d.ts +1 -1
  62. package/dest/providers/index.d.ts.map +1 -1
  63. package/dest/providers/index.js +2 -2
  64. package/dest/public/bytecode_errors.d.ts +4 -0
  65. package/dest/public/bytecode_errors.d.ts.map +1 -0
  66. package/dest/public/bytecode_errors.js +7 -0
  67. package/dest/public/enqueued_call_side_effect_trace.d.ts +10 -4
  68. package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
  69. package/dest/public/enqueued_call_side_effect_trace.js +63 -13
  70. package/dest/public/execution.d.ts +2 -2
  71. package/dest/public/execution.d.ts.map +1 -1
  72. package/dest/public/execution.js +1 -1
  73. package/dest/public/executor_metrics.d.ts +2 -0
  74. package/dest/public/executor_metrics.d.ts.map +1 -1
  75. package/dest/public/executor_metrics.js +11 -1
  76. package/dest/public/fee_payment.d.ts.map +1 -1
  77. package/dest/public/fee_payment.js +4 -3
  78. package/dest/public/fixtures/index.d.ts +17 -11
  79. package/dest/public/fixtures/index.d.ts.map +1 -1
  80. package/dest/public/fixtures/index.js +103 -35
  81. package/dest/public/public_db_sources.d.ts.map +1 -1
  82. package/dest/public/public_db_sources.js +7 -6
  83. package/dest/public/public_processor.d.ts +15 -7
  84. package/dest/public/public_processor.d.ts.map +1 -1
  85. package/dest/public/public_processor.js +119 -75
  86. package/dest/public/public_processor_metrics.d.ts +10 -2
  87. package/dest/public/public_processor_metrics.d.ts.map +1 -1
  88. package/dest/public/public_processor_metrics.js +49 -2
  89. package/dest/public/public_tx_context.d.ts +5 -0
  90. package/dest/public/public_tx_context.d.ts.map +1 -1
  91. package/dest/public/public_tx_context.js +40 -20
  92. package/dest/public/public_tx_simulator.d.ts +2 -1
  93. package/dest/public/public_tx_simulator.d.ts.map +1 -1
  94. package/dest/public/public_tx_simulator.js +35 -6
  95. package/dest/public/side_effect_errors.js +2 -2
  96. package/dest/public/side_effect_trace_interface.d.ts +2 -1
  97. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  98. package/dest/public/transitional_adapters.d.ts.map +1 -1
  99. package/dest/public/transitional_adapters.js +2 -35
  100. package/dest/public/unique_class_ids.d.ts +37 -0
  101. package/dest/public/unique_class_ids.d.ts.map +1 -0
  102. package/dest/public/unique_class_ids.js +66 -0
  103. package/package.json +12 -12
  104. package/src/acvm/oracle/oracle.ts +2 -2
  105. package/src/acvm/oracle/typed_oracle.ts +2 -2
  106. package/src/avm/avm_memory_types.ts +56 -38
  107. package/src/avm/avm_simulator.ts +48 -20
  108. package/src/avm/avm_tree.ts +35 -92
  109. package/src/avm/errors.ts +13 -2
  110. package/src/avm/fixtures/index.ts +4 -2
  111. package/src/avm/journal/journal.ts +39 -29
  112. package/src/avm/journal/nullifiers.ts +0 -11
  113. package/src/avm/journal/public_storage.ts +2 -21
  114. package/src/avm/opcodes/addressing_mode.ts +2 -2
  115. package/src/avm/opcodes/conversion.ts +21 -16
  116. package/src/avm/opcodes/ec_add.ts +4 -3
  117. package/src/avm/opcodes/external_calls.ts +1 -1
  118. package/src/avm/opcodes/hashing.ts +6 -4
  119. package/src/avm/opcodes/misc.ts +4 -3
  120. package/src/avm/opcodes/multi_scalar_mul.ts +10 -5
  121. package/src/avm/test_utils.ts +4 -0
  122. package/src/client/client_execution_context.ts +2 -0
  123. package/src/client/db_oracle.ts +8 -3
  124. package/src/client/index.ts +1 -0
  125. package/src/client/view_data_oracle.ts +6 -3
  126. package/src/providers/acvm_wasm.ts +1 -1
  127. package/src/providers/acvm_wasm_with_blobs.ts +25 -0
  128. package/src/providers/index.ts +1 -1
  129. package/src/public/bytecode_errors.ts +6 -0
  130. package/src/public/enqueued_call_side_effect_trace.ts +83 -19
  131. package/src/public/execution.ts +1 -2
  132. package/src/public/executor_metrics.ts +13 -0
  133. package/src/public/fee_payment.ts +3 -2
  134. package/src/public/fixtures/index.ts +152 -46
  135. package/src/public/public_db_sources.ts +6 -5
  136. package/src/public/public_processor.ts +171 -88
  137. package/src/public/public_processor_metrics.ts +64 -2
  138. package/src/public/public_tx_context.ts +57 -21
  139. package/src/public/public_tx_simulator.ts +34 -6
  140. package/src/public/side_effect_errors.ts +1 -1
  141. package/src/public/side_effect_trace_interface.ts +2 -1
  142. package/src/public/transitional_adapters.ts +0 -51
  143. package/src/public/unique_class_ids.ts +80 -0
@@ -56,6 +56,7 @@ export class PublicTxSimulator {
56
56
  telemetryClient: TelemetryClient,
57
57
  private globalVariables: GlobalVariables,
58
58
  private doMerkleOperations: boolean = false,
59
+ private enforceFeePayment: boolean = true,
59
60
  ) {
60
61
  this.log = createLogger(`simulator:public_tx_simulator`);
61
62
  this.metrics = new ExecutorMetrics(telemetryClient, 'PublicTxSimulator');
@@ -90,14 +91,20 @@ export class PublicTxSimulator {
90
91
  // FIXME: we shouldn't need to directly modify worldStateDb here!
91
92
  await this.worldStateDB.addNewContracts(tx);
92
93
 
94
+ const nonRevertStart = process.hrtime.bigint();
93
95
  await this.insertNonRevertiblesFromPrivate(context);
96
+ const nonRevertEnd = process.hrtime.bigint();
97
+ this.metrics.recordPrivateEffectsInsertion(Number(nonRevertEnd - nonRevertStart) / 1_000, 'non-revertible');
94
98
  const processedPhases: ProcessedPhase[] = [];
95
99
  if (context.hasPhase(TxExecutionPhase.SETUP)) {
96
100
  const setupResult: ProcessedPhase = await this.simulateSetupPhase(context);
97
101
  processedPhases.push(setupResult);
98
102
  }
99
103
 
104
+ const revertStart = process.hrtime.bigint();
100
105
  await this.insertRevertiblesFromPrivate(context);
106
+ const revertEnd = process.hrtime.bigint();
107
+ this.metrics.recordPrivateEffectsInsertion(Number(revertEnd - revertStart) / 1_000, 'revertible');
101
108
  if (context.hasPhase(TxExecutionPhase.APP_LOGIC)) {
102
109
  const appLogicResult: ProcessedPhase = await this.simulateAppLogicPhase(context);
103
110
  processedPhases.push(appLogicResult);
@@ -134,7 +141,11 @@ export class PublicTxSimulator {
134
141
 
135
142
  return {
136
143
  avmProvingRequest,
137
- gasUsed: { totalGas: context.getActualGasUsed(), teardownGas: context.teardownGasUsed },
144
+ gasUsed: {
145
+ totalGas: context.getActualGasUsed(),
146
+ teardownGas: context.teardownGasUsed,
147
+ publicGas: context.getActualPublicGasUsed(),
148
+ },
138
149
  revertCode,
139
150
  revertReason: context.revertReason,
140
151
  processedPhases: processedPhases,
@@ -344,7 +355,7 @@ export class PublicTxSimulator {
344
355
  const avmCallResult = await simulator.execute();
345
356
  const result = avmCallResult.finalize();
346
357
 
347
- this.log.debug(
358
+ this.log.verbose(
348
359
  result.reverted
349
360
  ? `Simulation of enqueued public call ${fnName} reverted with reason ${result.revertReason}.`
350
361
  : `Simulation of enqueued public call ${fnName} completed successfully.`,
@@ -378,6 +389,11 @@ export class PublicTxSimulator {
378
389
  );
379
390
  }
380
391
  }
392
+ for (const noteHash of context.nonRevertibleAccumulatedDataFromPrivate.noteHashes) {
393
+ if (!noteHash.isEmpty()) {
394
+ stateManager.writeUniqueNoteHash(noteHash);
395
+ }
396
+ }
381
397
  }
382
398
 
383
399
  /**
@@ -397,6 +413,12 @@ export class PublicTxSimulator {
397
413
  );
398
414
  }
399
415
  }
416
+ for (const noteHash of context.revertibleAccumulatedDataFromPrivate.noteHashes) {
417
+ if (!noteHash.isEmpty()) {
418
+ // Revertible note hashes from private are not hashed with nonce, since private can't know their final position, only we can.
419
+ stateManager.writeSiloedNoteHash(noteHash);
420
+ }
421
+ }
400
422
  }
401
423
 
402
424
  private async payFee(context: PublicTxContext) {
@@ -413,12 +435,18 @@ export class PublicTxSimulator {
413
435
  this.log.debug(`Deducting ${txFee.toBigInt()} balance in Fee Juice for ${context.feePayer}`);
414
436
  const stateManager = context.state.getActiveStateManager();
415
437
 
416
- const currentBalance = await stateManager.readStorage(feeJuiceAddress, balanceSlot);
438
+ let currentBalance = await stateManager.readStorage(feeJuiceAddress, balanceSlot);
439
+ // We allow to fake the balance of the fee payer to allow fee estimation
440
+ // When mocking the balance of the fee payer, the circuit should not be able to prove the simulation
417
441
 
418
442
  if (currentBalance.lt(txFee)) {
419
- throw new Error(
420
- `Not enough balance for fee payer to pay for transaction (got ${currentBalance.toBigInt()} needs ${txFee.toBigInt()})`,
421
- );
443
+ if (this.enforceFeePayment) {
444
+ throw new Error(
445
+ `Not enough balance for fee payer to pay for transaction (got ${currentBalance.toBigInt()} needs ${txFee.toBigInt()})`,
446
+ );
447
+ } else {
448
+ currentBalance = txFee;
449
+ }
422
450
  }
423
451
 
424
452
  const updatedBalance = currentBalance.sub(txFee);
@@ -1,6 +1,6 @@
1
1
  export class SideEffectLimitReachedError extends Error {
2
2
  constructor(sideEffectType: string, limit: number) {
3
- super(`Reached the limit on number of '${sideEffectType}' side effects: ${limit}`);
3
+ super(`Reached the limit (${limit}) on number of '${sideEffectType}' per tx`);
4
4
  this.name = 'SideEffectLimitReachedError';
5
5
  }
6
6
  }
@@ -39,7 +39,8 @@ export interface PublicSideEffectTraceInterface {
39
39
  insertionPath?: Fr[],
40
40
  ): void;
41
41
  traceNoteHashCheck(contractAddress: AztecAddress, noteHash: Fr, leafIndex: Fr, exists: boolean, path?: Fr[]): void;
42
- traceNewNoteHash(contractAddress: AztecAddress, noteHash: Fr, leafIndex?: Fr, path?: Fr[]): void;
42
+ traceNewNoteHash(uniqueNoteHash: Fr, leafIndex?: Fr, path?: Fr[]): void;
43
+ getNoteHashCount(): number;
43
44
  traceNullifierCheck(
44
45
  siloedNullifier: Fr,
45
46
  exists: boolean,
@@ -6,7 +6,6 @@ import {
6
6
  type GasSettings,
7
7
  type GlobalVariables,
8
8
  MAX_L2_TO_L1_MSGS_PER_TX,
9
- MAX_NOTE_HASHES_PER_TX,
10
9
  MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
11
10
  PrivateToAvmAccumulatedData,
12
11
  PrivateToAvmAccumulatedDataArrayLengths,
@@ -19,7 +18,6 @@ import {
19
18
  countAccumulatedItems,
20
19
  mergeAccumulatedData,
21
20
  } from '@aztec/circuits.js';
22
- import { computeNoteHashNonce, computeUniqueNoteHash, siloNoteHash } from '@aztec/circuits.js/hash';
23
21
  import { padArrayEnd } from '@aztec/foundation/collection';
24
22
  import { assertLength } from '@aztec/foundation/serialize';
25
23
 
@@ -86,55 +84,6 @@ export function generateAvmCircuitPublicInputs(
86
84
  revertibleAccumulatedDataFromPrivate,
87
85
  );
88
86
 
89
- const txHash = avmCircuitPublicInputs.previousNonRevertibleAccumulatedData.nullifiers[0];
90
-
91
- // Add nonces to revertible note hashes from private. These don't have nonces since we don't know
92
- // the final position in the tx until the AVM has executed.
93
- // TODO: Use the final position in the tx
94
- for (
95
- let revertibleIndex = 0;
96
- revertibleIndex < avmCircuitPublicInputs.previousRevertibleAccumulatedData.noteHashes.length;
97
- revertibleIndex++
98
- ) {
99
- const noteHash = avmCircuitPublicInputs.previousRevertibleAccumulatedData.noteHashes[revertibleIndex];
100
- if (noteHash.isZero()) {
101
- continue;
102
- }
103
- const indexInTx =
104
- revertibleIndex + avmCircuitPublicInputs.previousNonRevertibleAccumulatedDataArrayLengths.noteHashes;
105
-
106
- const nonce = computeNoteHashNonce(txHash, indexInTx);
107
- const uniqueNoteHash = computeUniqueNoteHash(nonce, noteHash);
108
- avmCircuitPublicInputs.previousRevertibleAccumulatedData.noteHashes[revertibleIndex] = uniqueNoteHash;
109
- }
110
-
111
- // merge all revertible & non-revertible side effects into output accumulated data
112
- const noteHashesFromPrivate = revertCode.isOK()
113
- ? mergeAccumulatedData(
114
- avmCircuitPublicInputs.previousNonRevertibleAccumulatedData.noteHashes,
115
- avmCircuitPublicInputs.previousRevertibleAccumulatedData.noteHashes,
116
- )
117
- : avmCircuitPublicInputs.previousNonRevertibleAccumulatedData.noteHashes;
118
- avmCircuitPublicInputs.accumulatedData.noteHashes = assertLength(
119
- mergeAccumulatedData(noteHashesFromPrivate, avmCircuitPublicInputs.accumulatedData.noteHashes),
120
- MAX_NOTE_HASHES_PER_TX,
121
- );
122
-
123
- // Silo and add nonces for note hashes emitted by the AVM
124
- const scopedNoteHashesFromPublic = trace.getSideEffects().noteHashes;
125
- for (let i = 0; i < scopedNoteHashesFromPublic.length; i++) {
126
- const scopedNoteHash = scopedNoteHashesFromPublic[i];
127
- const noteHash = scopedNoteHash.value;
128
- if (!noteHash.isZero()) {
129
- const noteHashIndexInTx = i + countAccumulatedItems(noteHashesFromPrivate);
130
- const nonce = computeNoteHashNonce(txHash, noteHashIndexInTx);
131
- const siloedNoteHash = siloNoteHash(scopedNoteHash.contractAddress, noteHash);
132
- const uniqueNoteHash = computeUniqueNoteHash(nonce, siloedNoteHash);
133
-
134
- avmCircuitPublicInputs.accumulatedData.noteHashes[noteHashIndexInTx] = uniqueNoteHash;
135
- }
136
- }
137
-
138
87
  const msgsFromPrivate = revertCode.isOK()
139
88
  ? mergeAccumulatedData(
140
89
  avmCircuitPublicInputs.previousNonRevertibleAccumulatedData.l2ToL1Msgs,
@@ -0,0 +1,80 @@
1
+ import { MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS } from '@aztec/circuits.js';
2
+
3
+ import { strict as assert } from 'assert';
4
+
5
+ /**
6
+ * A class manage a de-duplicated set of class IDs that errors if you try to add a duplicate.
7
+ * Useful for bytecode retrieval hints to avoid duplicates in parent trace & grandparent trace....
8
+ */
9
+ export class UniqueClassIds {
10
+ private readonly classIds: Set<string> = new Set();
11
+
12
+ constructor(private readonly parent?: UniqueClassIds) {}
13
+
14
+ /**
15
+ * Create a fork that references this one as its parent
16
+ */
17
+ public fork() {
18
+ return new UniqueClassIds(/*parent=*/ this);
19
+ }
20
+
21
+ /**
22
+ * Check for a class ID here or in parent's (recursively).
23
+ *
24
+ * @param classId - the contract class ID (as a string) to check
25
+ * @returns boolean: whether the class ID is here
26
+ */
27
+ public has(classId: string): boolean {
28
+ // First try check this' classIds
29
+ let here = this.classIds.has(classId);
30
+ // Then try parent's
31
+ if (!here && this.parent) {
32
+ // Note: this will recurse to grandparent/etc until we reach top or find it
33
+ here = this.parent.has(classId);
34
+ }
35
+ return here;
36
+ }
37
+
38
+ /**
39
+ * Get the total number of classIds
40
+ */
41
+ public size(): number {
42
+ return this.classIds.size + (this.parent ? this.parent.size() : 0);
43
+ }
44
+
45
+ /**
46
+ * Add a class ID (if not already present) to the set.
47
+ *
48
+ * @param classId - the contract class ID (as a string)
49
+ */
50
+ public add(classId: string) {
51
+ assert(!this.has(classId), `Bug! Tried to add duplicate classId ${classId} to set of unique classIds.`);
52
+ if (!this.has(classId)) {
53
+ this.classIds.add(classId);
54
+ assert(
55
+ this.size() <= MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS,
56
+ `Bug! Surpassed limit (${MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS}) of unique contract class IDs used for bytecode retrievals.`,
57
+ );
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Merge in another set of unique class IDs into this one, but fail on duplicates.
63
+ *
64
+ * @param incoming: other unique class IDs
65
+ */
66
+ public acceptAndMerge(incoming: UniqueClassIds) {
67
+ for (const classId of incoming.classIds.keys()) {
68
+ assert(
69
+ !this.has(classId),
70
+ `Bug! Cannot merge classId ${classId} into set of unique classIds as it already exists.`,
71
+ );
72
+ this.classIds.add(classId);
73
+ }
74
+ // since set() has an assertion, and size() always checks parent, this should be impossible
75
+ assert(
76
+ this.size() <= MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS,
77
+ `Bug! Merging unique class Ids should never exceed the limit of ${MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS}.`,
78
+ );
79
+ }
80
+ }