@aztec/pxe 0.66.0 → 0.67.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 (93) hide show
  1. package/dest/bin/index.js +5 -6
  2. package/dest/config/index.d.ts +0 -9
  3. package/dest/config/index.d.ts.map +1 -1
  4. package/dest/config/index.js +1 -17
  5. package/dest/config/package_info.d.ts +5 -0
  6. package/dest/config/package_info.d.ts.map +1 -0
  7. package/dest/config/package_info.js +4 -0
  8. package/dest/contract_data_oracle/index.js +2 -2
  9. package/dest/database/incoming_note_dao.d.ts +1 -1
  10. package/dest/database/incoming_note_dao.d.ts.map +1 -1
  11. package/dest/database/incoming_note_dao.js +2 -2
  12. package/dest/database/kv_pxe_database.d.ts +10 -13
  13. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  14. package/dest/database/kv_pxe_database.js +153 -230
  15. package/dest/database/outgoing_note_dao.js +2 -2
  16. package/dest/database/pxe_database.d.ts +7 -25
  17. package/dest/database/pxe_database.d.ts.map +1 -1
  18. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  19. package/dest/database/pxe_database_test_suite.js +18 -59
  20. package/dest/index.d.ts +2 -0
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +3 -1
  23. package/dest/kernel_oracle/index.d.ts.map +1 -1
  24. package/dest/kernel_oracle/index.js +3 -3
  25. package/dest/kernel_prover/index.d.ts +1 -0
  26. package/dest/kernel_prover/index.d.ts.map +1 -1
  27. package/dest/kernel_prover/index.js +2 -1
  28. package/dest/kernel_prover/kernel_prover.d.ts +1 -0
  29. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  30. package/dest/kernel_prover/kernel_prover.js +38 -4
  31. package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
  32. package/dest/kernel_prover/test/test_circuit_prover.js +4 -4
  33. package/dest/note_decryption_utils/add_public_values_to_payload.js +2 -2
  34. package/dest/note_decryption_utils/brute_force_note_info.d.ts +3 -3
  35. package/dest/note_decryption_utils/brute_force_note_info.d.ts.map +1 -1
  36. package/dest/note_decryption_utils/brute_force_note_info.js +8 -8
  37. package/dest/note_decryption_utils/produce_note_daos.d.ts +3 -6
  38. package/dest/note_decryption_utils/produce_note_daos.d.ts.map +1 -1
  39. package/dest/note_decryption_utils/produce_note_daos.js +5 -19
  40. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts +1 -1
  41. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts.map +1 -1
  42. package/dest/pxe_service/error_enriching.d.ts +3 -3
  43. package/dest/pxe_service/error_enriching.d.ts.map +1 -1
  44. package/dest/pxe_service/error_enriching.js +10 -10
  45. package/dest/pxe_service/index.d.ts +0 -1
  46. package/dest/pxe_service/index.d.ts.map +1 -1
  47. package/dest/pxe_service/index.js +1 -2
  48. package/dest/pxe_service/pxe_service.d.ts +2 -16
  49. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  50. package/dest/pxe_service/pxe_service.js +70 -95
  51. package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
  52. package/dest/pxe_service/test/pxe_test_suite.js +1 -3
  53. package/dest/simulator/index.d.ts +1 -1
  54. package/dest/simulator/index.d.ts.map +1 -1
  55. package/dest/simulator/index.js +2 -2
  56. package/dest/simulator_oracle/index.d.ts +7 -6
  57. package/dest/simulator_oracle/index.d.ts.map +1 -1
  58. package/dest/simulator_oracle/index.js +59 -42
  59. package/dest/synchronizer/synchronizer.d.ts +10 -40
  60. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  61. package/dest/synchronizer/synchronizer.js +35 -69
  62. package/dest/{pxe_service → utils}/create_pxe_service.d.ts +1 -1
  63. package/dest/utils/create_pxe_service.d.ts.map +1 -0
  64. package/dest/utils/create_pxe_service.js +49 -0
  65. package/package.json +31 -19
  66. package/src/bin/index.ts +4 -5
  67. package/src/config/index.ts +0 -21
  68. package/src/config/package_info.ts +3 -0
  69. package/src/contract_data_oracle/index.ts +1 -1
  70. package/src/database/incoming_note_dao.ts +2 -2
  71. package/src/database/kv_pxe_database.ts +212 -309
  72. package/src/database/outgoing_note_dao.ts +1 -1
  73. package/src/database/pxe_database.ts +7 -28
  74. package/src/database/pxe_database_test_suite.ts +20 -75
  75. package/src/index.ts +2 -0
  76. package/src/kernel_oracle/index.ts +2 -2
  77. package/src/kernel_prover/index.ts +2 -0
  78. package/src/kernel_prover/kernel_prover.ts +61 -2
  79. package/src/kernel_prover/test/test_circuit_prover.ts +5 -3
  80. package/src/note_decryption_utils/add_public_values_to_payload.ts +1 -1
  81. package/src/note_decryption_utils/brute_force_note_info.ts +9 -9
  82. package/src/note_decryption_utils/produce_note_daos.ts +5 -48
  83. package/src/note_decryption_utils/produce_note_daos_for_key.ts +1 -1
  84. package/src/pxe_service/error_enriching.ts +14 -12
  85. package/src/pxe_service/index.ts +0 -1
  86. package/src/pxe_service/pxe_service.ts +123 -169
  87. package/src/pxe_service/test/pxe_test_suite.ts +0 -3
  88. package/src/simulator/index.ts +1 -1
  89. package/src/simulator_oracle/index.ts +63 -70
  90. package/src/synchronizer/synchronizer.ts +37 -77
  91. package/src/{pxe_service → utils}/create_pxe_service.ts +10 -10
  92. package/dest/pxe_service/create_pxe_service.d.ts.map +0 -1
  93. package/dest/pxe_service/create_pxe_service.js +0 -49
