@aztec/simulator 0.66.0 → 0.67.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 (125) hide show
  1. package/dest/acvm/acvm.js +3 -3
  2. package/dest/acvm/oracle/oracle.d.ts +1 -1
  3. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  4. package/dest/acvm/oracle/oracle.js +3 -3
  5. package/dest/acvm/oracle/typed_oracle.d.ts +2 -2
  6. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  7. package/dest/acvm/oracle/typed_oracle.js +3 -3
  8. package/dest/acvm/serialize.js +2 -2
  9. package/dest/avm/avm_context.d.ts +2 -2
  10. package/dest/avm/avm_context.d.ts.map +1 -1
  11. package/dest/avm/avm_context.js +3 -4
  12. package/dest/avm/avm_execution_environment.d.ts +4 -6
  13. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  14. package/dest/avm/avm_execution_environment.js +8 -13
  15. package/dest/avm/avm_memory_types.d.ts +2 -2
  16. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  17. package/dest/avm/avm_memory_types.js +3 -3
  18. package/dest/avm/avm_simulator.d.ts +3 -3
  19. package/dest/avm/avm_simulator.d.ts.map +1 -1
  20. package/dest/avm/avm_simulator.js +22 -13
  21. package/dest/avm/errors.d.ts +3 -3
  22. package/dest/avm/errors.d.ts.map +1 -1
  23. package/dest/avm/errors.js +8 -15
  24. package/dest/avm/fixtures/index.d.ts.map +1 -1
  25. package/dest/avm/fixtures/index.js +4 -4
  26. package/dest/avm/journal/journal.d.ts +15 -4
  27. package/dest/avm/journal/journal.d.ts.map +1 -1
  28. package/dest/avm/journal/journal.js +108 -29
  29. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  30. package/dest/avm/opcodes/external_calls.js +4 -11
  31. package/dest/avm/opcodes/misc.d.ts.map +1 -1
  32. package/dest/avm/opcodes/misc.js +3 -3
  33. package/dest/client/client_execution_context.d.ts +3 -3
  34. package/dest/client/client_execution_context.d.ts.map +1 -1
  35. package/dest/client/client_execution_context.js +14 -8
  36. package/dest/client/db_oracle.d.ts +2 -2
  37. package/dest/client/db_oracle.d.ts.map +1 -1
  38. package/dest/client/execution_note_cache.d.ts +9 -1
  39. package/dest/client/execution_note_cache.d.ts.map +1 -1
  40. package/dest/client/execution_note_cache.js +10 -3
  41. package/dest/client/private_execution.d.ts.map +1 -1
  42. package/dest/client/private_execution.js +4 -4
  43. package/dest/client/simulator.d.ts.map +1 -1
  44. package/dest/client/simulator.js +4 -4
  45. package/dest/client/unconstrained_execution.d.ts.map +1 -1
  46. package/dest/client/unconstrained_execution.js +3 -3
  47. package/dest/client/view_data_oracle.d.ts +2 -2
  48. package/dest/client/view_data_oracle.d.ts.map +1 -1
  49. package/dest/client/view_data_oracle.js +5 -6
  50. package/dest/common/debug_fn_name.d.ts +2 -2
  51. package/dest/common/debug_fn_name.d.ts.map +1 -1
  52. package/dest/common/debug_fn_name.js +8 -14
  53. package/dest/providers/acvm_native.js +4 -4
  54. package/dest/providers/factory.d.ts +2 -2
  55. package/dest/providers/factory.d.ts.map +1 -1
  56. package/dest/providers/factory.js +4 -4
  57. package/dest/public/enqueued_call_side_effect_trace.d.ts +11 -23
  58. package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
  59. package/dest/public/enqueued_call_side_effect_trace.js +37 -58
  60. package/dest/public/executor_metrics.d.ts.map +1 -1
  61. package/dest/public/executor_metrics.js +2 -5
  62. package/dest/public/fixtures/index.d.ts +24 -1
  63. package/dest/public/fixtures/index.d.ts.map +1 -1
  64. package/dest/public/fixtures/index.js +15 -9
  65. package/dest/public/index.d.ts +0 -1
  66. package/dest/public/index.d.ts.map +1 -1
  67. package/dest/public/index.js +1 -2
  68. package/dest/public/public_db_sources.d.ts.map +1 -1
  69. package/dest/public/public_db_sources.js +4 -4
  70. package/dest/public/public_processor.d.ts +7 -8
  71. package/dest/public/public_processor.d.ts.map +1 -1
  72. package/dest/public/public_processor.js +30 -22
  73. package/dest/public/public_tx_context.d.ts +13 -10
  74. package/dest/public/public_tx_context.d.ts.map +1 -1
  75. package/dest/public/public_tx_context.js +46 -31
  76. package/dest/public/public_tx_simulator.d.ts +2 -2
  77. package/dest/public/public_tx_simulator.d.ts.map +1 -1
  78. package/dest/public/public_tx_simulator.js +43 -23
  79. package/dest/public/side_effect_trace_interface.d.ts +4 -17
  80. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  81. package/dest/public/transitional_adapters.d.ts +2 -2
  82. package/dest/public/transitional_adapters.d.ts.map +1 -1
  83. package/dest/public/transitional_adapters.js +28 -24
  84. package/package.json +16 -9
  85. package/src/acvm/acvm.ts +2 -2
  86. package/src/acvm/oracle/oracle.ts +2 -2
  87. package/src/acvm/oracle/typed_oracle.ts +3 -3
  88. package/src/acvm/serialize.ts +1 -1
  89. package/src/avm/avm_context.ts +2 -3
  90. package/src/avm/avm_execution_environment.ts +6 -31
  91. package/src/avm/avm_memory_types.ts +2 -2
  92. package/src/avm/avm_simulator.ts +24 -20
  93. package/src/avm/errors.ts +12 -14
  94. package/src/avm/fixtures/index.ts +2 -3
  95. package/src/avm/journal/journal.ts +189 -63
  96. package/src/avm/opcodes/external_calls.ts +3 -19
  97. package/src/avm/opcodes/misc.ts +2 -2
  98. package/src/client/client_execution_context.ts +17 -9
  99. package/src/client/db_oracle.ts +2 -2
  100. package/src/client/execution_note_cache.ts +13 -3
  101. package/src/client/private_execution.ts +3 -3
  102. package/src/client/simulator.ts +4 -4
  103. package/src/client/unconstrained_execution.ts +2 -2
  104. package/src/client/view_data_oracle.ts +5 -6
  105. package/src/common/debug_fn_name.ts +7 -13
  106. package/src/providers/acvm_native.ts +3 -3
  107. package/src/providers/factory.ts +3 -3
  108. package/src/public/enqueued_call_side_effect_trace.ts +54 -74
  109. package/src/public/executor_metrics.ts +0 -4
  110. package/src/public/fixtures/index.ts +23 -10
  111. package/src/public/index.ts +0 -1
  112. package/src/public/public_db_sources.ts +3 -3
  113. package/src/public/public_processor.ts +46 -47
  114. package/src/public/public_tx_context.ts +52 -32
  115. package/src/public/public_tx_simulator.ts +58 -38
  116. package/src/public/side_effect_trace_interface.ts +8 -15
  117. package/src/public/transitional_adapters.ts +39 -24
  118. package/dest/public/dual_side_effect_trace.d.ts +0 -77
  119. package/dest/public/dual_side_effect_trace.d.ts.map +0 -1
  120. package/dest/public/dual_side_effect_trace.js +0 -119
  121. package/dest/public/side_effect_trace.d.ts +0 -96
  122. package/dest/public/side_effect_trace.d.ts.map +0 -1
  123. package/dest/public/side_effect_trace.js +0 -309
  124. package/src/public/dual_side_effect_trace.ts +0 -242
  125. package/src/public/side_effect_trace.ts +0 -536
