@aztec/native 0.0.1-commit.03f7ef2 → 0.0.1-commit.04d373f

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.
@@ -1,4 +1,4 @@
1
- import { type LogLevel } from '@aztec/foundation/log';
1
+ import { type LogLevel, type Logger } from '@aztec/foundation/log';
2
2
  import type { MessageReceiver } from './msgpack_channel.js';
3
3
  interface NativeClassCtor {
4
4
  new (...args: unknown[]): MessageReceiver;
@@ -76,25 +76,40 @@ export declare function createCancellationToken(): CancellationToken;
76
76
  * @param token - The cancellation token previously passed to avmSimulate
77
77
  */
78
78
  export declare function cancelSimulation(token: CancellationToken): void;
79
+ /**
80
+ * Maximum number of concurrent AVM simulations. Each simulation spawns a dedicated OS thread,
81
+ * so this controls resource usage. Defaults to 4. Set to 0 for unlimited.
82
+ */
83
+ export declare const AVM_MAX_CONCURRENT_SIMULATIONS: number;
79
84
  /**
80
85
  * AVM simulation function that takes serialized inputs and a contract provider.
81
86
  * The contract provider enables C++ to callback to TypeScript for contract data during simulation.
87
+ *
88
+ * Simulations run on dedicated std::threads (not the libuv thread pool), so there is no risk
89
+ * of libuv thread pool exhaustion or deadlock from C++ BlockingCall callbacks.
90
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
91
+ *
82
92
  * @param inputs - Msgpack-serialized AvmFastSimulationInputs buffer
83
93
  * @param contractProvider - Object with callbacks for fetching contract instances and classes
84
94
  * @param worldStateHandle - Native handle to WorldState instance
85
- * @param logLevel - Log level to control C++ verbosity
95
+ * @param logLevel - Optional log level to control C++ verbosity (only used if loggerFunction is provided)
96
+ * @param logger - Optional logger object for C++ logging callbacks
86
97
  * @param cancellationToken - Optional token to enable cancellation support
87
98
  * @returns Promise resolving to msgpack-serialized AvmCircuitPublicInputs buffer
88
99
  */
89
- export declare function avmSimulate(inputs: Buffer, contractProvider: ContractProvider, worldStateHandle: any, logLevel?: LogLevel, cancellationToken?: CancellationToken): Promise<Buffer>;
100
+ export declare function avmSimulate(inputs: Buffer, contractProvider: ContractProvider, worldStateHandle: any, logLevel?: LogLevel, logger?: Logger, cancellationToken?: CancellationToken): Promise<Buffer>;
90
101
  /**
91
102
  * AVM simulation function that uses pre-collected hints from TypeScript simulation.
92
103
  * All contract data and merkle tree hints are included in the AvmCircuitInputs, so no runtime
93
104
  * callbacks to TS or WS pointer are needed.
105
+ *
106
+ * Simulations run on dedicated std::threads (not the libuv thread pool).
107
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
108
+ *
94
109
  * @param inputs - Msgpack-serialized AvmCircuitInputs (AvmProvingInputs in C++) buffer
95
110
  * @param logLevel - Log level to control C++ verbosity
96
111
  * @returns Promise resolving to msgpack-serialized simulation results buffer
97
112
  */
98
113
  export declare function avmSimulateWithHintedDbs(inputs: Buffer, logLevel?: LogLevel): Promise<Buffer>;
99
114
  export {};
100
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0aXZlX21vZHVsZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25hdGl2ZV9tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEtBQUssUUFBUSxFQUFhLE1BQU0sdUJBQXVCLENBQUM7QUFLakUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFNUQsVUFBVSxlQUFlO0lBQ3ZCLEtBQUssR0FBRyxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsZUFBZSxDQUFDO0NBQzNDO0FBYUQsZUFBTyxNQUFNLGdCQUFnQixFQUFFLGVBQTRELENBQUM7QUFDNUYsZUFBTyxNQUFNLGVBQWUsRUFBRSxlQUEyRCxDQUFDO0FBRTFGOzs7R0FHRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0I7Ozs7T0FJRztJQUNILG1CQUFtQixDQUFDLE9BQU8sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQztJQUNsRTs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRS9EOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsc0JBQXNCLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUU1RDs7OztPQUlHO0lBQ0gscUJBQXFCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRXBFOzs7OztPQUtHO0lBQ0gsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBQUM7SUFFckY7Ozs7T0FJRztJQUNILGdCQUFnQixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQzs7O09BR0c7SUFDSCxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFbEM7OztPQUdHO0lBQ0gsZ0JBQWdCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ25DO0FBbUJEOzs7O0dBSUc7QUFDSCxNQUFNLE1BQU0saUJBQWlCLEdBQUcsR0FBRyxDQUFDO0FBRXBDOzs7O0dBSUc7QUFDSCx3QkFBZ0IsdUJBQXVCLElBQUksaUJBQWlCLENBRTNEO0FBRUQ7Ozs7R0FJRztBQUNILHdCQUFnQixnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxDQUUvRDtBQWlCRDs7Ozs7Ozs7O0dBU0c7QUFDSCx3QkFBc0IsV0FBVyxDQUMvQixNQUFNLEVBQUUsTUFBTSxFQUNkLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxnQkFBZ0IsRUFBRSxHQUFHLEVBQ3JCLFFBQVEsR0FBRSxRQUFpQixFQUMzQixpQkFBaUIsQ0FBQyxFQUFFLGlCQUFpQixHQUNwQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBYWpCO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILHdCQUFzQix3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsR0FBRSxRQUFpQixHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FPM0cifQ==
115
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0aXZlX21vZHVsZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25hdGl2ZV9tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEtBQUssUUFBUSxFQUFhLEtBQUssTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFLOUUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFNUQsVUFBVSxlQUFlO0lBQ3ZCLEtBQUssR0FBRyxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsZUFBZSxDQUFDO0NBQzNDO0FBYUQsZUFBTyxNQUFNLGdCQUFnQixFQUFFLGVBQTRELENBQUM7QUFDNUYsZUFBTyxNQUFNLGVBQWUsRUFBRSxlQUEyRCxDQUFDO0FBRTFGOzs7R0FHRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0I7Ozs7T0FJRztJQUNILG1CQUFtQixDQUFDLE9BQU8sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQztJQUNsRTs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRS9EOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsc0JBQXNCLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUU1RDs7OztPQUlHO0lBQ0gscUJBQXFCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRXBFOzs7OztPQUtHO0lBQ0gsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBQUM7SUFFckY7Ozs7T0FJRztJQUNILGdCQUFnQixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQzs7O09BR0c7SUFDSCxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFbEM7OztPQUdHO0lBQ0gsZ0JBQWdCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ25DO0FBb0JEOzs7O0dBSUc7QUFDSCxNQUFNLE1BQU0saUJBQWlCLEdBQUcsR0FBRyxDQUFDO0FBRXBDOzs7O0dBSUc7QUFDSCx3QkFBZ0IsdUJBQXVCLElBQUksaUJBQWlCLENBRTNEO0FBRUQ7Ozs7R0FJRztBQUNILHdCQUFnQixnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxDQUUvRDtBQUVEOzs7R0FHRztBQUNILGVBQU8sTUFBTSw4QkFBOEIsUUFBa0UsQ0FBQztBQWdCOUc7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsd0JBQWdCLFdBQVcsQ0FDekIsTUFBTSxFQUFFLE1BQU0sRUFDZCxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFDbEMsZ0JBQWdCLEVBQUUsR0FBRyxFQUNyQixRQUFRLEdBQUUsUUFBaUIsRUFDM0IsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUNmLGlCQUFpQixDQUFDLEVBQUUsaUJBQWlCLEdBQ3BDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FXakI7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILHdCQUFnQix3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsR0FBRSxRQUFpQixHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FFckcifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"native_module.d.ts","sourceRoot":"","sources":["../src/native_module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAa,MAAM,uBAAuB,CAAC;AAKjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,UAAU,eAAe;IACvB,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC;CAC3C;AAaD,eAAO,MAAM,gBAAgB,EAAE,eAA4D,CAAC;AAC5F,eAAO,MAAM,eAAe,EAAE,eAA2D,CAAC;AAE1F;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAE/D;;;;OAIG;IACH,YAAY,CAAC,sBAAsB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D;;;;OAIG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEpE;;;;;OAKG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAErF;;;;OAIG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAmBD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE/D;AAiBD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,GAAG,EACrB,QAAQ,GAAE,QAAiB,EAC3B,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,OAAO,CAAC,MAAM,CAAC,CAajB;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3G"}
1
+ {"version":3,"file":"native_module.d.ts","sourceRoot":"","sources":["../src/native_module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAa,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAK9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,UAAU,eAAe;IACvB,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC;CAC3C;AAaD,eAAO,MAAM,gBAAgB,EAAE,eAA4D,CAAC;AAC5F,eAAO,MAAM,eAAe,EAAE,eAA2D,CAAC;AAE1F;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAE/D;;;;OAIG;IACH,YAAY,CAAC,sBAAsB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D;;;;OAIG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEpE;;;;;OAKG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAErF;;;;OAIG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAoBD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE/D;AAED;;;GAGG;AACH,eAAO,MAAM,8BAA8B,QAAkE,CAAC;AAgB9G;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,GAAG,EACrB,QAAQ,GAAE,QAAiB,EAC3B,MAAM,CAAC,EAAE,MAAM,EACf,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAErG"}
@@ -33,47 +33,50 @@ const nativeCancelSimulation = nativeModule.cancelSimulation;
33
33
  nativeCancelSimulation(token);
34
34
  }
35
35
  /**
36
- * Concurrency limiting for C++ AVM simulation to prevent libuv thread pool exhaustion.
37
- *
38
- * The C++ simulator uses NAPI BlockingCall to callback to TypeScript for contract data.
39
- * This blocks the libuv thread while waiting for the callback to complete. If all libuv
40
- * threads are blocked waiting for callbacks, no threads remain to service those callbacks,
41
- * causing deadlock.
42
- *
43
- * We limit concurrent simulations to UV_THREADPOOL_SIZE / 2 to ensure threads remain
44
- * available for callback processing.
45
- */ const UV_THREADPOOL_SIZE = parseInt(process.env.UV_THREADPOOL_SIZE ?? '4', 10);
46
- const MAX_CONCURRENT_AVM_SIMULATIONS = Math.max(1, Math.floor(UV_THREADPOOL_SIZE / 2));
47
- const avmSimulationSemaphore = new Semaphore(MAX_CONCURRENT_AVM_SIMULATIONS);
36
+ * Maximum number of concurrent AVM simulations. Each simulation spawns a dedicated OS thread,
37
+ * so this controls resource usage. Defaults to 4. Set to 0 for unlimited.
38
+ */ export const AVM_MAX_CONCURRENT_SIMULATIONS = parseInt(process.env.AVM_MAX_CONCURRENT_SIMULATIONS ?? '4', 10);
39
+ const avmSimulationSemaphore = AVM_MAX_CONCURRENT_SIMULATIONS > 0 ? new Semaphore(AVM_MAX_CONCURRENT_SIMULATIONS) : null;
40
+ async function withAvmConcurrencyLimit(fn) {
41
+ if (!avmSimulationSemaphore) {
42
+ return fn();
43
+ }
44
+ await avmSimulationSemaphore.acquire();
45
+ try {
46
+ return await fn();
47
+ } finally{
48
+ avmSimulationSemaphore.release();
49
+ }
50
+ }
48
51
  /**
49
52
  * AVM simulation function that takes serialized inputs and a contract provider.
50
53
  * The contract provider enables C++ to callback to TypeScript for contract data during simulation.
54
+ *
55
+ * Simulations run on dedicated std::threads (not the libuv thread pool), so there is no risk
56
+ * of libuv thread pool exhaustion or deadlock from C++ BlockingCall callbacks.
57
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
58
+ *
51
59
  * @param inputs - Msgpack-serialized AvmFastSimulationInputs buffer
52
60
  * @param contractProvider - Object with callbacks for fetching contract instances and classes
53
61
  * @param worldStateHandle - Native handle to WorldState instance
54
- * @param logLevel - Log level to control C++ verbosity
62
+ * @param logLevel - Optional log level to control C++ verbosity (only used if loggerFunction is provided)
63
+ * @param logger - Optional logger object for C++ logging callbacks
55
64
  * @param cancellationToken - Optional token to enable cancellation support
56
65
  * @returns Promise resolving to msgpack-serialized AvmCircuitPublicInputs buffer
57
- */ export async function avmSimulate(inputs, contractProvider, worldStateHandle, logLevel = 'info', cancellationToken) {
58
- await avmSimulationSemaphore.acquire();
59
- try {
60
- return await nativeAvmSimulate(inputs, contractProvider, worldStateHandle, LogLevels.indexOf(logLevel), cancellationToken);
61
- } finally{
62
- avmSimulationSemaphore.release();
63
- }
66
+ */ export function avmSimulate(inputs, contractProvider, worldStateHandle, logLevel = 'info', logger, cancellationToken) {
67
+ return withAvmConcurrencyLimit(()=>nativeAvmSimulate(inputs, contractProvider, worldStateHandle, LogLevels.indexOf(logLevel), logger ? (level, msg)=>logger[level](msg) : null, cancellationToken));
64
68
  }
65
69
  /**
66
70
  * AVM simulation function that uses pre-collected hints from TypeScript simulation.
67
71
  * All contract data and merkle tree hints are included in the AvmCircuitInputs, so no runtime
68
72
  * callbacks to TS or WS pointer are needed.
73
+ *
74
+ * Simulations run on dedicated std::threads (not the libuv thread pool).
75
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
76
+ *
69
77
  * @param inputs - Msgpack-serialized AvmCircuitInputs (AvmProvingInputs in C++) buffer
70
78
  * @param logLevel - Log level to control C++ verbosity
71
79
  * @returns Promise resolving to msgpack-serialized simulation results buffer
72
- */ export async function avmSimulateWithHintedDbs(inputs, logLevel = 'info') {
73
- await avmSimulationSemaphore.acquire();
74
- try {
75
- return await nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel));
76
- } finally{
77
- avmSimulationSemaphore.release();
78
- }
80
+ */ export function avmSimulateWithHintedDbs(inputs, logLevel = 'info') {
81
+ return withAvmConcurrencyLimit(()=>nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel)));
79
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/native",
3
- "version": "0.0.1-commit.03f7ef2",
3
+ "version": "0.0.1-commit.04d373f",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js"
@@ -15,15 +15,15 @@
15
15
  "../package.common.json"
