@aztec/simulator 2.1.0-rc.9 → 3.0.0-devnet.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 (161) hide show
  1. package/dest/private/acvm_native.d.ts +1 -2
  2. package/dest/private/acvm_native.d.ts.map +1 -1
  3. package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts +1 -1
  4. package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts.map +1 -1
  5. package/dest/public/avm/avm_execution_environment.d.ts +2 -1
  6. package/dest/public/avm/avm_execution_environment.d.ts.map +1 -1
  7. package/dest/public/avm/avm_execution_environment.js +5 -2
  8. package/dest/public/avm/avm_gas.js +2 -2
  9. package/dest/public/avm/avm_simulator.d.ts +1 -1
  10. package/dest/public/avm/avm_simulator.d.ts.map +1 -1
  11. package/dest/public/avm/avm_simulator.js +14 -21
  12. package/dest/public/avm/errors.d.ts +5 -14
  13. package/dest/public/avm/errors.d.ts.map +1 -1
  14. package/dest/public/avm/errors.js +7 -20
  15. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +2 -1
  16. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
  17. package/dest/public/avm/fixtures/avm_simulation_tester.js +2 -3
  18. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +2 -0
  19. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
  20. package/dest/public/avm/fixtures/base_avm_simulation_tester.js +22 -0
  21. package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
  22. package/dest/public/avm/fixtures/initializers.js +2 -2
  23. package/dest/public/avm/opcodes/accrued_substate.d.ts +2 -2
  24. package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
  25. package/dest/public/avm/opcodes/accrued_substate.js +7 -7
  26. package/dest/public/avm/opcodes/addressing_mode.d.ts.map +1 -1
  27. package/dest/public/avm/opcodes/addressing_mode.js +2 -3
  28. package/dest/public/avm/opcodes/conversion.d.ts.map +1 -1
  29. package/dest/public/avm/opcodes/conversion.js +3 -0
  30. package/dest/public/avm/opcodes/ec_add.d.ts.map +1 -1
  31. package/dest/public/avm/opcodes/ec_add.js +3 -2
  32. package/dest/public/avm/opcodes/environment_getters.d.ts.map +1 -1
  33. package/dest/public/avm/opcodes/environment_getters.js +5 -7
  34. package/dest/public/avm/opcodes/instruction.d.ts.map +1 -1
  35. package/dest/public/avm/opcodes/instruction.js +5 -6
  36. package/dest/public/avm/opcodes/misc.d.ts +2 -1
  37. package/dest/public/avm/opcodes/misc.d.ts.map +1 -1
  38. package/dest/public/avm/opcodes/misc.js +28 -8
  39. package/dest/public/avm/serialization/instruction_serialization.d.ts +8 -0
  40. package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -1
  41. package/dest/public/avm/serialization/instruction_serialization.js +10 -0
  42. package/dest/public/avm/test_utils.d.ts +2 -2
  43. package/dest/public/avm/test_utils.d.ts.map +1 -1
  44. package/dest/public/avm/test_utils.js +6 -9
  45. package/dest/public/fixtures/bulk_test.d.ts.map +1 -1
  46. package/dest/public/fixtures/bulk_test.js +63 -130
  47. package/dest/public/fixtures/custom_bytecode_tester.d.ts +12 -0
  48. package/dest/public/fixtures/custom_bytecode_tester.d.ts.map +1 -0
  49. package/dest/public/fixtures/custom_bytecode_tester.js +29 -0
  50. package/dest/public/fixtures/custom_bytecode_tests.d.ts +9 -0
  51. package/dest/public/fixtures/custom_bytecode_tests.d.ts.map +1 -0
  52. package/dest/public/fixtures/custom_bytecode_tests.js +109 -0
  53. package/dest/public/fixtures/index.d.ts +2 -1
  54. package/dest/public/fixtures/index.d.ts.map +1 -1
  55. package/dest/public/fixtures/index.js +2 -1
  56. package/dest/public/fixtures/minimal_public_tx.d.ts +2 -1
  57. package/dest/public/fixtures/minimal_public_tx.d.ts.map +1 -1
  58. package/dest/public/fixtures/minimal_public_tx.js +8 -22
  59. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +4 -2
  60. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
  61. package/dest/public/fixtures/public_tx_simulation_tester.js +11 -6
  62. package/dest/public/fixtures/utils.js +1 -1
  63. package/dest/public/hinting_db_sources.d.ts +2 -0
  64. package/dest/public/hinting_db_sources.d.ts.map +1 -1
  65. package/dest/public/hinting_db_sources.js +3 -0
  66. package/dest/public/index.d.ts +1 -1
  67. package/dest/public/index.d.ts.map +1 -1
  68. package/dest/public/public_db_sources.d.ts +2 -2
  69. package/dest/public/public_db_sources.d.ts.map +1 -1
  70. package/dest/public/public_db_sources.js +11 -1
  71. package/dest/public/public_errors.d.ts +12 -0
  72. package/dest/public/public_errors.d.ts.map +1 -0
  73. package/dest/public/public_errors.js +13 -0
  74. package/dest/public/public_processor/guarded_merkle_tree.d.ts +2 -0
  75. package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -1
  76. package/dest/public/public_processor/guarded_merkle_tree.js +3 -0
  77. package/dest/public/public_processor/public_processor.d.ts +9 -4
  78. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  79. package/dest/public/public_processor/public_processor.js +12 -6
  80. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +41 -0
  81. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -0
  82. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +89 -0
  83. package/dest/public/public_tx_simulator/index.d.ts +1 -0
  84. package/dest/public/public_tx_simulator/index.d.ts.map +1 -1
  85. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +5 -4
  86. package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -1
  87. package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +3 -4
  88. package/dest/public/public_tx_simulator/public_tx_context.d.ts +4 -2
  89. package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
  90. package/dest/public/public_tx_simulator/public_tx_context.js +12 -8
  91. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +24 -11
  92. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
  93. package/dest/public/public_tx_simulator/public_tx_simulator.js +112 -44
  94. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts +9 -0
  95. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts.map +1 -0
  96. package/dest/public/public_tx_simulator/public_tx_simulator_interface.js +1 -0
  97. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +2 -1
  98. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -1
  99. package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +2 -2
  100. package/dest/public/side_effect_errors.d.ts +41 -1
  101. package/dest/public/side_effect_errors.d.ts.map +1 -1
  102. package/dest/public/side_effect_errors.js +70 -1
  103. package/dest/public/side_effect_trace.d.ts +11 -4
  104. package/dest/public/side_effect_trace.d.ts.map +1 -1
  105. package/dest/public/side_effect_trace.js +35 -20
  106. package/dest/public/side_effect_trace_interface.d.ts +6 -0
  107. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  108. package/dest/public/state_manager/nullifiers.d.ts +0 -3
  109. package/dest/public/state_manager/nullifiers.d.ts.map +1 -1
  110. package/dest/public/state_manager/nullifiers.js +1 -6
  111. package/dest/public/state_manager/state_manager.d.ts +7 -2
  112. package/dest/public/state_manager/state_manager.d.ts.map +1 -1
  113. package/dest/public/state_manager/state_manager.js +54 -15
  114. package/package.json +21 -17
  115. package/src/private/acvm_native.ts +1 -2
  116. package/src/private/circuit_recording/simulator_recorder_wrapper.ts +1 -1
  117. package/src/public/avm/avm_execution_environment.ts +4 -1
  118. package/src/public/avm/avm_gas.ts +2 -2
  119. package/src/public/avm/avm_simulator.ts +16 -27
  120. package/src/public/avm/errors.ts +7 -24
  121. package/src/public/avm/fixtures/avm_simulation_tester.ts +4 -2
  122. package/src/public/avm/fixtures/base_avm_simulation_tester.ts +32 -0
  123. package/src/public/avm/fixtures/initializers.ts +2 -1
  124. package/src/public/avm/opcodes/accrued_substate.ts +4 -4
  125. package/src/public/avm/opcodes/addressing_mode.ts +3 -3
  126. package/src/public/avm/opcodes/conversion.ts +4 -0
  127. package/src/public/avm/opcodes/ec_add.ts +3 -2
  128. package/src/public/avm/opcodes/environment_getters.ts +6 -8
  129. package/src/public/avm/opcodes/instruction.ts +8 -6
  130. package/src/public/avm/opcodes/misc.ts +41 -7
  131. package/src/public/avm/serialization/instruction_serialization.ts +12 -0
  132. package/src/public/avm/test_utils.ts +6 -14
  133. package/src/public/fixtures/bulk_test.ts +41 -23
  134. package/src/public/fixtures/custom_bytecode_tester.ts +49 -0
  135. package/src/public/fixtures/custom_bytecode_tests.ts +135 -0
  136. package/src/public/fixtures/index.ts +2 -1
  137. package/src/public/fixtures/minimal_public_tx.ts +8 -31
  138. package/src/public/fixtures/public_tx_simulation_tester.ts +16 -12
  139. package/src/public/fixtures/utils.ts +1 -1
  140. package/src/public/hinting_db_sources.ts +5 -0
  141. package/src/public/index.ts +6 -1
  142. package/src/public/public_db_sources.ts +19 -3
  143. package/src/public/public_errors.ts +14 -0
  144. package/src/public/public_processor/guarded_merkle_tree.ts +4 -0
  145. package/src/public/public_processor/public_processor.ts +23 -25
  146. package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +128 -0
  147. package/src/public/public_tx_simulator/index.ts +1 -0
  148. package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +12 -9
  149. package/src/public/public_tx_simulator/public_tx_context.ts +11 -4
  150. package/src/public/public_tx_simulator/public_tx_simulator.ts +178 -60
  151. package/src/public/public_tx_simulator/public_tx_simulator_interface.ts +11 -0
  152. package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +3 -12
  153. package/src/public/side_effect_errors.ts +91 -1
  154. package/src/public/side_effect_trace.ts +48 -23
  155. package/src/public/side_effect_trace_interface.ts +6 -0
  156. package/src/public/state_manager/nullifiers.ts +1 -7
  157. package/src/public/state_manager/state_manager.ts +73 -25
  158. package/dest/public/bytecode_errors.d.ts +0 -4
  159. package/dest/public/bytecode_errors.d.ts.map +0 -1
  160. package/dest/public/bytecode_errors.js +0 -6
  161. package/src/public/bytecode_errors.ts +0 -6
