@aztec/pxe 0.82.0 → 0.82.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dest/config/index.js +1 -1
  2. package/dest/private_kernel/private_kernel_execution_prover.d.ts +0 -1
  3. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  4. package/dest/private_kernel/private_kernel_execution_prover.js +3 -12
  5. package/dest/private_kernel/private_kernel_oracle_impl.d.ts +1 -1
  6. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
  7. package/dest/private_kernel/private_kernel_oracle_impl.js +11 -1
  8. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
  9. package/dest/pxe_oracle_interface/pxe_oracle_interface.js +6 -0
  10. package/dest/pxe_service/error_enriching.d.ts.map +1 -1
  11. package/dest/pxe_service/error_enriching.js +5 -8
  12. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  13. package/dest/pxe_service/pxe_service.js +8 -4
  14. package/dest/storage/contract_data_provider/contract_data_provider.d.ts +10 -44
  15. package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
  16. package/dest/storage/contract_data_provider/contract_data_provider.js +92 -72
  17. package/dest/storage/contract_data_provider/index.d.ts +0 -1
  18. package/dest/storage/contract_data_provider/index.d.ts.map +1 -1
  19. package/dest/storage/contract_data_provider/index.js +0 -1
  20. package/dest/storage/contract_data_provider/private_functions_tree.d.ts +3 -42
  21. package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
  22. package/dest/storage/contract_data_provider/private_functions_tree.js +9 -61
  23. package/dest/test/pxe_test_suite.d.ts.map +1 -1
  24. package/dest/test/pxe_test_suite.js +1 -1
  25. package/package.json +15 -15
  26. package/src/config/index.ts +1 -1
  27. package/src/private_kernel/private_kernel_execution_prover.ts +4 -20
  28. package/src/private_kernel/private_kernel_oracle_impl.ts +13 -1
  29. package/src/pxe_oracle_interface/pxe_oracle_interface.ts +6 -0
  30. package/src/pxe_service/error_enriching.ts +8 -14
  31. package/src/pxe_service/pxe_service.ts +10 -4
  32. package/src/storage/contract_data_provider/contract_data_provider.ts +110 -80
  33. package/src/storage/contract_data_provider/index.ts +0 -1
  34. package/src/storage/contract_data_provider/private_functions_tree.ts +11 -75
  35. package/src/test/pxe_test_suite.ts +3 -1
@@ -1,5 +1,3 @@
1
- import { PUBLIC_DISPATCH_SELECTOR } from '@aztec/constants';
2
- import { Fr } from '@aztec/foundation/fields';
3
1
  import type { Logger } from '@aztec/foundation/log';
