@aztec/simulator 0.87.4 → 0.87.5

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 (58) hide show
  1. package/dest/client.d.ts +0 -2
  2. package/dest/client.d.ts.map +1 -1
  3. package/dest/client.js +0 -2
  4. package/dest/private/acvm/acvm.d.ts +0 -4
  5. package/dest/private/acvm/acvm.d.ts.map +1 -1
  6. package/dest/private/acvm/oracle/oracle.d.ts +1 -1
  7. package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
  8. package/dest/private/acvm/oracle/oracle.js +2 -2
  9. package/dest/private/acvm/oracle/typed_oracle.d.ts +1 -1
  10. package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -1
  11. package/dest/private/acvm/oracle/typed_oracle.js +2 -2
  12. package/dest/private/private_execution.d.ts.map +1 -1
  13. package/dest/private/private_execution.js +1 -2
  14. package/dest/private/private_execution_oracle.d.ts +1 -1
  15. package/dest/private/private_execution_oracle.d.ts.map +1 -1
  16. package/dest/private/private_execution_oracle.js +1 -1
  17. package/dest/private/providers/circuit_recording/circuit_recorder.d.ts +19 -39
  18. package/dest/private/providers/circuit_recording/circuit_recorder.d.ts.map +1 -1
  19. package/dest/private/providers/circuit_recording/circuit_recorder.js +126 -90
  20. package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.d.ts +1 -3
  21. package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.d.ts.map +1 -1
  22. package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.js +11 -16
  23. package/dest/private/utility_execution_oracle.d.ts +1 -1
  24. package/dest/private/utility_execution_oracle.d.ts.map +1 -1
  25. package/dest/private/utility_execution_oracle.js +1 -1
  26. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +0 -1
  27. package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
  28. package/dest/public/avm/fixtures/base_avm_simulation_tester.js +0 -6
  29. package/dest/public/public_tx_simulator/apps_tests/amm_test.d.ts.map +1 -1
  30. package/dest/public/public_tx_simulator/apps_tests/amm_test.js +55 -27
  31. package/dest/server.d.ts +0 -2
  32. package/dest/server.d.ts.map +1 -1
  33. package/dest/server.js +0 -2
  34. package/dest/testing.d.ts +1 -1
  35. package/dest/testing.d.ts.map +1 -1
  36. package/dest/testing.js +1 -1
  37. package/package.json +15 -15
  38. package/src/client.ts +0 -2
  39. package/src/private/acvm/acvm.ts +0 -3
  40. package/src/private/acvm/oracle/oracle.ts +2 -2
  41. package/src/private/acvm/oracle/typed_oracle.ts +2 -2
  42. package/src/private/private_execution.ts +0 -1
  43. package/src/private/private_execution_oracle.ts +1 -1
  44. package/src/private/providers/circuit_recording/circuit_recorder.ts +136 -114
  45. package/src/private/providers/circuit_recording/simulation_provider_recorder_wrapper.ts +14 -22
  46. package/src/private/utility_execution_oracle.ts +1 -1
  47. package/src/public/avm/fixtures/base_avm_simulation_tester.ts +0 -5
  48. package/src/public/public_tx_simulator/apps_tests/amm_test.ts +44 -49
  49. package/src/server.ts +0 -2
  50. package/src/testing.ts +1 -1
  51. package/dest/private/providers/circuit_recording/file_circuit_recorder.d.ts +0 -31
  52. package/dest/private/providers/circuit_recording/file_circuit_recorder.d.ts.map +0 -1
  53. package/dest/private/providers/circuit_recording/file_circuit_recorder.js +0 -135
  54. package/dest/private/providers/circuit_recording/memory_circuit_recorder.d.ts +0 -5
  55. package/dest/private/providers/circuit_recording/memory_circuit_recorder.d.ts.map +0 -1
  56. package/dest/private/providers/circuit_recording/memory_circuit_recorder.js +0 -9
  57. package/src/private/providers/circuit_recording/file_circuit_recorder.ts +0 -158
  58. package/src/private/providers/circuit_recording/memory_circuit_recorder.ts +0 -11
@@ -1,59 +1,28 @@
1
- import { sha512 } from '@aztec/foundation/crypto';
2
1
  import { createLogger } from '@aztec/foundation/log';
