@aztec/native 0.0.1-commit.fce3e4f → 0.0.1-commit.ffe5b04ea

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 { Fr } from '@aztec/foundation/fields';
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { MessageHeader, TypedMessage } from '@aztec/foundation/message';
3
3
  import { Encoder, addExtension } from 'msgpackr';
4
4
  import { isAnyArrayBuffer } from 'util/types';
@@ -1,3 +1,4 @@
1
+ import { type LogLevel, type Logger } from '@aztec/foundation/log';
1
2
  import type { MessageReceiver } from './msgpack_channel.js';
2
3
  interface NativeClassCtor {
3
4
  new (...args: unknown[]): MessageReceiver;
@@ -57,23 +58,53 @@ export interface ContractProvider {
57
58
  */
58
59
  revertCheckpoint(): Promise<void>;
59
60
  }
61
+ /**
62
+ * Cancellation token handle used to cancel C++ AVM simulation.
63
+ * The token is created via createCancellationToken() and can be cancelled via cancelSimulation().
64
+ * Pass it to avmSimulate to enable cancellation support.
65
+ */
66
+ export type CancellationToken = any;
67
+ /**
68
+ * Create a new cancellation token for C++ simulation.
69
+ * This token can be passed to avmSimulate and later cancelled via cancelSimulation().
70
+ * @returns A handle to a cancellation token
71
+ */
72
+ export declare function createCancellationToken(): CancellationToken;
73
+ /**
74
+ * Signal cancellation to a C++ simulation.
75
+ * The simulation will stop at the next opcode or before the next WorldState write.
76
+ * @param token - The cancellation token previously passed to avmSimulate
77
+ */
78
+ export declare function cancelSimulation(token: CancellationToken): void;
60
79
  /**
61
80
  * AVM simulation function that takes serialized inputs and a contract provider.
62
81
  * The contract provider enables C++ to callback to TypeScript for contract data during simulation.
82
+ *
83
+ * Simulations run on dedicated std::threads (not the libuv thread pool), so there is no risk
84
+ * of libuv thread pool exhaustion or deadlock from C++ BlockingCall callbacks.
85
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
86
+ *
63
87
  * @param inputs - Msgpack-serialized AvmFastSimulationInputs buffer
64
88
  * @param contractProvider - Object with callbacks for fetching contract instances and classes
65
89
  * @param worldStateHandle - Native handle to WorldState instance
66
- * TODO(MW): include generate_hints bool
90
+ * @param logLevel - Optional log level to control C++ verbosity (only used if loggerFunction is provided)
91
+ * @param logger - Optional logger object for C++ logging callbacks
92
+ * @param cancellationToken - Optional token to enable cancellation support
67
93
  * @returns Promise resolving to msgpack-serialized AvmCircuitPublicInputs buffer
68
94
  */
69
- export declare const avmSimulate: (inputs: Buffer, contractProvider: ContractProvider, worldStateHandle: any) => Promise<Buffer>;
95
+ export declare function avmSimulate(inputs: Buffer, contractProvider: ContractProvider, worldStateHandle: any, logLevel?: LogLevel, logger?: Logger, cancellationToken?: CancellationToken): Promise<Buffer>;
70
96
  /**
71
97
  * AVM simulation function that uses pre-collected hints from TypeScript simulation.
72
98
  * All contract data and merkle tree hints are included in the AvmCircuitInputs, so no runtime
73
99
  * callbacks to TS or WS pointer are needed.
100
+ *
101
+ * Simulations run on dedicated std::threads (not the libuv thread pool).
102
+ * Concurrency is limited by AVM_MAX_CONCURRENT_SIMULATIONS (default 4, 0 = unlimited).
103
+ *
74
104
  * @param inputs - Msgpack-serialized AvmCircuitInputs (AvmProvingInputs in C++) buffer
105
+ * @param logLevel - Log level to control C++ verbosity
75
106
  * @returns Promise resolving to msgpack-serialized simulation results buffer
76
107
  */
77
- export declare const avmSimulateWithHintedDbs: (inputs: Buffer) => Promise<Buffer>;
108
+ export declare function avmSimulateWithHintedDbs(inputs: Buffer, logLevel?: LogLevel): Promise<Buffer>;
78
109
  export {};
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0aXZlX21vZHVsZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25hdGl2ZV9tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFNUQsVUFBVSxlQUFlO0lBQ3ZCLEtBQUssR0FBRyxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsZUFBZSxDQUFDO0NBQzNDO0FBYUQsZUFBTyxNQUFNLGdCQUFnQixFQUFFLGVBQTRELENBQUM7QUFDNUYsZUFBTyxNQUFNLGVBQWUsRUFBRSxlQUEyRCxDQUFDO0FBRTFGOzs7R0FHRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0I7Ozs7T0FJRztJQUNILG1CQUFtQixDQUFDLE9BQU8sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQztJQUNsRTs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRS9EOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsc0JBQXNCLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUU1RDs7OztPQUlHO0lBQ0gscUJBQXFCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRXBFOzs7OztPQUtHO0lBQ0gsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBQUM7SUFFckY7Ozs7T0FJRztJQUNILGdCQUFnQixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQzs7O09BR0c7SUFDSCxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFbEM7OztPQUdHO0lBQ0gsZ0JBQWdCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ25DO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxlQUFPLE1BQU0sV0FBVyxFQUFFLENBQ3hCLE1BQU0sRUFBRSxNQUFNLEVBQ2QsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQ2xDLGdCQUFnQixFQUFFLEdBQUcsS0FDbEIsT0FBTyxDQUFDLE1BQU0sQ0FJQyxDQUFDO0FBQ3JCOzs7Ozs7R0FNRztBQUNILGVBQU8sTUFBTSx3QkFBd0IsRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLEtBQUssT0FBTyxDQUFDLE1BQU0sQ0FFckQsQ0FBQyJ9
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0aXZlX21vZHVsZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25hdGl2ZV9tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEtBQUssUUFBUSxFQUFhLEtBQUssTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFLOUUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFNUQsVUFBVSxlQUFlO0lBQ3ZCLEtBQUssR0FBRyxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsZUFBZSxDQUFDO0NBQzNDO0FBYUQsZUFBTyxNQUFNLGdCQUFnQixFQUFFLGVBQTRELENBQUM7QUFDNUYsZUFBTyxNQUFNLGVBQWUsRUFBRSxlQUEyRCxDQUFDO0FBRTFGOzs7R0FHRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0I7Ozs7T0FJRztJQUNILG1CQUFtQixDQUFDLE9BQU8sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQztJQUNsRTs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRS9EOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsc0JBQXNCLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUU1RDs7OztPQUlHO0lBQ0gscUJBQXFCLENBQUMsT0FBTyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBRXBFOzs7OztPQUtHO0lBQ0gsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBQUM7SUFFckY7Ozs7T0FJRztJQUNILGdCQUFnQixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQzs7O09BR0c7SUFDSCxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFbEM7OztPQUdHO0lBQ0gsZ0JBQWdCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ25DO0FBb0JEOzs7O0dBSUc7QUFDSCxNQUFNLE1BQU0saUJBQWlCLEdBQUcsR0FBRyxDQUFDO0FBRXBDOzs7O0dBSUc7QUFDSCx3QkFBZ0IsdUJBQXVCLElBQUksaUJBQWlCLENBRTNEO0FBRUQ7Ozs7R0FJRztBQUNILHdCQUFnQixnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxDQUUvRDtBQXNCRDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCx3QkFBZ0IsV0FBVyxDQUN6QixNQUFNLEVBQUUsTUFBTSxFQUNkLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxnQkFBZ0IsRUFBRSxHQUFHLEVBQ3JCLFFBQVEsR0FBRSxRQUFpQixFQUMzQixNQUFNLENBQUMsRUFBRSxNQUFNLEVBQ2YsaUJBQWlCLENBQUMsRUFBRSxpQkFBaUIsR0FDcEMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQVdqQjtBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsd0JBQWdCLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxHQUFFLFFBQWlCLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUVyRyJ9
@@ -1 +1 @@
1
- {"version":3,"file":"native_module.d.ts","sourceRoot":"","sources":["../src/native_module.ts"],"names":[],"mappings":"AAIA,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;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,CACxB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,GAAG,KAClB,OAAO,CAAC,MAAM,CAIC,CAAC;AACrB;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAErD,CAAC"}
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;AAsBD;;;;;;;;;;;;;;;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"}
@@ -1,4 +1,6 @@
1
1
  import { findNapiBinary } from '@aztec/bb.js';
2
+ import { LogLevels } from '@aztec/foundation/log';
3
+ import { Semaphore } from '@aztec/foundation/queue';
2
4
  import { createRequire } from 'module';
3
5
  function loadNativeModule() {
4
6
  const require = createRequire(import.meta.url);
@@ -11,19 +13,70 @@ function loadNativeModule() {
11
13
  const nativeModule = loadNativeModule();
12
14
  export const NativeWorldState = nativeModule.WorldState;
13
15
  export const NativeLMDBStore = nativeModule.LMDBStore;
16
+ // Internal native functions with numeric log level
17
+ const nativeAvmSimulate = nativeModule.avmSimulate;
18
+ const nativeAvmSimulateWithHintedDbs = nativeModule.avmSimulateWithHintedDbs;
19
+ const nativeCreateCancellationToken = nativeModule.createCancellationToken;
20
+ const nativeCancelSimulation = nativeModule.cancelSimulation;
21
+ /**
22
+ * Create a new cancellation token for C++ simulation.
23
+ * This token can be passed to avmSimulate and later cancelled via cancelSimulation().
24
+ * @returns A handle to a cancellation token
25
+ */ export function createCancellationToken() {
26
+ return nativeCreateCancellationToken();
27
+ }
28
+ /**
29
+ * Signal cancellation to a C++ simulation.
30
+ * The simulation will stop at the next opcode or before the next WorldState write.
31
+ * @param token - The cancellation token previously passed to avmSimulate
32
+ */ export function cancelSimulation(token) {
33
+ nativeCancelSimulation(token);
34
+ }
35
+ /**
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
+ */ 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
+ }
14
51
  /**
15
52
  * AVM simulation function that takes serialized inputs and a contract provider.
16
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
+ *
17
59
  * @param inputs - Msgpack-serialized AvmFastSimulationInputs buffer
18
60
  * @param contractProvider - Object with callbacks for fetching contract instances and classes
19
61
  * @param worldStateHandle - Native handle to WorldState instance
20
- * TODO(MW): include generate_hints bool
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
64
+ * @param cancellationToken - Optional token to enable cancellation support
21
65
  * @returns Promise resolving to msgpack-serialized AvmCircuitPublicInputs buffer
22
- */ export const avmSimulate = nativeModule.avmSimulate;
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));
68
+ }
23
69
  /**
24
70
  * AVM simulation function that uses pre-collected hints from TypeScript simulation.
25
71
  * All contract data and merkle tree hints are included in the AvmCircuitInputs, so no runtime
26
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
+ *
27
77
  * @param inputs - Msgpack-serialized AvmCircuitInputs (AvmProvingInputs in C++) buffer
78
+ * @param logLevel - Log level to control C++ verbosity
28
79
  * @returns Promise resolving to msgpack-serialized simulation results buffer
29
- */ export const avmSimulateWithHintedDbs = nativeModule.avmSimulateWithHintedDbs;
80
+ */ export function avmSimulateWithHintedDbs(inputs, logLevel = 'info') {
81
+ return withAvmConcurrencyLimit(()=>nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel)));
82
+ }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@aztec/native",
3
- "version": "0.0.1-commit.fce3e4f",
3
+ "version": "0.0.1-commit.ffe5b04ea",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js"
7
7
  },