4
2
  import { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '@aztec/simulator/client';
5
3
  import { FunctionSelector } from '@aztec/stdlib/abi';
@@ -66,24 +64,20 @@ export async function enrichPublicSimulationError(
66
64
  ) {
67
65
  const callStack = err.getCallStack();
68
66
  const originalFailingFunction = callStack[callStack.length - 1];
69
- // TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Properly fix this.
70
- // To be able to resolve the assertion message, we need to use the information from the public dispatch function,
71
- // no matter what the call stack selector points to (since we've modified it to point to the target function).
72
- // We should remove this because the AVM (or public protocol) shouldn't be aware of the public dispatch calling convention.
73
67
 
74
- const artifact = await contractDataProvider.getFunctionArtifact(
75
- originalFailingFunction.contractAddress,
76
- FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
77
- );
68
+ const artifact = await contractDataProvider.getPublicFunctionArtifact(originalFailingFunction.contractAddress);
69
+ if (!artifact) {
70
+ throw new Error(
71
+ `Artifact not found when enriching public simulation error. Contract address: ${originalFailingFunction.contractAddress}.`,
72
+ );
73
+ }
74
+
78
75
  const assertionMessage = resolveAssertionMessageFromRevertData(err.revertData, artifact);
79
76
  if (assertionMessage) {
80
77
  err.setOriginalMessage(err.getOriginalMessage() + `${assertionMessage}`);
81
78
  }
82
79
 
83
- const debugInfo = await contractDataProvider.getFunctionDebugMetadata(
84
- originalFailingFunction.contractAddress,
85
- FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
86
- );
80
+ const debugInfo = await contractDataProvider.getPublicFunctionDebugMetadata(originalFailingFunction.contractAddress);
87
81
 
88
82
  const noirCallStack = err.getNoirCallStack();
89
83
  if (debugInfo) {
@@ -450,10 +450,8 @@ export class PXEService implements PXE {
450
450
  isContractClassPubliclyRegistered: boolean;
451
451
  artifact: ContractArtifact | undefined;
452
452
  }> {
453
- let artifact;
454
- try {
455
- artifact = await this.contractDataProvider.getContractArtifact(id);
456
- } catch {
453
+ const artifact = await this.contractDataProvider.getContractArtifact(id);
454
+ if (!artifact) {
457
455
  this.log.warn(`No artifact found for contract class ${id.toString()} when looking for its metadata`);
458
456
  }
459
457
 
@@ -572,6 +570,11 @@ export class PXEService implements PXE {
572
570
  } else {
573
571
  // Otherwise, make sure there is an artifact already registered for that class id
574
572
  artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
573
+ if (!artifact) {
574
+ throw new Error(
575
+ `Artifact not found when registering an instance. Contract class: ${instance.currentContractClassId}.`,
576
+ );
577
+ }
575
578
  }
576
579
 
577
580
  await this.contractDataProvider.addContractInstance(instance);
@@ -585,6 +588,9 @@ export class PXEService implements PXE {
585
588
  // class while we're simulating it.
586
589
  return this.#putInJobQueue(async () => {
587
590
  const currentInstance = await this.contractDataProvider.getContractInstance(contractAddress);
591
+ if (!currentInstance) {
592
+ throw new Error(`Instance not found when updating a contract. Contract address: ${contractAddress}.`);
593
+ }
588
594
  const contractClass = await getContractClassFromArtifact(artifact);
589
595
  await this.synchronizer.sync();
590
596
 
@@ -2,9 +2,9 @@ import type { Fr } from '@aztec/foundation/fields';
2
2
  import { toArray } from '@aztec/foundation/iterable';
3
3
  import type { MembershipWitness } from '@aztec/foundation/trees';
4
4
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
5
- import { ContractClassNotFoundError, ContractNotFoundError } from '@aztec/simulator/client';
6
5
  import {
7
6
  type ContractArtifact,
7
+ type FunctionAbi,
8
8
  type FunctionArtifact,
9
9
  type FunctionArtifactWithContractName,
10
10
  type FunctionDebugMetadata,
@@ -19,6 +19,7 @@ import {
19
19
  type ContractClass,
20
20
  type ContractInstanceWithAddress,
21
21
  SerializableContractInstance,
22
+ getContractClassFromArtifact,
22
23
  } from '@aztec/stdlib/contract';
23
24
 
24
25
  import type { DataProvider } from '../data_provider.js';
@@ -33,7 +34,11 @@ import { PrivateFunctionsTree } from './private_functions_tree.js';
33
34
  */
34
35
  export class ContractDataProvider implements DataProvider {
35
36
  /** Map from contract class id to private function tree. */
36
- private contractClassesCache: Map<string, PrivateFunctionsTree> = new Map();
37
+ // TODO: Update it to be LRU cache so that it doesn't keep all the data all the time.
38
+ #privateFunctionTrees: Map<string, PrivateFunctionsTree> = new Map();
39
+
40
+ /** Map from contract address to contract class id */
41
+ #contractClassIdMap: Map<string, Fr> = new Map();
37
42
 
38
43
  #contractArtifacts: AztecAsyncMap<string, Buffer>;
39
44
  #contractInstances: AztecAsyncMap<string, Buffer>;
@@ -66,6 +71,8 @@ export class ContractDataProvider implements DataProvider {
66
71
  }
67
72
 
68
73
  async addContractInstance(contract: ContractInstanceWithAddress): Promise<void> {
74
+ this.#contractClassIdMap.set(contract.address.toString(), contract.currentContractClassId);
75
+
69
76
  await this.#contractInstances.set(
70
77
  contract.address.toString(),
71
78
  new SerializableContractInstance(contract).toBuffer(),
@@ -74,15 +81,15 @@ export class ContractDataProvider implements DataProvider {
74
81
 
75
82
  // Private getters
76
83
 
77
- async #getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
78
- const contract = await this.#contractInstances.getAsync(address.toString());
79
- return contract && SerializableContractInstance.fromBuffer(contract).withAddress(address);
80
- }
81
-
82
- async #getContractArtifact(id: Fr): Promise<ContractArtifact | undefined> {
83
- const contract = await this.#contractArtifacts.getAsync(id.toString());
84
- // TODO(@spalladino): AztecAsyncMap lies and returns Uint8Arrays instead of Buffers, hence the extra Buffer.from.
85
- return contract && contractArtifactFromBuffer(Buffer.from(contract));
84
+ async #getContractClassId(contractAddress: AztecAddress): Promise<Fr | undefined> {
85
+ if (!this.#contractClassIdMap.has(contractAddress.toString())) {
86
+ const instance = await this.getContractInstance(contractAddress);
87
+ if (!instance) {
88
+ return;
89
+ }
90
+ this.#contractClassIdMap.set(contractAddress.toString(), instance.currentContractClassId);
91
+ }
92
+ return this.#contractClassIdMap.get(contractAddress.toString());
86
93
  }
87
94
 
88
95
  /**
@@ -95,31 +102,21 @@ export class ContractDataProvider implements DataProvider {
95
102
  * @returns A ContractTree instance associated with the specified contract address.
96
103
  * @throws An Error if the contract is not found in the ContractDatabase.
97
104
  */
98
- private async getTreeForClassId(classId: Fr): Promise<PrivateFunctionsTree> {
99
- if (!this.contractClassesCache.has(classId.toString())) {
100
- const artifact = await this.#getContractArtifact(classId);
105
+ async #getPrivateFunctionTreeForClassId(classId: Fr): Promise<PrivateFunctionsTree | undefined> {
106
+ if (!this.#privateFunctionTrees.has(classId.toString())) {
107
+ const artifact = await this.getContractArtifact(classId);
101
108
  if (!artifact) {
102
- throw new ContractClassNotFoundError(classId.toString());
109
+ return;
103
110
  }
104
111
  const tree = await PrivateFunctionsTree.create(artifact);
105
- this.contractClassesCache.set(classId.toString(), tree);
112
+ this.#privateFunctionTrees.set(classId.toString(), tree);
106
113
  }
107
- return this.contractClassesCache.get(classId.toString())!;
114
+ return this.#privateFunctionTrees.get(classId.toString())!;
108
115
  }
109
116
 
110
- /**
111
- * Retrieve or create a ContractTree instance based on the provided AztecAddress.
112
- * If an existing tree with the same contract address is found in the cache, it will be returned.
113
- * Otherwise, a new ContractTree instance will be created using the contract data from the database
114
- * and added to the cache before returning.
115
- *
116
- * @param contractAddress - The AztecAddress of the contract for which the ContractTree is required.
117
- * @returns A ContractTree instance associated with the specified contract address.
118
- * @throws An Error if the contract is not found in the ContractDatabase.
119
- */
120
- private async getTreeForAddress(contractAddress: AztecAddress): Promise<PrivateFunctionsTree> {
121
- const instance = await this.getContractInstance(contractAddress);
122
- return this.getTreeForClassId(instance.currentContractClassId);
117
+ async #getContractArtifactByAddress(contractAddress: AztecAddress): Promise<ContractArtifact | undefined> {
118
+ const contractClassId = await this.#getContractClassId(contractAddress);
119
+ return contractClassId && this.getContractArtifact(contractClassId);
123
120
  }
124
121
 
125
122
  // Public getters
@@ -130,32 +127,33 @@ export class ContractDataProvider implements DataProvider {
130
127
  }
131
128
 
132
129
  /** Returns a contract instance for a given address. Throws if not found. */
133
- public async getContractInstance(contractAddress: AztecAddress): Promise<ContractInstanceWithAddress> {
134
- const instance = await this.#getContractInstance(contractAddress);
135
- if (!instance) {
136
- throw new ContractNotFoundError(contractAddress.toString());
137
- }
138
- return instance;
130
+ public async getContractInstance(contractAddress: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
131
+ const contract = await this.#contractInstances.getAsync(contractAddress.toString());
132
+ return contract && SerializableContractInstance.fromBuffer(contract).withAddress(contractAddress);
139
133
  }
140
134
 
141
- public async getContractArtifact(contractClassId: Fr): Promise<ContractArtifact> {
142
- const tree = await this.getTreeForClassId(contractClassId);
143
- return tree.getArtifact();
135
+ public async getContractArtifact(contractClassId: Fr): Promise<ContractArtifact | undefined> {
136
+ const contract = await this.#contractArtifacts.getAsync(contractClassId.toString());
137
+ // TODO(@spalladino): AztecAsyncMap lies and returns Uint8Arrays instead of Buffers, hence the extra Buffer.from.
138
+ return contract && contractArtifactFromBuffer(Buffer.from(contract));
144
139
  }
145
140
 
146
141
  /** Returns a contract class for a given class id. Throws if not found. */
147
- public async getContractClass(contractClassId: Fr): Promise<ContractClass> {
148
- const tree = await this.getTreeForClassId(contractClassId);
149
- return tree.getContractClass();
142
+ public async getContractClass(contractClassId: Fr): Promise<ContractClass | undefined> {
143
+ const artifact = await this.getContractArtifact(contractClassId);
144
+ return artifact && getContractClassFromArtifact(artifact);
150
145
  }
151
146
 
152
147
  public async getContract(
153
148
  address: AztecAddress,
154
149
  ): Promise<(ContractInstanceWithAddress & ContractArtifact) | undefined> {
155
150
  const instance = await this.getContractInstance(address);
156
- const artifact = instance && (await this.getContractArtifact(instance?.currentContractClassId));
157
- if (!instance || !artifact) {
158
- return undefined;
151
+ if (!instance) {
152
+ return;
153
+ }
154
+ const artifact = await this.getContractArtifact(instance.currentContractClassId);
155
+ if (!artifact) {
156
+ return;
159
157
  }
160
158
  return { ...instance, ...artifact };
161
159
  }
@@ -172,14 +170,18 @@ export class ContractDataProvider implements DataProvider {
172
170
  public async getFunctionArtifact(
173
171
  contractAddress: AztecAddress,
174
172
  selector: FunctionSelector,
175
- ): Promise<FunctionArtifactWithContractName> {
176
- const tree = await this.getTreeForAddress(contractAddress);
177
- const contractArtifact = tree.getArtifact();
178
- const functionArtifact = await tree.getFunctionArtifact(selector);
179
- return {
180
- ...functionArtifact,
181
- contractName: contractArtifact.name,
182
- };
173
+ ): Promise<FunctionArtifactWithContractName | undefined> {
174
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
175
+ const fnArtifact = artifact && (await this.#findFunctionArtifactBySelector(artifact, selector));
176
+ return fnArtifact && { ...fnArtifact, contractName: artifact.name };
177
+ }
178
+
179
+ public async getPublicFunctionArtifact(
180
+ contractAddress: AztecAddress,
181
+ ): Promise<FunctionArtifactWithContractName | undefined> {
182
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
183
+ const fnArtifact = artifact && artifact.functions.find(fn => fn.functionType === FunctionType.PUBLIC);
184
+ return fnArtifact && { ...fnArtifact, contractName: artifact.name };
183
185
  }
184
186
 
185
187
  /**
@@ -195,8 +197,16 @@ export class ContractDataProvider implements DataProvider {
195
197
  contractAddress: AztecAddress,
196
198
  functionName: string,
197
199
  ): Promise<FunctionArtifact | undefined> {
198
- const tree = await this.getTreeForAddress(contractAddress);
199
- return tree.getArtifact().functions.find(f => f.name === functionName);
200
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
201
+ return artifact?.functions.find(fn => fn.name === functionName);
202
+ }
203
+
204
+ public async getFunctionAbi(
205
+ contractAddress: AztecAddress,
206
+ selector: FunctionSelector,
207
+ ): Promise<FunctionAbi | undefined> {
208
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
209
+ return artifact && (await this.#findFunctionAbiBySelector(artifact, selector));
200
210
  }
201
211
 
202
212
  /**
@@ -213,24 +223,17 @@ export class ContractDataProvider implements DataProvider {
213
223
  contractAddress: AztecAddress,
214
224
  selector: FunctionSelector,
215
225
  ): Promise<FunctionDebugMetadata | undefined> {
216
- const tree = await this.getTreeForAddress(contractAddress);
217
- const artifact = await tree.getFunctionArtifact(selector);
218
- return getFunctionDebugMetadata(tree.getArtifact(), artifact);
226
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
227
+ const fnArtifact = artifact && (await this.#findFunctionArtifactBySelector(artifact, selector));
228
+ return fnArtifact && getFunctionDebugMetadata(artifact, fnArtifact);
219
229
  }
220
230
 
221
- /**
222
- * Retrieve the bytecode of a specific function in a contract at the given address.
223
- * The returned bytecode is required for executing and verifying the function's behavior
224
- * in the Aztec network. Throws an error if the contract or function cannot be found.
225
- *
226
- * @param contractAddress - The contract's address.
227
- * @param selector - The function selector.
228
- * @returns A Promise that resolves to a Buffer containing the bytecode of the specified function.
229
- * @throws Error if the contract address is unknown or not found.
230
- */
231
- public async getBytecode(contractAddress: AztecAddress, selector: FunctionSelector) {
232
- const tree = await this.getTreeForAddress(contractAddress);
233
- return tree.getBytecode(selector);
231
+ public async getPublicFunctionDebugMetadata(
232
+ contractAddress: AztecAddress,
233
+ ): Promise<FunctionDebugMetadata | undefined> {
234
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
235
+ const fnArtifact = artifact && artifact.functions.find(fn => fn.functionType === FunctionType.PUBLIC);
236
+ return fnArtifact && getFunctionDebugMetadata(artifact, fnArtifact);
234
237
  }
235
238
 
236
239
  /**
@@ -245,21 +248,20 @@ export class ContractDataProvider implements DataProvider {
245
248
  public async getFunctionMembershipWitness(
246
249
  contractClassId: Fr,
247
250
  selector: FunctionSelector,
248
- ): Promise<MembershipWitness<5>> {
249
- const tree = await this.getTreeForClassId(contractClassId);
250
- return tree.getFunctionMembershipWitness(selector);
251
+ ): Promise<MembershipWitness<5> | undefined> {
252
+ const tree = await this.#getPrivateFunctionTreeForClassId(contractClassId);
253
+ return tree?.getFunctionMembershipWitness(selector);
251
254
  }
252
255
 
253
256
  public async getDebugContractName(contractAddress: AztecAddress) {
254
- const tree = await this.getTreeForAddress(contractAddress);
255
- return tree.getArtifact().name;
257
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
258
+ return artifact?.name;
256
259
  }
257
260
 
258
261
  public async getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector) {
259
- const tree = await this.getTreeForAddress(contractAddress);
260
- const { name: contractName } = tree.getArtifact();
261
- const { name: functionName } = await tree.getFunctionArtifact(selector);
262
- return `${contractName}:${functionName}`;
262
+ const artifact = await this.#getContractArtifactByAddress(contractAddress);
263
+ const fnArtifact = artifact && (await this.#findFunctionAbiBySelector(artifact, selector));
264
+ return `${artifact?.name ?? contractAddress}:${fnArtifact?.name ?? selector}`;
263
265
  }
264
266
 
265
267
  public async getSize() {
@@ -267,4 +269,32 @@ export class ContractDataProvider implements DataProvider {
267
269
  .concat(await toArray(this.#contractArtifacts.valuesAsync()))
268
270
  .reduce((sum, value) => sum + value.length, 0);
269
271
  }
272
+
273
+ async #findFunctionArtifactBySelector(
274
+ artifact: ContractArtifact,
275
+ selector: FunctionSelector,
276
+ ): Promise<FunctionArtifact | undefined> {
277
+ const functions = artifact.functions;
278
+ for (let i = 0; i < functions.length; i++) {
279
+ const fn = functions[i];
280
+ const fnSelector = await FunctionSelector.fromNameAndParameters(fn.name, fn.parameters);
281
+ if (fnSelector.equals(selector)) {
282
+ return fn;
283
+ }
284
+ }
285
+ }
286
+
287
+ async #findFunctionAbiBySelector(
288
+ artifact: ContractArtifact,
289
+ selector: FunctionSelector,
290
+ ): Promise<FunctionAbi | undefined> {
291
+ const functions = [...artifact.functions, ...(artifact.nonDispatchPublicFunctions ?? [])];
292
+ for (let i = 0; i < functions.length; i++) {
293
+ const fn = functions[i];
294
+ const fnSelector = await FunctionSelector.fromNameAndParameters(fn.name, fn.parameters);
295
+ if (fnSelector.equals(selector)) {
296
+ return fn;
297
+ }
298
+ }
299
+ }
270
300
  }
@@ -1,2 +1 @@
1
1
  export { ContractDataProvider } from './contract_data_provider.js';
2
- export { PrivateFunctionsTree } from './private_functions_tree.js';
@@ -2,12 +2,12 @@ import { FUNCTION_TREE_HEIGHT } from '@aztec/constants';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
3
  import { assertLength } from '@aztec/foundation/serialize';
4
4
  import { MembershipWitness, type MerkleTree } from '@aztec/foundation/trees';
5
- import { type ContractArtifact, type FunctionArtifact, FunctionSelector } from '@aztec/stdlib/abi';
5
+ import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
6
6
  import {
7
- type ContractClassWithId,
7
+ type PrivateFunction,
8
8
  computePrivateFunctionLeaf,
9
9
  computePrivateFunctionsTree,
10
- getContractClassFromArtifact,
10
+ getContractClassPrivateFunctionFromArtifact,
11
11
  } from '@aztec/stdlib/contract';
12
12
 
13
13
  /**
@@ -19,78 +19,15 @@ import {
19
19
  export class PrivateFunctionsTree {
20
20
  private tree?: MerkleTree;
21
21
 
22
- private constructor(private readonly artifact: ContractArtifact, private contractClass: ContractClassWithId) {}
22
+ private constructor(private readonly privateFunctions: PrivateFunction[]) {}
23
23
 
24
24
  static async create(artifact: ContractArtifact) {
25
- const contractClass = await getContractClassFromArtifact(artifact);
26
- return new PrivateFunctionsTree(artifact, contractClass);
27
- }
28
-
29
- /**
30
- * Retrieve the artifact of a given function.
31
- * The function is identified by its selector, which represents a unique identifier for the function's signature.
32
- * Throws an error if the function with the provided selector is not found in the contract.
33
- *
34
- * @param selector - The function selector.
35
- * @returns The artifact object containing relevant information about the targeted function.
36
- */
37
- public async getFunctionArtifact(selector: FunctionSelector): Promise<FunctionArtifact> {
38
- const functionsAndSelectors = await Promise.all(
39
- this.artifact.functions.map(async f => ({
40
- f,
41
- selector: await FunctionSelector.fromNameAndParameters(f.name, f.parameters),
42
- })),
25
+ const privateFunctions = await Promise.all(
26
+ artifact.functions
27
+ .filter(fn => fn.functionType === FunctionType.PRIVATE)
28
+ .map(getContractClassPrivateFunctionFromArtifact),
43
29
  );
44
- const artifact = functionsAndSelectors.find(f => selector.equals(f.selector))?.f;
45
- if (!artifact) {
46
- throw new Error(
47
- `Unknown function. Selector ${selector.toString()} not found in the artifact ${
48
- this.artifact.name
49
- } with class ${this.getContractClassId().toString()}.`,
50
- );
51
- }
52
- return artifact;
53
- }
54
-
55
- /**
56
- * Retrieve the bytecode of a function in the contract by its function selector.
57
- * The function selector is a unique identifier for each function in a contract.
58
- * Throws an error if the function with the given selector is not found in the contract.
59
- *
60
- * @param selector - The selector of a function to get bytecode for.
61
- * @returns The bytecode of the function as a string.
62
- */
63
- public async getBytecode(selector: FunctionSelector) {
64
- const artifact = await this.getFunctionArtifact(selector);
65
- return artifact.bytecode;
66
- }
67
-
68
- /**
69
- * Calculate and return the root of the function tree for the current contract.
70
- * This root is a cryptographic commitment to the set of constrained functions within the contract,
71
- * which is used in the Aztec node's proof system. The root will be cached after the first call.
72
- *
73
- * @returns A promise that resolves to the Fr (finite field element) representation of the function tree root.
74
- */
75
- public getFunctionTreeRoot() {
76
- return this.getTree();
77
- }
78
-
79
- /** Returns the contract class object. */
80
- public getContractClass() {
81
- return this.contractClass;
82
- }
83
-
84
- /** Returns the contract artifact. */
85
- public getArtifact() {
86
- return this.artifact;
87
- }
88
-
89
- /**
90
- * Returns the contract class identifier for the given artifact.
91
- */
92
- public getContractClassId() {
93
- return this.getContractClass().id;
30
+ return new PrivateFunctionsTree(privateFunctions);
94
31
  }
95
32
 
96
33
  /**
@@ -105,7 +42,7 @@ export class PrivateFunctionsTree {
105
42
  public async getFunctionMembershipWitness(
106
43
  selector: FunctionSelector,
107
44
  ): Promise<MembershipWitness<typeof FUNCTION_TREE_HEIGHT>> {
108
- const fn = this.getContractClass().privateFunctions.find(f => f.selector.equals(selector));
45
+ const fn = this.privateFunctions.find(f => f.selector.equals(selector));
109
46
  if (!fn) {
110
47
  throw new Error(`Private function with selector ${selector.toString()} not found in contract class.`);
111
48
  }
@@ -123,8 +60,7 @@ export class PrivateFunctionsTree {
123
60
 
124
61
  private async getTree() {
125
62
  if (!this.tree) {
126
- const fns = this.getContractClass().privateFunctions;
127
- this.tree = await computePrivateFunctionsTree(fns);
63
+ this.tree = await computePrivateFunctionsTree(this.privateFunctions);
128
64
  }
129
65
  return this.tree;
130
66
  }
@@ -81,7 +81,9 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
81
81
 
82
82
  it('refuses to register a contract with a class that has not been registered', async () => {
83
83
  const instance = await randomContractInstanceWithAddress();
84
- await expect(pxe.registerContract({ instance })).rejects.toThrow(/DB has no contract class with id/i);
84
+ await expect(pxe.registerContract({ instance })).rejects.toThrow(
85
+ /Artifact not found when registering an instance/,
86
+ );
85
87
  });
86
88
 
87
89
  it('refuses to register a contract with an artifact with mismatching class id', async () => {