From f6a20c698cace8da45350cb40e18878cff644391 Mon Sep 17 00:00:00 2001 From: dbanks12 Date: Wed, 26 Nov 2025 19:21:12 +0000 Subject: [PATCH] feat(avm): TS triggers C++ simulation with an associated log level --- .../avm_simulate/avm_simulate_napi.cpp | 57 +++++++++++++------ yarn-project/native/src/native_module.ts | 35 ++++++++---- .../cpp_public_tx_simulator.ts | 4 +- ...cpp_public_tx_simulator_with_hinted_dbs.ts | 4 +- .../cpp_vs_ts_public_tx_simulator.ts | 4 +- 5 files changed, 72 insertions(+), 32 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/nodejs_module/avm_simulate/avm_simulate_napi.cpp b/barretenberg/cpp/src/barretenberg/nodejs_module/avm_simulate/avm_simulate_napi.cpp index cc4ab96e613f..b7d5c948835a 100644 --- a/barretenberg/cpp/src/barretenberg/nodejs_module/avm_simulate/avm_simulate_napi.cpp +++ b/barretenberg/cpp/src/barretenberg/nodejs_module/avm_simulate/avm_simulate_napi.cpp @@ -14,6 +14,20 @@ namespace bb::nodejs { namespace { +// Log levels from TS foundation/src/log/log-levels.ts: ['silent', 'fatal', 'error', 'warn', 'info', 'verbose', 'debug', +// 'trace'] Map: 0=silent, 1=fatal, 2=error, 3=warn, 4=info, 5=verbose, 6=debug, 7=trace +constexpr int LOG_LEVEL_VERBOSE = 5; +constexpr int LOG_LEVEL_TRACE = 7; + +// Helper to set logging flags based on TS log level +inline void set_logging_from_level(int log_level) +{ + // Turn verbose_logging on if log level is verbose (5) or above + verbose_logging = (log_level >= LOG_LEVEL_VERBOSE); + // Turn debug_logging on if log level is trace (7) or above + debug_logging = (log_level >= LOG_LEVEL_TRACE); +} + // Callback method names constexpr const char* CALLBACK_GET_CONTRACT_INSTANCE = "getContractInstance"; constexpr const char* CALLBACK_GET_CONTRACT_CLASS = "getContractClass"; @@ -100,20 +114,17 @@ struct ContractCallbacks { Napi::Value AvmSimulateNapi::simulate(const Napi::CallbackInfo& cb_info) { - // TODO(dbanks12): configurable verbosity (maybe based on TS log level) - // verbose_logging = true; - // debug_logging = true; - Napi::Env env = cb_info.Env(); - // Validate arguments - expects 3 arguments + // Validate arguments - expects 4 arguments // arg[0]: inputs Buffer (required) // arg[1]: contractProvider object (required) // arg[2]: worldStateHandle external (required) - if (cb_info.Length() < 3) { + // arg[3]: logLevel number (required) - index into TS LogLevels array + if (cb_info.Length() < 4) { throw Napi::TypeError::New(env, - "Wrong number of arguments. Expected 3 arguments: inputs Buffer, contractProvider " - "object, and worldStateHandle."); + "Wrong number of arguments. Expected 4 arguments: inputs Buffer, contractProvider " + "object, worldStateHandle, and logLevel."); } if (!cb_info[0].IsBuffer()) { @@ -129,6 +140,14 @@ Napi::Value AvmSimulateNapi::simulate(const Napi::CallbackInfo& cb_info) throw Napi::TypeError::New(env, "Third argument must be a WorldState handle (External)"); } + if (!cb_info[3].IsNumber()) { + throw Napi::TypeError::New(env, "Fourth argument must be a log level number (0-7)"); + } + + // Extract log level and set logging flags + int log_level = cb_info[3].As().Int32Value(); + set_logging_from_level(log_level); + // Extract the inputs buffer auto inputs_buffer = cb_info[0].As>(); size_t length = inputs_buffer.Length(); @@ -215,17 +234,15 @@ Napi::Value AvmSimulateNapi::simulate(const Napi::CallbackInfo& cb_info) Napi::Value AvmSimulateNapi::simulateWithHintedDbs(const Napi::CallbackInfo& cb_info) { - // TODO(dbanks12): configurable verbosity (maybe based on TS log level) - verbose_logging = true; - debug_logging = true; - Napi::Env env = cb_info.Env(); - // Validate arguments - expects 1 argument + // Validate arguments - expects 2 arguments // arg[0]: inputs Buffer (required) - AvmProvingInputs - if (cb_info.Length() < 1) { - throw Napi::TypeError::New( - env, "Wrong number of arguments. Expected 1 argument: AvmProvingInputs/AvmCircuitInputs msgpack Buffer."); + // arg[1]: logLevel number (required) - index into TS LogLevels array + if (cb_info.Length() < 2) { + throw Napi::TypeError::New(env, + "Wrong number of arguments. Expected 2 arguments: AvmProvingInputs/AvmCircuitInputs " + "msgpack Buffer and logLevel."); } if (!cb_info[0].IsBuffer()) { @@ -233,6 +250,14 @@ Napi::Value AvmSimulateNapi::simulateWithHintedDbs(const Napi::CallbackInfo& cb_ env, "First argument must be a Buffer containing serialized AvmProvingInputs/AvmCircuitInputs"); } + if (!cb_info[1].IsNumber()) { + throw Napi::TypeError::New(env, "Second argument must be a log level number (0-7)"); + } + + // Extract log level and set logging flags + int log_level = cb_info[1].As().Int32Value(); + set_logging_from_level(log_level); + // Extract the inputs buffer auto inputs_buffer = cb_info[0].As>(); size_t length = inputs_buffer.Length(); diff --git a/yarn-project/native/src/native_module.ts b/yarn-project/native/src/native_module.ts index 74e2510d44c0..2994d29f8c20 100644 --- a/yarn-project/native/src/native_module.ts +++ b/yarn-project/native/src/native_module.ts @@ -1,4 +1,5 @@ import { findNapiBinary } from '@aztec/bb.js'; +import { type LogLevel, LogLevels } from '@aztec/foundation/log'; import { createRequire } from 'module'; @@ -82,31 +83,45 @@ export interface ContractProvider { revertCheckpoint(): Promise; } +// Internal native functions with numeric log level +const nativeAvmSimulate = nativeModule.avmSimulate as ( + inputs: Buffer, + contractProvider: ContractProvider, + worldStateHandle: any, + logLevel: number, +) => Promise; + +const nativeAvmSimulateWithHintedDbs = nativeModule.avmSimulateWithHintedDbs as ( + inputs: Buffer, + logLevel: number, +) => Promise; + /** * AVM simulation function that takes serialized inputs and a contract provider. * The contract provider enables C++ to callback to TypeScript for contract data during simulation. * @param inputs - Msgpack-serialized AvmFastSimulationInputs buffer * @param contractProvider - Object with callbacks for fetching contract instances and classes * @param worldStateHandle - Native handle to WorldState instance - * TODO(MW): include generate_hints bool + * @param logLevel - Log level to control C++ verbosity * @returns Promise resolving to msgpack-serialized AvmCircuitPublicInputs buffer */ -export const avmSimulate: ( +export function avmSimulate( inputs: Buffer, contractProvider: ContractProvider, worldStateHandle: any, -) => Promise = nativeModule.avmSimulate as ( - inputs: Buffer, - contractProvider: ContractProvider, - worldStateHandle: any, -) => Promise; + logLevel: LogLevel = 'info', +): Promise { + return nativeAvmSimulate(inputs, contractProvider, worldStateHandle, LogLevels.indexOf(logLevel)); +} + /** * AVM simulation function that uses pre-collected hints from TypeScript simulation. * All contract data and merkle tree hints are included in the AvmCircuitInputs, so no runtime * callbacks to TS or WS pointer are needed. * @param inputs - Msgpack-serialized AvmCircuitInputs (AvmProvingInputs in C++) buffer + * @param logLevel - Log level to control C++ verbosity * @returns Promise resolving to msgpack-serialized simulation results buffer */ -export const avmSimulateWithHintedDbs: (inputs: Buffer) => Promise = nativeModule.avmSimulateWithHintedDbs as ( - inputs: Buffer, -) => Promise; +export function avmSimulateWithHintedDbs(inputs: Buffer, logLevel: LogLevel = 'info'): Promise { + return nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel)); +} diff --git a/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator.ts b/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator.ts index 39252ecd8b7b..bf88470962ad 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator.ts @@ -1,4 +1,4 @@ -import { type Logger, createLogger } from '@aztec/foundation/log'; +import { type Logger, createLogger, logLevel } from '@aztec/foundation/log'; import { avmSimulate } from '@aztec/native'; import { ProtocolContractsList } from '@aztec/protocol-contracts'; import { @@ -88,7 +88,7 @@ export class CppPublicTxSimulator extends PublicTxSimulator implements PublicTxS let resultBuffer: Buffer; try { this.log.debug(`Calling C++ simulator for tx ${txHash}`); - resultBuffer = await avmSimulate(inputBuffer, contractProvider, wsCppHandle); + resultBuffer = await avmSimulate(inputBuffer, contractProvider, wsCppHandle, logLevel); } catch (error: any) { throw new SimulationError(`C++ simulation failed: ${error.message}`, []); } diff --git a/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts b/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts index 2fe967fad4f9..4f7ca2d74414 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts @@ -1,4 +1,4 @@ -import { type Logger, createLogger } from '@aztec/foundation/log'; +import { type Logger, createLogger, logLevel } from '@aztec/foundation/log'; import { avmSimulateWithHintedDbs } from '@aztec/native'; import { AvmCircuitInputs, @@ -74,7 +74,7 @@ export class CppPublicTxSimulatorHintedDbs extends PublicTxSimulator implements let resultBuffer: Buffer; try { - resultBuffer = await avmSimulateWithHintedDbs(inputBuffer); + resultBuffer = await avmSimulateWithHintedDbs(inputBuffer, logLevel); } catch (error: any) { throw new SimulationError(`C++ hinted simulation failed: ${error.message}`, []); } diff --git a/yarn-project/simulator/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts b/yarn-project/simulator/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts index 5eff0e9ea45a..8c8d41dd15f6 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts @@ -1,4 +1,4 @@ -import { type Logger, createLogger } from '@aztec/foundation/log'; +import { type Logger, createLogger, logLevel } from '@aztec/foundation/log'; import { writeTestData } from '@aztec/foundation/testing/files'; import { avmSimulate } from '@aztec/native'; import { ProtocolContractsList } from '@aztec/protocol-contracts'; @@ -113,7 +113,7 @@ export class CppVsTsPublicTxSimulator extends PublicTxSimulator implements Publi let resultBuffer: Buffer; try { this.log.debug(`Calling C++ simulator for tx ${txHash}`); - resultBuffer = await avmSimulate(inputBuffer, contractProvider, wsCppHandle); + resultBuffer = await avmSimulate(inputBuffer, contractProvider, wsCppHandle, logLevel); } catch (error: any) { throw new SimulationError(`C++ simulation failed: ${error.message}`, []); }