Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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()) {
Expand All @@ -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<Napi::Number>().Int32Value();
set_logging_from_level(log_level);

// Extract the inputs buffer
auto inputs_buffer = cb_info[0].As<Napi::Buffer<uint8_t>>();
size_t length = inputs_buffer.Length();
Expand Down Expand Up @@ -215,24 +234,30 @@ 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()) {
throw Napi::TypeError::New(
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<Napi::Number>().Int32Value();
set_logging_from_level(log_level);

// Extract the inputs buffer
auto inputs_buffer = cb_info[0].As<Napi::Buffer<uint8_t>>();
size_t length = inputs_buffer.Length();
Expand Down
35 changes: 25 additions & 10 deletions yarn-project/native/src/native_module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { findNapiBinary } from '@aztec/bb.js';
import { type LogLevel, LogLevels } from '@aztec/foundation/log';

import { createRequire } from 'module';

Expand Down Expand Up @@ -82,31 +83,45 @@ export interface ContractProvider {
revertCheckpoint(): Promise<void>;
}

// Internal native functions with numeric log level
const nativeAvmSimulate = nativeModule.avmSimulate as (
inputs: Buffer,
contractProvider: ContractProvider,
worldStateHandle: any,
logLevel: number,
) => Promise<Buffer>;

const nativeAvmSimulateWithHintedDbs = nativeModule.avmSimulateWithHintedDbs as (
inputs: Buffer,
logLevel: number,
) => Promise<Buffer>;

/**
* 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<Buffer> = nativeModule.avmSimulate as (
inputs: Buffer,
contractProvider: ContractProvider,
worldStateHandle: any,
) => Promise<Buffer>;
logLevel: LogLevel = 'info',
): Promise<Buffer> {
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<Buffer> = nativeModule.avmSimulateWithHintedDbs as (
inputs: Buffer,
) => Promise<Buffer>;
export function avmSimulateWithHintedDbs(inputs: Buffer, logLevel: LogLevel = 'info'): Promise<Buffer> {
return nativeAvmSimulateWithHintedDbs(inputs, LogLevels.indexOf(logLevel));
}
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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}`, []);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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}`, []);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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}`, []);
}
Expand Down
Loading