diff --git a/yarn-project/circuit-types/src/simulation_error.ts b/yarn-project/circuit-types/src/simulation_error.ts index b8d1b0be4bf..735a7fd39d5 100644 --- a/yarn-project/circuit-types/src/simulation_error.ts +++ b/yarn-project/circuit-types/src/simulation_error.ts @@ -78,6 +78,8 @@ export function isNoirCallStackUnresolved(callStack: NoirCallStack): callStack i * An error during the simulation of a function call. */ export class SimulationError extends Error { + private aztecContext: string = ''; + constructor( private originalMessage: string, private functionErrorStack: FailingFunction[], @@ -124,7 +126,9 @@ export class SimulationError extends Error { getMessage() { if (this.noirErrorStack && !isNoirCallStackUnresolved(this.noirErrorStack) && this.noirErrorStack.length) { - return `${this.originalMessage} '${this.noirErrorStack[this.noirErrorStack.length - 1].locationText}'`; + return `${this.originalMessage} '${this.noirErrorStack[this.noirErrorStack.length - 1].locationText}'${ + this.aztecContext + }`; } return this.originalMessage; } @@ -212,6 +216,10 @@ export class SimulationError extends Error { this.noirErrorStack = callStack; } + setAztecContext(context: string) { + this.aztecContext = context; + } + toJSON() { return { originalMessage: this.originalMessage, diff --git a/yarn-project/foundation/src/abi/event_selector.ts b/yarn-project/foundation/src/abi/event_selector.ts index 0203d562380..b06b56d7f47 100644 --- a/yarn-project/foundation/src/abi/event_selector.ts +++ b/yarn-project/foundation/src/abi/event_selector.ts @@ -62,7 +62,7 @@ export class EventSelector extends Selector { static fromString(selector: string) { const buf = fromHex(selector); if (buf.length !== Selector.SIZE) { - throw new Error(`Invalid Selector length ${buf.length} (expected ${Selector.SIZE}).`); + throw new Error(`Invalid EventSelector length ${buf.length} (expected ${Selector.SIZE}).`); } return EventSelector.fromBuffer(buf); } diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index 00b75d1b500..d5fd68545f4 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -91,7 +91,7 @@ export class FunctionSelector extends Selector { static fromString(selector: string) { const buf = fromHex(selector); if (buf.length !== Selector.SIZE) { - throw new Error(`Invalid Selector length ${buf.length} (expected ${Selector.SIZE}).`); + throw new Error(`Invalid FunctionSelector length ${buf.length} (expected ${Selector.SIZE}).`); } return FunctionSelector.fromBuffer(buf); } diff --git a/yarn-project/pxe/src/pxe_service/error_enriching.ts b/yarn-project/pxe/src/pxe_service/error_enriching.ts index 722dc06713b..cb71823fe13 100644 --- a/yarn-project/pxe/src/pxe_service/error_enriching.ts +++ b/yarn-project/pxe/src/pxe_service/error_enriching.ts @@ -11,26 +11,26 @@ import { type ContractDataOracle, type PxeDatabase } from '../index.js'; * @param err - The error to enrich. */ export async function enrichSimulationError(err: SimulationError, db: PxeDatabase, logger: Logger) { - // Maps contract addresses to the set of functions selectors that were in error. + // Maps contract addresses to the set of function names that were in error. // Map and Set do reference equality for their keys instead of value equality, so we store the string // representation to get e.g. different contract address objects with the same address value to match. const mentionedFunctions: Map> = new Map(); - err.getCallStack().forEach(({ contractAddress, functionSelector }) => { + err.getCallStack().forEach(({ contractAddress, functionName }) => { if (!mentionedFunctions.has(contractAddress.toString())) { mentionedFunctions.set(contractAddress.toString(), new Set()); } - mentionedFunctions.get(contractAddress.toString())!.add(functionSelector?.toString() ?? ''); + mentionedFunctions.get(contractAddress.toString())!.add(functionName?.toString() ?? ''); }); await Promise.all( - [...mentionedFunctions.entries()].map(async ([contractAddress, selectors]) => { + [...mentionedFunctions.entries()].map(async ([contractAddress, fnNames]) => { const parsedContractAddress = AztecAddress.fromString(contractAddress); const contract = await db.getContract(parsedContractAddress); if (contract) { err.enrichWithContractName(parsedContractAddress, contract.name); - selectors.forEach(selector => { - const functionArtifact = contract.functions.find(f => FunctionSelector.fromString(selector).equals(f)); + fnNames.forEach(fnName => { + const functionArtifact = contract.functions.find(f => fnName === f.name); if (functionArtifact) { err.enrichWithFunctionName( parsedContractAddress, @@ -39,7 +39,7 @@ export async function enrichSimulationError(err: SimulationError, db: PxeDatabas ); } else { logger.warn( - `Could not function artifact in contract ${contract.name} for selector ${selector} when enriching error callstack`, + `Could not function artifact in contract ${contract.name} for function '${fnName}' when enriching error callstack`, ); } }); diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 7db11578b10..1362778826a 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -1004,10 +1004,15 @@ export class PXEService implements PXE { } private contextualizeError(err: Error, ...context: string[]): Error { - this.log.error(err.name, err); - this.log.debug('Context:'); - for (const c of context) { - this.log.debug(c); + let contextStr = ''; + if (context.length > 0) { + contextStr = `\nContext:\n${context.join('\n')}`; + } + if (err instanceof SimulationError) { + err.setAztecContext(contextStr); + } else { + this.log.error(err.name, err); + this.log.debug(contextStr); } return err; } diff --git a/yarn-project/simulator/src/common/debug_fn_name.ts b/yarn-project/simulator/src/common/debug_fn_name.ts index aba0827b011..271bd688bfe 100644 --- a/yarn-project/simulator/src/common/debug_fn_name.ts +++ b/yarn-project/simulator/src/common/debug_fn_name.ts @@ -12,5 +12,5 @@ export async function getPublicFunctionDebugName( calldata[0] !== undefined ? await db.getDebugFunctionName(contractAddress, FunctionSelector.fromField(calldata[0])) : ` (Contract Address: ${contractAddress})`; - return `${targetFunction} (via dispatch)`; + return `${targetFunction}`; }