3
- import { Timer } from '@aztec/foundation/timer';
4
2
  import type { ForeignCallHandler, ForeignCallInput, ForeignCallOutput } from '@aztec/noir-acvm_js';
5
3
 
4
+ import { createHash } from 'crypto';
5
+ import fs from 'fs/promises';
6
+ import path from 'path';
7
+
6
8
  import type { ACIRCallback } from '../../acvm/acvm.js';
7
9
  import type { ACVMWitness } from '../../acvm/acvm_types.js';
8
10
  import { Oracle } from '../../acvm/oracle/oracle.js';
9
11
 
10
- export type OracleCall = {
11
- name: string;
12
- inputs: unknown[];
13
- outputs: unknown;
14
- time: number;
15
- // Due to the recursive nature of the simulator, we might have
16
- // oracle calls performed after a foreign call (which is itself an oracle call)
17
- // We keep track of the stack depth in this variable to ensure the recorded oracle
18
- // calls are correctly associated with the right circuit.
19
- // This is only use as a debugging tool
20
- stackDepth: number;
21
- };
22
-
23
- export class CircuitRecording {
24
- circuitName: string;
25
- functionName: string;
26
- bytecodeSHA512Hash: string;
27
- timestamp: number;
28
- inputs: Record<string, string>;
29
- oracleCalls: OracleCall[];
30
- error?: string;
31
- parent?: CircuitRecording;
32
-
33
- constructor(circuitName: string, functionName: string, bytecodeSHA512Hash: string, inputs: Record<string, string>) {
34
- this.circuitName = circuitName;
35
- this.functionName = functionName;
36
- this.bytecodeSHA512Hash = bytecodeSHA512Hash;
37
- this.timestamp = Date.now();
38
- this.inputs = inputs;
39
- this.oracleCalls = [];
40
- }
41
-
42
- setParent(recording?: CircuitRecording): void {
43
- this.parent = recording;
44
- }
45
- }
46
-
47
12
  /**
48
13
  * Class responsible for recording circuit inputs necessary to replay the circuit. These inputs are the initial witness
49
14
  * map and the oracle calls made during the circuit execution/witness generation.
50
15
  *
51
- * Example recording object:
16
+ * The recording is stored in a JSON file called `circuit_name_circuit_function_name_YYYY-MM-DD_N.json` where N is
17
+ * a counter to ensure unique filenames. The file is stored in the `recordDir` directory provided as a parameter to
18
+ * CircuitRecorder.start().
19
+ *
20
+ * Example recording file:
52
21
  * ```json
53
22
  * {
54
23
  * "circuitName": "AMM",
55
24
  * "functionName": "add_liquidity",
56
- * "bytecodeSHA512Hash": "b46c640ed38f20eac5f61a5e41d8dd1e",
25
+ * "bytecodeMd5Hash": "b46c640ed38f20eac5f61a5e41d8dd1e",
57
26
  * "timestamp": 1740691464360,
58
27
  * "inputs": {
59
28
  * "0": "0x1e89de1f0ad5204263733b7ddf65bec45b8f44714a4da85a46474dad677679ef",
@@ -82,7 +51,7 @@ export class CircuitRecording {
82
51
  * ]
83
52
  * },
84
53
  * {
85
- * "name": "fetchTaggedLogs",
54
+ * "name": "syncPrivateState",
86
55
  * "inputs": []
87
56
  * }
88
57
  * ]
@@ -90,14 +59,10 @@ export class CircuitRecording {
90
59
  * ```
91
60
  */
