Skip to content

Commit 172586c

Browse files
committed
refactor(wallets): narrow stub-class cache to just the class id
Callers only ever consume the `id` field from `getContractClassFromArtifact`, so cache `Map<AccountType, Promise<Fr>>` instead of the full `ContractClassWithId & ContractClassIdPreimage`. Method renamed `#getStubClass` → `#getStubClassId`, map renamed `#stubClasses` → `#stubClassIds`, callers drop the destructure. Drop the verbose Promise-as-value rationale comment — the idiom is established in this codebase (see ContractSyncService) and the PXE precedents document the cache contract briefly without explaining the dedupe pattern.
1 parent a498f65 commit 172586c

3 files changed

Lines changed: 32 additions & 52 deletions

File tree

yarn-project/cli-wallet/src/utils/wallet.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import type { PXEConfig } from '@aztec/pxe/config';
1717
import type { PXE } from '@aztec/pxe/server';
1818
import { createPXE, getPXEConfig } from '@aztec/pxe/server';
1919
import { AztecAddress } from '@aztec/stdlib/aztec-address';
20-
import type { ContractClassIdPreimage, ContractClassWithId } from '@aztec/stdlib/contract';
2120
import { deriveSigningKey } from '@aztec/stdlib/keys';
2221
import { NoteDao } from '@aztec/stdlib/note';
2322
import type { SimulationOverrides, TxExecutionRequest, TxProvingResult } from '@aztec/stdlib/tx';
@@ -31,13 +30,8 @@ import { printGasEstimates } from './options/fees.js';
3130

3231
export class CLIWallet extends BaseWallet {
3332
private accountCache = new Map<string, Account>();
34-
/**
35-
* Per-account-type cache of the stub class id and preimage. The Promise is stored (not the resolved
36-
* value) so concurrent first-time callers dedupe on the same hashing + registration work. ECDSA
37-
* variants all map to the same stub artifact but get their own cache slot, so we may hash + register
38-
* the same artifact one extra time per variant on first miss; that cost is bounded and one-time.
39-
*/
40-
#stubClasses = new Map<AccountType, Promise<ContractClassWithId & ContractClassIdPreimage>>();
33+
// Per-account-type cache of the stub class id, populated lazily on first use.
34+
#stubClassIds = new Map<AccountType, Promise<Fr>>();
4135

4236
constructor(
4337
pxe: PXE,
@@ -208,25 +202,25 @@ export class CLIWallet extends BaseWallet {
208202
const { type } = await this.db!.retrieveAccount(address);
209203
const stubAccount =
210204
type === 'schnorr' ? createStubSchnorrAccount(originalAddress) : createStubEcdsaAccount(originalAddress);
211-
const { id: stubClassId } = await this.#getStubClass(type);
205+
const stubClassId = await this.#getStubClassId(type);
212206
const instance = { ...contractInstance, currentContractClassId: stubClassId };
213207
return { account: stubAccount, instance };
214208
}
215209

216210
/**
217-
* Lazily hashes and registers the stub class for the given account type, caching the result so
218-
* subsequent simulations skip the artifact-hashing + registration round-trip.
211+
* Lazily hashes and registers the stub class for the given account type, caching the resulting class
212+
* id so subsequent simulations skip the artifact-hashing + registration round-trip.
219213
*/
220-
#getStubClass(type: AccountType): Promise<ContractClassWithId & ContractClassIdPreimage> {
221-
let cached = this.#stubClasses.get(type);
214+
#getStubClassId(type: AccountType): Promise<Fr> {
215+
let cached = this.#stubClassIds.get(type);
222216
if (!cached) {
223217
cached = (async () => {
224218
const artifact = type === 'schnorr' ? StubSchnorrAccountContractArtifact : StubEcdsaAccountContractArtifact;
225-
const stubClass = await getContractClassFromArtifact(artifact);
219+
const { id } = await getContractClassFromArtifact(artifact);
226220
await this.pxe.registerContractClass(artifact);
227-
return stubClass;
221+
return id;
228222
})();
229-
this.#stubClasses.set(type, cached);
223+
this.#stubClassIds.set(type, cached);
230224
}
231225
return cached;
232226
}

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

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,7 @@ import { type PXEConfig, getPXEConfig } from '@aztec/pxe/config';
2525
import { PXE, type PXECreationOptions, createPXE } from '@aztec/pxe/server';
2626
import { AuthWitness } from '@aztec/stdlib/auth-witness';
2727
import { AztecAddress } from '@aztec/stdlib/aztec-address';
28-
import {
29-
type ContractClassIdPreimage,
30-
type ContractClassWithId,
31-
getContractClassFromArtifact,
32-
} from '@aztec/stdlib/contract';
28+
import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
3329
import { deriveSigningKey } from '@aztec/stdlib/keys';
3430
import type { NoteDao } from '@aztec/stdlib/note';
3531
import {
@@ -116,26 +112,23 @@ export class TestWallet extends BaseWallet {
116112
});
117113
}
118114

119-
/**
120-
* Per-account-type cache of the stub class id and preimage. The Promise is stored (not the resolved
121-
* value) so concurrent first-time callers dedupe on the same hashing + registration work.
122-
*/
123-
#stubClasses = new Map<AccountType, Promise<ContractClassWithId & ContractClassIdPreimage>>();
115+
// Per-account-type cache of the stub class id, populated lazily on first use.
116+
#stubClassIds = new Map<AccountType, Promise<Fr>>();
124117