@@ -1,27 +1,31 @@
1
1
  import {
2
+ FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH,
2
3
  MAX_L2_TO_L1_MSGS_PER_TX,
3
4
  MAX_NOTE_HASHES_PER_TX,
4
5
  MAX_NULLIFIERS_PER_TX,
5
6
  MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS,
6
7
  MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
7
- MAX_PUBLIC_LOGS_PER_TX,
8
8
  PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
9
- PUBLIC_LOG_SIZE_IN_FIELDS,
10
9
  } from '@aztec/constants';
11
- import { padArrayEnd } from '@aztec/foundation/collection';
12
10
  import { EthAddress } from '@aztec/foundation/eth-address';
13
11
  import { Fr } from '@aztec/foundation/fields';
14
- import { createLogger } from '@aztec/foundation/log';
12
+ import { type LogLevel, createLogger } from '@aztec/foundation/log';
15
13
  import { PublicDataUpdateRequest } from '@aztec/stdlib/avm';
16
14
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
17
15
  import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
18
16
  import { NoteHash, Nullifier } from '@aztec/stdlib/kernel';
19
- import { PublicLog } from '@aztec/stdlib/logs';
17
+ import { DebugLog, PublicLog } from '@aztec/stdlib/logs';
20
18
  import { L2ToL1Message, ScopedL2ToL1Message } from '@aztec/stdlib/messaging';