92
61
  export class CircuitRecorder {
93
- protected readonly logger = createLogger('simulator:acvm:recording');
62
+ private readonly logger = createLogger('simulator:acvm:recording');
63
+ private isFirstCall = true;
94
64
 
95
- protected recording?: CircuitRecording;
96
-
97
- private stackDepth: number = 0;
98
- private newCircuit: boolean = true;
99
-
100
- protected constructor() {}
65
+ private constructor(private readonly filePath: string) {}
101
66
 
102
67
  /**
103
68
  * Initializes a new circuit recording session.
@@ -107,20 +72,82 @@ export class CircuitRecorder {
107
72
  * @param circuitName - Name of the circuit
108
73
  * @param functionName - Name of the circuit function (defaults to 'main'). This is meaningful only for
109
74
  * contracts as protocol circuits artifacts always contain a single entrypoint function called 'main'.
75
+ * @returns A new CircuitRecorder instance
110
76
  */
111
- start(input: ACVMWitness, circuitBytecode: Buffer, circuitName: string, functionName: string): Promise<void> {
112
- const parentRef = this.recording;
113
- if (this.newCircuit) {
114
- this.recording = new CircuitRecording(
115
- circuitName,
116
- functionName,
117
- sha512(circuitBytecode).toString('hex'),
118
- Object.fromEntries(input),
119
- );
77
+ static async start(
78
+ recordDir: string,
79
+ input: ACVMWitness,
80
+ circuitBytecode: Buffer,
81
+ circuitName: string,
82
+ functionName: string = 'main',
83
+ ): Promise<CircuitRecorder> {
84
+ const recording = {
85
+ circuitName: circuitName,
86
+ functionName: functionName,
87
+ bytecodeMd5Hash: createHash('md5').update(circuitBytecode).digest('hex'),
88
+ timestamp: Date.now(),
89
+ inputs: Object.fromEntries(input),
90
+ };
91
+
92
+ const recordingStringWithoutClosingBracket = JSON.stringify(recording, null, 2).slice(0, -2);
93
+
94
+ try {
95
+ // Check if the recording directory exists and is a directory
96
+ const stats = await fs.stat(recordDir);
97
+ if (!stats.isDirectory()) {
98
+ throw new Error(`Recording path ${recordDir} exists but is not a directory`);
99
+ }
100
+ } catch (err) {
101
+ if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
102
+ // The directory does not exist so we create it
103
+ await fs.mkdir(recordDir, { recursive: true });
104
+ } else {
105
+ throw err;
106
+ }
120
107
  }
121
- this.recording!.setParent(parentRef);
122
108
 
123
- return Promise.resolve();
109
+ const filePath = await CircuitRecorder.#computeFilePathAndStoreInitialRecording(
110
+ recordDir,
111
+ circuitName,
112
+ functionName,
113
+ recordingStringWithoutClosingBracket,
114
+ );
115
+ return new CircuitRecorder(filePath);
116
+ }
117
+
118
+ /**
119
+ * Computes a unique file path for the recording by trying different counter values.
120
+ * This is needed because multiple recordings of the same circuit could be happening simultaneously or an older
121
+ * recording might be present.
122
+ * @param recordDir - Directory to store the recording
123
+ * @param circuitName - Name of the circuit
124
+ * @param functionName - Name of the circuit function
125
+ * @param recordingContent - Initial recording content
126
+ * @returns A unique file path for the recording
127
+ */
128
+ static async #computeFilePathAndStoreInitialRecording(
129
+ recordDir: string,
130
+ circuitName: string,
131
+ functionName: string,
132
+ recordingContent: string,
133
+ ): Promise<string> {
134
+ let counter = 0;
135
+ while (true) {
136
+ try {
137
+ const filePath = getFilePath(recordDir, circuitName, functionName, counter);
138
+ // Write the initial recording content to the file
139
+ await fs.writeFile(filePath, recordingContent + ',\n "oracleCalls": [\n', {
140
+ flag: 'wx', // wx flag fails if file exists
141
+ });
142
+ return filePath;
143
+ } catch (err) {
144
+ if ((err as NodeJS.ErrnoException).code === 'EEXIST') {
145
+ counter++;
146
+ continue;
147
+ }
148
+ throw err;
149
+ }
150
+ }
124
151
  }
125
152
 