@@ -1,536 +0,0 @@
1
- import { PublicExecutionRequest, UnencryptedFunctionL2Logs, UnencryptedL2Log } from '@aztec/circuit-types';
2
- import {
3
- AvmAppendTreeHint,
4
- AvmContractBytecodeHints,
5
- AvmContractInstanceHint,
6
- AvmExecutionHints,
7
- AvmExternalCallHint,
8
- AvmKeyValueHint,
9
- AvmNullifierReadTreeHint,
10
- AvmNullifierWriteTreeHint,
11
- AvmPublicDataReadTreeHint,
12
- AvmPublicDataWriteTreeHint,
13
- type AztecAddress,
14
- CallContext,
15
- type ContractClassIdPreimage,
16
- type ContractInstanceWithAddress,
17
- ContractStorageRead,
18
- ContractStorageUpdateRequest,
19
- EthAddress,
20
- Gas,
21
- L1_TO_L2_MSG_TREE_HEIGHT,
22
- L2ToL1Message,
23
- LogHash,
24
- MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX,
25
- MAX_L2_TO_L1_MSGS_PER_TX,
26
- MAX_NOTE_HASHES_PER_TX,
27
- MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
28
- MAX_NULLIFIERS_PER_TX,
29
- MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX,
30
- MAX_NULLIFIER_READ_REQUESTS_PER_TX,
31
- MAX_PUBLIC_DATA_READS_PER_TX,
32
- MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
33
- MAX_UNENCRYPTED_LOGS_PER_TX,
34
- NOTE_HASH_TREE_HEIGHT,
35
- NULLIFIER_TREE_HEIGHT,
36
- NoteHash,
37
- Nullifier,
38
- NullifierLeafPreimage,
39
- PUBLIC_DATA_TREE_HEIGHT,
40
- type PublicCallRequest,
41
- PublicDataTreeLeafPreimage,
42
- type PublicInnerCallRequest,
43
- ReadRequest,
44
- SerializableContractInstance,
45
- TreeLeafReadRequest,
46
- } from '@aztec/circuits.js';
47
- import { Fr } from '@aztec/foundation/fields';
48
- import { jsonStringify } from '@aztec/foundation/json-rpc';
49
- import { createDebugLogger } from '@aztec/foundation/log';
50
-
51
- import { assert } from 'console';
52
-
53
- import { type AvmContractCallResult, type AvmFinalizedCallResult } from '../avm/avm_contract_call_result.js';
54
- import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js';
55
- import {
56
- type EnqueuedPublicCallExecutionResultWithSideEffects,
57
- type PublicFunctionCallResult,
58
- resultToPublicCallRequest,
59
- } from './execution.js';
60
- import { SideEffectLimitReachedError } from './side_effect_errors.js';
61
- import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js';
62
-
63
- export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress;
64
-
65
- const emptyPublicDataPath = () => new Array(PUBLIC_DATA_TREE_HEIGHT).fill(Fr.zero());
66
- const emptyNoteHashPath = () => new Array(NOTE_HASH_TREE_HEIGHT).fill(Fr.zero());
67
- const emptyNullifierPath = () => new Array(NULLIFIER_TREE_HEIGHT).fill(Fr.zero());
68
- const emptyL1ToL2MessagePath = () => new Array(L1_TO_L2_MSG_TREE_HEIGHT).fill(Fr.zero());
69
-
70
- export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
71
- public log = createDebugLogger('aztec:public_side_effect_trace');
72
-
73
- /** The side effect counter increments with every call to the trace. */
74
- private sideEffectCounter: number; // kept as number until finalized for efficiency
75
-
76
- private contractStorageReads: ContractStorageRead[] = [];
77
- private contractStorageUpdateRequests: ContractStorageUpdateRequest[] = [];
78
-
79
- private noteHashReadRequests: TreeLeafReadRequest[] = [];
80
- private noteHashes: NoteHash[] = [];
81
-
82
- private nullifierReadRequests: ReadRequest[] = [];
83
- private nullifierNonExistentReadRequests: ReadRequest[] = [];
84
- private nullifiers: Nullifier[] = [];
85
-
86
- private l1ToL2MsgReadRequests: TreeLeafReadRequest[] = [];
87
- private newL2ToL1Messages: L2ToL1Message[] = [];
88
-
89
- private unencryptedLogs: UnencryptedL2Log[] = [];
90
- private allUnencryptedLogs: UnencryptedL2Log[] = [];
91
- private unencryptedLogsHashes: LogHash[] = [];
92
-
93
- private publicCallRequests: PublicInnerCallRequest[] = [];
94
-
95
- private nestedExecutions: PublicFunctionCallResult[] = [];
96
-
97
- private avmCircuitHints: AvmExecutionHints;
98
-
99
- constructor(
100
- /** The counter of this trace's first side effect. */
101
- public readonly startSideEffectCounter: number = 0,
102
- ) {
103
- this.sideEffectCounter = startSideEffectCounter;
104
- this.avmCircuitHints = AvmExecutionHints.empty();
105
- }
106
-
107
- public fork() {
108
- return new PublicSideEffectTrace(this.sideEffectCounter);
109
- }
110
-
111
- public getCounter() {
112
- return this.sideEffectCounter;
113
- }
114
-
115
- private incrementSideEffectCounter() {
116
- this.sideEffectCounter++;
117
- }
118
-
119
- public tracePublicStorageRead(
120
- contractAddress: AztecAddress,
121
- slot: Fr,
122
- value: Fr,
123
- leafPreimage: PublicDataTreeLeafPreimage = PublicDataTreeLeafPreimage.empty(),
124
- leafIndex: Fr = Fr.zero(),
125
- path: Fr[] = emptyPublicDataPath(),
126
- ) {
127
- if (!leafIndex.equals(Fr.zero())) {
128
- // if we have real merkle hint content, make sure the value matches the the provided preimage
129
- assert(leafPreimage.value.equals(value), 'Value mismatch when tracing in public data write');
130
- }
131
- if (this.contractStorageReads.length >= MAX_PUBLIC_DATA_READS_PER_TX) {
132
- throw new SideEffectLimitReachedError('contract storage read', MAX_PUBLIC_DATA_READS_PER_TX);
133
- }
134
-
135
- this.contractStorageReads.push(new ContractStorageRead(slot, value, this.sideEffectCounter, contractAddress));
136
- this.avmCircuitHints.storageValues.items.push(
137
- new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ value),
138
- );
139
-
140
- // New hinting
141
- this.avmCircuitHints.publicDataReads.items.push(new AvmPublicDataReadTreeHint(leafPreimage, leafIndex, path));
142
-
143
- this.log.debug(`SLOAD cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`);
144
- this.incrementSideEffectCounter();
145
- }
146
-
147
- public tracePublicStorageWrite(
148
- contractAddress: AztecAddress,
149
- slot: Fr,
150
- value: Fr,
151
- lowLeafPreimage: PublicDataTreeLeafPreimage = PublicDataTreeLeafPreimage.empty(),
152
- lowLeafIndex: Fr = Fr.zero(),
153
- lowLeafPath: Fr[] = emptyPublicDataPath(),
154
- newLeafPreimage: PublicDataTreeLeafPreimage = PublicDataTreeLeafPreimage.empty(),
155
- insertionPath: Fr[] = emptyPublicDataPath(),
156
- ) {
157
- if (!lowLeafIndex.equals(Fr.zero())) {
158
- // if we have real merkle hint content, make sure the value matches the the provided preimage
159
- assert(newLeafPreimage.value.equals(value), 'Value mismatch when tracing in public data read');
160
- }
161
- if (this.contractStorageUpdateRequests.length >= MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) {
162
- throw new SideEffectLimitReachedError('contract storage write', MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX);
163
- }
164
-
165
- this.contractStorageUpdateRequests.push(
166
- new ContractStorageUpdateRequest(slot, value, this.sideEffectCounter, contractAddress),
167
- );
168
-
169
- // New hinting
170
- const readHint = new AvmPublicDataReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath);
171
- this.avmCircuitHints.publicDataWrites.items.push(
172
- new AvmPublicDataWriteTreeHint(readHint, newLeafPreimage, insertionPath),
173
- );
174
- this.log.debug(`SSTORE cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`);
175
- this.incrementSideEffectCounter();
176
- }
177
-
178
- // TODO(8287): _exists can be removed once we have the vm properly handling the equality check
179
- public traceNoteHashCheck(
180
- _contractAddress: AztecAddress,
181
- noteHash: Fr,
182
- leafIndex: Fr,
183
- exists: boolean,
184
- path: Fr[] = emptyNoteHashPath(),
185
- ) {
186
- // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call
187
- if (this.noteHashReadRequests.length >= MAX_NOTE_HASH_READ_REQUESTS_PER_TX) {
188
- throw new SideEffectLimitReachedError('note hash read request', MAX_NOTE_HASH_READ_REQUESTS_PER_TX);
189
- }
190
- // Temp for backward compatibility
191
- this.noteHashReadRequests.push(new TreeLeafReadRequest(noteHash, leafIndex));
192
- this.avmCircuitHints.noteHashExists.items.push(
193
- new AvmKeyValueHint(/*key=*/ new Fr(leafIndex), /*value=*/ exists ? Fr.ONE : Fr.ZERO),
194
- );
195
- // New Hinting
196
- this.avmCircuitHints.noteHashReads.items.push(new AvmAppendTreeHint(leafIndex, noteHash, path));
197
- // NOTE: counter does not increment for note hash checks (because it doesn't rely on pending note hashes)
198
- }
199
-
200
- public traceNewNoteHash(
201
- _contractAddress: AztecAddress,
202
- noteHash: Fr,
203
- leafIndex: Fr = Fr.zero(),
204
- path: Fr[] = emptyNoteHashPath(),
205
- ) {
206
- if (this.noteHashes.length >= MAX_NOTE_HASHES_PER_TX) {
207
- throw new SideEffectLimitReachedError('note hash', MAX_NOTE_HASHES_PER_TX);
208
- }
209
- this.noteHashes.push(new NoteHash(noteHash, this.sideEffectCounter));
210
- this.log.debug(`NEW_NOTE_HASH cnt: ${this.sideEffectCounter}`);
211
-
212
- // New Hinting
213
- this.avmCircuitHints.noteHashWrites.items.push(new AvmAppendTreeHint(leafIndex, noteHash, path));
214
- this.incrementSideEffectCounter();
215
- }
216
-
217
- public traceNullifierCheck(
218
- siloedNullifier: Fr,
219
- exists: boolean,
220
- lowLeafPreimage: NullifierLeafPreimage = NullifierLeafPreimage.empty(),
221
- lowLeafIndex: Fr = Fr.zero(),
222
- lowLeafPath: Fr[] = emptyNullifierPath(),
223
- ) {
224
- // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call
225
- // NOTE: isPending and leafIndex are unused for now but may be used for optimizations or kernel hints later
226
-
227
- this.enforceLimitOnNullifierChecks();
228
-
229
- const readRequest = new ReadRequest(siloedNullifier, this.sideEffectCounter);
230
- if (exists) {
231
- this.nullifierReadRequests.push(readRequest);
232
- } else {
233
- this.nullifierNonExistentReadRequests.push(readRequest);
234
- }
235
- this.avmCircuitHints.nullifierExists.items.push(
236
- new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ new Fr(exists ? 1 : 0)),
237
- );
238
-
239
- // New Hints
240
- this.avmCircuitHints.nullifierReads.items.push(
241
- new AvmNullifierReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath),
242
- );
243
- this.log.debug(`NULLIFIER_EXISTS cnt: ${this.sideEffectCounter}`);
244
- this.incrementSideEffectCounter();
245
- }
246
-
247
- public traceNewNullifier(
248
- siloedNullifier: Fr,
249
- lowLeafPreimage: NullifierLeafPreimage = NullifierLeafPreimage.empty(),
250
- lowLeafIndex: Fr = Fr.zero(),
251
- lowLeafPath: Fr[] = emptyNullifierPath(),
252
- insertionPath: Fr[] = emptyNullifierPath(),
253
- ) {
254
- // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call
255
- if (this.nullifiers.length >= MAX_NULLIFIERS_PER_TX) {
256
- throw new SideEffectLimitReachedError('nullifier', MAX_NULLIFIERS_PER_TX);
257
- }
258
- // this will be wrong for siloedNullifier
259
- this.nullifiers.push(new Nullifier(siloedNullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO));
260
- // New hinting
261
- const lowLeafReadHint = new AvmNullifierReadTreeHint(lowLeafPreimage, lowLeafIndex, lowLeafPath);
262
- this.avmCircuitHints.nullifierWrites.items.push(new AvmNullifierWriteTreeHint(lowLeafReadHint, insertionPath));
263
- this.log.debug(`NEW_NULLIFIER cnt: ${this.sideEffectCounter}`);
264
- this.incrementSideEffectCounter();
265
- }
266
-
267
- // TODO(8287): _exists can be removed once we have the vm properly handling the equality check
268
- public traceL1ToL2MessageCheck(
269
- _contractAddress: AztecAddress,
270
- msgHash: Fr,
271
- msgLeafIndex: Fr,
272
- exists: boolean,
273
- path: Fr[] = emptyL1ToL2MessagePath(),
274
- ) {
275
- // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call
276
- if (this.l1ToL2MsgReadRequests.length >= MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX) {
277
- throw new SideEffectLimitReachedError('l1 to l2 message read request', MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX);
278
- }
279
- this.l1ToL2MsgReadRequests.push(new TreeLeafReadRequest(msgHash, msgLeafIndex));
280
- this.avmCircuitHints.l1ToL2MessageExists.items.push(
281
- new AvmKeyValueHint(/*key=*/ new Fr(msgLeafIndex), /*value=*/ exists ? Fr.ONE : Fr.ZERO),
282
- );
283
-
284
- // New Hinting
285
- this.avmCircuitHints.l1ToL2MessageReads.items.push(new AvmAppendTreeHint(msgLeafIndex, msgHash, path));
286
- // NOTE: counter does not increment for l1tol2 message checks (because it doesn't rely on pending messages)
287
- }
288
-
289
- public traceNewL2ToL1Message(_contractAddress: AztecAddress, recipient: Fr, content: Fr) {
290
- if (this.newL2ToL1Messages.length >= MAX_L2_TO_L1_MSGS_PER_TX) {
291
- throw new SideEffectLimitReachedError('l2 to l1 message', MAX_L2_TO_L1_MSGS_PER_TX);
292
- }
293
- const recipientAddress = EthAddress.fromField(recipient);
294
- this.newL2ToL1Messages.push(new L2ToL1Message(recipientAddress, content, this.sideEffectCounter));
295
- this.log.debug(`NEW_L2_TO_L1_MSG cnt: ${this.sideEffectCounter}`);
296
- this.incrementSideEffectCounter();
297
- }
298
-
299
- public traceUnencryptedLog(contractAddress: AztecAddress, log: Fr[]) {
300
- if (this.unencryptedLogs.length >= MAX_UNENCRYPTED_LOGS_PER_TX) {
301
- throw new SideEffectLimitReachedError('unencrypted log', MAX_UNENCRYPTED_LOGS_PER_TX);
302
- }
303
- const ulog = new UnencryptedL2Log(contractAddress, Buffer.concat(log.map(f => f.toBuffer())));
304
- const basicLogHash = Fr.fromBuffer(ulog.hash());
305
- this.unencryptedLogs.push(ulog);
306
- this.allUnencryptedLogs.push(ulog);
307
- // This length is for charging DA and is checked on-chain - has to be length of log preimage + 4 bytes.
308
- // The .length call also has a +4 but that is unrelated
309
- this.unencryptedLogsHashes.push(new LogHash(basicLogHash, this.sideEffectCounter, new Fr(ulog.length + 4)));
310
- this.log.debug(`NEW_UNENCRYPTED_LOG cnt: ${this.sideEffectCounter}`);
311
- this.incrementSideEffectCounter();
312
- }
313
-
314
- public traceGetContractInstance(
315
- contractAddress: AztecAddress,
316
- exists: boolean,
317
- instance: SerializableContractInstance = SerializableContractInstance.default(),
318
- ) {
319
- this.enforceLimitOnNullifierChecks('(contract address nullifier from GETCONTRACTINSTANCE)');
320
-
321
- this.avmCircuitHints.contractInstances.items.push(
322
- new AvmContractInstanceHint(
323
- contractAddress,
324
- exists,
325
- instance.salt,
326
- instance.deployer,
327
- instance.contractClassId,
328
- instance.initializationHash,
329
- instance.publicKeys,
330
- ),
331
- );
332
- this.log.debug(`CONTRACT_INSTANCE cnt: ${this.sideEffectCounter}`);
333
- this.incrementSideEffectCounter();
334
- }
335
-
336
- // This tracing function gets called everytime we start simulation/execution.
337
- // This happens both when starting a new top-level trace and the start of every nested trace
338
- // We use this to collect the AvmContractBytecodeHints
339
- // We need to trace teh merkle tree as well here
340
- public traceGetBytecode(
341
- contractAddress: AztecAddress,
342
- exists: boolean,
343
- bytecode: Buffer = Buffer.alloc(0),
344
- contractInstance: SerializableContractInstance = SerializableContractInstance.default(),
345
- contractClass: ContractClassIdPreimage = {
346
- artifactHash: Fr.zero(),
347
- privateFunctionsRoot: Fr.zero(),
348
- publicBytecodeCommitment: Fr.zero(),
349
- },
350
- ) {
351
- const instance = new AvmContractInstanceHint(
352
- contractAddress,
353
- exists,
354
- contractInstance.salt,
355
- contractInstance.deployer,
356
- contractInstance.contractClassId,
357
- contractInstance.initializationHash,
358
- contractInstance.publicKeys,
359
- );
360
- // We need to deduplicate the contract instances based on addresses
361
- this.avmCircuitHints.contractBytecodeHints.items.push(
362
- new AvmContractBytecodeHints(bytecode, instance, contractClass),
363
- );
364
- this.log.debug(
365
- `Bytecode retrieval for contract execution traced: exists=${exists}, instance=${jsonStringify(contractInstance)}`,
366
- );
367
- }
368
-
369
- /**
370
- * Trace a nested call.
371
- * Accept some results from a finished nested call's trace into this one.
372
- */
373
- public traceNestedCall(
374
- /** The trace of the nested call. */
375
- nestedCallTrace: PublicSideEffectTrace,
376
- /** The execution environment of the nested call. */
377
- nestedEnvironment: AvmExecutionEnvironment,
378
- /** How much gas was available for this public execution. */
379
- startGasLeft: Gas,
380
- /** Bytecode used for this execution. */
381
- bytecode: Buffer,
382
- /** The call's results */
383
- avmCallResults: AvmContractCallResult,
384
- /** Function name for logging */
385
- functionName: string = 'unknown',
386
- ) {
387
- // TODO(4805): check if some threshold is reached for max nested calls (to unique contracts?)
388
- // TODO(dbanks12): should emit a nullifier read request. There should be two thresholds.
389
- // one for max unique contract calls, and another based on max nullifier reads.
390
- // Since this trace function happens _after_ a nested call, such threshold limits must take
391
- // place in another trace function that occurs _before_ a nested call.
392
- const result = nestedCallTrace.toPublicFunctionCallResult(
393
- nestedEnvironment,
394
- startGasLeft,
395
- bytecode,
396
- avmCallResults.finalize(),
397
- functionName,
398
- );
399
- this.sideEffectCounter = result.endSideEffectCounter.toNumber();
400
- // when a nested call returns, caller accepts its updated counter
401
- this.allUnencryptedLogs.push(...result.allUnencryptedLogs.logs);
402
- // NOTE: eventually if the AVM circuit processes an entire enqueued call,
403
- // this function will accept all of the nested's side effects into this instance
404
- this.nestedExecutions.push(result);
405
-
406
- const gasUsed = new Gas(
407
- result.startGasLeft.daGas - avmCallResults.gasLeft.daGas,
408
- result.startGasLeft.l2Gas - avmCallResults.gasLeft.l2Gas,
409
- );
410
-
411
- this.publicCallRequests.push(resultToPublicCallRequest(result));
412
-
413
- this.avmCircuitHints.externalCalls.items.push(
414
- new AvmExternalCallHint(
415
- /*success=*/ new Fr(result.reverted ? 0 : 1),
416
- result.returnValues,
417
- gasUsed,
418
- result.endSideEffectCounter,
419
- nestedEnvironment.address,
420
- ),
421
- );
422
- }
423
-
424
- public traceEnqueuedCall(
425
- /** The call request from private that enqueued this call. */
426
- _publicCallRequest: PublicCallRequest,
427
- /** The call's calldata */
428
- _calldata: Fr[],
429
- /** Did the call revert? */
430
- _reverted: boolean,
431
- ) {
432
- throw new Error('Not implemented');
433
- }
434
-
435
- public merge(_nestedTrace: this, _reverted: boolean = false) {
436
- throw new Error('Not implemented');
437
- }
438
-
439
- /**
440
- * Convert this trace to a PublicExecutionResult for use externally to the simulator.
441
- */
442
- public toPublicFunctionCallResult(
443
- /** The execution environment of the nested call. */
444
- avmEnvironment: AvmExecutionEnvironment,
445
- /** How much gas was available for this public execution. */
446
- startGasLeft: Gas,
447
- /** Bytecode used for this execution. */
448
- bytecode: Buffer,
449
- /** The call's results */
450
- avmCallResults: AvmFinalizedCallResult,
451
- /** Function name for logging */
452
- functionName: string = 'unknown',
453
- ): PublicFunctionCallResult {
454
- return {
455
- executionRequest: createPublicExecutionRequest(avmEnvironment),
456
-
457
- startSideEffectCounter: new Fr(this.startSideEffectCounter),
458
- endSideEffectCounter: new Fr(this.sideEffectCounter),
459
- startGasLeft,
460
- endGasLeft: avmCallResults.gasLeft,
461
- transactionFee: avmEnvironment.transactionFee,
462
-
463
- bytecode,
464
- calldata: avmEnvironment.calldata,
465
- returnValues: avmCallResults.output,
466
- reverted: avmCallResults.reverted,
467
- revertReason: avmCallResults.revertReason,
468
-
469
- contractStorageReads: this.contractStorageReads,
470
- contractStorageUpdateRequests: this.contractStorageUpdateRequests,
471
- noteHashReadRequests: this.noteHashReadRequests,
472
- noteHashes: this.noteHashes,
473
- nullifierReadRequests: this.nullifierReadRequests,
474
- nullifierNonExistentReadRequests: this.nullifierNonExistentReadRequests,
475
- nullifiers: this.nullifiers,
476
- l1ToL2MsgReadRequests: this.l1ToL2MsgReadRequests,
477
- l2ToL1Messages: this.newL2ToL1Messages,
478
- // correct the type on these now that they are finalized (lists won't grow)
479
- unencryptedLogs: new UnencryptedFunctionL2Logs(this.unencryptedLogs),
480
- allUnencryptedLogs: new UnencryptedFunctionL2Logs(this.allUnencryptedLogs),
481
- unencryptedLogsHashes: this.unencryptedLogsHashes,
482
-
483
- publicCallRequests: this.publicCallRequests,
484
- nestedExecutions: this.nestedExecutions,
485
-
486
- avmCircuitHints: this.avmCircuitHints,
487
-
488
- functionName,
489
- };
490
- }
491
-
492
- public toPublicEnqueuedCallExecutionResult(
493
- /** The call's results */
494
- _avmCallResults: AvmFinalizedCallResult,
495
- ): EnqueuedPublicCallExecutionResultWithSideEffects {
496
- throw new Error('Not implemented');
497
- }
498
-
499
- private enforceLimitOnNullifierChecks(errorMsgOrigin: string = '') {
500
- // NOTE: Why error if _either_ limit was reached? If user code emits either an existent or non-existent
501
- // nullifier read request (NULLIFIEREXISTS, GETCONTRACTINSTANCE, *CALL), and one of the limits has been
502
- // reached (MAX_NULLIFIER_NON_EXISTENT_RRS vs MAX_NULLIFIER_RRS), but not the other, we must prevent the
503
- // sequencer from lying and saying "this nullifier exists, but MAX_NULLIFIER_RRS has been reached, so I'm
504
- // going to skip the read request and just revert instead" when the nullifier actually doesn't exist
505
- // (or vice versa). So, if either maximum has been reached, any nullifier-reading operation must error.
506
- if (this.nullifierReadRequests.length >= MAX_NULLIFIER_READ_REQUESTS_PER_TX) {
507
- throw new SideEffectLimitReachedError(
508
- `nullifier read request ${errorMsgOrigin}`,
509
- MAX_NULLIFIER_READ_REQUESTS_PER_TX,
510
- );
511
- }
512
- if (this.nullifierNonExistentReadRequests.length >= MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX) {
513
- throw new SideEffectLimitReachedError(
514
- `nullifier non-existent read request ${errorMsgOrigin}`,
515
- MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX,
516
- );
517
- }
518
- }
519
-
520
- public getUnencryptedLogs(): UnencryptedL2Log[] {
521
- throw new Error('Not implemented');
522
- }
523
- }
524
-
525
- /**
526
- * Helper function to create a public execution request from an AVM execution environment
527
- */
528
- function createPublicExecutionRequest(avmEnvironment: AvmExecutionEnvironment): PublicExecutionRequest {
529
- const callContext = CallContext.from({
530
- msgSender: avmEnvironment.sender,
531
- contractAddress: avmEnvironment.address,
532
- functionSelector: avmEnvironment.functionSelector,
533
- isStaticCall: avmEnvironment.isStaticCall,
534
- });
535
- return new PublicExecutionRequest(callContext, avmEnvironment.calldata);
536
- }