8
8
  "scripts": {
9
- "build": "yarn clean && tsgo -b",
10
- "build:dev": "tsgo -b --watch",
9
+ "build": "yarn clean && ../scripts/tsc.sh",
10
+ "build:dev": "../scripts/tsc.sh --watch",
11
11
  "clean": "rm -rf ./dest .tsbuildinfo",
12
12
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
13
13
  },
@@ -15,15 +15,15 @@
15
15
  "../package.common.json"
16
16
  ],
17
17
  "dependencies": {
18
- "@aztec/bb.js": "0.0.1-commit.fce3e4f",
19
- "@aztec/foundation": "0.0.1-commit.fce3e4f",
18
+ "@aztec/bb.js": "0.0.1-commit.ffe5b04ea",
19
+ "@aztec/foundation": "0.0.1-commit.ffe5b04ea",
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,4 +1,4 @@
1
- import { Fr } from '@aztec/foundation/fields';
1
+ import { Fr } from '@aztec/foundation/curves/bn254';
2
2
  import { MessageHeader, TypedMessage } from '@aztec/foundation/message';
3
3
 
4
4
  import { Encoder, addExtension } from 'msgpackr';
@@ -1,4 +1,6 @@
1
1
  import { findNapiBinary } from '@aztec/bb.js';
2
+ import { type LogLevel, LogLevels, type Logger } from '@aztec/foundation/log';
3
+ import { Semaphore } from '@aztec/foundation/queue';
2
4
 
3
5
  import { createRequire } from 'module';
4
6
 
@@ -82,31 +84,117 @@ export interface ContractProvider {
82
84
  revertCheckpoint(): Promise<void>;
83
85
  }
84
86
 
87
+ // Internal native functions with numeric log level
88
+ const nativeAvmSimulate = nativeModule.avmSimulate as (
89
+ inputs: Buffer,
90
+ contractProvider: ContractProvider,
91
+ worldStateHandle: any,
92
+ logLevel: number,
93
+ logFunction?: any,
94
+ cancellationToken?: any,
95
+ ) => Promise<Buffer>;
96
+
97
+ const nativeAvmSimulateWithHintedDbs = nativeModule.avmSimulateWithHintedDbs as (
98
+ inputs: Buffer,
99
+ logLevel: number,
100
+ ) => Promise<Buffer>;
101
+
102
+ const nativeCreateCancellationToken = nativeModule.createCancellationToken as () => any;
103
+ const nativeCancelSimulation = nativeModule.cancelSimulation as (token: any) => void;
104
+
105
+ /**
106
+ * Cancellation token handle used to cancel C++ AVM simulation.
107
+ * The token is created via createCancellationToken() and can be cancelled via cancelSimulation().
108
+ * Pass it to avmSimulate to enable cancellation support.
109
+ */
110
+ export type CancellationToken = any;
111
+
112
+ /**
113
+ * Create a new cancellation token for C++ simulation.
114
+ * This token can be passed to avmSimulate and later cancelled via cancelSimulation().
115
+ * @returns A handle to a cancellation token
116
+ */
117
+ export function createCancellationToken(): CancellationToken {
118
+ return nativeCreateCancellationToken();
119
+ }
120
+
121
+ /**
122
+ * Signal cancellation to a C++ simulation.
123
+ * The simulation will stop at the next opcode or before the next WorldState write.
124
+ * @param token - The cancellation token previously passed to avmSimulate
125
+ */
126
+ export function cancelSimulation(token: CancellationToken): void {
127
+ nativeCancelSimulation(token);
128
+ }
129
+
130
+ /**
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.
133
+ */
134
+ 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
+ }
149
+
85
150
  /**
86
151
  * AVM simulation function that takes serialized inputs and a contract provider.
87
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
+ *
88
158
  * @param inputs - Msgpack-serialized AvmFastSimulationInputs buffer
89
159
  * @param contractProvider - Object with callbacks for fetching contract instances and classes
90
160
  * @param worldStateHandle - Native handle to WorldState instance
91
- * TODO(MW): include generate_hints bool
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
163
+ * @param cancellationToken - Optional token to enable cancellation support
92
164
  * @returns Promise resolving to msgpack-serialized AvmCircuitPublicInputs buffer
93
165
  */
