Skip to content

Commit 2c36088

Browse files
authored
fix: simulation error enriching (#10595)
Fixes: - `Failed to enrich public simulation` - `Error: Invalid Function Selector length 0 (expected 4)` - Full source code being printed out on error - [This commit](7227b48) caused entire `SimulationError` and therefore its source code member to be printed out.
1 parent a37f82d commit 2c36088

File tree

6 files changed

+28
-15
lines changed

6 files changed

+28
-15
lines changed

yarn-project/circuit-types/src/simulation_error.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ export function isNoirCallStackUnresolved(callStack: NoirCallStack): callStack i
7878
* An error during the simulation of a function call.
7979
*/
8080
export class SimulationError extends Error {
81+
private aztecContext: string = '';
82+
8183
constructor(
8284
private originalMessage: string,
8385
private functionErrorStack: FailingFunction[],
@@ -124,7 +126,9 @@ export class SimulationError extends Error {
124126

125127
getMessage() {
126128
if (this.noirErrorStack && !isNoirCallStackUnresolved(this.noirErrorStack) && this.noirErrorStack.length) {
127-
return `${this.originalMessage} '${this.noirErrorStack[this.noirErrorStack.length - 1].locationText}'`;
129+
return `${this.originalMessage} '${this.noirErrorStack[this.noirErrorStack.length - 1].locationText}'${
130+
this.aztecContext
131+
}`;
128132
}
129133
return this.originalMessage;
130134
}
@@ -212,6 +216,10 @@ export class SimulationError extends Error {
212216
this.noirErrorStack = callStack;
213217
}
214218

219+
setAztecContext(context: string) {
220+
this.aztecContext = context;
221+
}
222+
215223
toJSON() {
216224
return {
217225
originalMessage: this.originalMessage,

yarn-project/foundation/src/abi/event_selector.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class EventSelector extends Selector {
6262
static fromString(selector: string) {
6363
const buf = fromHex(selector);
6464
if (buf.length !== Selector.SIZE) {
65-
throw new Error(`Invalid Selector length ${buf.length} (expected ${Selector.SIZE}).`);
65+
throw new Error(`Invalid EventSelector length ${buf.length} (expected ${Selector.SIZE}).`);
6666
}
6767
return EventSelector.fromBuffer(buf);
6868
}

yarn-project/foundation/src/abi/function_selector.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export class FunctionSelector extends Selector {
9191
static fromString(selector: string) {
9292
const buf = fromHex(selector);
9393
if (buf.length !== Selector.SIZE) {
94-
throw new Error(`Invalid Selector length ${buf.length} (expected ${Selector.SIZE}).`);
94+
throw new Error(`Invalid FunctionSelector length ${buf.length} (expected ${Selector.SIZE}).`);
9595
}
9696
return FunctionSelector.fromBuffer(buf);
9797
}

yarn-project/pxe/src/pxe_service/error_enriching.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@ import { type ContractDataOracle, type PxeDatabase } from '../index.js';
1111
* @param err - The error to enrich.
1212
*/
1313
export async function enrichSimulationError(err: SimulationError, db: PxeDatabase, logger: Logger) {
14-
// Maps contract addresses to the set of functions selectors that were in error.
14+
// Maps contract addresses to the set of function names that were in error.
1515
// Map and Set do reference equality for their keys instead of value equality, so we store the string
1616
// representation to get e.g. different contract address objects with the same address value to match.
1717
const mentionedFunctions: Map<string, Set<string>> = new Map();
1818

19-
err.getCallStack().forEach(({ contractAddress, functionSelector }) => {
19+
err.getCallStack().forEach(({ contractAddress, functionName }) => {
2020
if (!mentionedFunctions.has(contractAddress.toString())) {
2121
mentionedFunctions.set(contractAddress.toString(), new Set());
2222
}
23-
mentionedFunctions.get(contractAddress.toString())!.add(functionSelector?.toString() ?? '');
23+
mentionedFunctions.get(contractAddress.toString())!.add(functionName?.toString() ?? '');
2424
});
2525

2626
await Promise.all(
27-
[...mentionedFunctions.entries()].map(async ([contractAddress, selectors]) => {
27+
[...mentionedFunctions.entries()].map(async ([contractAddress, fnNames]) => {
2828
const parsedContractAddress = AztecAddress.fromString(contractAddress);
2929
const contract = await db.getContract(parsedContractAddress);
3030
if (contract) {
3131
err.enrichWithContractName(parsedContractAddress, contract.name);
32-
selectors.forEach(selector => {
33-
const functionArtifact = contract.functions.find(f => FunctionSelector.fromString(selector).equals(f));
32+
fnNames.forEach(fnName => {
33+
const functionArtifact = contract.functions.find(f => fnName === f.name);
3434
if (functionArtifact) {
3535
err.enrichWithFunctionName(
3636
parsedContractAddress,
@@ -39,7 +39,7 @@ export async function enrichSimulationError(err: SimulationError, db: PxeDatabas
3939
);
4040
} else {
4141
logger.warn(
42-
`Could not function artifact in contract ${contract.name} for selector ${selector} when enriching error callstack`,
42+
`Could not function artifact in contract ${contract.name} for function '${fnName}' when enriching error callstack`,
4343
);
4444
}
4545
});

yarn-project/pxe/src/pxe_service/pxe_service.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -1004,10 +1004,15 @@ export class PXEService implements PXE {
10041004
}
10051005

10061006
private contextualizeError(err: Error, ...context: string[]): Error {
1007-
this.log.error(err.name, err);
1008-
this.log.debug('Context:');
1009-
for (const c of context) {
1010-
this.log.debug(c);
1007+
let contextStr = '';
1008+
if (context.length > 0) {
1009+
contextStr = `\nContext:\n${context.join('\n')}`;
1010+
}
1011+
if (err instanceof SimulationError) {
1012+
err.setAztecContext(contextStr);
1013+
} else {
1014+
this.log.error(err.name, err);
1015+
this.log.debug(contextStr);
10111016
}
10121017
return err;
10131018
}

yarn-project/simulator/src/common/debug_fn_name.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ export async function getPublicFunctionDebugName(
1212
calldata[0] !== undefined
1313
? await db.getDebugFunctionName(contractAddress, FunctionSelector.fromField(calldata[0]))
1414
: `<calldata[0] undefined> (Contract Address: ${contractAddress})`;
15-
return `${targetFunction} (via dispatch)`;
15+
return `${targetFunction}`;
1616
}

0 commit comments

Comments
 (0)