125118
/**
126-
* Lazily hashes and registers the stub class for the given account type, caching the result so
127-
* subsequent simulations skip the artifact-hashing + registration round-trip.
119+
* Lazily hashes and registers the stub class for the given account type, caching the resulting
120+
* class id so subsequent simulations skip the artifact-hashing + registration round-trip.
128121
*/
129-
#getStubClass(type: AccountType): Promise<ContractClassWithId & ContractClassIdPreimage> {
130-
let cached = this.#stubClasses.get(type);
122+
#getStubClassId(type: AccountType): Promise<Fr> {
123+
let cached = this.#stubClassIds.get(type);
131124
if (!cached) {
132125
cached = (async () => {
133126
const stubArtifact = type === 'schnorr' ? StubSchnorrAccountContractArtifact : StubEcdsaAccountContractArtifact;
134-
const stubClass = await getContractClassFromArtifact(stubArtifact);
127+
const { id } = await getContractClassFromArtifact(stubArtifact);
135128
await this.pxe.registerContractClass(stubArtifact);
136-
return stubClass;
129+
return id;
137130
})();
138-
this.#stubClasses.set(type, cached);
131+
this.#stubClassIds.set(type, cached);
139132
}
140133
return cached;
141134
}
@@ -160,7 +153,7 @@ export class TestWallet extends BaseWallet {
160153
);
161154
}
162155

163-
const { id: stubClassId } = await this.#getStubClass(this.getTypeFor(address));
156+
const stubClassId = await this.#getStubClassId(this.getTypeFor(address));
164157

165158
contracts[address.toString()] = {
166159
instance: { ...contractInstance, currentContractClassId: stubClassId },

yarn-project/wallets/src/embedded/embedded_wallet.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ import type { AztecAsyncKVStore } from '@aztec/kv-store';
1111
import type { PXEConfig, PXECreationOptions } from '@aztec/pxe/client/lazy';
1212
import type { PXE } from '@aztec/pxe/server';
1313
import { AztecAddress } from '@aztec/stdlib/aztec-address';
14-
import {
15-
type ContractClassIdPreimage,
16-
type ContractClassWithId,
17-
getContractClassFromArtifact,
18-
} from '@aztec/stdlib/contract';
14+
import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
1915
import { GasSettings } from '@aztec/stdlib/gas';
2016
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
2117
import { deriveSigningKey } from '@aztec/stdlib/keys';
@@ -80,11 +76,8 @@ const DEFAULT_ESTIMATED_GAS_PADDING = 0.1;
8076
export class EmbeddedWallet extends BaseWallet {
8177
protected estimatedGasPadding = DEFAULT_ESTIMATED_GAS_PADDING;
8278

83-
/**
84-
* Per-account-type cache of the stub class id and preimage. The Promise is stored (not the resolved
85-
* value) so concurrent first-time callers dedupe on the same hashing + registration work.
86-
*/
87-
#stubClasses = new Map<AccountType, Promise<ContractClassWithId & ContractClassIdPreimage>>();
79+
// Per-account-type cache of the stub class id, populated lazily on first use.
80+
#stubClassIds = new Map<AccountType, Promise<Fr>>();
8881

8982
constructor(
9083
pxe: PXE,
@@ -203,19 +196,19 @@ export class EmbeddedWallet extends BaseWallet {
203196
}
204197

205198
/**
206-
* Lazily hashes and registers the stub class for the given account type, caching the result so
207-
* subsequent simulations skip the artifact-hashing + registration round-trip.
199+
* Lazily hashes and registers the stub class for the given account type, caching the resulting
200+
* class id so subsequent simulations skip the artifact-hashing + registration round-trip.
208201
*/
209-
#getStubClass(type: AccountType): Promise<ContractClassWithId & ContractClassIdPreimage> {
210-
let cached = this.#stubClasses.get(type);
202+
#getStubClassId(type: AccountType): Promise<Fr> {
203+
let cached = this.#stubClassIds.get(type);
211204
if (!cached) {
212205
cached = (async () => {
213206
const stubArtifact = await this.accountContracts.getStubAccountContractArtifact(type);
214-
const stubClass = await getContractClassFromArtifact(stubArtifact);
207+
const { id } = await getContractClassFromArtifact(stubArtifact);
215208
await this.pxe.registerContractClass(stubArtifact);
216-
return stubClass;
209+
return id;
217210
})();
218-
this.#stubClasses.set(type, cached);
211+
this.#stubClassIds.set(type, cached);
219212
}
220213
return cached;
221214
}
@@ -233,7 +226,7 @@ export class EmbeddedWallet extends BaseWallet {
233226
for (const account of filtered) {
234227
const address = account.item;
235228
const { type } = await this.walletDB.retrieveAccount(address);
236-
const { id: stubClassId } = await this.#getStubClass(type);
229+
const stubClassId = await this.#getStubClassId(type);
237230

238231
const originalAccount = await this.getAccountFromAddress(address);
239232
const completeAddress = originalAccount.getCompleteAddress();

0 commit comments

Comments
 (0)