94
- export const avmSimulate: (
166
+ export function avmSimulate(
95
167
  inputs: Buffer,
96
168
  contractProvider: ContractProvider,
97
169
  worldStateHandle: any,
98
- ) => Promise<Buffer> = nativeModule.avmSimulate as (
99
- inputs: Buffer,
100
- contractProvider: ContractProvider,
101
- worldStateHandle: any,
102
- ) => Promise<Buffer>;
170
+ logLevel: LogLevel = 'info',
171
+ logger?: Logger,
172
+ cancellationToken?: CancellationToken,
173
+ ): Promise<Buffer> {
174
+ return withAvmConcurrencyLimit(() =>
175
+ nativeAvmSimulate(
176
+ inputs,
177
+ contractProvider,
178
+ worldStateHandle,
179
+ LogLevels.indexOf(logLevel),
180
+ logger ? (level: LogLevel, msg: string) => logger[level](msg) : null,
181
+ cancellationToken,
182
+ ),
183
+ );
184
+ }
185
+
103
186
  /**
104
187
  * AVM simulation function that uses pre-collected hints from TypeScript simulation.
105
188
  * All contract data and merkle tree hints are included in the AvmCircuitInputs, so no runtime
106
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
+ *
107
194
  * @param inputs - Msgpack-serialized AvmCircuitInputs (AvmProvingInputs in C++) buffer
195
+ * @param logLevel - Log level to control C++ verbosity
108
196
  * @returns Promise resolving to msgpack-serialized simulation results buffer
109
197
  */
110
- export const avmSimulateWithHintedDbs: (inputs: Buffer) => Promise<Buffer> = nativeModule.avmSimulateWithHintedDbs as (
111
- inputs: Buffer,
112
- ) => Promise<Buffer>;
198
+ export function avmSimulateWithHintedDbs(inputs: Buffer, logLevel: LogLevel = 'info'): Promise<Buffer> {
199
+ return withAvmConcurrencyLimit(() => nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel)));
200
+ }