21
19
 
22
20
  import { strict as assert } from 'assert';
23
21
 
24
- import { SideEffectLimitReachedError } from './side_effect_errors.js';
22
+ import {
23
+ L2ToL1MessageLimitReachedError,
24
+ MaxCallsToUniqueContractClassIdsError,
25
+ NoteHashLimitReachedError,
26
+ NullifierLimitReachedError,
27
+ SideEffectLimitReachedError,
28
+ } from './side_effect_errors.js';
25
29
  import type { PublicSideEffectTraceInterface } from './side_effect_trace_interface.js';
26
30
  import { UniqueClassIds } from './unique_class_ids.js';
27
31
 
@@ -45,7 +49,7 @@ export class SideEffectArrayLengths {
45
49
  public readonly noteHashes: number,
46
50
  public readonly nullifiers: number,
47
51
  public readonly l2ToL1Msgs: number,
48
- public readonly publicLogs: number,
52
+ public readonly publicLogFields: number,
49
53
  ) {}
50
54
 
51
55
  static empty() {
@@ -69,7 +73,6 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
69
73
  private nullifiers: Nullifier[] = [];
70
74
  private l2ToL1Messages: ScopedL2ToL1Message[] = [];
71
75
  private publicLogs: PublicLog[] = [];
72
-
73
76
  /** Make sure a forked trace is never merged twice. */
74
77
  private alreadyMergedIntoParent = false;
75
78
 
@@ -83,6 +86,8 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
83
86
  /** We need to track the set of class IDs used, to enforce limits. */
84
87
  private uniqueClassIds: UniqueClassIds = new UniqueClassIds(),
85
88
  private writtenPublicDataSlots: Set<string> = new Set(),
89
+ private debugLogs: DebugLog[] = [],
90
+ private debugLogMemoryReads: number = 0,
86
91
  ) {
87
92
  this.sideEffectCounter = startSideEffectCounter;
88
93
  }
