@aztec/pxe 0.81.0 → 0.82.0

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 (72) hide show
  1. package/dest/config/package_info.js +1 -1
  2. package/dest/entrypoints/server/utils.d.ts +15 -7
  3. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  4. package/dest/entrypoints/server/utils.js +17 -9
  5. package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.d.ts +2 -2
  6. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -0
  7. package/dest/private_kernel/hints/index.d.ts.map +1 -0
  8. package/dest/private_kernel/index.d.ts +3 -0
  9. package/dest/private_kernel/index.d.ts.map +1 -0
  10. package/dest/private_kernel/index.js +2 -0
  11. package/dest/{kernel_prover/kernel_prover.d.ts → private_kernel/private_kernel_execution_prover.d.ts} +13 -14
  12. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -0
  13. package/dest/{kernel_prover/kernel_prover.js → private_kernel/private_kernel_execution_prover.js} +64 -64
  14. package/dest/{kernel_prover/proving_data_oracle.d.ts → private_kernel/private_kernel_oracle.d.ts} +17 -28
  15. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -0
  16. package/dest/private_kernel/private_kernel_oracle.js +4 -0
  17. package/dest/{kernel_oracle/index.d.ts → private_kernel/private_kernel_oracle_impl.d.ts} +5 -5
  18. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -0
  19. package/dest/{kernel_oracle/index.js → private_kernel/private_kernel_oracle_impl.js} +2 -2
  20. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +7 -16
  21. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
  22. package/dest/pxe_oracle_interface/pxe_oracle_interface.js +11 -32
  23. package/dest/pxe_service/pxe_service.d.ts +13 -27
  24. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  25. package/dest/pxe_service/pxe_service.js +207 -235
  26. package/dest/storage/contract_data_provider/contract_data_provider.d.ts +2 -2
  27. package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
  28. package/dest/storage/contract_data_provider/contract_data_provider.js +6 -1
  29. package/dest/storage/contract_data_provider/private_functions_tree.d.ts +2 -2
  30. package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
  31. package/dest/storage/index.d.ts +1 -2
  32. package/dest/storage/index.d.ts.map +1 -1
  33. package/dest/storage/index.js +1 -2
  34. package/dest/storage/metadata.d.ts +2 -0
  35. package/dest/storage/metadata.d.ts.map +1 -0
  36. package/dest/storage/metadata.js +1 -0
  37. package/package.json +15 -15
  38. package/src/config/package_info.ts +1 -1
  39. package/src/entrypoints/server/utils.ts +25 -11
  40. package/src/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.ts +4 -4
  41. package/src/private_kernel/index.ts +2 -0
  42. package/src/{kernel_prover/kernel_prover.ts → private_kernel/private_kernel_execution_prover.ts} +76 -71
  43. package/src/{kernel_prover/proving_data_oracle.ts → private_kernel/private_kernel_oracle.ts} +17 -29
  44. package/src/{kernel_oracle/index.ts → private_kernel/private_kernel_oracle_impl.ts} +6 -5
  45. package/src/pxe_oracle_interface/pxe_oracle_interface.ts +25 -40
  46. package/src/pxe_service/pxe_service.ts +279 -293
  47. package/src/storage/contract_data_provider/contract_data_provider.ts +11 -2
  48. package/src/storage/contract_data_provider/private_functions_tree.ts +2 -2
  49. package/src/storage/index.ts +1 -3
  50. package/src/storage/metadata.ts +1 -0
  51. package/dest/kernel_oracle/index.d.ts.map +0 -1
  52. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
  53. package/dest/kernel_prover/hints/index.d.ts.map +0 -1
  54. package/dest/kernel_prover/index.d.ts +0 -3
  55. package/dest/kernel_prover/index.d.ts.map +0 -1
  56. package/dest/kernel_prover/index.js +0 -2
  57. package/dest/kernel_prover/kernel_prover.d.ts.map +0 -1
  58. package/dest/kernel_prover/proving_data_oracle.d.ts.map +0 -1
  59. package/dest/kernel_prover/proving_data_oracle.js +0 -4
  60. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts +0 -11
  61. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts.map +0 -1
  62. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.js +0 -20
  63. package/dest/storage/auth_witness_data_provider/index.d.ts +0 -2
  64. package/dest/storage/auth_witness_data_provider/index.d.ts.map +0 -1
  65. package/dest/storage/auth_witness_data_provider/index.js +0 -1
  66. package/src/kernel_prover/index.ts +0 -2
  67. package/src/storage/auth_witness_data_provider/auth_witness_data_provider.ts +0 -34
  68. package/src/storage/auth_witness_data_provider/index.ts +0 -1
  69. /package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.js +0 -0
  70. /package/dest/{kernel_prover → private_kernel}/hints/index.d.ts +0 -0
  71. /package/dest/{kernel_prover → private_kernel}/hints/index.js +0 -0
  72. /package/src/{kernel_prover → private_kernel}/hints/index.ts +0 -0
