@aztec/simulator 0.43.0 → 0.45.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 (155) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +3 -1
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +12 -6
  4. package/dest/acvm/oracle/typed_oracle.d.ts +6 -4
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +8 -2
  7. package/dest/avm/avm_context.d.ts +1 -1
  8. package/dest/avm/avm_context.d.ts.map +1 -1
  9. package/dest/avm/avm_context.js +3 -3
  10. package/dest/avm/{avm_message_call_result.d.ts → avm_contract_call_result.d.ts} +2 -2
  11. package/dest/avm/avm_contract_call_result.d.ts.map +1 -0
  12. package/dest/avm/avm_contract_call_result.js +18 -0
  13. package/dest/avm/avm_execution_environment.d.ts +8 -10
  14. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  15. package/dest/avm/avm_execution_environment.js +15 -19
  16. package/dest/avm/avm_gas.js +2 -2
  17. package/dest/avm/avm_simulator.d.ts +4 -4
  18. package/dest/avm/avm_simulator.d.ts.map +1 -1
  19. package/dest/avm/avm_simulator.js +7 -8
  20. package/dest/avm/bytecode_utils.d.ts +5 -0
  21. package/dest/avm/bytecode_utils.d.ts.map +1 -0
  22. package/dest/avm/bytecode_utils.js +29 -0
  23. package/dest/avm/errors.js +2 -2
  24. package/dest/avm/fixtures/index.d.ts +10 -6
  25. package/dest/avm/fixtures/index.d.ts.map +1 -1
  26. package/dest/avm/fixtures/index.js +10 -17
  27. package/dest/avm/journal/journal.d.ts +56 -65
  28. package/dest/avm/journal/journal.d.ts.map +1 -1
  29. package/dest/avm/journal/journal.js +80 -117
  30. package/dest/avm/journal/nullifiers.d.ts +21 -8
  31. package/dest/avm/journal/nullifiers.d.ts.map +1 -1
  32. package/dest/avm/journal/nullifiers.js +26 -8
  33. package/dest/avm/journal/public_storage.d.ts +5 -1
  34. package/dest/avm/journal/public_storage.d.ts.map +1 -1
  35. package/dest/avm/journal/public_storage.js +11 -2
  36. package/dest/avm/opcodes/accrued_substate.d.ts +1 -2
  37. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  38. package/dest/avm/opcodes/accrued_substate.js +8 -17
  39. package/dest/avm/opcodes/environment_getters.d.ts +13 -8
  40. package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
  41. package/dest/avm/opcodes/environment_getters.js +20 -13
  42. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  43. package/dest/avm/opcodes/external_calls.js +11 -27
  44. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  45. package/dest/avm/serialization/bytecode_serialization.js +5 -5
  46. package/dest/avm/serialization/instruction_serialization.d.ts +9 -9
  47. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  48. package/dest/avm/serialization/instruction_serialization.js +10 -10
  49. package/dest/avm/test_utils.d.ts +14 -0
  50. package/dest/avm/test_utils.d.ts.map +1 -0
  51. package/dest/avm/test_utils.js +36 -0
  52. package/dest/client/client_execution_context.d.ts +6 -4
  53. package/dest/client/client_execution_context.d.ts.map +1 -1
  54. package/dest/client/client_execution_context.js +8 -6
  55. package/dest/client/execution_note_cache.d.ts.map +1 -1
  56. package/dest/client/execution_note_cache.js +1 -1
  57. package/dest/client/execution_result.d.ts +2 -1
  58. package/dest/client/execution_result.d.ts.map +1 -1
  59. package/dest/client/execution_result.js +1 -1
  60. package/dest/client/index.d.ts +2 -0
  61. package/dest/client/index.d.ts.map +1 -1
  62. package/dest/client/index.js +3 -1
  63. package/dest/client/simulator.d.ts +3 -3
  64. package/dest/client/simulator.d.ts.map +1 -1
  65. package/dest/client/simulator.js +1 -1
  66. package/dest/client/view_data_oracle.d.ts +5 -1
  67. package/dest/client/view_data_oracle.d.ts.map +1 -1
  68. package/dest/client/view_data_oracle.js +12 -4
  69. package/dest/mocks/fixtures.d.ts +3 -3
  70. package/dest/mocks/fixtures.d.ts.map +1 -1
  71. package/dest/mocks/fixtures.js +6 -5
  72. package/dest/public/abstract_phase_manager.d.ts +1 -0
  73. package/dest/public/abstract_phase_manager.d.ts.map +1 -1
  74. package/dest/public/abstract_phase_manager.js +17 -14
  75. package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
  76. package/dest/public/app_logic_phase_manager.js +2 -1
  77. package/dest/public/execution.d.ts +33 -30
  78. package/dest/public/execution.d.ts.map +1 -1
  79. package/dest/public/execution.js +2 -2
  80. package/dest/public/executor.d.ts +12 -7
  81. package/dest/public/executor.d.ts.map +1 -1
  82. package/dest/public/executor.js +42 -33
  83. package/dest/public/hints_builder.d.ts +1 -1
  84. package/dest/public/index.d.ts +1 -1
  85. package/dest/public/index.d.ts.map +1 -1
  86. package/dest/public/index.js +1 -1
  87. package/dest/public/public_kernel.d.ts +1 -1
  88. package/dest/public/public_kernel.d.ts.map +1 -1
  89. package/dest/public/public_kernel.js +2 -2
  90. package/dest/public/public_processor.d.ts +5 -2
  91. package/dest/public/public_processor.d.ts.map +1 -1
  92. package/dest/public/public_processor.js +142 -123
  93. package/dest/public/side_effect_trace.d.ts +87 -0
  94. package/dest/public/side_effect_trace.d.ts.map +1 -0
  95. package/dest/public/side_effect_trace.js +236 -0
  96. package/dest/public/side_effect_trace_interface.d.ts +36 -0
  97. package/dest/public/side_effect_trace_interface.d.ts.map +1 -0
  98. package/dest/public/side_effect_trace_interface.js +2 -0
  99. package/dest/public/teardown_phase_manager.d.ts.map +1 -1
  100. package/dest/public/teardown_phase_manager.js +2 -1
  101. package/dest/rollup/rollup.d.ts +1 -1
  102. package/dest/rollup/rollup.d.ts.map +1 -1
  103. package/dest/rollup/rollup.js +2 -2
  104. package/package.json +18 -9
  105. package/src/acvm/oracle/oracle.ts +23 -5
  106. package/src/acvm/oracle/typed_oracle.ts +23 -4
  107. package/src/avm/avm_context.ts +2 -2
  108. package/src/avm/{avm_message_call_result.ts → avm_contract_call_result.ts} +1 -1
  109. package/src/avm/avm_execution_environment.ts +16 -26
  110. package/src/avm/avm_gas.ts +1 -1
  111. package/src/avm/avm_simulator.ts +10 -13
  112. package/src/avm/bytecode_utils.ts +32 -0
  113. package/src/avm/errors.ts +1 -1
  114. package/src/avm/fixtures/index.ts +21 -23
  115. package/src/avm/journal/journal.ts +118 -224
  116. package/src/avm/journal/nullifiers.ts +30 -13
  117. package/src/avm/journal/public_storage.ts +12 -2
  118. package/src/avm/opcodes/accrued_substate.ts +12 -21
  119. package/src/avm/opcodes/environment_getters.ts +23 -14
  120. package/src/avm/opcodes/external_calls.ts +13 -36
  121. package/src/avm/serialization/bytecode_serialization.ts +4 -3
  122. package/src/avm/serialization/instruction_serialization.ts +3 -3
  123. package/src/avm/test_utils.ts +53 -0
  124. package/src/client/client_execution_context.ts +22 -7
  125. package/src/client/execution_note_cache.ts +0 -1
  126. package/src/client/execution_result.ts +2 -1
  127. package/src/client/index.ts +2 -0
  128. package/src/client/simulator.ts +8 -2
  129. package/src/client/view_data_oracle.ts +20 -3
  130. package/src/mocks/fixtures.ts +7 -6
  131. package/src/public/abstract_phase_manager.ts +32 -21
  132. package/src/public/app_logic_phase_manager.ts +1 -0
  133. package/src/public/execution.ts +45 -31
  134. package/src/public/executor.ts +71 -49
  135. package/src/public/index.ts +1 -1
  136. package/src/public/public_kernel.ts +2 -1
  137. package/src/public/public_processor.ts +11 -2
  138. package/src/public/side_effect_trace.ts +341 -0
  139. package/src/public/side_effect_trace_interface.ts +41 -0
  140. package/src/public/teardown_phase_manager.ts +1 -0
  141. package/src/rollup/rollup.ts +3 -1
  142. package/dest/avm/avm_message_call_result.d.ts.map +0 -1
  143. package/dest/avm/avm_message_call_result.js +0 -18
  144. package/dest/avm/journal/trace.d.ts +0 -33
  145. package/dest/avm/journal/trace.d.ts.map +0 -1
  146. package/dest/avm/journal/trace.js +0 -152
  147. package/dest/avm/journal/trace_types.d.ts +0 -55
  148. package/dest/avm/journal/trace_types.d.ts.map +0 -1
  149. package/dest/avm/journal/trace_types.js +0 -2
  150. package/dest/public/transitional_adaptors.d.ts +0 -21
  151. package/dest/public/transitional_adaptors.d.ts.map +0 -1
  152. package/dest/public/transitional_adaptors.js +0 -90
  153. package/src/avm/journal/trace.ts +0 -181
  154. package/src/avm/journal/trace_types.ts +0 -91
  155. package/src/public/transitional_adaptors.ts +0 -168