126
153
  /**
@@ -160,38 +187,15 @@ export class CircuitRecorder {
160
187
  throw new Error(`Oracle method ${name} not found when setting up recording callback`);
161
188
  }
162
189
 
163
- const isExternalCall = (name as keyof ACIRCallback) === 'callPrivateFunction';
164
-
165
190
  recordingCallback[name as keyof ACIRCallback] = (...args: ForeignCallInput[]): ReturnType<typeof fn> => {
166
- const timer = new Timer();
167
- // If we're entering another circuit via `callPrivateFunction`, we increase the stack depth and set the
168
- // newCircuit variable to ensure we are creating a new recording object.
169
- if (isExternalCall) {
170
- this.stackDepth++;
171
- this.newCircuit = true;
172
- }
173
191
  const result = fn.call(callback, ...args);
174
192
  if (result instanceof Promise) {
175
193
  return result.then(async r => {
176
- // Once we leave the nested circuit, we decrease the stack depth and set newCircuit to false
177
- // since we are going back to the "parent" circuit which can never be new
178
- if (isExternalCall) {
179
- this.stackDepth--;
180
- this.newCircuit = false;
181
- this.recording = this.recording!.parent;
182
- }
183
- await this.recordCall(name, args, r, timer.ms(), this.stackDepth);
194
+ await this.#recordCall(name, args, r);
184
195
  return r;
185
196
  }) as ReturnType<typeof fn>;
186
197
  }
187
- // Once we leave the nested circuit, we decrease the stack depth and set newCircuit to false
188
- // since we are going back to the "parent" circuit which can never be new
189
- if (isExternalCall) {
190
- this.stackDepth--;
191
- this.newCircuit = false;
192
- this.recording = this.recording!.parent;
193
- }
194
- void this.recordCall(name, args, result, timer.ms(), this.stackDepth);
198
+ void this.#recordCall(name, args, result);
195
199
  return result;
196
200
  };
197
201
  }
@@ -206,9 +210,8 @@ export class CircuitRecorder {
206
210
  */
207
211
  #wrapProtocolCircuitCallback(callback: ForeignCallHandler): ForeignCallHandler {
208
212
  return async (name: string, inputs: ForeignCallInput[]): Promise<ForeignCallOutput[]> => {
209
- const timer = new Timer();
210
213
  const result = await callback(name, inputs);
211
- await this.recordCall(name, inputs, result, timer.ms(), 0);
214
+ await this.#recordCall(name, inputs, result);
212
215
  return result;
213
216
  };
214
217
  }
