Skip to content

Commit b20ac72

Browse files
PhilWindleAztecBot
authored andcommitted
fix(bench): handle void worker-wallet returns in inclusion sweep
WorkerWallet.call unconditionally JSON.parse'd the transport response, but void-returning methods (registerContract, registerContractClass) come back as `undefined` from the worker. JSON.parse(undefined) throws `SyntaxError: "undefined" is not valid JSON`, which crashed registerSponsoredFPC during n_tps.test.ts setup and failed every nightly bench inclusion-sweep point (1/5/10 TPS) deterministically. Pass an undefined response straight to the method's schema, whose z.void() output accepts it, and widen callRaw's return type to string | undefined to match.
1 parent 2413b09 commit b20ac72

2 files changed

Lines changed: 27 additions & 3 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { ContractArtifact } from '@aztec/stdlib/abi';
2+
import type { ContractInstancePreimage } from '@aztec/stdlib/contract';
3+
4+
import { WorkerWallet } from './worker_wallet.js';
5+
6+
describe('WorkerWallet', () => {
7+
// The private constructor spawns a worker; call() only touches the transport client, so we build the
8+
// instance directly with a stub client and never start a worker.
9+
const walletRespondingWith = (requestResult: unknown): WorkerWallet => {
10+
const client = { request: () => Promise.resolve(requestResult) };
11+
return Reflect.construct(WorkerWallet, [undefined, client]);
12+
};
13+
14+
// registerContract / registerContractClass return void, which the worker serializes as `undefined`.
15+
// Feeding that to JSON.parse throws `"undefined" is not valid JSON` — the crash that failed every
16+
// inclusion-sweep bench point during setup.
17+
it('resolves a void-returning method when the worker responds with undefined', async () => {
18+
const wallet = walletRespondingWith(undefined);
19+
await expect(wallet.registerContract({} as ContractInstancePreimage)).resolves.toBeUndefined();
20+
await expect(wallet.registerContractClass({} as ContractArtifact)).resolves.toBeUndefined();
21+
});
22+
});

yarn-project/end-to-end/src/test-wallet/worker_wallet.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,17 @@ export class WorkerWallet implements Wallet {
116116
return wallet;
117117
}
118118

119-
private async callRaw(fn: string, ...args: any[]): Promise<string> {
119+
private async callRaw(fn: string, ...args: any[]): Promise<string | undefined> {
120120
const argsJson = jsonStringify(args);
121-
return (await this.client.request({ fn, args: argsJson })) as string;
121+
return (await this.client.request({ fn, args: argsJson })) as string | undefined;
122122
}
123123

124124
private async call(fn: string, ...args: any[]): Promise<any> {
125125
const resultJson = await this.callRaw(fn, ...args);
126126
const methodSchema = (WorkerWalletSchema as ApiSchema)[fn];
127-
return getSchemaReturnType(methodSchema).parseAsync(JSON.parse(resultJson));
127+
// Void-returning methods (e.g. registerContract) serialize to `undefined` on the worker side, which
128+
// JSON.parse cannot handle; hand it straight to the schema, whose `z.void()` output accepts undefined.
129+
return getSchemaReturnType(methodSchema).parseAsync(resultJson === undefined ? undefined : JSON.parse(resultJson));
128130
}
129131

130132
getChainInfo(): Promise<ChainInfo> {

0 commit comments

Comments
 (0)