@@ -0,0 +1,341 @@
1
+ import { UnencryptedFunctionL2Logs, UnencryptedL2Log } from '@aztec/circuit-types';
2
+ import {
3
+ AvmContractInstanceHint,
4
+ AvmExecutionHints,
5
+ AvmExternalCallHint,
6
+ AvmKeyValueHint,
7
+ AztecAddress,
8
+ CallContext,
9
+ ContractStorageRead,
10
+ ContractStorageUpdateRequest,
11
+ EthAddress,
12
+ Gas,
13
+ L2ToL1Message,
14
+ LogHash,
15
+ NoteHash,
16
+ Nullifier,
17
+ ReadRequest,
18
+ } from '@aztec/circuits.js';
19
+ import { EventSelector } from '@aztec/foundation/abi';
20
+ import { Fr } from '@aztec/foundation/fields';
21
+ import { createDebugLogger } from '@aztec/foundation/log';
22
+ import { type ContractInstanceWithAddress } from '@aztec/types/contracts';
23
+
24
+ import { type AvmContractCallResult } from '../avm/avm_contract_call_result.js';
25
+ import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js';
26
+ import { createSimulationError } from '../common/errors.js';
27
+ import { type PublicExecutionRequest, type PublicExecutionResult } from './execution.js';
28
+ import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js';
29
+
30
+ export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress;
31
+
32
+ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
33
+ public logger = createDebugLogger('aztec:public_side_effect_trace');
34
+
35
+ /** The side effect counter increments with every call to the trace. */
36
+ private sideEffectCounter: number; // kept as number until finalized for efficiency
37
+
38
+ private contractStorageReads: ContractStorageRead[] = [];
39
+ private contractStorageUpdateRequests: ContractStorageUpdateRequest[] = [];
40
+
41
+ private noteHashReadRequests: ReadRequest[] = [];
42
+ private newNoteHashes: NoteHash[] = [];
43
+
44
+ private nullifierReadRequests: ReadRequest[] = [];
45
+ private nullifierNonExistentReadRequests: ReadRequest[] = [];
46
+ private newNullifiers: Nullifier[] = [];
47
+
48
+ private l1ToL2MsgReadRequests: ReadRequest[] = [];
49
+ private newL2ToL1Messages: L2ToL1Message[] = [];
50
+
51
+ private unencryptedLogs: UnencryptedL2Log[] = [];
52
+ private allUnencryptedLogs: UnencryptedL2Log[] = [];
53
+ private unencryptedLogsHashes: LogHash[] = [];
54
+
55
+ private gotContractInstances: ContractInstanceWithAddress[] = [];
56
+
57
+ private nestedExecutions: PublicExecutionResult[] = [];
58
+
59
+ private avmCircuitHints: AvmExecutionHints;
60
+
61
+ constructor(
62
+ /** The counter of this trace's first side effect. */
63
+ public readonly startSideEffectCounter: number = 0,
64
+ ) {
65
+ this.sideEffectCounter = startSideEffectCounter;
66
+ this.avmCircuitHints = AvmExecutionHints.empty();
67
+ }
68
+
69
+ public fork() {
70
+ return new PublicSideEffectTrace(this.sideEffectCounter);
71
+ }
72
+
73
+ public getCounter() {
74
+ return this.sideEffectCounter;
75
+ }
76
+
77
+ private incrementSideEffectCounter() {
78
+ this.sideEffectCounter++;
79
+ }
80
+
81
+ public tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, _exists: boolean, _cached: boolean) {
82
+ // TODO(4805): check if some threshold is reached for max storage reads
83
+ // (need access to parent length, or trace needs to be initialized with parent's contents)
84
+ // NOTE: exists and cached are unused for now but may be used for optimizations or kernel hints later
85
+ this.contractStorageReads.push(
86
+ new ContractStorageRead(slot, value, this.sideEffectCounter, AztecAddress.fromField(storageAddress)),
87
+ );
88
+ this.avmCircuitHints.storageValues.items.push(
89
+ new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ value),
90
+ );
91
+ this.logger.debug(`SLOAD cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`);
92
+ this.incrementSideEffectCounter();
93
+ }
94
+
95
+ public tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr) {
96
+ // TODO(4805): check if some threshold is reached for max storage writes
97
+ // (need access to parent length, or trace needs to be initialized with parent's contents)
98
+ this.contractStorageUpdateRequests.push(
99
+ new ContractStorageUpdateRequest(slot, value, this.sideEffectCounter, storageAddress),
100
+ );
101
+ this.logger.debug(`SSTORE cnt: ${this.sideEffectCounter} val: ${value} slot: ${slot}`);
102
+ this.incrementSideEffectCounter();
103
+ }
104
+
105
+ public traceNoteHashCheck(_storageAddress: Fr, noteHash: Fr, _leafIndex: Fr, exists: boolean) {
106
+ // TODO(4805): check if some threshold is reached for max note hash checks
107
+ // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call
108
+ // TODO(dbanks12): leafIndex is unused for now but later must be used by kernel to constrain that the kernel
109
+ // is in fact checking the leaf indicated by the user
110
+ this.noteHashReadRequests.push(new ReadRequest(noteHash, this.sideEffectCounter));
111
+ this.avmCircuitHints.noteHashExists.items.push(
112
+ new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ new Fr(exists ? 1 : 0)),
113
+ );
114
+ this.logger.debug(`NOTE_HASH_CHECK cnt: ${this.sideEffectCounter}`);
115
+ this.incrementSideEffectCounter();
116
+ }
117
+
118
+ public traceNewNoteHash(_storageAddress: Fr, noteHash: Fr) {
119
+ // TODO(4805): check if some threshold is reached for max new note hash
120
+ // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call
121
+ // TODO(dbanks12): non-existent note hashes should emit a read request of the note hash that actually
122
+ // IS there, and the AVM circuit should accept THAT noteHash as a hint. The circuit will then compare
123
+ // the noteHash against the one provided by the user code to determine what to return to the user (exists or not),
124
+ // and will then propagate the actually-present noteHash to its public inputs.
125
+ this.newNoteHashes.push(new NoteHash(noteHash, this.sideEffectCounter));
126
+ this.logger.debug(`NEW_NOTE_HASH cnt: ${this.sideEffectCounter}`);
127
+ this.incrementSideEffectCounter();
128
+ }
129
+
130
+ public traceNullifierCheck(_storageAddress: Fr, nullifier: Fr, _leafIndex: Fr, exists: boolean, _isPending: boolean) {
131
+ // TODO(4805): check if some threshold is reached for max new nullifier
132
+ // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call
133
+ // NOTE: isPending and leafIndex are unused for now but may be used for optimizations or kernel hints later
134
+ const readRequest = new ReadRequest(nullifier, this.sideEffectCounter);
135
+ if (exists) {
136
+ this.nullifierReadRequests.push(readRequest);
137
+ } else {
138
+ this.nullifierNonExistentReadRequests.push(readRequest);
139
+ }
140
+ this.avmCircuitHints.nullifierExists.items.push(
141
+ new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ new Fr(exists ? 1 : 0)),
142
+ );
143
+ this.logger.debug(`NULLIFIER_EXISTS cnt: ${this.sideEffectCounter}`);
144
+ this.incrementSideEffectCounter();
145
+ }
146
+
147
+ public traceNewNullifier(_storageAddress: Fr, nullifier: Fr) {
148
+ // TODO(4805): check if some threshold is reached for max new nullifier
149
+ // NOTE: storageAddress is unused but will be important when an AVM circuit processes an entire enqueued call
150
+ this.newNullifiers.push(new Nullifier(nullifier, this.sideEffectCounter, /*noteHash=*/ Fr.ZERO));
151
+ this.logger.debug(`NEW_NULLIFIER cnt: ${this.sideEffectCounter}`);
152
+ this.incrementSideEffectCounter();
153
+ }
154
+
155
+ public traceL1ToL2MessageCheck(_contractAddress: Fr, msgHash: Fr, _msgLeafIndex: Fr, exists: boolean) {
156
+ // TODO(4805): check if some threshold is reached for max message reads
157
+ // NOTE: contractAddress is unused but will be important when an AVM circuit processes an entire enqueued call
158
+ // TODO(dbanks12): leafIndex is unused for now but later must be used by kernel to constrain that the kernel
159
+ // is in fact checking the leaf indicated by the user
160
+ this.l1ToL2MsgReadRequests.push(new ReadRequest(msgHash, this.sideEffectCounter));
161
+ this.avmCircuitHints.l1ToL2MessageExists.items.push(
162
+ new AvmKeyValueHint(/*key=*/ new Fr(this.sideEffectCounter), /*value=*/ new Fr(exists ? 1 : 0)),
163
+ );
164
+ this.logger.debug(`L1_TO_L2_MSG_CHECK cnt: ${this.sideEffectCounter}`);
165
+ this.incrementSideEffectCounter();
166
+ }
167
+
168
+ public traceNewL2ToL1Message(recipient: Fr, content: Fr) {
169
+ // TODO(4805): check if some threshold is reached for max messages
170
+ const recipientAddress = EthAddress.fromField(recipient);
171
+ this.newL2ToL1Messages.push(new L2ToL1Message(recipientAddress, content, this.sideEffectCounter));
172
+ this.logger.debug(`NEW_L2_TO_L1_MSG cnt: ${this.sideEffectCounter}`);
173
+ this.incrementSideEffectCounter();
174
+ }
175
+
176
+ public traceUnencryptedLog(contractAddress: Fr, log: Fr[]) {
177
+ // TODO(4805): check if some threshold is reached for max logs
178
+ const ulog = new UnencryptedL2Log(
179
+ AztecAddress.fromField(contractAddress),
180
+ // TODO(#7198): Remove event selector from UnencryptedL2Log
181
+ EventSelector.fromField(new Fr(0)),
182
+ Buffer.concat(log.map(f => f.toBuffer())),
183
+ );
184
+ const basicLogHash = Fr.fromBuffer(ulog.hash());
185
+ this.unencryptedLogs.push(ulog);
186
+ this.allUnencryptedLogs.push(ulog);
187
+ // TODO(6578): explain magic number 4 here
188
+ this.unencryptedLogsHashes.push(new LogHash(basicLogHash, this.sideEffectCounter, new Fr(ulog.length + 4)));
189
+ this.logger.debug(`NEW_UNENCRYPTED_LOG cnt: ${this.sideEffectCounter}`);
190
+ this.incrementSideEffectCounter();
191
+ }
192
+
193
+ public traceGetContractInstance(instance: TracedContractInstance) {
194
+ // TODO(4805): check if some threshold is reached for max contract instance retrievals
195
+ this.gotContractInstances.push(instance);
196
+ this.avmCircuitHints.contractInstances.items.push(
197
+ new AvmContractInstanceHint(
198
+ instance.address,
199
+ new Fr(instance.exists ? 1 : 0),
200
+ instance.salt,
201
+ instance.deployer,
202
+ instance.contractClassId,
203
+ instance.initializationHash,
204
+ instance.publicKeysHash,
205
+ ),
206
+ );
207
+ this.logger.debug(`CONTRACT_INSTANCE cnt: ${this.sideEffectCounter}`);
208
+ this.incrementSideEffectCounter();
209
+ }
210
+
211
+ /**
212
+ * Trace a nested call.
213
+ * Accept some results from a finished nested call's trace into this one.
214
+ */
215
+ public traceNestedCall(
216
+ /** The trace of the nested call. */
217
+ nestedCallTrace: PublicSideEffectTrace,
218
+ /** The execution environment of the nested call. */
219
+ nestedEnvironment: AvmExecutionEnvironment,
220
+ /** How much gas was available for this public execution. */
221
+ startGasLeft: Gas,
222
+ /** How much gas was left after this public execution. */
223
+ endGasLeft: Gas,
224
+ /** Bytecode used for this execution. */
225
+ bytecode: Buffer,
226
+ /** The call's results */
227
+ avmCallResults: AvmContractCallResult,
228
+ /** Function name for logging */
229
+ functionName: string = 'unknown',
230
+ ) {
231
+ const result = nestedCallTrace.toPublicExecutionResult(
232
+ nestedEnvironment,
233
+ startGasLeft,
234
+ endGasLeft,
235
+ bytecode,
236
+ avmCallResults,
237
+ functionName,
238
+ );
239
+ this.sideEffectCounter = result.endSideEffectCounter.toNumber();
240
+ // when a nested call returns, caller accepts its updated counter
241
+ this.allUnencryptedLogs.push(...result.allUnencryptedLogs.logs);
242
+ // NOTE: eventually if the AVM circuit processes an entire enqueued call,
243
+ // this function will accept all of the nested's side effects into this instance
244
+ this.nestedExecutions.push(result);
245
+
246
+ const gasUsed = new Gas(
247
+ result.startGasLeft.daGas - result.endGasLeft.daGas,
248
+ result.startGasLeft.l2Gas - result.endGasLeft.l2Gas,
249
+ );
250
+ this.avmCircuitHints.externalCalls.items.push(
251
+ new AvmExternalCallHint(
252
+ /*success=*/ new Fr(result.reverted ? 0 : 1),
253
+ result.returnValues,
254
+ gasUsed,
255
+ result.endSideEffectCounter,
256
+ ),
257
+ );
258
+ }
259
+
260
+ /**
261
+ * Convert this trace to a PublicExecutionResult for use externally to the simulator.
262
+ */
263
+ public toPublicExecutionResult(
264
+ /** The execution environment of the nested call. */
265
+ avmEnvironment: AvmExecutionEnvironment,
266
+ /** How much gas was available for this public execution. */
267
+ startGasLeft: Gas,
268
+ /** How much gas was left after this public execution. */
269
+ endGasLeft: Gas,
270
+ /** Bytecode used for this execution. */
271
+ bytecode: Buffer,
272
+ /** The call's results */
273
+ avmCallResults: AvmContractCallResult,
274
+ /** Function name for logging */
275
+ functionName: string = 'unknown',
276
+ /** The side effect counter of the execution request itself */
277
+ requestSideEffectCounter: number = this.startSideEffectCounter,
278
+ ): PublicExecutionResult {
279
+ return {
280
+ executionRequest: createPublicExecutionRequest(requestSideEffectCounter, avmEnvironment),
281
+
282
+ startSideEffectCounter: new Fr(this.startSideEffectCounter),
283
+ endSideEffectCounter: new Fr(this.sideEffectCounter),
284
+ startGasLeft,
285
+ endGasLeft,
286
+ transactionFee: avmEnvironment.transactionFee,
287
+
288
+ bytecode,
289
+ calldata: avmEnvironment.calldata,
290
+ returnValues: avmCallResults.output,
291
+ reverted: avmCallResults.reverted,
292
+ revertReason: avmCallResults.revertReason ? createSimulationError(avmCallResults.revertReason) : undefined,
293
+
294
+ contractStorageReads: this.contractStorageReads,
295
+ contractStorageUpdateRequests: this.contractStorageUpdateRequests,
296
+ noteHashReadRequests: this.noteHashReadRequests,
297
+ newNoteHashes: this.newNoteHashes,
298
+ nullifierReadRequests: this.nullifierReadRequests,
299
+ nullifierNonExistentReadRequests: this.nullifierNonExistentReadRequests,
300
+ newNullifiers: this.newNullifiers,
301
+ l1ToL2MsgReadRequests: this.l1ToL2MsgReadRequests,
302
+ newL2ToL1Messages: this.newL2ToL1Messages,
303
+ // correct the type on these now that they are finalized (lists won't grow)
304
+ unencryptedLogs: new UnencryptedFunctionL2Logs(this.unencryptedLogs),
305
+ allUnencryptedLogs: new UnencryptedFunctionL2Logs(this.allUnencryptedLogs),
306
+ unencryptedLogsHashes: this.unencryptedLogsHashes,
307
+ // TODO(dbanks12): process contract instance read requests in public kernel
308
+ //gotContractInstances: this.gotContractInstances,
309
+
310
+ nestedExecutions: this.nestedExecutions,
311
+
312
+ avmCircuitHints: this.avmCircuitHints,
313
+
314
+ functionName,
315
+ };
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Helper function to create a public execution request from an AVM execution environment
321
+ */
322
+ function createPublicExecutionRequest(
323
+ requestSideEffectCounter: number,
324
+ avmEnvironment: AvmExecutionEnvironment,
325
+ ): PublicExecutionRequest {
326
+ const callContext = CallContext.from({
327
+ msgSender: avmEnvironment.sender,
328
+ storageContractAddress: avmEnvironment.storageAddress,
329
+ functionSelector: avmEnvironment.functionSelector,
330
+ isDelegateCall: avmEnvironment.isDelegateCall,
331
+ isStaticCall: avmEnvironment.isStaticCall,
332
+ sideEffectCounter: requestSideEffectCounter,
333
+ });
334
+ return {
335
+ contractAddress: avmEnvironment.address,
336
+ functionSelector: avmEnvironment.functionSelector,
337
+ callContext,
338
+ // execution request does not contain AvmContextInputs prefix
339
+ args: avmEnvironment.getCalldataWithoutPrefix(),
340
+ };
341
+ }
@@ -0,0 +1,41 @@
1
+ import { type Gas } from '@aztec/circuits.js';
2
+ import { type Fr } from '@aztec/foundation/fields';
3
+
4
+ import { type AvmContractCallResult } from '../avm/avm_contract_call_result.js';
5
+ import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.js';
6
+ import { type TracedContractInstance } from './side_effect_trace.js';
7
+
8
+ export interface PublicSideEffectTraceInterface {
9
+ fork(): PublicSideEffectTraceInterface;
10
+ getCounter(): number;
11
+ tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean): void;
12
+ tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr): void;
13
+ traceNoteHashCheck(storageAddress: Fr, noteHash: Fr, leafIndex: Fr, exists: boolean): void;
14
+ traceNewNoteHash(storageAddress: Fr, noteHash: Fr): void;
15
+ traceNullifierCheck(storageAddress: Fr, nullifier: Fr, leafIndex: Fr, exists: boolean, isPending: boolean): void;
16
+ traceNewNullifier(storageAddress: Fr, nullifier: Fr): void;
17
+ traceL1ToL2MessageCheck(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr, exists: boolean): void;
18
+ // TODO(dbanks12): should new message accept contract address as arg?
19
+ traceNewL2ToL1Message(recipient: Fr, content: Fr): void;
20
+ traceUnencryptedLog(contractAddress: Fr, log: Fr[]): void;
21
+ // TODO(dbanks12): odd that getContractInstance is a one-off in that it accepts an entire object instead of components
22
+ traceGetContractInstance(instance: TracedContractInstance): void;
23
+ traceNestedCall(
24
+ /** The trace of the nested call. */
25
+ nestedCallTrace: PublicSideEffectTraceInterface,
26
+ /** The execution environment of the nested call. */
27
+ nestedEnvironment: AvmExecutionEnvironment,
28
+ /** How much gas was available for this public execution. */
29
+ // TODO(dbanks12): consider moving to AvmExecutionEnvironment
30
+ startGasLeft: Gas,
31
+ /** How much gas was left after this public execution. */
32
+ // TODO(dbanks12): consider moving to AvmContractCallResults
33
+ endGasLeft: Gas,
34
+ /** Bytecode used for this execution. */
35
+ bytecode: Buffer,
36
+ /** The call's results */
37
+ avmCallResults: AvmContractCallResult,
38
+ /** Function name */
39
+ functionName: string,
40
+ ): void;
41
+ }
@@ -44,6 +44,7 @@ export class TeardownPhaseManager extends AbstractPhaseManager {
44
44
  );