@@ -1,7 +1,7 @@
1
1
  import { type SimulationError, isNoirCallStackUnresolved } from '@aztec/circuit-types';
2
2
  import { AztecAddress, Fr, FunctionSelector, PUBLIC_DISPATCH_SELECTOR } from '@aztec/circuits.js';
3
- import { type DebugLogger } from '@aztec/foundation/log';
4
- import { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '@aztec/simulator';
3
+ import { type Logger } from '@aztec/foundation/log';
4
+ import { resolveAssertionMessageFromRevertData, resolveOpcodeLocations } from '@aztec/simulator/errors';
5
5
 
6
6
  import { type ContractDataOracle, type PxeDatabase } from '../index.js';
7
7
 
@@ -10,27 +10,27 @@ import { type ContractDataOracle, type PxeDatabase } from '../index.js';
10
10
  * can be found in the PXE database
11
11
  * @param err - The error to enrich.
12
12
  */
13
- export async function enrichSimulationError(err: SimulationError, db: PxeDatabase, logger: DebugLogger) {
14
- // Maps contract addresses to the set of functions selectors that were in error.
13
+ export async function enrichSimulationError(err: SimulationError, db: PxeDatabase, logger: Logger) {
14
+ // Maps contract addresses to the set of function names that were in error.
15
15
  // Map and Set do reference equality for their keys instead of value equality, so we store the string
16
16
  // representation to get e.g. different contract address objects with the same address value to match.
17
17
  const mentionedFunctions: Map<string, Set<string>> = new Map();
18
18
 
19
- err.getCallStack().forEach(({ contractAddress, functionSelector }) => {
19
+ err.getCallStack().forEach(({ contractAddress, functionName }) => {
20
20
  if (!mentionedFunctions.has(contractAddress.toString())) {
21
21
  mentionedFunctions.set(contractAddress.toString(), new Set());
22
22
  }
23
- mentionedFunctions.get(contractAddress.toString())!.add(functionSelector.toString());
23
+ mentionedFunctions.get(contractAddress.toString())!.add(functionName?.toString() ?? '');
24
24
  });
25
25
 
26
26
  await Promise.all(
27
- [...mentionedFunctions.entries()].map(async ([contractAddress, selectors]) => {
27
+ [...mentionedFunctions.entries()].map(async ([contractAddress, fnNames]) => {
28
28
  const parsedContractAddress = AztecAddress.fromString(contractAddress);
29
29
  const contract = await db.getContract(parsedContractAddress);
30
30
  if (contract) {
31
31
  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);
34
34
  if (functionArtifact) {
35
35
  err.enrichWithFunctionName(
36
36
  parsedContractAddress,
@@ -39,7 +39,7 @@ export async function enrichSimulationError(err: SimulationError, db: PxeDatabas
39
39
  );
40
40
  } else {
41
41
  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`,
43
43
  );
44
44
  }
45
45
  });
@@ -56,7 +56,7 @@ export async function enrichPublicSimulationError(
56
56
  err: SimulationError,
57
57
  contractDataOracle: ContractDataOracle,
58
58
  db: PxeDatabase,
59
- logger: DebugLogger,
59
+ logger: Logger,
60
60
  ) {
61
61
  const callStack = err.getCallStack();
62
62
  const originalFailingFunction = callStack[callStack.length - 1];
@@ -89,7 +89,9 @@ export async function enrichPublicSimulationError(
89
89
  err.setNoirCallStack(parsedCallStack);
90
90
  } catch (err) {
91
91
  logger.warn(
92
- `Could not resolve noir call stack for ${originalFailingFunction.contractAddress.toString()}:${originalFailingFunction.functionSelector.toString()}: ${err}`,
92
+ `Could not resolve noir call stack for ${originalFailingFunction.contractAddress.toString()}:${
93
+ originalFailingFunction.functionName?.toString() ?? ''
94
+ }: ${err}`,
93
95
  );
94
96
  }
95
97
  }
@@ -1,4 +1,3 @@
1
1
  export * from './pxe_service.js';
2
- export * from './create_pxe_service.js';
3
2
  export { enrichPublicSimulationError } from './error_enriching.js';
4
3
  export { pxeTestSuite } from './test/pxe_test_suite.js';
@@ -12,7 +12,6 @@ import {
12
12
  type L2Block,
13
13
  type LogFilter,
14
14
  MerkleTreeId,
15
- type OutgoingNotesFilter,
16
15
  type PXE,
17
16
  type PXEInfo,
18
17
  type PrivateExecutionResult,
@@ -56,8 +55,7 @@ import {
56
55
  encodeArguments,
57
56
  } from '@aztec/foundation/abi';
58
57
  import { Fr, type Point } from '@aztec/foundation/fields';
59
- import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
60
- import { SerialQueue } from '@aztec/foundation/queue';
58
+ import { type Logger, createLogger } from '@aztec/foundation/log';
61
59
  import { type KeyStore } from '@aztec/key-store';
62
60
  import { type L2TipsStore } from '@aztec/kv-store/stores';
63
61
  import {
@@ -65,11 +63,12 @@ import {
65
63
  getCanonicalProtocolContract,
66
64
  protocolContractNames,
67
65
  } from '@aztec/protocol-contracts';
68
- import { type AcirSimulator } from '@aztec/simulator';
66
+ import { type AcirSimulator } from '@aztec/simulator/client';
69
67
 
70
68
  import { inspect } from 'util';
71
69
 
72
- import { type PXEServiceConfig, getPackageInfo } from '../config/index.js';
70
+ import { type PXEServiceConfig } from '../config/index.js';
71
+ import { getPackageInfo } from '../config/package_info.js';
73
72
  import { ContractDataOracle } from '../contract_data_oracle/index.js';
74
73
  import { IncomingNoteDao } from '../database/incoming_note_dao.js';
75
74
  import { type PxeDatabase } from '../database/index.js';
@@ -87,11 +86,8 @@ export class PXEService implements PXE {
87
86
  private synchronizer: Synchronizer;
88
87
  private contractDataOracle: ContractDataOracle;
89
88
  private simulator: AcirSimulator;
90
- private log: DebugLogger;
89
+ private log: Logger;
91
90
  private packageVersion: string;
92
- // serialize synchronizer and calls to proveTx.
93
- // ensures that state is not changed while simulating
94
- private jobQueue = new SerialQueue();
95
91
 
96
92
  constructor(
97
93
  private keyStore: KeyStore,
@@ -102,13 +98,11 @@ export class PXEService implements PXE {
102
98
  config: PXEServiceConfig,
103
99
  logSuffix?: string,
104
100
  ) {
105
- this.log = createDebugLogger(logSuffix ? `aztec:pxe_service_${logSuffix}` : `aztec:pxe_service`);
101
+ this.log = createLogger(logSuffix ? `pxe:service:${logSuffix}` : `pxe:service`);
106
102
  this.synchronizer = new Synchronizer(node, db, tipsStore, config, logSuffix);
107
103
  this.contractDataOracle = new ContractDataOracle(db);
108
104
  this.simulator = getAcirSimulator(db, node, keyStore, this.contractDataOracle);
109
105
  this.packageVersion = getPackageInfo().version;
110
-
111
- this.jobQueue.start();
112
106
  }
113
107
 
114
108
  /**
@@ -116,27 +110,12 @@ export class PXEService implements PXE {
116
110
  *
117
111
  * @returns A promise that resolves when the server has started successfully.
118
112
  */
119
- public async start() {
120
- await this.synchronizer.start();
113
+ public async init() {
121
114
  await this.#registerProtocolContracts();
122
115
  const info = await this.getNodeInfo();
123
116
  this.log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.protocolVersion}`);
124
117
  }
125
118
 
126
- /**
127
- * Stops the PXE Service, halting processing of new transactions and shutting down the synchronizer.
128
- * This function ensures that all ongoing tasks are completed before stopping the server.
129
- * It is useful for gracefully shutting down the server during maintenance or restarts.
130
- *
131
- * @returns A Promise resolving once the server has been stopped successfully.
132
- */
133
- public async stop() {
134
- await this.jobQueue.cancel();
135
- this.log.info('Cancelled Job Queue');
136
- await this.synchronizer.stop();
137
- this.log.info('Stopped Synchronizer');
138
- }
139
-
140
119
  isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean> {
141
120
  return this.node.isL1ToL2MessageSynced(l1ToL2Message);
142
121
  }
@@ -320,33 +299,6 @@ export class PXEService implements PXE {
320
299
  return Promise.all(extendedNotes);
321
300
  }
322
301
 
323
- public async getOutgoingNotes(filter: OutgoingNotesFilter): Promise<UniqueNote[]> {
324
- const noteDaos = await this.db.getOutgoingNotes(filter);
325
-
326
- const extendedNotes = noteDaos.map(async dao => {
327
- let owner = filter.owner;
328
- if (owner === undefined) {
329
- const completeAddresses = (await this.db.getCompleteAddresses()).find(address =>
330
- address.publicKeys.masterOutgoingViewingPublicKey.equals(dao.ovpkM),
331
- );
332
- if (completeAddresses === undefined) {
333
- throw new Error(`Cannot find complete address for OvpkM ${dao.ovpkM.toString()}`);
334
- }
335
- owner = completeAddresses.address;
336
- }
337
- return new UniqueNote(
338
- dao.note,
339
- owner,
340
- dao.contractAddress,
341
- dao.storageSlot,
342
- dao.noteTypeId,
343
- dao.txHash,
344
- dao.nonce,
345
- );
346
- });
347
- return Promise.all(extendedNotes);
348
- }
349
-
350
302
  public async getL1ToL2MembershipWitness(
351
303
  contractAddress: AztecAddress,
352
304
  messageHash: Fr,
@@ -367,7 +319,7 @@ export class PXEService implements PXE {
367
319
  }
368
320
 
369
321
  for (const nonce of nonces) {
370
- const { noteHash, siloedNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
322
+ const { noteHash, uniqueNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
371
323
  note.contractAddress,
372
324
  nonce,
373
325
  note.storageSlot,
@@ -376,7 +328,7 @@ export class PXEService implements PXE {
376
328
  note.note,
377
329
  );
378
330
 
379
- const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
331
+ const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [uniqueNoteHash]);
380
332
  if (index === undefined) {
381
333
  throw new Error('Note does not exist.');
382
334
  }
@@ -416,7 +368,7 @@ export class PXEService implements PXE {
416
368
  }
417
369
 
418
370
  for (const nonce of nonces) {
419
- const { noteHash, siloedNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
371
+ const { noteHash, uniqueNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
420
372
  note.contractAddress,
421
373
  nonce,
422
374
  note.storageSlot,
@@ -429,7 +381,7 @@ export class PXEService implements PXE {
429
381
  throw new Error('Unexpectedly received non-zero nullifier.');
430
382
  }
431
383
 
432
- const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
384
+ const [index] = await this.node.findLeavesIndexes('latest', MerkleTreeId.NOTE_HASH_TREE, [uniqueNoteHash]);
433
385
  if (index === undefined) {
434
386
  throw new Error('Note does not exist.');
435
387
  }
@@ -475,7 +427,7 @@ export class PXEService implements PXE {
475
427
  }
476
428
 
477
429
  const nonce = computeNoteHashNonce(firstNullifier, i);
478
- const { siloedNoteHash } = await this.simulator.computeNoteHashAndOptionallyANullifier(
430
+ const { uniqueNoteHash } = await this.simulator.computeNoteHashAndOptionallyANullifier(
479
431
  note.contractAddress,
480
432
  nonce,
481
433
  note.storageSlot,
@@ -483,7 +435,7 @@ export class PXEService implements PXE {
483
435
  false,
484
436
  note.note,
485
437
  );
486
- if (hash.equals(siloedNoteHash)) {
438
+ if (hash.equals(uniqueNoteHash)) {
487
439
  nonces.push(nonce);
488
440
  }
489
441
  }
@@ -511,22 +463,16 @@ export class PXEService implements PXE {
511
463
  return result.publicInputs;
512
464
  }
513
465
 
514
- public proveTx(
466
+ public async proveTx(
515
467
  txRequest: TxExecutionRequest,
516
468
  privateExecutionResult: PrivateExecutionResult,
517
469
  ): Promise<TxProvingResult> {
518
- return this.jobQueue
519
- .put(async () => {
520
- const { publicInputs, clientIvcProof } = await this.#prove(
521
- txRequest,
522
- this.proofCreator,
523
- privateExecutionResult,
524
- );
525
- return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
526
- })
527
- .catch(err => {
528
- throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
529
- });
470
+ try {
471
+ const { publicInputs, clientIvcProof } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult);
472
+ return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof!);
473
+ } catch (err: any) {
474
+ throw this.contextualizeError(err, inspect(txRequest), inspect(privateExecutionResult));
475
+ }
530
476
  }
531
477
 
532
478
  // TODO(#7456) Prevent msgSender being defined here for the first call
@@ -538,59 +484,77 @@ export class PXEService implements PXE {
538
484
  profile: boolean = false,
539
485
  scopes?: AztecAddress[],
540
486
  ): Promise<TxSimulationResult> {
541
- return await this.jobQueue
542
- .put(async () => {
543
- const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
544
-
545
- let publicInputs: PrivateKernelTailCircuitPublicInputs;
546
- let profileResult;
547
- if (profile) {
548
- ({ publicInputs, profileResult } = await this.#profileKernelProver(
549
- txRequest,
550
- this.proofCreator,
551
- privateExecutionResult,
552
- ));
553
- } else {
554
- publicInputs = await this.#simulateKernels(txRequest, privateExecutionResult);
555
- }
487
+ try {
488
+ const txInfo = {
489
+ origin: txRequest.origin,
490
+ functionSelector: txRequest.functionSelector,
491
+ simulatePublic,
492
+ msgSender,
493
+ chainId: txRequest.txContext.chainId,
494
+ version: txRequest.txContext.version,
495
+ authWitnesses: txRequest.authWitnesses.map(w => w.requestHash),
496
+ };
497
+ this.log.verbose(
498
+ `Simulating transaction execution request to ${txRequest.functionSelector} at ${txRequest.origin}`,
499
+ txInfo,
500
+ );
501
+ await this.synchronizer.sync();
502
+ const privateExecutionResult = await this.#executePrivate(txRequest, msgSender, scopes);
556
503
 
557
- const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
558
- const simulatedTx = privateSimulationResult.toSimulatedTx();
559
- let publicOutput: PublicSimulationOutput | undefined;
560
- if (simulatePublic) {
561
- publicOutput = await this.#simulatePublicCalls(simulatedTx);
562
- }
504
+ let publicInputs: PrivateKernelTailCircuitPublicInputs;
505
+ let profileResult;
506
+ if (profile) {
507
+ ({ publicInputs, profileResult } = await this.#profileKernelProver(
508
+ txRequest,
509
+ this.proofCreator,
510
+ privateExecutionResult,
511
+ ));
512
+ } else {
513
+ publicInputs = await this.#simulateKernels(txRequest, privateExecutionResult);
514
+ }
563
515
 
564
- if (!skipTxValidation) {
565
- if (!(await this.node.isValidTx(simulatedTx, true))) {
566
- throw new Error('The simulated transaction is unable to be added to state and is invalid.');
567
- }
568
- }
516
+ const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
517
+ const simulatedTx = privateSimulationResult.toSimulatedTx();
518
+ let publicOutput: PublicSimulationOutput | undefined;
519
+ if (simulatePublic) {
520
+ publicOutput = await this.#simulatePublicCalls(simulatedTx);
521
+ }
569
522
 
570
- // We log only if the msgSender is undefined, as simulating with a different msgSender
571
- // is unlikely to be a real transaction, and likely to be only used to read data.
572
- // Meaning that it will not necessarily have produced a nullifier (and thus have no TxHash)
573
- // If we log, the `getTxHash` function will throw.
574
- if (!msgSender) {
575
- this.log.info(`Executed local simulation for ${simulatedTx.getTxHash()}`);
523
+ if (!skipTxValidation) {
524
+ if (!(await this.node.isValidTx(simulatedTx, true))) {
525
+ throw new Error('The simulated transaction is unable to be added to state and is invalid.');
576
526
  }
577
- return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(
578
- privateSimulationResult,
579
- publicOutput,
580
- profileResult,
581
- );
582
- })
583
- .catch(err => {
584
- throw this.contextualizeError(
585
- err,
586
- inspect(txRequest),
587
- `simulatePublic=${simulatePublic}`,
588
- `msgSender=${msgSender?.toString() ?? 'undefined'}`,
589
- `skipTxValidation=${skipTxValidation}`,
590
- `profile=${profile}`,
591
- `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
592
- );
527
+ }
528
+
529
+ this.log.info(`Simulation completed for ${simulatedTx.tryGetTxHash()}`, {
530
+ txHash: simulatedTx.tryGetTxHash(),
531
+ ...txInfo,
532
+ ...(profileResult ? { gateCounts: profileResult.gateCounts } : {}),
533
+ ...(publicOutput
534
+ ? {
535
+ gasUsed: publicOutput.gasUsed,
536
+ revertCode: publicOutput.txEffect.revertCode.getCode(),
537
+ revertReason: publicOutput.revertReason,
538
+ }
539
+ : {}),
593
540
  });
541
+
542
+ return TxSimulationResult.fromPrivateSimulationResultAndPublicOutput(
543
+ privateSimulationResult,
544
+ publicOutput,
545
+ profileResult,
546
+ );
547
+ } catch (err: any) {
548
+ throw this.contextualizeError(
549
+ err,
550
+ inspect(txRequest),
551
+ `simulatePublic=${simulatePublic}`,
552
+ `msgSender=${msgSender?.toString() ?? 'undefined'}`,
553
+ `skipTxValidation=${skipTxValidation}`,
554
+ `profile=${profile}`,
555
+ `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
556
+ );
557
+ }
594
558
  }
595
559
 
596
560
  public async sendTx(tx: Tx): Promise<TxHash> {
@@ -598,7 +562,7 @@ export class PXEService implements PXE {
598
562
  if (await this.node.getTxEffect(txHash)) {
599
563
  throw new Error(`A settled tx with equal hash ${txHash.toString()} exists.`);
600
564
  }
601
- this.log.info(`Sending transaction ${txHash}`);
565
+ this.log.debug(`Sending transaction ${txHash}`);
602
566
  await this.node.sendTx(tx).catch(err => {
603
567
  throw this.contextualizeError(err, inspect(tx));
604
568
  });
@@ -613,24 +577,22 @@ export class PXEService implements PXE {
613
577
  _from?: AztecAddress,
614
578
  scopes?: AztecAddress[],
615
579
  ): Promise<AbiDecoded> {
616
- // all simulations must be serialized w.r.t. the synchronizer
617
- return await this.jobQueue
618
- .put(async () => {
619
- // TODO - Should check if `from` has the permission to call the view function.
620
- const functionCall = await this.#getFunctionCall(functionName, args, to);
621
- const executionResult = await this.#simulateUnconstrained(functionCall, scopes);
622
-
623
- // TODO - Return typed result based on the function artifact.
624
- return executionResult;
625
- })
626
- .catch(err => {
627
- const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
628
- throw this.contextualizeError(
629
- err,
630
- `simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`,
631
- `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
632
- );
633
- });
580
+ try {
581
+ await this.synchronizer.sync();
582
+ // TODO - Should check if `from` has the permission to call the view function.
583
+ const functionCall = await this.#getFunctionCall(functionName, args, to);
584
+ const executionResult = await this.#simulateUnconstrained(functionCall, scopes);
585
+
586
+ // TODO - Return typed result based on the function artifact.
587
+ return executionResult;
588
+ } catch (err: any) {
589
+ const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
590
+ throw this.contextualizeError(
591
+ err,
592
+ `simulateUnconstrained ${to}:${functionName}(${stringifiedArgs})`,
593
+ `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
594
+ );
595
+ }
634
596
  }
635
597
 
636
598
  public getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
@@ -727,12 +689,14 @@ export class PXEService implements PXE {
727
689
  }
728
690
 
729
691
  async #registerProtocolContracts() {
692
+ const registered: Record<string, string> = {};
730
693
  for (const name of protocolContractNames) {
731
694
  const { address, contractClass, instance, artifact } = getCanonicalProtocolContract(name);
732
695
  await this.db.addContractArtifact(contractClass.id, artifact);
733
696
  await this.db.addContractInstance(instance);
734
- this.log.info(`Added protocol contract ${name} at ${address.toString()}`);
697
+ registered[name] = address.toString();
735
698
  }
699
+ this.log.verbose(`Registered protocol contracts in pxe`, registered);
736
700
  }
737
701
 
738
702
  /**
@@ -764,13 +728,11 @@ export class PXEService implements PXE {
764
728
  scopes?: AztecAddress[],
765
729
  ): Promise<PrivateExecutionResult> {
766
730
  // TODO - Pause syncing while simulating.
767
-
768
731
  const { contractAddress, functionArtifact } = await this.#getSimulationParameters(txRequest);
769
732
 
770
- this.log.debug('Executing simulator...');
771
733
  try {
772
734
  const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, msgSender, scopes);
773
- this.log.verbose(`Simulation completed for ${contractAddress.toString()}:${functionArtifact.name}`);
735
+ this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionArtifact.name}`);
774
736
  return result;
775
737
  } catch (err) {
776
738
  if (err instanceof SimulationError) {
@@ -848,19 +810,14 @@ export class PXEService implements PXE {
848
810
  }
849
811
 
850
812
  /**
851
- * Simulate a transaction, generate a kernel proof, and create a private transaction object.
852
- * The function takes in a transaction request, simulates it, and then generates a kernel proof
853
- * using the simulation result. Finally, it creates a private
854
- * transaction object with the generated proof and public inputs. If a new contract address is provided,
855
- * the function will also include the new contract's public functions in the transaction object.
813
+ * Generate a kernel proof, and create a private kernel output.
814
+ * The function takes in a transaction execution request, and the result of private execution
815
+ * and then generates a kernel proof.
856
816
  *
857
817
  * @param txExecutionRequest - The transaction request to be simulated and proved.
858
818
  * @param proofCreator - The proof creator to use for proving the execution.
859
- * @param msgSender - (Optional) The message sender to use for the simulation.
860
- * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
861
- * @returns An object that contains:
862
- * A private transaction object containing the proof, public inputs, and encrypted logs.
863
- * The return values of the private execution
819
+ * @param privateExecutionResult - The result of the private execution
820
+ * @returns An object that contains the output of the kernel execution, including the ClientIvcProof if proving is enabled.
864
821
  */
865
822
  async #prove(
866
823
  txExecutionRequest: TxExecutionRequest,
@@ -875,14 +832,6 @@ export class PXEService implements PXE {
875
832
  return await kernelProver.prove(txExecutionRequest.toTxRequest(), privateExecutionResult);
876
833
  }
877
834
 
878
- public async isGlobalStateSynchronized() {
879
- return await this.synchronizer.isGlobalStateSynchronized();
880
- }
881
-
882
- public getSyncStatus() {
883
- return Promise.resolve(this.synchronizer.getSyncStatus());
884
- }
885
-
886
835
  public async isContractClassPubliclyRegistered(id: Fr): Promise<boolean> {
887
836
  return !!(await this.node.getContractClass(id));
888
837
  }
@@ -915,7 +864,7 @@ export class PXEService implements PXE {
915
864
 
916
865
  const vsks = await Promise.all(
917
866
  vpks.map(async vpk => {
918
- const [keyPrefix, account] = this.keyStore.getKeyPrefixAndAccount(vpk);
867
+ const [keyPrefix, account] = await this.keyStore.getKeyPrefixAndAccount(vpk);
919
868
  let secretKey = await this.keyStore.getMasterSecretKey(vpk);
920
869
  if (keyPrefix === 'iv') {
921
870
  const registeredAccount = await this.getRegisteredAccount(account);
@@ -936,7 +885,7 @@ export class PXEService implements PXE {
936
885
  for (const sk of vsks) {
937
886
  // TODO: Verify that the first field of the log is the tag siloed with contract address.
938
887
  // Or use tags to query logs, like we do with notes.
939
- const decryptedEvent = L1EventPayload.decryptAsIncoming(log, sk) ?? L1EventPayload.decryptAsOutgoing(log, sk);
888
+ const decryptedEvent = L1EventPayload.decryptAsIncoming(log, sk);
940
889
  if (decryptedEvent !== undefined) {
941
890
  return [decryptedEvent];
942
891
  }
@@ -1003,10 +952,15 @@ export class PXEService implements PXE {
1003
952
  }
1004
953
 
1005
954
  private contextualizeError(err: Error, ...context: string[]): Error {
1006
- this.log.error(err.name, err);
1007
- this.log.debug('Context:');
1008
- for (const c of context) {
1009
- this.log.debug(c);
955
+ let contextStr = '';
956
+ if (context.length > 0) {
957
+ contextStr = `\nContext:\n${context.join('\n')}`;
958
+ }
959
+ if (err instanceof SimulationError) {
960
+ err.setAztecContext(contextStr);
961
+ } else {
962
+ this.log.error(err.name, err);
963
+ this.log.debug(contextStr);
1010
964
  }
1011
965
  return err;
1012
966
  }
@@ -115,8 +115,5 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise<PXE>) =>
115
115
  expect(typeof nodeInfo.l1ChainId).toEqual('number');
116
116
  expect(nodeInfo.l1ContractAddresses.rollupAddress.toString()).toMatch(/0x[a-fA-F0-9]+/);
117
117
  });
118
-
119
- // Note: Not testing `isGlobalStateSynchronized`, `isAccountStateSynchronized` and `getSyncStatus` as these methods
120
- // only call synchronizer.
121
118
  });
122
119
  };
@@ -1,6 +1,6 @@
1
1
  import { type AztecNode } from '@aztec/circuit-types';
2
2
  import { type KeyStore } from '@aztec/key-store';
3
- import { AcirSimulator } from '@aztec/simulator';
3
+ import { AcirSimulator } from '@aztec/simulator/client';
4
4
 
5
5
  import { ContractDataOracle } from '../contract_data_oracle/index.js';
6
6
  import { type PxeDatabase } from '../database/pxe_database.js';