@@ -219,43 +222,62 @@ export class CircuitRecorder {
219
222
  * @param inputs - Input arguments
220
223
  * @param outputs - Output results
221
224
  */
222
- recordCall(name: string, inputs: unknown[], outputs: unknown, time: number, stackDepth: number): Promise<OracleCall> {
223
- const entry = {
224
- name,
225
- inputs,
226
- outputs,
227
- time,
228
- stackDepth,
229
- };
230
- this.recording!.oracleCalls.push(entry);
231
- return Promise.resolve(entry);
225
+ async #recordCall(name: string, inputs: unknown[], outputs: unknown) {
226
+ try {
227
+ const entry = {
228
+ name,
229
+ inputs,
230
+ outputs,
231
+ };
232
+ const prefix = this.isFirstCall ? ' ' : ' ,';
233
+ this.isFirstCall = false;
234
+ await fs.appendFile(this.filePath, prefix + JSON.stringify(entry) + '\n');
235
+ } catch (err) {
236
+ this.logger.error('Failed to log circuit call', { error: err });
237
+ }
232
238
  }
233
239
 
234
240
  /**
235
- * Finalizes the recording by resetting the state and returning the recording object.
241
+ * Finalizes the recording file by adding closing brackets. Without calling this method, the recording file is
242
+ * incomplete and it fails to parse.
236
243
  */
237
- finish(): Promise<CircuitRecording> {
238
- const result = this.recording;
239
- // If this is the top-level circuit recording, we reset the state for the next simulator call
240
- if (!result!.parent) {
241
- this.newCircuit = true;
242
- this.recording = undefined;
244
+ async finish(): Promise<void> {
245
+ try {
246
+ await fs.appendFile(this.filePath, ' ]\n}\n');
247
+ } catch (err) {
248
+ this.logger.error('Failed to finalize recording file', { error: err });
243
249
  }
244
- return Promise.resolve(result!);
245
250
  }
246
251
 
247
252
  /**
248
- * Finalizes the recording by resetting the state and returning the recording object with an attached error.
253
+ * Finalizes the recording file by adding the error and closing brackets. Without calling this method or `finish`,
254
+ * the recording file is incomplete and it fails to parse.
249
255
  * @param error - The error that occurred during circuit execution
250
256
  */
251
- finishWithError(error: unknown): Promise<CircuitRecording> {
252
- const result = this.recording;
253
- // If this is the top-level circuit recording, we reset the state for the next simulator call
254
- if (!result!.parent) {
255
- this.newCircuit = true;
256
- this.recording = undefined;
257
+ async finishWithError(error: unknown): Promise<void> {
258
+ try {
259
+ await fs.appendFile(this.filePath, ' ],\n');
260
+ await fs.appendFile(this.filePath, ` "error": ${JSON.stringify(error)}\n`);
261
+ await fs.appendFile(this.filePath, '}\n');
262
+ } catch (err) {
263
+ this.logger.error('Failed to finalize recording file with error', { error: err });
257
264
  }
258
- result!.error = JSON.stringify(error);
259
- return Promise.resolve(result!);
260
265
  }
261
266
  }
267
+
268
+ /**
269
+ * Generates a file path for storing circuit recordings. The format of the filename is:
270
+ * `circuit_name_circuit_function_name_YYYY-MM-DD_N.json` where N is a counter to ensure unique filenames.
271
+ * @param recordDir - Base directory for recordings
272
+ * @param circuitName - Name of the circuit
273
+ * @param functionName - Name of the circuit function
274
+ * @param counter - Counter to ensure unique filenames. This is expected to be incremented in a loop until there is no
275
+ * existing file with the same name.
276
+ * @returns A file path for the recording.
277
+ */
278
+ function getFilePath(recordDir: string, circuitName: string, functionName: string, counter: number): string {
279
+ const date = new Date();
280
+ const formattedDate = date.toISOString().split('T')[0];
281
+ const filename = `${circuitName}_${functionName}_${formattedDate}_${counter}.json`;
282
+ return path.join(recordDir, filename);
283
+ }
@@ -2,21 +2,18 @@ import type { ForeignCallHandler } from '@aztec/noir-protocol-circuits-types/typ
2
2
  import type { FunctionArtifactWithContractName } from '@aztec/stdlib/abi';
3
3
  import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
4
4
 
5
- import type { ACIRCallback, ACIRCallbackStats, ACIRExecutionResult } from '../../acvm/acvm.js';
5
+ import type { ACIRCallback, ACIRExecutionResult } from '../../acvm/acvm.js';
6
6
  import type { ACVMWitness } from '../../acvm/acvm_types.js';
7
7
  import type { ACVMSuccess } from '../acvm_native.js';
8
8
  import type { SimulationProvider } from '../simulation_provider.js';
9
- import type { CircuitRecorder } from './circuit_recorder.js';
9
+ import { CircuitRecorder } from './circuit_recorder.js';
10
10
 
11
11
  /**
12
12
  * Takes a simulation provider and wraps it in a circuit recorder. See CircuitRecorder for more details on how circuit
13
13
  * recording works.
14
14
  */
15
15
  export class SimulationProviderRecorderWrapper implements SimulationProvider {
16
- constructor(
17
- private simulator: SimulationProvider,
18
- private recorder: CircuitRecorder,
19
- ) {}
16
+ constructor(private simulator: SimulationProvider) {}
20
17
 
21
18
  executeProtocolCircuit(
22
19
  input: ACVMWitness,
@@ -50,7 +47,7 @@ export class SimulationProviderRecorderWrapper implements SimulationProvider {
50
47
  );
51
48
  }
52
49
 
53
- async #simulate<C extends ACIRCallback | ForeignCallHandler | undefined, T extends ACIRExecutionResult | ACVMSuccess>(
50
+ async #simulate<C extends ACIRCallback | ForeignCallHandler | undefined, T>(
54
51
  simulateFn: (wrappedCallback: C) => Promise<T>,
55
52
  input: ACVMWitness,
56
53
  bytecode: Buffer,
@@ -58,33 +55,28 @@ export class SimulationProviderRecorderWrapper implements SimulationProvider {
58
55
  functionName: string,
59
56
  callback: C,
60
57
  ): Promise<T> {
58
+ const recordDir = process.env.CIRCUIT_RECORD_DIR;
59
+ if (!recordDir) {
60
+ // Recording is not enabled so we just execute the circuit
61
+ return simulateFn(callback);
62
+ }
63
+
61
64
  // Start recording circuit execution
62
- await this.recorder.start(input, bytecode, contractName, functionName);
65
+ const recorder = await CircuitRecorder.start(recordDir, input, bytecode, contractName, functionName);
63
66
 
64
67
  // If callback was provided, we wrap it in a circuit recorder callback wrapper
65
- const wrappedCallback = this.recorder.wrapCallback(callback);
68
+ const wrappedCallback = recorder.wrapCallback(callback);
66
69
  let result: T;
67
70
  try {
68
71
  result = await simulateFn(wrappedCallback as C);
69
72
  } catch (error) {
70
73
  // If an error occurs, we finalize the recording file with the error
71
- await this.recorder.finishWithError(error);
74
+ await recorder.finishWithError(error);
72
75
  throw error;
73
76
  }
74
77
 
75
78
  // Witness generation is complete so we finish the circuit recorder
76
- const recording = await this.recorder.finish();
77
-
78
- (result as ACIRExecutionResult).oracles = recording.oracleCalls?.reduce(
79
- (acc, { time, name }) => {
80
- if (!acc[name]) {
81
- acc[name] = { times: [] };
82
- }
83
- acc[name].times.push(time);
84
- return acc;
85
- },
86
- {} as Record<string, ACIRCallbackStats>,
87
- );
79
+ await recorder.finish();
88
80
 
89
81
  return result;
90
82
  }
@@ -274,7 +274,7 @@ export class UtilityExecutionOracle extends TypedOracle {
274
274
  return await this.executionDataProvider.getIndexedTaggingSecretAsSender(this.contractAddress, sender, recipient);
275
275
  }
276
276
 
277
- public override async fetchTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr) {
277
+ public override async syncPrivateState(pendingTaggedLogArrayBaseSlot: Fr) {
278
278
  await this.executionDataProvider.syncTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, this.scopes);
279
279
 
280
280
  await this.executionDataProvider.removeNullifiedNotes(this.contractAddress);
@@ -100,9 +100,4 @@ export abstract class BaseAvmSimulationTester {
100
100
  );
101
101
  await this.merkleTrees.sequentialInsert(MerkleTreeId.NULLIFIER_TREE, [contractAddressNullifier.toBuffer()]);
102
102
  }
103
-
104
- async insertNullifier(contractThatEmitted: AztecAddress, nullifier: Fr) {
105
- const siloedNullifier = await siloNullifier(contractThatEmitted, nullifier);
106
- await this.merkleTrees.sequentialInsert(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()]);
107
- }
108
103
  }
@@ -1,5 +1,3 @@
1
- import { GeneratorIndex } from '@aztec/constants';
2
- import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto';
3
1
  import { Fr } from '@aztec/foundation/fields';
4
2
  import type { Logger } from '@aztec/foundation/log';
5
3
  import { AMMContractArtifact } from '@aztec/noir-contracts.js/AMM';
@@ -139,24 +137,6 @@ async function addLiquidity(
139
137
  const liquidityPartialNote = {
140
138
  commitment: new Fr(99),
141
139
  };
142
- const refundToken0PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
143
- refundToken0PartialNote,
144
- amm.address,
145
- );
146
- const refundToken1PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
147
- refundToken1PartialNote,
148
- amm.address,
149
- );
150
- const liquidityPartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
151
- liquidityPartialNote,
152
- amm.address,
153
- );
154
-
155
- // We need to inject the validity commitments into the nullifier tree as that would be performed by the private token
156
- // functions that are not invoked in this test.
157
- await tester.insertNullifier(token0.address, refundToken0PartialNoteValidityCommitment);
158
- await tester.insertNullifier(token1.address, refundToken1PartialNoteValidityCommitment);
159
- await tester.insertNullifier(liquidityToken.address, liquidityPartialNoteValidityCommitment);
160
140
 