45
45
  if (revertReason) {
46
46
  await this.publicStateDB.rollbackToCheckpoint();
47
+ tx.filterRevertedLogs(kernelOutput);
47
48
  } else {
48
49
  // TODO(#6464): Should we allow emitting contracts in the public teardown phase?
49
50
  // if so, we should insert them here
@@ -28,7 +28,9 @@ import {
28
28
  convertSimulatedBaseRollupInputsToWitnessMap,
29
29
  convertSimulatedBaseRollupOutputsFromWitnessMap,
30
30
  } from '@aztec/noir-protocol-circuits-types';
31
- import { type SimulationProvider, WASMSimulator } from '@aztec/simulator';
31
+
32
+ import { WASMSimulator } from '../providers/acvm_wasm.js';
33
+ import { type SimulationProvider } from '../providers/simulation_provider.js';
32
34
 
33
35
  /**
34
36
  * Circuit simulator for the rollup circuits.
@@ -1 +0,0 @@
1
- {"version":3,"file":"avm_message_call_result.d.ts","sourceRoot":"","sources":["../../src/avm/avm_message_call_result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;GAEG;AACH,qBAAa,sBAAsB;IACd,QAAQ,EAAE,OAAO;IAAS,MAAM,EAAE,EAAE,EAAE;IAAS,YAAY,CAAC;gBAA5D,QAAQ,EAAE,OAAO,EAAS,MAAM,EAAE,EAAE,EAAE,EAAS,YAAY,CAAC,6BAAiB;IAEhG,QAAQ,IAAI,MAAM;CAOnB"}
@@ -1,18 +0,0 @@
1
- /**
2
- * Results of an contract call's execution in the AVM.
3
- */
4
- export class AvmContractCallResults {
5
- constructor(reverted, output, revertReason) {
6
- this.reverted = reverted;
7
- this.output = output;
8
- this.revertReason = revertReason;
9
- }
10
- toString() {
11
- let resultsStr = `reverted: ${this.reverted}, output: ${this.output}`;
12
- if (this.revertReason) {
13
- resultsStr += `, revertReason: ${this.revertReason}`;
14
- }
15
- return resultsStr;
16
- }
17
- }
18
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXZtX21lc3NhZ2VfY2FsbF9yZXN1bHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXZtL2F2bV9tZXNzYWdlX2NhbGxfcmVzdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBOztHQUVHO0FBQ0gsTUFBTSxPQUFPLHNCQUFzQjtJQUNqQyxZQUFtQixRQUFpQixFQUFTLE1BQVksRUFBUyxZQUE4QjtRQUE3RSxhQUFRLEdBQVIsUUFBUSxDQUFTO1FBQVMsV0FBTSxHQUFOLE1BQU0sQ0FBTTtRQUFTLGlCQUFZLEdBQVosWUFBWSxDQUFrQjtJQUFHLENBQUM7SUFFcEcsUUFBUTtRQUNOLElBQUksVUFBVSxHQUFHLGFBQWEsSUFBSSxDQUFDLFFBQVEsYUFBYSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdEUsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEIsVUFBVSxJQUFJLG1CQUFtQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdkQsQ0FBQztRQUNELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7Q0FDRiJ9
@@ -1,33 +0,0 @@
1
- import { Fr } from '@aztec/foundation/fields';
2
- import { type TracedContractInstance, type TracedL1toL2MessageCheck, type TracedNoteHash, type TracedNoteHashCheck, type TracedNullifier, type TracedNullifierCheck, type TracedPublicStorageRead, type TracedPublicStorageWrite, type TracedUnencryptedL2Log } from './trace_types.js';
3
- export declare class WorldStateAccessTrace {
4
- accessCounter: number;
5
- publicStorageReads: TracedPublicStorageRead[];
6
- publicStorageWrites: TracedPublicStorageWrite[];
7
- noteHashChecks: TracedNoteHashCheck[];
8
- newNoteHashes: TracedNoteHash[];
9
- nullifierChecks: TracedNullifierCheck[];
10
- newNullifiers: TracedNullifier[];
11
- l1ToL2MessageChecks: TracedL1toL2MessageCheck[];
12
- newLogsHashes: TracedUnencryptedL2Log[];
13
- gotContractInstances: TracedContractInstance[];
14
- constructor(parentTrace?: WorldStateAccessTrace);
15
- getAccessCounter(): number;
16
- tracePublicStorageRead(storageAddress: Fr, slot: Fr, value: Fr, exists: boolean, cached: boolean): void;
17
- tracePublicStorageWrite(storageAddress: Fr, slot: Fr, value: Fr): void;
18
- traceNoteHashCheck(storageAddress: Fr, noteHash: Fr, exists: boolean, leafIndex: Fr): void;
19
- traceNewNoteHash(storageAddress: Fr, noteHash: Fr): void;
20
- traceNullifierCheck(storageAddress: Fr, nullifier: Fr, exists: boolean, isPending: boolean, leafIndex: Fr): void;
21
- traceNewNullifier(storageAddress: Fr, nullifier: Fr): void;
22
- traceL1ToL2MessageCheck(msgHash: Fr, msgLeafIndex: Fr, exists: boolean): void;
23
- traceNewLog(logHash: Fr): void;
24
- traceGetContractInstance(instance: TracedContractInstance): void;
25
- private incrementAccessCounter;
26
- /**
27
- * Merges another trace into this one
28
- *
29
- * @param incomingTrace - the incoming trace to merge into this instance
30
- */
31
- acceptAndMerge(incomingTrace: WorldStateAccessTrace): void;
32
- }
33
- //# sourceMappingURL=trace.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../../src/avm/journal/trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAE1B,qBAAa,qBAAqB;IACzB,aAAa,EAAE,MAAM,CAAC;IAEtB,kBAAkB,EAAE,uBAAuB,EAAE,CAAM;IACnD,mBAAmB,EAAE,wBAAwB,EAAE,CAAM;IAErD,cAAc,EAAE,mBAAmB,EAAE,CAAM;IAC3C,aAAa,EAAE,cAAc,EAAE,CAAM;IACrC,eAAe,EAAE,oBAAoB,EAAE,CAAM;IAC7C,aAAa,EAAE,eAAe,EAAE,CAAM;IACtC,mBAAmB,EAAE,wBAAwB,EAAE,CAAM;IACrD,aAAa,EAAE,sBAAsB,EAAE,CAAM;IAC7C,oBAAoB,EAAE,sBAAsB,EAAE,CAAM;gBAK/C,WAAW,CAAC,EAAE,qBAAqB;IAKxC,gBAAgB;IAIhB,sBAAsB,CAAC,cAAc,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;IAiBhG,uBAAuB,CAAC,cAAc,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE;IAe/D,kBAAkB,CAAC,cAAc,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE;IAcnF,gBAAgB,CAAC,cAAc,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;IAajD,mBAAmB,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE;IAgBzG,iBAAiB,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE;IAanD,uBAAuB,CAAC,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO;IActE,WAAW,CAAC,OAAO,EAAE,EAAE;IASvB,wBAAwB,CAAC,QAAQ,EAAE,sBAAsB;IAKhE,OAAO,CAAC,sBAAsB;IAI9B;;;;OAIG;IACI,cAAc,CAAC,aAAa,EAAE,qBAAqB;CAe3D"}
@@ -1,152 +0,0 @@
1
- import { Fr } from '@aztec/foundation/fields';
2
- export class WorldStateAccessTrace {
3
- //public contractCalls: TracedContractCall[] = [];
4
- //public archiveChecks: TracedArchiveLeafCheck[] = [];
5
- constructor(parentTrace) {
6
- this.publicStorageReads = [];
7
- this.publicStorageWrites = [];
8
- this.noteHashChecks = [];
9
- this.newNoteHashes = [];
10
- this.nullifierChecks = [];
11
- this.newNullifiers = [];
12
- this.l1ToL2MessageChecks = [];
13
- this.newLogsHashes = [];
14
- this.gotContractInstances = [];
15
- this.accessCounter = parentTrace ? parentTrace.accessCounter : 0;
16
- // TODO(4805): consider tracking the parent's trace vector lengths so we can enforce limits
17
- }
18
- getAccessCounter() {
19
- return this.accessCounter;
20
- }
21
- tracePublicStorageRead(storageAddress, slot, value, exists, cached) {
22
- // TODO(4805): check if some threshold is reached for max storage reads
23
- // (need access to parent length, or trace needs to be initialized with parent's contents)
24
- const traced = {
25
- // callPointer: Fr.ZERO,
26
- storageAddress,
27
- slot,
28
- value,
29
- exists,
30
- cached,
31
- counter: new Fr(this.accessCounter),
32
- // endLifetime: Fr.ZERO,
33
- };
34
- this.publicStorageReads.push(traced);
35
- this.incrementAccessCounter();
36
- }
37
- tracePublicStorageWrite(storageAddress, slot, value) {
38
- // TODO(4805): check if some threshold is reached for max storage writes
39
- // (need access to parent length, or trace needs to be initialized with parent's contents)
40
- const traced = {
41
- // callPointer: Fr.ZERO,
42
- storageAddress,
43
- slot,
44
- value,
45
- counter: new Fr(this.accessCounter),
46
- // endLifetime: Fr.ZERO,
47
- };
48
- this.publicStorageWrites.push(traced);
49
- this.incrementAccessCounter();
50
- }
51
- traceNoteHashCheck(storageAddress, noteHash, exists, leafIndex) {
52
- const traced = {
53
- // callPointer: Fr.ZERO,
54
- storageAddress,
55
- noteHash,
56
- exists,
57
- counter: new Fr(this.accessCounter),
58
- // endLifetime: Fr.ZERO,
59
- leafIndex,
60
- };
61
- this.noteHashChecks.push(traced);
62
- this.incrementAccessCounter();
63
- }
64
- traceNewNoteHash(storageAddress, noteHash) {
65
- // TODO(4805): check if some threshold is reached for max new note hash
66
- const traced = {
67
- // callPointer: Fr.ZERO,
68
- storageAddress,
69
- noteHash,
70
- counter: new Fr(this.accessCounter),
71
- // endLifetime: Fr.ZERO,
72
- };
73
- this.newNoteHashes.push(traced);
74
- this.incrementAccessCounter();
75
- }
76
- traceNullifierCheck(storageAddress, nullifier, exists, isPending, leafIndex) {
77
- // TODO(4805): check if some threshold is reached for max new nullifier
78
- const traced = {
79
- // callPointer: Fr.ZERO,
80
- storageAddress,
81
- nullifier,
82
- exists,
83
- counter: new Fr(this.accessCounter),
84
- // endLifetime: Fr.ZERO,
85
- isPending,
86
- leafIndex,
87
- };
88
- this.nullifierChecks.push(traced);
89
- this.incrementAccessCounter();
90
- }
91
- traceNewNullifier(storageAddress, nullifier) {
92
- // TODO(4805): check if some threshold is reached for max new nullifier
93
- const tracedNullifier = {
94
- // callPointer: Fr.ZERO,
95
- storageAddress,
96
- nullifier,
97
- counter: new Fr(this.accessCounter),
98
- // endLifetime: Fr.ZERO,
99
- };
100
- this.newNullifiers.push(tracedNullifier);
101
- this.incrementAccessCounter();
102
- }
103
- traceL1ToL2MessageCheck(msgHash, msgLeafIndex, exists) {
104
- // TODO(4805): check if some threshold is reached for max message reads
105
- const traced = {
106
- //callPointer: Fr.ZERO, // FIXME
107
- leafIndex: msgLeafIndex,
108
- msgHash: msgHash,
109
- exists: exists,
110
- counter: new Fr(this.accessCounter),
111
- //endLifetime: Fr.ZERO, // FIXME
112
- };
113
- this.l1ToL2MessageChecks.push(traced);
114
- this.incrementAccessCounter();
115
- }
116
- traceNewLog(logHash) {
117
- const traced = {
118
- logHash,
119
- counter: new Fr(this.accessCounter),
120
- };
121
- this.newLogsHashes.push(traced);
122
- this.incrementAccessCounter();
123
- }
124
- traceGetContractInstance(instance) {
125
- this.gotContractInstances.push(instance);
126
- this.incrementAccessCounter();
127
- }
128
- incrementAccessCounter() {
129
- this.accessCounter++;
130
- }
131
- /**
132
- * Merges another trace into this one
133
- *
134
- * @param incomingTrace - the incoming trace to merge into this instance
135
- */
136
- acceptAndMerge(incomingTrace) {
137
- // Merge storage read and write journals
138
- this.publicStorageReads.push(...incomingTrace.publicStorageReads);
139
- this.publicStorageWrites.push(...incomingTrace.publicStorageWrites);
140
- // Merge new note hashes and nullifiers
141
- this.noteHashChecks.push(...incomingTrace.noteHashChecks);
142
- this.newNoteHashes.push(...incomingTrace.newNoteHashes);
143
- this.nullifierChecks.push(...incomingTrace.nullifierChecks);
144
- this.newNullifiers.push(...incomingTrace.newNullifiers);
145
- this.l1ToL2MessageChecks.push(...incomingTrace.l1ToL2MessageChecks);
146
- this.newLogsHashes.push(...incomingTrace.newLogsHashes);
147
- this.gotContractInstances.push(...incomingTrace.gotContractInstances);
148
- // it is assumed that the incoming trace was initialized with this as parent, so accept counter
149
- this.accessCounter = incomingTrace.accessCounter;
150
- }
151
- }
152
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXZtL2pvdXJuYWwvdHJhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBYzlDLE1BQU0sT0FBTyxxQkFBcUI7SUFjaEMsa0RBQWtEO0lBQ2xELHNEQUFzRDtJQUV0RCxZQUFZLFdBQW1DO1FBZHhDLHVCQUFrQixHQUE4QixFQUFFLENBQUM7UUFDbkQsd0JBQW1CLEdBQStCLEVBQUUsQ0FBQztRQUVyRCxtQkFBYyxHQUEwQixFQUFFLENBQUM7UUFDM0Msa0JBQWEsR0FBcUIsRUFBRSxDQUFDO1FBQ3JDLG9CQUFlLEdBQTJCLEVBQUUsQ0FBQztRQUM3QyxrQkFBYSxHQUFzQixFQUFFLENBQUM7UUFDdEMsd0JBQW1CLEdBQStCLEVBQUUsQ0FBQztRQUNyRCxrQkFBYSxHQUE2QixFQUFFLENBQUM7UUFDN0MseUJBQW9CLEdBQTZCLEVBQUUsQ0FBQztRQU16RCxJQUFJLENBQUMsYUFBYSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLDJGQUEyRjtJQUM3RixDQUFDO0lBRU0sZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRU0sc0JBQXNCLENBQUMsY0FBa0IsRUFBRSxJQUFRLEVBQUUsS0FBUyxFQUFFLE1BQWUsRUFBRSxNQUFlO1FBQ3JHLHVFQUF1RTtRQUN2RSwwRkFBMEY7UUFDMUYsTUFBTSxNQUFNLEdBQTRCO1lBQ3RDLHlCQUF5QjtZQUN6QixjQUFjO1lBQ2QsSUFBSTtZQUNKLEtBQUs7WUFDTCxNQUFNO1lBQ04sTUFBTTtZQUNOLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ25DLHlCQUF5QjtTQUMxQixDQUFDO1FBQ0Ys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