@@ -96,10 +101,13 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
96
101
  this.previousSideEffectArrayLengths.noteHashes + this.noteHashes.length,
97
102
  this.previousSideEffectArrayLengths.nullifiers + this.nullifiers.length,
98
103
  this.previousSideEffectArrayLengths.l2ToL1Msgs + this.l2ToL1Messages.length,
99
- this.previousSideEffectArrayLengths.publicLogs + this.publicLogs.length,
104
+ this.previousSideEffectArrayLengths.publicLogFields +
105
+ this.publicLogs.reduce((acc, log) => acc + log.sizeInFields(), 0),
100
106
  ),
101
107
  this.uniqueClassIds.fork(),
102
108
  new Set(this.writtenPublicDataSlots),
109
+ this.debugLogs.slice(),
110
+ this.debugLogMemoryReads,
103
111
  );
104
112
  }
105
113
 
@@ -113,6 +121,8 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
113
121
 
114
122
  this.sideEffectCounter = forkedTrace.sideEffectCounter;
115
123
  this.uniqueClassIds.acceptAndMerge(forkedTrace.uniqueClassIds);
124
+ this.debugLogs = forkedTrace.debugLogs;
125
+ this.debugLogMemoryReads = forkedTrace.debugLogMemoryReads;
116
126
 
117
127
  if (!reverted) {
118
128
  this.publicDataWrites.push(...forkedTrace.publicDataWrites);
@@ -193,7 +203,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
193
203
 
194
204
  public traceNewNoteHash(noteHash: Fr) {
195
205
  if (this.noteHashes.length + this.previousSideEffectArrayLengths.noteHashes >= MAX_NOTE_HASHES_PER_TX) {
196
- throw new SideEffectLimitReachedError('note hash', MAX_NOTE_HASHES_PER_TX);
206
+ throw new NoteHashLimitReachedError();
197
207
  }
198
208
 
199
209
  this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter));
@@ -203,10 +213,10 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
203
213
 