161
141
  return await tester.simulateTxWithLabel(
162
142
  /*txLabel=*/ 'AMM/add_liquidity',
@@ -170,6 +150,13 @@ async function addLiquidity(
170
150
  args: [/*to=*/ amm.address, /*amount=*/ amount0Max],
171
151
  address: token0.address,
172
152
  },
153
+ // token0.prepare_private_balance_increase enqueues a call to _store_balances_set_partial_note
154
+ {
155
+ sender: token0.address, // INTERNAL FUNCTION! Sender must be 'this'.
156
+ fnName: '_store_balances_set_partial_note',
157
+ args: [refundToken0PartialNote],
158
+ address: token0.address,
159
+ },
173
160
  // token1.transfer_to_public enqueues a call to _increase_public_balance
174
161
  {
175
162
  sender: token1.address, // INTERNAL FUNCTION! Sender must be 'this'.
@@ -177,6 +164,20 @@ async function addLiquidity(
177
164
  args: [/*to=*/ amm.address, /*amount=*/ amount1Max],
178
165
  address: token1.address,
179
166
  },
167
+ // token1.prepare_private_balance_increase enqueues a call to _store_balances_set_partial_note
168
+ {
169
+ sender: token1.address, // INTERNAL FUNCTION! Sender must be 'this'.
170
+ fnName: '_store_balances_set_partial_note',
171
+ args: [refundToken1PartialNote],
172
+ address: token1.address,
173
+ },
174
+ // liquidityToken.prepare_private_balance_increase enqueues a call to _store_balances_set_partial_note
175
+ {
176
+ sender: liquidityToken.address, // INTERNAL FUNCTION! Sender must be 'this'.
177
+ fnName: '_store_balances_set_partial_note',
178
+ args: [liquidityPartialNote],
179
+ address: liquidityToken.address,
180
+ },
180
181
  // amm.add_liquidity enqueues a call to _add_liquidity
181
182
  {
182
183
  sender: amm.address, // INTERNAL FUNCTION! Sender must be 'this'.
@@ -213,16 +214,8 @@ async function swapExactTokensForTokens(
213
214
  _nonce?: bigint,
214
215
  ) {
215
216
  const tokenOutPartialNote = {
216
- commitment: new Fr(166),
217
+ commitment: new Fr(66),
217
218
  };
218
- const tokenOutPartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
219
- tokenOutPartialNote,
220
- amm.address,
221
- );
222
-
223
- // We need to inject the validity commitment into the nullifier tree as that would be performed by the private token
224
- // function that is not invoked in this test.
225
- await tester.insertNullifier(tokenOut.address, tokenOutPartialNoteValidityCommitment);
226
219
 
227
220
  return await tester.simulateTxWithLabel(
228
221
  /*txLabel=*/ 'AMM/swap_exact_tokens_for_tokens',
@@ -236,6 +229,14 @@ async function swapExactTokensForTokens(
236
229
  args: [/*to=*/ amm.address, /*amount=*/ amountIn],
237
230
  address: tokenIn.address,
238
231
  },
232
+ // tokenOut.prepare_private_balance_increase enqueues a call to _store_balances_set_partial_note
233
+ {
234
+ sender: tokenOut.address, // INTERNAL FUNCTION! Sender must be 'this'.
235
+ fnName: '_store_balances_set_partial_note',
236
+ args: [tokenOutPartialNote],
237
+ address: tokenOut.address,
238
+ },
239
+
239
240
  {
240
241
  sender: amm.address, // INTERNAL FUNCTION! Sender must be 'this'.
241
242
  fnName: '_swap_exact_tokens_for_tokens',
@@ -264,19 +265,6 @@ async function removeLiquidity(
264
265
  const token1PartialNote = {
265
266
  commitment: new Fr(222),
266
267
  };
267
- const token0PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
268
- token0PartialNote,
269
- amm.address,
270
- );
271
- const token1PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
272
- token1PartialNote,
273
- amm.address,
274
- );
275
-
276
- // We need to inject the validity commitments into the nullifier tree as that would be performed by the private token
277
- // functions that are not invoked in this test.
278
- await tester.insertNullifier(token0.address, token0PartialNoteValidityCommitment);
279
- await tester.insertNullifier(token1.address, token1PartialNoteValidityCommitment);
280
268
 
281
269
  return await tester.simulateTxWithLabel(
282
270
  /*txLabel=*/ 'AMM/remove_liquidity',
@@ -290,6 +278,20 @@ async function removeLiquidity(
290
278
  args: [/*to=*/ amm.address, /*amount=*/ liquidity],
291
279
  address: liquidityToken.address,
292
280
  },
281
+ // token0.prepare_private_balance_increase enqueues a call to _store_balances_set_partial_note
282
+ {
283
+ sender: token0.address, // INTERNAL FUNCTION! Sender must be 'this'.
284
+ fnName: '_store_balances_set_partial_note',
285
+ args: [token0PartialNote],
286
+ address: token0.address,
287
+ },
288
+ // token1.prepare_private_balance_increase enqueues a call to _store_balances_set_partial_note
289
+ {
290
+ sender: token1.address, // INTERNAL FUNCTION! Sender must be 'this'.
291
+ fnName: '_store_balances_set_partial_note',
292
+ args: [token1PartialNote],
293
+ address: token1.address,
294
+ },
293
295
  // amm.remove_liquidity enqueues a call to _remove_liquidity
294
296
  {
295
297
  sender: amm.address, // INTERNAL FUNCTION! Sender must be 'this'.
@@ -312,10 +314,3 @@ async function removeLiquidity(
312
314
  ],
313
315
  );
314
316
  }
315
-
316
- async function computePartialNoteValidityCommitment(partialNote: { commitment: Fr }, completer: AztecAddress) {
317
- return await poseidon2HashWithSeparator(
318
- [partialNote.commitment, completer],
319
- GeneratorIndex.PARTIAL_NOTE_VALIDITY_COMMITMENT,
320
- );
321
- }
package/src/server.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export * from './public/index.js';
2
2
  export { WASMSimulatorWithBlobs } from './private/providers/acvm_wasm_with_blobs.js';
3
3
  export { NativeACVMSimulator } from './private/providers/acvm_native.js';
4
- export { SimulationProviderRecorderWrapper } from './private/providers/circuit_recording/simulation_provider_recorder_wrapper.js';
5
- export { MemoryCircuitRecorder } from './private/providers/circuit_recording/memory_circuit_recorder.js';
6
4
  export { type SimulationProvider } from './private/providers/simulation_provider.js';
7
5
  export * from './common/index.js';
package/src/testing.ts CHANGED
@@ -1 +1 @@
1
- export { FileCircuitRecorder } from './private/providers/circuit_recording/file_circuit_recorder.js';
1
+ export { SimulationProviderRecorderWrapper } from './private/providers/circuit_recording/simulation_provider_recorder_wrapper.js';
@@ -1,31 +0,0 @@
1
- import type { ACVMWitness } from '../../acvm/acvm_types.js';
2
- import { CircuitRecorder, type CircuitRecording } from './circuit_recorder.js';
3
- export declare class FileCircuitRecorder extends CircuitRecorder {
4
- #private;
5
- private readonly recordDir;
6
- recording?: CircuitRecording & {
7
- filePath: string;
8
- isFirstCall: boolean;
9
- };
10
- constructor(recordDir: string);
11
- start(input: ACVMWitness, circuitBytecode: Buffer, circuitName: string, functionName?: string): Promise<void>;
12
- /**
13
- * Records a single oracle/foreign call with its inputs and outputs.
14
- * @param name - Name of the call
15
- * @param inputs - Input arguments
16
- * @param outputs - Output results
17
- */
18
- recordCall(name: string, inputs: unknown[], outputs: unknown, time: number, stackDepth: number): Promise<import("./circuit_recorder.js").OracleCall>;
19
- /**
20
- * Finalizes the recording file by adding closing brackets. Without calling this method, the recording file is
21
- * incomplete and it fails to parse.
22
- */
23
- finish(): Promise<CircuitRecording>;
24
- /**
25
- * Finalizes the recording file by adding the error and closing brackets. Without calling this method or `finish`,
26
- * the recording file is incomplete and it fails to parse.
27
- * @param error - The error that occurred during circuit execution
28
- */
29
- finishWithError(error: unknown): Promise<CircuitRecording>;
30
- }
31
- //# sourceMappingURL=file_circuit_recorder.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file_circuit_recorder.d.ts","sourceRoot":"","sources":["../../../../src/private/providers/circuit_recording/file_circuit_recorder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE/E,qBAAa,mBAAoB,SAAQ,eAAe;;IAG1C,OAAO,CAAC,QAAQ,CAAC,SAAS;IAF9B,SAAS,CAAC,EAAE,gBAAgB,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;gBAErD,SAAS,EAAE,MAAM;IAI/B,KAAK,CAClB,KAAK,EAAE,WAAW,EAClB,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAe;IAqE/B;;;;;OAKG;IACY,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAY7G;;;OAGG;IACY,MAAM,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAalD;;;;OAIG;IACY,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAc1E"}