16
16
  ],
17
17
  "dependencies": {
18
- "@aztec/bb.js": "0.0.1-commit.03f7ef2",
19
- "@aztec/foundation": "0.0.1-commit.03f7ef2",
18
+ "@aztec/bb.js": "0.0.1-commit.04d373f",
19
+ "@aztec/foundation": "0.0.1-commit.04d373f",
20
20
  "msgpackr": "^1.11.2"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@jest/globals": "^30.0.0",
24
24
  "@types/jest": "^30.0.0",
25
25
  "@types/node": "^22.15.17",
26
- "@typescript/native-preview": "7.0.0-dev.20251126.1",
26
+ "@typescript/native-preview": "7.0.0-dev.20260113.1",
27
27
  "jest": "^30.0.0",
28
28
  "ts-node": "^10.9.1",
29
29
  "typescript": "^5.3.3"
@@ -1,5 +1,5 @@
1
1
  import { findNapiBinary } from '@aztec/bb.js';
2
- import { type LogLevel, LogLevels } from '@aztec/foundation/log';
2
+ import { type LogLevel, LogLevels, type Logger } from '@aztec/foundation/log';
3
3
  import { Semaphore } from '@aztec/foundation/queue';
4
4
 
5
5
  import { createRequire } from 'module';
@@ -90,6 +90,7 @@ const nativeAvmSimulate = nativeModule.avmSimulate as (
90
90
  contractProvider: ContractProvider,
91
91
  worldStateHandle: any,
92
92
  logLevel: number,
93
+ logFunction?: any,
93
94
  cancellationToken?: any,
94
95
  ) => Promise<Buffer>;
95
96
 
@@ -127,64 +128,73 @@ export function cancelSimulation(token: CancellationToken): void {
127
128
  }
128
129
 
129
130
  /**
130
- * Concurrency limiting for C++ AVM simulation to prevent libuv thread pool exhaustion.
131
- *
132
- * The C++ simulator uses NAPI BlockingCall to callback to TypeScript for contract data.
133
- * This blocks the libuv thread while waiting for the callback to complete. If all libuv
134
- * threads are blocked waiting for callbacks, no threads remain to service those callbacks,
135
- * causing deadlock.
136
- *
137
- * We limit concurrent simulations to UV_THREADPOOL_SIZE / 2 to ensure threads remain
138
- * available for callback processing.
131
+ * Maximum number of concurrent AVM simulations. Each simulation spawns a dedicated OS thread,
132
+ * so this controls resource usage. Defaults to 4. Set to 0 for unlimited.
139
133
  */
140
- const UV_THREADPOOL_SIZE = parseInt(process.env.UV_THREADPOOL_SIZE ?? '4', 10);
141
- const MAX_CONCURRENT_AVM_SIMULATIONS = Math.max(1, Math.floor(UV_THREADPOOL_SIZE / 2));
142
- const avmSimulationSemaphore = new Semaphore(MAX_CONCURRENT_AVM_SIMULATIONS);
134
+ export const AVM_MAX_CONCURRENT_SIMULATIONS = parseInt(process.env.AVM_MAX_CONCURRENT_SIMULATIONS ?? '4', 10);
135
+ const avmSimulationSemaphore =
136
+ AVM_MAX_CONCURRENT_SIMULATIONS > 0 ? new Semaphore(AVM_MAX_CONCURRENT_SIMULATIONS) : null;
137
+
138
+ async function withAvmConcurrencyLimit<T>(fn: () => Promise<T>): Promise<T> {
139
+ if (!avmSimulationSemaphore) {
140
+ return fn();
141
+ }
142
+ await avmSimulationSemaphore.acquire();
143
+ try {
144
+ return await fn();
145
+ } finally {
146
+ avmSimulationSemaphore.release();
147
+ }
148
+ }
143
149
 
144
150
  /**
145
151
  * AVM simulation function that takes serialized inputs and a contract provider.
146
152
  * The contract provider enables C++ to callback to TypeScript for contract data during simulation.
153
+ *
154
+ * Simulations run on dedicated std::threads (not the libuv thread pool), so there is no risk
155
+ * of libuv thread pool exhaustion or deadlock from C++ BlockingCall callbacks.
156
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
157
+ *
147
158
  * @param inputs - Msgpack-serialized AvmFastSimulationInputs buffer
148
159
  * @param contractProvider - Object with callbacks for fetching contract instances and classes
149
160
  * @param worldStateHandle - Native handle to WorldState instance
150
- * @param logLevel - Log level to control C++ verbosity
161
+ * @param logLevel - Optional log level to control C++ verbosity (only used if loggerFunction is provided)
162
+ * @param logger - Optional logger object for C++ logging callbacks
151
163
  * @param cancellationToken - Optional token to enable cancellation support
152
164
  * @returns Promise resolving to msgpack-serialized AvmCircuitPublicInputs buffer
153
165
  */
154
- export async function avmSimulate(
166
+ export function avmSimulate(
155
167
  inputs: Buffer,
156
168
  contractProvider: ContractProvider,
157
169
  worldStateHandle: any,
158
170
  logLevel: LogLevel = 'info',
171
+ logger?: Logger,
159
172
  cancellationToken?: CancellationToken,
160
173
  ): Promise<Buffer> {
161
- await avmSimulationSemaphore.acquire();
162
- try {
163
- return await nativeAvmSimulate(
174
+ return withAvmConcurrencyLimit(() =>
175
+ nativeAvmSimulate(
164
176
  inputs,
165
177
  contractProvider,
166
178
  worldStateHandle,
167
179
  LogLevels.indexOf(logLevel),
180
+ logger ? (level: LogLevel, msg: string) => logger[level](msg) : null,
168
181
  cancellationToken,
169
- );
170
- } finally {
171
- avmSimulationSemaphore.release();
172
- }
182
+ ),
183
+ );
173
184
  }
174
185
 
175
186
  /**
176
187
  * AVM simulation function that uses pre-collected hints from TypeScript simulation.
177
188
  * All contract data and merkle tree hints are included in the AvmCircuitInputs, so no runtime
178
189
  * callbacks to TS or WS pointer are needed.
190
+ *
191
+ * Simulations run on dedicated std::threads (not the libuv thread pool).
192
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
193
+ *
179
194
  * @param inputs - Msgpack-serialized AvmCircuitInputs (AvmProvingInputs in C++) buffer
180
195
  * @param logLevel - Log level to control C++ verbosity
181
196
  * @returns Promise resolving to msgpack-serialized simulation results buffer
182
197
  */
183
- export async function avmSimulateWithHintedDbs(inputs: Buffer, logLevel: LogLevel = 'info'): Promise<Buffer> {
184
- await avmSimulationSemaphore.acquire();
185
- try {
186
- return await nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel));
187
- } finally {
188
- avmSimulationSemaphore.release();
189
- }
198
+ export function avmSimulateWithHintedDbs(inputs: Buffer, logLevel: LogLevel = 'info'): Promise<Buffer> {
199
+ return withAvmConcurrencyLimit(() => nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel)));
190
200
  }