@@ -48,7 +48,7 @@ import type {
48
48
  PXEInfo,
49
49
  PrivateKernelProver,
50
50
  } from '@aztec/stdlib/interfaces/client';
51
- import { type PrivateKernelSimulateOutput, PrivateKernelTailCircuitPublicInputs } from '@aztec/stdlib/kernel';
51
+ import type { PrivateKernelExecutionProofOutput, PrivateKernelTailCircuitPublicInputs } from '@aztec/stdlib/kernel';
52
52
  import { computeAddressSecret } from '@aztec/stdlib/keys';
53
53
  import type { LogFilter } from '@aztec/stdlib/logs';
54
54
  import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
@@ -57,11 +57,12 @@ import { MerkleTreeId } from '@aztec/stdlib/trees';
57
57
  import {
58
58
  PrivateExecutionResult,
59
59
  PrivateSimulationResult,
60
- type PublicSimulationOutput,
61
- type Tx,
60
+ PublicSimulationOutput,
61
+ Tx,
62
62
  type TxEffect,
63
- type TxExecutionRequest,
63
+ TxExecutionRequest,
64
64
  type TxHash,
65
+ TxProfileResult,
65
66
  TxProvingResult,
66
67
  type TxReceipt,
67
68
  TxSimulationResult,
@@ -71,11 +72,13 @@ import { inspect } from 'util';
71
72
 
72
73
  import type { PXEServiceConfig } from '../config/index.js';
73
74
  import { getPackageInfo } from '../config/package_info.js';
74
- import { KernelOracle } from '../kernel_oracle/index.js';
75
- import { KernelProver, type ProvingConfig } from '../kernel_prover/kernel_prover.js';
75
+ import {
76
+ PrivateKernelExecutionProver,
77
+ type PrivateKernelExecutionProverConfig,
78
+ } from '../private_kernel/private_kernel_execution_prover.js';
79
+ import { PrivateKernelOracleImpl } from '../private_kernel/private_kernel_oracle_impl.js';
76
80
  import { PXEOracleInterface } from '../pxe_oracle_interface/pxe_oracle_interface.js';
77
81
  import { AddressDataProvider } from '../storage/address_data_provider/address_data_provider.js';
78
- import { AuthWitnessDataProvider } from '../storage/auth_witness_data_provider/auth_witness_data_provider.js';
79
82
  import { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
80
83
  import { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
81
84
  import { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
@@ -98,7 +101,6 @@ export class PXEService implements PXE {
98
101
  private syncDataProvider: SyncDataProvider,
99
102
  private taggingDataProvider: TaggingDataProvider,
100
103
  private addressDataProvider: AddressDataProvider,
101
- private authWitnessDataProvider: AuthWitnessDataProvider,
102
104
  private simulator: AcirSimulator,
103
105
  private packageVersion: string,
104
106
  private proverEnabled: boolean,
@@ -132,7 +134,6 @@ export class PXEService implements PXE {
132
134
  const packageVersion = getPackageInfo().version;
133
135
  const proverEnabled = !!config.proverEnabled;
134
136
  const addressDataProvider = new AddressDataProvider(store);
135
- const authWitnessDataProvider = new AuthWitnessDataProvider(store);
136
137
  const contractDataProvider = new ContractDataProvider(store);
137
138
  const noteDataProvider = await NoteDataProvider.create(store);
138
139
  const syncDataProvider = new SyncDataProvider(store);
@@ -159,7 +160,6 @@ export class PXEService implements PXE {
159
160
  syncDataProvider,
160
161
  taggingDataProvider,
161
162
  addressDataProvider,
162
- authWitnessDataProvider,
163
163
  log,
164
164
  );
165
165
  const simulator = new AcirSimulator(pxeOracleInterface, simulationProvider);
@@ -175,7 +175,6 @@ export class PXEService implements PXE {
175
175
  syncDataProvider,
176
176
  taggingDataProvider,
177
177
  addressDataProvider,
178
- authWitnessDataProvider,
179
178
  simulator,
180
179
  packageVersion,
181
180
  proverEnabled,
@@ -193,6 +192,68 @@ export class PXEService implements PXE {
193
192
  return pxeService;
194
193
  }
195
194
 
195
+ // Aztec node proxy methods
196
+
197
+ public isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean> {
198
+ return this.node.isL1ToL2MessageSynced(l1ToL2Message);
199
+ }
200
+
201
+ public getL2ToL1MembershipWitness(blockNumber: number, l2Tol1Message: Fr): Promise<[bigint, SiblingPath<number>]> {
202
+ return this.node.getL2ToL1MessageMembershipWitness(blockNumber, l2Tol1Message);
203
+ }
204
+
205
+ public getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
206
+ return this.node.getTxReceipt(txHash);
207
+ }
208
+
209
+ public getTxEffect(txHash: TxHash): Promise<InBlock<TxEffect> | undefined> {
210
+ return this.node.getTxEffect(txHash);
211
+ }
212
+
213
+ public getBlockNumber(): Promise<number> {
214
+ return this.node.getBlockNumber();
215
+ }
216
+
217
+ public getProvenBlockNumber(): Promise<number> {
218
+ return this.node.getProvenBlockNumber();
219
+ }
220
+
221
+ public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
222
+ return this.node.getPublicLogs(filter);
223
+ }
224
+
225
+ public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
226
+ return this.node.getContractClassLogs(filter);
227
+ }
228
+
229
+ public getPublicStorageAt(contract: AztecAddress, slot: Fr) {
230
+ return this.node.getPublicStorageAt('latest', contract, slot);
231
+ }
232
+
233
+ public async getL1ToL2MembershipWitness(
234
+ contractAddress: AztecAddress,
235
+ messageHash: Fr,
236
+ secret: Fr,
237
+ ): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>]> {
238
+ return await getNonNullifiedL1ToL2MessageWitness(this.node, contractAddress, messageHash, secret);
239
+ }
240
+
241
+ // Internal methods
242
+
243
+ #contextualizeError(err: Error, ...context: string[]): Error {
244
+ let contextStr = '';
245
+ if (context.length > 0) {
246
+ contextStr = `\nContext:\n${context.join('\n')}`;
247
+ }
248
+ if (err instanceof SimulationError) {
249
+ err.setAztecContext(contextStr);
250
+ } else {
251
+ this.log.error(err.name, err);
252
+ this.log.debug(contextStr);
253
+ }
254
+ return err;
255
+ }
256
+
196
257
  /**
197
258
  * Enqueues a job for execution once no other jobs are running. Returns a promise that will resolve once the job is
198
259
  * complete.
@@ -210,16 +271,164 @@ export class PXEService implements PXE {
210
271
  return this.jobQueue.put(fn);
211
272
  }
212
273
 
213
- isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean> {
214
- return this.node.isL1ToL2MessageSynced(l1ToL2Message);
274
+ async #registerProtocolContracts() {
275
+ const registered: Record<string, string> = {};
276
+ for (const name of protocolContractNames) {
277
+ const { address, contractClass, instance, artifact } =
278
+ await this.protocolContractsProvider.getProtocolContractArtifact(name);
279
+ await this.contractDataProvider.addContractArtifact(contractClass.id, artifact);
280
+ await this.contractDataProvider.addContractInstance(instance);
281
+ registered[name] = address.toString();
282
+ }
283
+ this.log.verbose(`Registered protocol contracts in pxe`, registered);
284
+ }
285
+
286
+ async #isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
287
+ return !!(await this.node.getContractClass(id));
215
288
  }
216
289
 
290
+ async #isContractPubliclyDeployed(address: AztecAddress): Promise<boolean> {
291
+ return !!(await this.node.getContract(address));
292
+ }
293
+
294
+ async #isContractInitialized(address: AztecAddress): Promise<boolean> {
295
+ const initNullifier = await siloNullifier(address, address.toField());
296
+ return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
297
+ }
298
+
299
+ async #getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall> {
300
+ const contract = await this.contractDataProvider.getContract(to);
301
+ if (!contract) {
302
+ throw new Error(
303
+ `Unknown contract ${to}: add it to PXE Service by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/reference/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
304
+ );
305
+ }
306
+
307
+ const functionDao = contract.functions.find(f => f.name === functionName);
308
+ if (!functionDao) {
309
+ throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
310
+ }
311
+
312
+ return {
313
+ name: functionDao.name,
314
+ args: encodeArguments(functionDao, args),
315
+ selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
316
+ type: functionDao.functionType,
317
+ to,
318
+ isStatic: functionDao.isStatic,
319
+ returnTypes: functionDao.returnTypes,
320
+ };
321
+ }
322
+
323
+ async #executePrivate(
324
+ txRequest: TxExecutionRequest,
325
+ msgSender?: AztecAddress,
326
+ scopes?: AztecAddress[],
327
+ ): Promise<PrivateExecutionResult> {
328
+ const { origin: contractAddress, functionSelector } = txRequest;
329
+
330
+ try {
331
+ const result = await this.simulator.run(txRequest, contractAddress, functionSelector, msgSender, scopes);
332
+ this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
333
+ return result;
334
+ } catch (err) {
335
+ if (err instanceof SimulationError) {
336
+ await enrichSimulationError(err, this.contractDataProvider, this.log);
337
+ }
338
+ throw err;
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Simulate an unconstrained transaction on the given contract, without considering constraints set by ACIR.
344
+ * The simulation parameters are fetched using ContractDataProvider and executed using AcirSimulator.
345
+ * Returns the simulation result containing the outputs of the unconstrained function.
346
+ *
347
+ * @param execRequest - The transaction request object containing the target contract and function data.
348
+ * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
349
+ * @returns The simulation result containing the outputs of the unconstrained function.
350
+ */
351
+ async #simulateUnconstrained(execRequest: FunctionCall, authWitnesses?: AuthWitness[], scopes?: AztecAddress[]) {
352
+ const { to: contractAddress, selector: functionSelector } = execRequest;
353
+
354
+ this.log.debug('Executing unconstrained simulator...');
355
+ try {
356
+ const result = await this.simulator.runUnconstrained(
357
+ execRequest,
358
+ contractAddress,
359
+ functionSelector,
360
+ authWitnesses ?? [],
361
+ scopes,
362
+ );
363
+ this.log.verbose(`Unconstrained simulation for ${contractAddress}.${functionSelector} completed`);
364
+
365
+ return result;
366
+ } catch (err) {
367
+ if (err instanceof SimulationError) {
368
+ await enrichSimulationError(err, this.contractDataProvider, this.log);
369
+ }
370
+ throw err;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Simulate the public part of a transaction.
376
+ * This allows to catch public execution errors before submitting the transaction.
377
+ * It can also be used for estimating gas in the future.
378
+ * @param tx - The transaction to be simulated.
379
+ */
380
+ async #simulatePublicCalls(tx: Tx, skipFeeEnforcement: boolean) {
381
+ // Simulating public calls can throw if the TX fails in a phase that doesn't allow reverts (setup)
382
+ // Or return as reverted if it fails in a phase that allows reverts (app logic, teardown)
383
+ try {
384
+ const result = await this.node.simulatePublicCalls(tx, skipFeeEnforcement);
385
+ if (result.revertReason) {
386
+ throw result.revertReason;
387
+ }
388
+ return result;
389
+ } catch (err) {
390
+ if (err instanceof SimulationError) {
391
+ try {
392
+ await enrichPublicSimulationError(err, this.contractDataProvider, this.log);
393
+ } catch (enrichErr) {
394
+ this.log.error(`Failed to enrich public simulation error: ${enrichErr}`);
395
+ }
396
+ }
397
+ throw err;
398
+ }
399
+ }
400
+
401
+ /**
402
+ * Generate a kernel proof, and create a private kernel output.
403
+ * The function takes in a transaction execution request, and the result of private execution
404
+ * and then generates a kernel proof.
405
+ *
406
+ * @param txExecutionRequest - The transaction request to be simulated and proved.
407
+ * @param proofCreator - The proof creator to use for proving the execution.
408
+ * @param privateExecutionResult - The result of the private execution
409
+ * @param config - The configuration for the kernel execution prover.
410
+ * @returns An object that contains the output of the kernel execution, including the ClientIvcProof if proving is enabled.
411
+ */
412
+ async #prove(
413
+ txExecutionRequest: TxExecutionRequest,
414
+ proofCreator: PrivateKernelProver,
415
+ privateExecutionResult: PrivateExecutionResult,
416
+ config: PrivateKernelExecutionProverConfig,
417
+ ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
418
+ const block = privateExecutionResult.getSimulationBlockNumber();
419
+ const kernelOracle = new PrivateKernelOracleImpl(this.contractDataProvider, this.keyStore, this.node, block);
420
+ const kernelTraceProver = new PrivateKernelExecutionProver(kernelOracle, proofCreator, !this.proverEnabled);
421
+ this.log.debug(`Executing kernel trace prover (${JSON.stringify(config)})...`);
422
+ return await kernelTraceProver.proveWithKernels(txExecutionRequest.toTxRequest(), privateExecutionResult, config);
423
+ }
424
+
425
+ // Public API
426
+
217
427
  /** Returns an estimate of the db size in bytes. */
218
428
  public async estimateDbSize() {
219
429
  const treeRootsSize = Object.keys(MerkleTreeId).length * Fr.SIZE_IN_BYTES;
220
430
  const dbSizes = await Promise.all([
221
431
  this.addressDataProvider.getSize(),
222
- this.authWitnessDataProvider.getSize(),
223
432
  this.capsuleDataProvider.getSize(),
224
433
  this.contractDataProvider.getSize(),
225
434
  this.noteDataProvider.getSize(),
@@ -229,18 +438,6 @@ export class PXEService implements PXE {
229
438
  return [...dbSizes, treeRootsSize].reduce((sum, size) => sum + size, 0);
230
439
  }
231
440
 
232
- public addAuthWitness(witness: AuthWitness) {
233
- return this.authWitnessDataProvider.addAuthWitness(witness.requestHash, witness.witness);
234
- }
235
-
236
- public getAuthWitness(messageHash: Fr): Promise<Fr[] | undefined> {
237
- return this.authWitnessDataProvider.getAuthWitness(messageHash);
238
- }
239
-
240
- public storeCapsule(contract: AztecAddress, storageSlot: Fr, capsule: Fr[]) {
241
- return this.capsuleDataProvider.storeCapsule(contract, storageSlot, capsule);
242
- }
243
-
244
441
  public getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
245
442
  return this.contractDataProvider.getContractInstance(address);
246
443
  }
@@ -320,9 +517,7 @@ export class PXEService implements PXE {
320
517
  }
321
518
 
322
519
  public getSenders(): Promise<AztecAddress[]> {
323
- const senders = this.taggingDataProvider.getSenderAddresses();
324
-
325
- return Promise.resolve(senders);
520
+ return this.taggingDataProvider.getSenderAddresses();
326
521
  }
327
522
 
328
523
  public async removeSender(address: AztecAddress): Promise<void> {
@@ -333,8 +528,6 @@ export class PXEService implements PXE {
333
528
  } else {
334
529
  this.log.info(`Sender:\n "${address.toString()}"\n not in address book.`);
335
530
  }
336
-
337
- return Promise.resolve();
338
531
  }
339
532
 
340
533
  public async getRegisteredAccounts(): Promise<CompleteAddress[]> {
@@ -376,9 +569,6 @@ export class PXEService implements PXE {
376
569
  .filter(fn => fn.functionType === FunctionType.PUBLIC)
377
570
  .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
378
571
  await this.node.registerContractFunctionSignatures(instance.address, publicFunctionSignatures);
379
-
380
- // TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
381
- await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
382
572
  } else {
383
573
  // Otherwise, make sure there is an artifact already registered for that class id
384
574
  artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
@@ -417,8 +607,6 @@ export class PXEService implements PXE {
417
607
  .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
418
608
  await this.node.registerContractFunctionSignatures(contractAddress, publicFunctionSignatures);
419
609
 
420
- // TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
421
- await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
422
610
  currentInstance.currentContractClassId = contractClass.id;
423
611
  await this.contractDataProvider.addContractInstance(currentInstance);
424
612
  this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
@@ -429,10 +617,6 @@ export class PXEService implements PXE {
429
617
  return this.contractDataProvider.getContractsAddresses();
430
618
  }
431
619
 
432
- public async getPublicStorageAt(contract: AztecAddress, slot: Fr) {
433
- return await this.node.getPublicStorageAt('latest', contract, slot);
434
- }
435
-
436
620
  public async getNotes(filter: NotesFilter): Promise<UniqueNote[]> {
437
621
  const noteDaos = await this.noteDataProvider.getNotes(filter);
438
622
 
@@ -454,18 +638,6 @@ export class PXEService implements PXE {
454
638
  return Promise.all(extendedNotes);
455
639
  }
456
640
 
457
- public async getL1ToL2MembershipWitness(
458
- contractAddress: AztecAddress,
459
- messageHash: Fr,
460
- secret: Fr,
461
- ): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>]> {
462
- return await getNonNullifiedL1ToL2MessageWitness(this.node, contractAddress, messageHash, secret);
463
- }
464
-
465
- public getL2ToL1MembershipWitness(blockNumber: number, l2Tol1Message: Fr): Promise<[bigint, SiblingPath<number>]> {
466
- return this.node.getL2ToL1MessageMembershipWitness(blockNumber, l2Tol1Message);
467
- }
468
-
469
641
  public async getBlock(blockNumber: number): Promise<L2Block | undefined> {
470
642
  // If a negative block number is provided the current block number is fetched.
471
643
  if (blockNumber < 0) {
@@ -493,12 +665,54 @@ export class PXEService implements PXE {
493
665
  {
494
666
  simulate: false,
495
667
  skipFeeEnforcement: false,
496
- profile: false,
668
+ profileMode: 'none',
497
669
  },
498
670
  );
499
671
  return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
500
672
  } catch (err: any) {
501
- throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
673
+ throw this.#contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
674
+ }
675
+ });
676
+ }
677
+
678
+ public profileTx(
679
+ txRequest: TxExecutionRequest,
680
+ profileMode: 'full' | 'execution-steps' | 'gates',
681
+ msgSender?: AztecAddress,
682
+ ): Promise<TxProfileResult> {
683
+ // We disable concurrent profiles for consistency with simulateTx.
684
+ return this.#putInJobQueue(async () => {
685
+ try {
686
+ const txInfo = {
687
+ origin: txRequest.origin,
688
+ functionSelector: txRequest.functionSelector,
689
+ simulatePublic: false,
690
+ msgSender,
691
+ chainId: txRequest.txContext.chainId,
692
+ version: txRequest.txContext.version,
693
+ authWitnesses: txRequest.authWitnesses.map(w => w.requestHash),
694
+ };
695
+ this.log.info(
696
+ `Profiling transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
697
+ txInfo,
698
+ );
699
+ await this.synchronizer.sync();
700
+ const privateExecutionResult = await this.#executePrivate(txRequest, msgSender);
701
+
702
+ const { executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
703
+ simulate: true,
704
+ skipFeeEnforcement: false,
705
+ profileMode,
706
+ });
707
+
708
+ return new TxProfileResult(executionSteps);
709
+ } catch (err: any) {
710
+ throw this.#contextualizeError(
711
+ err,
712
+ inspect(txRequest),
713
+ `profileMode=${profileMode}`,
714
+ `msgSender=${msgSender?.toString() ?? 'undefined'}`,
715
+ );
502
716
  }
503
717
  });
504
718
  }
@@ -510,7 +724,6 @@ export class PXEService implements PXE {
510
724
  msgSender: AztecAddress | undefined = undefined,
511
725
  skipTxValidation: boolean = false,
512
726
  skipFeeEnforcement: boolean = false,
513
- profile: boolean = false,
514
727
  scopes?: AztecAddress[],
515
728
  ): Promise<TxSimulationResult> {
516
729
  // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
@@ -535,16 +748,11 @@ export class PXEService implements PXE {
535
748
  await this.synchronizer.sync();
536
749
  const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
537
750
 
538
- const { publicInputs, profileResult } = await this.#prove(
539
- txRequest,
540
- this.proofCreator,
541
- privateExecutionResult,
542
- {
543
- simulate: !profile,
544
- skipFeeEnforcement,
545
- profile,
546
- },
547
- );
751
+ const { publicInputs } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
752
+ simulate: true,
753
+ skipFeeEnforcement,
754
+ profileMode: 'none',
755
+ });
548
756
 
549
757
  const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
550
758
  const simulatedTx = privateSimulationResult.toSimulatedTx();
@@ -564,7 +772,6 @@ export class PXEService implements PXE {
564
772
  this.log.info(`Simulation completed for ${txHash.toString()} in ${timer.ms()}ms`, {
565
773
  txHash,
566
774
  ...txInfo,
567
- ...(profileResult ? { gateCounts: profileResult.gateCounts } : {}),
568
775
  ...(publicOutput
569
776
  ? {
570
777
  gasUsed: publicOutput.gasUsed,
@@ -574,19 +781,14 @@ export class PXEService implements PXE {
574
781
  : {}),
575
782
  });
576
783
 
577
- return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(
578
- privateSimulationResult,
579
- publicOutput,
580
- profileResult,
581
- );
784
+ return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput);
582
785
  } catch (err: any) {
583
- throw this.contextualizeError(
786
+ throw this.#contextualizeError(
584
787
  err,
585
788
  inspect(txRequest),
586
789
  `simulatePublic=${simulatePublic}`,
587
790
  `msgSender=${msgSender?.toString() ?? 'undefined'}`,
588
791
  `skipTxValidation=${skipTxValidation}`,
589
- `profile=${profile}`,
590
792
  `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
591
793
  );
592
794
  }
@@ -600,7 +802,7 @@ export class PXEService implements PXE {
600
802
  }
601
803
  this.log.debug(`Sending transaction ${txHash}`);
602
804
  await this.node.sendTx(tx).catch(err => {
603
- throw this.contextualizeError(err, inspect(tx));
805
+ throw this.#contextualizeError(err, inspect(tx));
604
806
  });
605
807
  this.log.info(`Sent transaction ${txHash}`);
606
808
  return txHash;
@@ -610,6 +812,7 @@ export class PXEService implements PXE {
610
812
  functionName: string,
611
813
  args: any[],
612
814
  to: AztecAddress,
815
+ authwits?: AuthWitness[],
613
816
  _from?: AztecAddress,
614
817
  scopes?: AztecAddress[],
615
818
  ): Promise<AbiDecoded> {
@@ -621,13 +824,13 @@ export class PXEService implements PXE {
621
824
  await this.synchronizer.sync();
622
825
  // TODO - Should check if `from` has the permission to call the view function.
623
826
  const functionCall = await this.#getFunctionCall(functionName, args, to);
624
- const executionResult = await this.#simulateUnconstrained(functionCall, scopes);
827
+ const executionResult = await this.#simulateUnconstrained(functionCall, authwits ?? [], scopes);
625
828
 
626
829
  // TODO - Return typed result based on the function artifact.
627
830
  return executionResult;
628
831
  } catch (err: any) {
629
832
  const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
630
- throw this.contextualizeError(
833
+ throw this.#contextualizeError(
631
834
  err,
632
835
  `simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`,
633
836
  `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
@@ -636,64 +839,6 @@ export class PXEService implements PXE {
636
839
  });
637
840
  }
638
841
 
639
- public getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
640
- return this.node.getTxReceipt(txHash);
641
- }
642
-
643
- public getTxEffect(txHash: TxHash): Promise<InBlock<TxEffect> | undefined> {
644
- return this.node.getTxEffect(txHash);
645
- }
646
-
647
- public async getBlockNumber(): Promise<number> {
648
- return await this.node.getBlockNumber();
649
- }
650
-
651
- public async getProvenBlockNumber(): Promise<number> {
652
- return await this.node.getProvenBlockNumber();
653
- }
654
-
655
- /**
656
- * Gets public logs based on the provided filter.
657
- * @param filter - The filter to apply to the logs.
658
- * @returns The requested logs.
659
- */
660
- public getPublicLogs(filter: LogFilter): Promise<GetPublicLogsResponse> {
661
- return this.node.getPublicLogs(filter);
662
- }
663
-
664
- /**
665
- * Gets contract class logs based on the provided filter.
666
- * @param filter - The filter to apply to the logs.
667
- * @returns The requested logs.
668
- */
669
- public getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse> {
670
- return this.node.getContractClassLogs(filter);
671
- }
672
-
673
- async #getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall> {
674
- const contract = await this.contractDataProvider.getContract(to);
675
- if (!contract) {
676
- throw new Error(
677
- `Unknown contract ${to}: add it to PXE Service by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/reference/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
678
- );
679
- }
680
-
681
- const functionDao = contract.functions.find(f => f.name === functionName);
682
- if (!functionDao) {
683
- throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
684
- }
685
-
686
- return {
687
- name: functionDao.name,
688
- args: encodeArguments(functionDao, args),
689
- selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
690
- type: functionDao.functionType,
691
- to,
692
- isStatic: functionDao.isStatic,
693
- returnTypes: functionDao.returnTypes,
694
- };
695
- }
696
-
697
842
  public async getNodeInfo(): Promise<NodeInfo> {
698
843
  const [nodeVersion, protocolVersion, chainId, enr, contractAddresses, protocolContractAddresses] =
699
844
  await Promise.all([
@@ -729,151 +874,6 @@ export class PXEService implements PXE {
729
874
  });
730
875
  }
731
876
 
732
- async #registerProtocolContracts() {
733
- const registered: Record<string, string> = {};
734
- for (const name of protocolContractNames) {
735
- const { address, contractClass, instance, artifact } =
736
- await this.protocolContractsProvider.getProtocolContractArtifact(name);
737
- await this.contractDataProvider.addContractArtifact(contractClass.id, artifact);
738
- await this.contractDataProvider.addContractInstance(instance);
739
- registered[name] = address.toString();
740
- }
741
- this.log.verbose(`Registered protocol contracts in pxe`, registered);
742
- }
743
-
744
- /**
745
- * Retrieves the simulation parameters required to run an ACIR simulation.
746
- * This includes the contract address, function artifact, and historical tree roots.
747
- *
748
- * @param execRequest - The transaction request object containing details of the contract call.
749
- * @returns An object containing the contract address, function artifact, and historical tree roots.
750
- */
751
- #getSimulationParameters(execRequest: FunctionCall | TxExecutionRequest) {
752
- const contractAddress = (execRequest as FunctionCall).to ?? (execRequest as TxExecutionRequest).origin;
753
- const functionSelector =
754
- (execRequest as FunctionCall).selector ?? (execRequest as TxExecutionRequest).functionSelector;
755
-
756
- return {
757
- contractAddress,
758
- functionSelector,
759
- };
760
- }
761
-
762
- async #executePrivate(
763
- txRequest: TxExecutionRequest,
764
- msgSender?: AztecAddress,
765
- scopes?: AztecAddress[],
766
- ): Promise<PrivateExecutionResult> {
767
- // TODO - Pause syncing while simulating.
768
- const { contractAddress, functionSelector } = this.#getSimulationParameters(txRequest);
769
-
770
- try {
771
- const result = await this.simulator.run(txRequest, contractAddress, functionSelector, msgSender, scopes);
772
- this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
773
- return result;
774
- } catch (err) {
775
- if (err instanceof SimulationError) {
776
- await enrichSimulationError(err, this.contractDataProvider, this.log);
777
- }
778
- throw err;
779
- }
780
- }
781
-
782
- /**
783
- * Simulate an unconstrained transaction on the given contract, without considering constraints set by ACIR.
784
- * The simulation parameters are fetched using ContractDataProvider and executed using AcirSimulator.
785
- * Returns the simulation result containing the outputs of the unconstrained function.
786
- *
787
- * @param execRequest - The transaction request object containing the target contract and function data.
788
- * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
789
- * @returns The simulation result containing the outputs of the unconstrained function.
790
- */
791
- async #simulateUnconstrained(execRequest: FunctionCall, scopes?: AztecAddress[]) {
792
- const { contractAddress, functionSelector } = this.#getSimulationParameters(execRequest);
793
-
794
- this.log.debug('Executing unconstrained simulator...');
795
- try {
796
- const result = await this.simulator.runUnconstrained(execRequest, contractAddress, functionSelector, scopes);
797
- this.log.verbose(`Unconstrained simulation for ${contractAddress}.${functionSelector} completed`);
798
-
799
- return result;
800
- } catch (err) {
801
- if (err instanceof SimulationError) {
802
- await enrichSimulationError(err, this.contractDataProvider, this.log);
803
- }
804
- throw err;
805
- }
806
- }
807
-
808
- /**
809
- * Simulate the public part of a transaction.
810
- * This allows to catch public execution errors before submitting the transaction.
811
- * It can also be used for estimating gas in the future.
812
- * @param tx - The transaction to be simulated.
813
- */
814
- async #simulatePublicCalls(tx: Tx, skipFeeEnforcement: boolean) {
815
- // Simulating public calls can throw if the TX fails in a phase that doesn't allow reverts (setup)
816
- // Or return as reverted if it fails in a phase that allows reverts (app logic, teardown)
817
- try {
818
- const result = await this.node.simulatePublicCalls(tx, skipFeeEnforcement);
819
- if (result.revertReason) {
820
- throw result.revertReason;
821
- }
822
- return result;
823
- } catch (err) {
824
- if (err instanceof SimulationError) {
825
- try {
826
- await enrichPublicSimulationError(err, this.contractDataProvider, this.log);
827
- } catch (enrichErr) {
828
- this.log.error(`Failed to enrich public simulation error: ${enrichErr}`);
829
- }
830
- }
831
- throw err;
832
- }
833
- }
834
-
835
- /**
836
- * Generate a kernel proof, and create a private kernel output.
837
- * The function takes in a transaction execution request, and the result of private execution
838
- * and then generates a kernel proof.
839
- *
840
- * @param txExecutionRequest - The transaction request to be simulated and proved.
841
- * @param proofCreator - The proof creator to use for proving the execution.
842
- * @param privateExecutionResult - The result of the private execution
843
- * @returns An object that contains the output of the kernel execution, including the ClientIvcProof if proving is enabled.
844
- */
845
- async #prove(
846
- txExecutionRequest: TxExecutionRequest,
847
- proofCreator: PrivateKernelProver,
848
- privateExecutionResult: PrivateExecutionResult,
849
- { simulate, skipFeeEnforcement, profile }: ProvingConfig,
850
- ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
851
- // use the block the tx was simulated against
852
- const block =
853
- privateExecutionResult.entrypoint.publicInputs.historicalHeader.globalVariables.blockNumber.toNumber();
854
- const kernelOracle = new KernelOracle(this.contractDataProvider, this.keyStore, this.node, block);
855
- const kernelProver = new KernelProver(kernelOracle, proofCreator, !this.proverEnabled);
856
- this.log.debug(`Executing kernel prover (simulate: ${simulate}, profile: ${profile})...`);
857
- return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult, {
858
- simulate,
859
- skipFeeEnforcement,
860
- profile,
861
- });
862
- }
863
-
864
- async #isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
865
- return !!(await this.node.getContractClass(id));
866
- }
867
-
868
- async #isContractPubliclyDeployed(address: AztecAddress): Promise<boolean> {
869
- return !!(await this.node.getContract(address));
870
- }
871
-
872
- async #isContractInitialized(address: AztecAddress): Promise<boolean> {
873
- const initNullifier = await siloNullifier(address, address.toField());
874
- return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
875
- }
876
-
877
877
  public async getPrivateEvents<T>(
878
878
  eventMetadataDef: EventMetadataDefinition,
879
879
  from: number,
@@ -978,18 +978,4 @@ export class PXEService implements PXE {
978
978
  async resetNoteSyncData() {
979
979
  return await this.taggingDataProvider.resetNoteSyncData();
980
980
  }
981
-
982
- private contextualizeError(err: Error, ...context: string[]): Error {
983
- let contextStr = '';
984
- if (context.length > 0) {
985
- contextStr = `\nContext:\n${context.join('\n')}`;
986
- }
987
- if (err instanceof SimulationError) {
988
- err.setAztecContext(contextStr);
989
- } else {
990
- this.log.error(err.name, err);
991
- this.log.debug(contextStr);
992
- }
993
- return err;
994
- }
995
981
  }