204
214
  public traceNewNullifier(siloedNullifier: Fr) {
205
215
  if (this.nullifiers.length + this.previousSideEffectArrayLengths.nullifiers >= MAX_NULLIFIERS_PER_TX) {
206
- throw new SideEffectLimitReachedError('nullifier', MAX_NULLIFIERS_PER_TX);
216
+ throw new NullifierLimitReachedError();
207
217
  }
208
218
 
209
- this.nullifiers.push(new Nullifier(siloedNullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO));
219
+ this.nullifiers.push(new Nullifier(siloedNullifier, /*noteHash=*/ Fr.ZERO, this.sideEffectCounter));
210
220
 
211
221
  this.log.trace(`Tracing new nullifier (counter=${this.sideEffectCounter})`);
212
222
  this.incrementSideEffectCounter();
@@ -214,7 +224,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
214
224
 
215
225
  public traceNewL2ToL1Message(contractAddress: AztecAddress, recipient: Fr, content: Fr) {
216
226
  if (this.l2ToL1Messages.length + this.previousSideEffectArrayLengths.l2ToL1Msgs >= MAX_L2_TO_L1_MSGS_PER_TX) {
217
- throw new SideEffectLimitReachedError('l2 to l1 message', MAX_L2_TO_L1_MSGS_PER_TX);
227
+ throw new L2ToL1MessageLimitReachedError();
218
228
  }
219
229
 
220
230
  const recipientAddress = EthAddress.fromField(recipient);
@@ -224,28 +234,43 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
224
234
  }
225
235
 
226
236
  public tracePublicLog(contractAddress: AztecAddress, log: Fr[]) {
227
- if (this.publicLogs.length + this.previousSideEffectArrayLengths.publicLogs >= MAX_PUBLIC_LOGS_PER_TX) {
228
- throw new SideEffectLimitReachedError('public log', MAX_PUBLIC_LOGS_PER_TX);
229
- }
237
+ const previouslyEmittedPublicLogFieldsCount =
238
+ this.previousSideEffectArrayLengths.publicLogFields +
239
+ this.publicLogs.reduce((acc, log) => acc + log.sizeInFields(), 0);
240
+
241
+ const publicLog = new PublicLog(contractAddress, log);
230
242
 
231
- if (log.length > PUBLIC_LOG_SIZE_IN_FIELDS) {
232
- throw new Error(`Emitted public log is too large, max: ${PUBLIC_LOG_SIZE_IN_FIELDS}, passed: ${log.length}`);
243
+ if (previouslyEmittedPublicLogFieldsCount + publicLog.sizeInFields() > FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH) {
244
+ throw new SideEffectLimitReachedError('public log fields', FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH);
233
245
  }
234
- const publicLog = new PublicLog(contractAddress, padArrayEnd(log, Fr.ZERO, PUBLIC_LOG_SIZE_IN_FIELDS), log.length);
246
+
235
247
  this.publicLogs.push(publicLog);
236
248
  this.log.trace(`Tracing new public log (counter=${this.sideEffectCounter})`);
237
249
  this.incrementSideEffectCounter();
238
250
  }
239
251
 
252
+ public traceDebugLog(contractAddress: AztecAddress, level: LogLevel, message: string, fields: Fr[]) {
253
+ this.debugLogs.push(new DebugLog(contractAddress, level, message, fields));
254
+ }
255
+
256
+ public getDebugLogs() {
257
+ return this.debugLogs;
258
+ }
259
+
260
+ public getDebugLogMemoryReads() {
261
+ return this.debugLogMemoryReads;
262
+ }
263
+
264
+ public traceDebugLogMemoryReads(memoryReads: number) {
265
+ this.debugLogMemoryReads += memoryReads;
266
+ }
267
+
240
268
  public traceGetContractClass(contractClassId: Fr, exists: boolean) {
241
269
  // We limit the number of unique contract class IDs due to hashing and the trace length limit.
242
270
  if (exists && !this.uniqueClassIds.has(contractClassId.toString())) {
243
271
  if (this.uniqueClassIds.size() >= MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS) {
244
272
  this.log.debug(`Bytecode retrieval failure for contract class ID ${contractClassId} (limit reached)`);
245
- throw new SideEffectLimitReachedError(
246
- 'contract calls to unique class IDs',
247
- MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS,
248
- );
273
+ throw new MaxCallsToUniqueContractClassIdsError();
249
274
  }
250
275
  this.log.trace(`Adding contract class ID ${contractClassId} (counter=${this.sideEffectCounter})`);
251
276
  this.uniqueClassIds.add(contractClassId.toString());
@@ -1,5 +1,7 @@
1
1
  import type { Fr } from '@aztec/foundation/fields';
2
+ import type { LogLevel } from '@aztec/foundation/log';
2
3
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
+ import type { DebugLog } from '@aztec/stdlib/logs';
3
5
 
4
6
  export interface PublicSideEffectTraceInterface {
5
7
  fork(): PublicSideEffectTraceInterface;
@@ -18,5 +20,9 @@ export interface PublicSideEffectTraceInterface {
18
20
  traceNewNullifier(siloedNullifier: Fr): void;
19
21
  traceNewL2ToL1Message(contractAddress: AztecAddress, recipient: Fr, content: Fr): void;
20
22
  tracePublicLog(contractAddress: AztecAddress, log: Fr[]): void;
23
+ traceDebugLog(contractAddress: AztecAddress, level: LogLevel, message: string, fields: Fr[]): void;
24
+ getDebugLogs(): DebugLog[];
25
+ getDebugLogMemoryReads(): number;
26
+ traceDebugLogMemoryReads(memoryReads: number): void;
21
27
  traceGetContractClass(contractClassId: Fr, exists: boolean): void;
22
28
  }
@@ -1,6 +1,7 @@
1
1
  import type { Fr } from '@aztec/foundation/fields';
2
2
 
3
3
  import type { PublicTreesDB } from '../public_db_sources.js';
4
+ import { NullifierCollisionError } from '../side_effect_errors.js';
4
5
 
5
6
  /**
6
7
  * A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
@@ -100,10 +101,3 @@ export class NullifierManager {
100
101
  this.cache = new Set([...this.cache, ...incomingNullifiers.cache]);
101
102
  }
102
103
  }
103
-
104
- export class NullifierCollisionError extends Error {
105
- constructor(message: string, ...rest: any[]) {
106
- super(message, ...rest);
107
- this.name = 'NullifierCollisionError';
108
- }
109
- }
@@ -9,13 +9,14 @@ import {
9
9
  import { poseidon2Hash } from '@aztec/foundation/crypto';
10
10
  import { Fr } from '@aztec/foundation/fields';
11
11
  import { jsonStringify } from '@aztec/foundation/json-rpc';
12
- import { createLogger } from '@aztec/foundation/log';
12
+ import { type LogLevel, createLogger } from '@aztec/foundation/log';
13
13
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
14
14
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
15
15
  import type { ContractClassPublicWithCommitment, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
16
16
  import { SerializableContractInstance } from '@aztec/stdlib/contract';
17
17
  import { DelayedPublicMutableValues, DelayedPublicMutableValuesWithHash } from '@aztec/stdlib/delayed-public-mutable';
18
18
  import { computeNoteHashNonce, computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
19
+ import type { DebugLog } from '@aztec/stdlib/logs';
19
20
  import { ScopedL2ToL1Message } from '@aztec/stdlib/messaging';
20
21
  import { MerkleTreeId } from '@aztec/stdlib/trees';
21
22
  import type { TreeSnapshots } from '@aztec/stdlib/tx';
@@ -27,8 +28,14 @@ import type { AvmExecutionEnvironment } from '../avm/avm_execution_environment.j
27
28
  import type { PublicContractsDBInterface } from '../db_interfaces.js';
28
29
  import { getPublicFunctionDebugName } from '../debug_fn_name.js';
29
30
  import type { PublicTreesDB } from '../public_db_sources.js';
31
+ import {
32
+ L1ToL2MessageIndexOutOfRangeError,
33
+ MaxCallsToUniqueContractClassIdsError,
34
+ NoteHashIndexOutOfRangeError,
35
+ NullifierCollisionError,
36
+ } from '../side_effect_errors.js';
30
37
  import type { PublicSideEffectTraceInterface } from '../side_effect_trace_interface.js';
31
- import { NullifierCollisionError, NullifierManager } from './nullifiers.js';
38
+ import { NullifierManager } from './nullifiers.js';
32
39
  import { PublicStorage } from './public_storage.js';
33
40
 
34
41
  /**
@@ -183,12 +190,21 @@ export class PublicPersistableStateManager {
183
190
  * @returns true if the note hash exists at the given leaf index, false otherwise
184
191
  */
185
192
  public async checkNoteHashExists(contractAddress: AztecAddress, noteHash: Fr, leafIndex: bigint): Promise<boolean> {
186
- const gotLeafValue = await this.treesDB.getNoteHash(leafIndex);
187
- const exists = gotLeafValue !== undefined && gotLeafValue.equals(noteHash);
188
- this.log.trace(
189
- `noteHashes(${contractAddress})@${noteHash} ?? leafIndex: ${leafIndex} | gotLeafValue: ${gotLeafValue}, exists: ${exists}.`,
190
- );
191
- return Promise.resolve(exists);
193
+ try {
194
+ const gotLeafValue = await this.treesDB.getNoteHash(leafIndex);
195
+ const exists = gotLeafValue.equals(noteHash);
196
+ this.log.trace(
197
+ `noteHashes(${contractAddress})@${noteHash} ?? leafIndex: ${leafIndex} | gotLeafValue: ${gotLeafValue}, exists: ${exists}.`,
198
+ );
199
+ return Promise.resolve(exists);
200
+ } catch (error) {
201
+ // If the index is out of range, note_hash_leaf_in_range = 0 and the circuit returns false:
202
+ if (error instanceof NoteHashIndexOutOfRangeError) {
203
+ return Promise.resolve(false);
204
+ }
205
+ // Otherwise, unknown error. This is a bug.
206
+ throw error;
207
+ }
192
208
  }
193
209
 
194
210
  /**
@@ -288,12 +304,21 @@ export class PublicPersistableStateManager {
288
304
  * @returns exists - whether the message exists in the L1 to L2 Messages tree
289
305
  */
290
306
  public async checkL1ToL2MessageExists(msgHash: Fr, msgLeafIndex: Fr): Promise<boolean> {
291
- const valueAtIndex = await this.treesDB.getL1ToL2LeafValue(msgLeafIndex.toBigInt());
292
- const exists = valueAtIndex !== undefined && valueAtIndex.equals(msgHash);
293
- this.log.trace(
294
- `l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`,
295
- );
296
- return Promise.resolve(exists);
307
+ try {
308
+ const valueAtIndex = await this.treesDB.getL1ToL2LeafValue(msgLeafIndex.toBigInt());
309
+ const exists = valueAtIndex.equals(msgHash);
310
+ this.log.trace(
311
+ `l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`,
312
+ );
313
+ return Promise.resolve(exists);
314
+ } catch (error) {
315
+ // If the index is out of range, l1_to_l2_msg_leaf_in_range = 0 and the circuit returns false:
316
+ if (error instanceof L1ToL2MessageIndexOutOfRangeError) {
317
+ return Promise.resolve(false);
318
+ }
319
+ // Otherwise, unknown error. This is a bug.
320
+ throw error;
321
+ }
297
322
  }
298
323
 
299
324
  /**
@@ -319,6 +344,22 @@ export class PublicPersistableStateManager {
319
344
  );
320
345
  }
321
346
 
347
+ public writeDebugLog(contractAddress: AztecAddress, level: LogLevel, message: string, fields: Fr[]) {
348
+ this.trace.traceDebugLog(contractAddress, level, message, fields);
349
+ }
350
+
351
+ public writeDebugLogMemoryReads(memoryReads: number) {
352
+ this.trace.traceDebugLogMemoryReads(memoryReads);
353
+ }
354
+
355
+ public getDebugLogMemoryReads() {
356
+ return this.trace.getDebugLogMemoryReads();
357
+ }
358
+
359
+ public getLogs(): DebugLog[] {
360
+ return this.trace.getDebugLogs();
361
+ }
362
+
322
363
  /**
323
364
  * Write a public log
324
365
  * @param contractAddress - address of the contract that emitted the log
@@ -368,7 +409,7 @@ export class PublicPersistableStateManager {
368
409
 
369
410
  this.log.trace(`Got contract instance (address=${contractAddress}): instance=${jsonStringify(instance!)}`);
370
411
 
371
- // All that is left is tocheck that the contract updatability information is correct.
412
+ // All that is left is to check that the contract updatability information is correct.
372
413
  // That is, that the current and original contract class ids are correct.
373
414
  await this.checkContractUpdateInformation(instanceWithAddress);
374
415
 
@@ -389,7 +430,7 @@ export class PublicPersistableStateManager {
389
430
  //
390
431
  // However, we will also be checking the hash of the delayed public mutable values.
391
432
  // This is a bit of a leak of information, since the circuit will use it to prove
392
- // one public read insted of N of the delayed public mutable values.
433
+ // one public read instead of N of the delayed public mutable values.
393
434
  const { delayedPublicMutableSlot, delayedPublicMutableHashSlot } =
394
435
  await DelayedPublicMutableValuesWithHash.getContractUpdateSlots(instance.address);
395
436
  const readDeployerStorage = async (storageSlot: Fr) =>
@@ -438,7 +479,7 @@ export class PublicPersistableStateManager {
438
479
  * @param classId - class id to retrieve.
439
480
  * @returns the contract class or undefined if it does not exist.
440
481
  */
441
- public async getContractClass(classId: Fr): Promise<ContractClassPublicWithCommitment | undefined> {
482
+ private async getContractClass(classId: Fr): Promise<ContractClassPublicWithCommitment | undefined> {
442
483
  this.log.trace(`Getting contract class for id ${classId}`);
443
484
  const contractClass = await this.contractsDB.getContractClass(classId);
444
485
  const exists = contractClass !== undefined;
@@ -459,7 +500,7 @@ export class PublicPersistableStateManager {
459
500
  publicBytecodeCommitment: bytecodeCommitment,
460
501
  };
461
502
  } else {
462
- this.log.debug(`Contract instance NOT FOUND (id=${classId})`);
503
+ this.log.debug(`Contract class NOT FOUND (id=${classId})`);
463
504
  }
464
505
 
465
506
  // TODO(dbanks12): does this need to be moved to before the DB accesses as was done with writeNullifier?
@@ -478,13 +519,20 @@ export class PublicPersistableStateManager {
478
519
  return undefined;
479
520
  }
480
521
 
481
- const contractClass = await this.getContractClass(contractInstance.currentContractClassId);
482
- assert(
483
- contractClass,
484
- `Contract class not found in DB, but a contract instance was found with this class ID (${contractInstance.currentContractClassId}). This should not happen!`,
485
- );
486
-
487
- return contractClass.packedBytecode;
522
+ try {
523
+ const contractClass = await this.getContractClass(contractInstance.currentContractClassId);
524
+ assert(
525
+ contractClass,
526
+ `Contract class not found in DB, but a contract instance was found with this class ID (${contractInstance.currentContractClassId}). This should not happen!`,
527
+ );
528
+ return contractClass.packedBytecode;
529
+ } catch (error) {
530
+ if (error instanceof MaxCallsToUniqueContractClassIdsError) {
531
+ return undefined;
532
+ }
533
+ // Otherwise, unknown error. This is a bug.
534
+ throw error;
535
+ }
488
536
  }
489
537
 
490
538
  public async getPublicFunctionDebugName(avmEnvironment: AvmExecutionEnvironment): Promise<string> {
@@ -1,4 +0,0 @@
1
- export declare class ContractClassBytecodeError extends Error {
2
- constructor(contractAddress: string);
3
- }
4
- //# sourceMappingURL=bytecode_errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bytecode_errors.d.ts","sourceRoot":"","sources":["../../src/public/bytecode_errors.ts"],"names":[],"mappings":"AAAA,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,eAAe,EAAE,MAAM;CAIpC"}
@@ -1,6 +0,0 @@
1
- export class ContractClassBytecodeError extends Error {
2
- constructor(contractAddress){
3
- super(`Failed to get bytecode for contract at address ${contractAddress}`);
4
- this.name = 'ContractClassBytecodeError';
5
- }
6
- }
@@ -1,6 +0,0 @@
1
- export class ContractClassBytecodeError extends Error {
2
- constructor(contractAddress: string) {
3
- super(`Failed to get bytecode for contract at address ${contractAddress}`);
4
- this.name = 'ContractClassBytecodeError';
5
- }
6
- }