@aztec/pxe 0.0.1-commit.cd76b27 → 0.0.1-commit.ce4f8c4f2

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 (139) hide show
  1. package/dest/config/index.d.ts +2 -2
  2. package/dest/config/index.d.ts.map +1 -1
  3. package/dest/config/index.js +1 -1
  4. package/dest/contract_function_simulator/contract_function_simulator.d.ts +9 -3
  5. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  6. package/dest/contract_function_simulator/contract_function_simulator.js +33 -11
  7. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +7 -7
  8. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
  9. package/dest/contract_function_simulator/execution_tagging_index_cache.js +19 -11
  10. package/dest/contract_function_simulator/index.d.ts +2 -1
  11. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  12. package/dest/contract_function_simulator/index.js +1 -0
  13. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +2 -3
  14. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  15. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +5 -4
  16. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
  17. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  18. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -3
  19. package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts +16 -0
  20. package/dest/contract_function_simulator/noir-structs/message_tx_context.d.ts.map +1 -0
  21. package/dest/contract_function_simulator/noir-structs/message_tx_context.js +57 -0
  22. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +2 -4
  23. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
  24. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +3 -5
  25. package/dest/contract_function_simulator/oracle/interfaces.d.ts +50 -45
  26. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  27. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts +9 -0
  28. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts.map +1 -0
  29. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.js +42 -0
  30. package/dest/contract_function_simulator/oracle/oracle.d.ts +45 -44
  31. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  32. package/dest/contract_function_simulator/oracle/oracle.js +163 -94
  33. package/dest/contract_function_simulator/oracle/private_execution.js +5 -3
  34. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +22 -47
  35. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  36. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +40 -80
  37. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +57 -39
  38. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  39. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +138 -63
  40. package/dest/contract_logging.d.ts +22 -0
  41. package/dest/contract_logging.d.ts.map +1 -0
  42. package/dest/contract_logging.js +23 -0
  43. package/dest/contract_sync/contract_sync_service.d.ts +5 -3
  44. package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
  45. package/dest/contract_sync/contract_sync_service.js +47 -30
  46. package/dest/entrypoints/client/bundle/index.d.ts +2 -1
  47. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  48. package/dest/entrypoints/client/bundle/index.js +1 -0
  49. package/dest/entrypoints/client/lazy/index.d.ts +2 -1
  50. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  51. package/dest/entrypoints/client/lazy/index.js +1 -0
  52. package/dest/logs/log_service.d.ts +1 -1
  53. package/dest/logs/log_service.d.ts.map +1 -1
  54. package/dest/logs/log_service.js +4 -4
  55. package/dest/messages/message_context_service.d.ts +17 -0
  56. package/dest/messages/message_context_service.d.ts.map +1 -0
  57. package/dest/messages/message_context_service.js +36 -0
  58. package/dest/oracle_version.d.ts +2 -2
  59. package/dest/oracle_version.js +3 -3
  60. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +4 -3
  61. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  62. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +125 -64
  63. package/dest/private_kernel/hints/test_utils.d.ts +122 -0
  64. package/dest/private_kernel/hints/test_utils.d.ts.map +1 -0
  65. package/dest/private_kernel/hints/test_utils.js +203 -0
  66. package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
  67. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  68. package/dest/private_kernel/private_kernel_execution_prover.js +13 -5
  69. package/dest/private_kernel/private_kernel_oracle.d.ts +6 -2
  70. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  71. package/dest/private_kernel/private_kernel_oracle.js +7 -3
  72. package/dest/pxe.d.ts +8 -4
  73. package/dest/pxe.d.ts.map +1 -1
  74. package/dest/pxe.js +55 -33
  75. package/dest/storage/contract_store/contract_store.d.ts +42 -15
  76. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  77. package/dest/storage/contract_store/contract_store.js +140 -64
  78. package/dest/storage/metadata.d.ts +1 -1
  79. package/dest/storage/metadata.js +1 -1
  80. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
  81. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  82. package/dest/storage/tagging_store/sender_tagging_store.d.ts +29 -28
  83. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  84. package/dest/storage/tagging_store/sender_tagging_store.js +141 -115
  85. package/dest/tagging/index.d.ts +3 -3
  86. package/dest/tagging/index.d.ts.map +1 -1
  87. package/dest/tagging/index.js +1 -1
  88. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +4 -5
  89. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
  90. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +3 -3
  91. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +6 -7
  92. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
  93. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +12 -11
  94. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -8
  95. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  96. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +13 -7
  97. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +4 -3
  98. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  99. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +20 -10
  100. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -7
  101. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  102. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +36 -24
  103. package/package.json +16 -16
  104. package/src/config/index.ts +1 -1
  105. package/src/contract_function_simulator/contract_function_simulator.ts +51 -20
  106. package/src/contract_function_simulator/execution_tagging_index_cache.ts +19 -14
  107. package/src/contract_function_simulator/index.ts +1 -0
  108. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +8 -5
  109. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -4
  110. package/src/contract_function_simulator/noir-structs/message_tx_context.ts +55 -0
  111. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +3 -6
  112. package/src/contract_function_simulator/oracle/interfaces.ts +54 -54
  113. package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +135 -0
  114. package/src/contract_function_simulator/oracle/oracle.ts +176 -138
  115. package/src/contract_function_simulator/oracle/private_execution.ts +4 -4
  116. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +45 -99
  117. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +200 -80
  118. package/src/contract_logging.ts +39 -0
  119. package/src/contract_sync/contract_sync_service.ts +67 -38
  120. package/src/entrypoints/client/bundle/index.ts +1 -0
  121. package/src/entrypoints/client/lazy/index.ts +1 -0
  122. package/src/logs/log_service.ts +10 -5
  123. package/src/messages/message_context_service.ts +45 -0
  124. package/src/oracle_version.ts +3 -3
  125. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +157 -110
  126. package/src/private_kernel/hints/test_utils.ts +325 -0
  127. package/src/private_kernel/private_kernel_execution_prover.ts +13 -6
  128. package/src/private_kernel/private_kernel_oracle.ts +7 -7
  129. package/src/pxe.ts +74 -34
  130. package/src/storage/contract_store/contract_store.ts +170 -71
  131. package/src/storage/metadata.ts +1 -1
  132. package/src/storage/tagging_store/recipient_tagging_store.ts +9 -5
  133. package/src/storage/tagging_store/sender_tagging_store.ts +185 -138
  134. package/src/tagging/index.ts +2 -2
  135. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +3 -6
  136. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +10 -15
  137. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +23 -10
  138. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +26 -11
  139. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +27 -26
package/src/pxe.ts CHANGED
@@ -61,12 +61,14 @@ import {
61
61
  generateSimulatedProvingResult,
62
62
  } from './contract_function_simulator/contract_function_simulator.js';
63
63
  import { ProxiedContractStoreFactory } from './contract_function_simulator/proxied_contract_data_source.js';
64
+ import { displayDebugLogs } from './contract_logging.js';
64
65
  import { ContractSyncService } from './contract_sync/contract_sync_service.js';
65
66
  import { readCurrentClassId } from './contract_sync/helpers.js';
66
67
  import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
67
68
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
68
69
  import { PrivateEventFilterValidator } from './events/private_event_filter_validator.js';
69
70
  import { JobCoordinator } from './job_coordinator/job_coordinator.js';
71
+ import { MessageContextService } from './messages/message_context_service.js';
70
72
  import {
71
73
  PrivateKernelExecutionProver,
72
74
  type PrivateKernelExecutionProverConfig,
@@ -105,7 +107,9 @@ export type SimulateTxOpts = {
105
107
  skipTxValidation?: boolean;
106
108
  /** If false, fees are enforced. */
107
109
  skipFeeEnforcement?: boolean;
108
- /** State overrides for the simulation, such as contract instances and artifacts. */
110
+ /** If true, kernel logic is emulated in TS for simulation */
111
+ skipKernels?: boolean;
112
+ /** State overrides for the simulation, such as contract instances and artifacts. Requires skipKernels: true */
109
113
  overrides?: SimulationOverrides;
110
114
  /** Addresses whose private state and keys are accessible during private execution */
111
115
  scopes: AccessScopes;
@@ -144,6 +148,7 @@ export type PXECreateArgs = {
144
148
  export class PXE {
145
149
  private constructor(
146
150
  private node: AztecNode,
151
+ private db: AztecAsyncKVStore,
147
152
  private blockStateSynchronizer: BlockSynchronizer,
148
153
  private keyStore: KeyStore,
149
154
  private contractStore: ContractStore,
@@ -156,6 +161,7 @@ export class PXE {
156
161
  private addressStore: AddressStore,
157
162
  private privateEventStore: PrivateEventStore,
158
163
  private contractSyncService: ContractSyncService,
164
+ private messageContextService: MessageContextService,
159
165
  private simulator: CircuitSimulator,
160
166
  private proverEnabled: boolean,
161
167
  private proofCreator: PrivateKernelProver,
@@ -211,6 +217,8 @@ export class PXE {
211
217
  noteStore,
212
218
  createLogger('pxe:contract_sync', bindings),
213
219
  );
220
+ const messageContextService = new MessageContextService(node);
221
+
214
222
  const synchronizer = new BlockSynchronizer(
215
223
  node,
216
224
  store,
@@ -239,6 +247,7 @@ export class PXE {
239
247
 
240
248
  const pxe = new PXE(
241
249
  node,
250
+ store,
242
251
  synchronizer,
243
252
  keyStore,
244
253
  contractStore,
@@ -251,6 +260,7 @@ export class PXE {
251
260
  addressStore,
252
261
  privateEventStore,
253
262
  contractSyncService,
263
+ messageContextService,
254
264
  simulator,
255
265
  proverEnabled,
256
266
  proofCreator,
@@ -292,6 +302,7 @@ export class PXE {
292
302
  privateEventStore: this.privateEventStore,
293
303
  simulator: this.simulator,
294
304
  contractSyncService: this.contractSyncService,
305
+ messageContextService: this.messageContextService,
295
306
  });
296
307
  }
297
308
 
@@ -344,9 +355,8 @@ export class PXE {
344
355
  async #registerProtocolContracts() {
345
356
  const registered: Record<string, string> = {};
346
357
  for (const name of protocolContractNames) {
347
- const { address, contractClass, instance, artifact } =
348
- await this.protocolContractsProvider.getProtocolContractArtifact(name);
349
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
358
+ const { address, instance, artifact } = await this.protocolContractsProvider.getProtocolContractArtifact(name);
359
+ await this.contractStore.addContractArtifact(artifact);
350
360
  await this.contractStore.addContractInstance(instance);
351
361
  registered[name] = address.toString();
352
362
  }
@@ -412,7 +422,14 @@ export class PXE {
412
422
  ) {
413
423
  try {
414
424
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
415
- return contractFunctionSimulator.runUtility(call, authWitnesses ?? [], anchorBlockHeader, scopes, jobId);
425
+ const { result, offchainEffects } = await contractFunctionSimulator.runUtility(
426
+ call,
427
+ authWitnesses ?? [],
428
+ anchorBlockHeader,
429
+ scopes,
430
+ jobId,
431
+ );
432
+ return { result, offchainEffects };
416
433
  } catch (err) {
417
434
  if (err instanceof SimulationError) {
418
435
  await enrichSimulationError(err, this.contractStore, this.log);
@@ -552,6 +569,9 @@ export class PXE {
552
569
 
553
570
  if (wasAdded) {
554
571
  this.log.info(`Added sender:\n ${sender.toString()}`);
572
+ // Wipe the entire sync cache: the new sender's tagged logs could contain notes/events for any contract, so
573
+ // all contracts must re-sync to discover them.
574
+ this.contractSyncService.wipe();
555
575
  } else {
556
576
  this.log.info(`Sender:\n "${sender.toString()}"\n already registered.`);
557
577
  }
@@ -601,8 +621,7 @@ export class PXE {
601
621
  * @param artifact - The build artifact for the contract class.
602
622
  */
603
623
  public async registerContractClass(artifact: ContractArtifact): Promise<void> {
604
- const { id: contractClassId } = await getContractClassFromArtifact(artifact);
605
- await this.contractStore.addContractArtifact(contractClassId, artifact);
624
+ const contractClassId = await this.contractStore.addContractArtifact(artifact);
606
625
  this.log.info(`Added contract class ${artifact.name} with id ${contractClassId}`);
607
626
  }
608
627
 
@@ -621,17 +640,17 @@ export class PXE {
621
640
  if (artifact) {
622
641
  // If the user provides an artifact, validate it against the expected class id and register it
623
642
  const contractClass = await getContractClassFromArtifact(artifact);
624
- const contractClassId = contractClass.id;
625
- if (!contractClassId.equals(instance.currentContractClassId)) {
643
+ if (!contractClass.id.equals(instance.currentContractClassId)) {
626
644
  throw new Error(
627
- `Artifact does not match expected class id (computed ${contractClassId} but instance refers to ${instance.currentContractClassId})`,
645
+ `Artifact does not match expected class id (computed ${contractClass.id} but instance refers to ${instance.currentContractClassId})`,
628
646
  );
629
647
  }
630
648
  const computedAddress = await computeContractAddressFromInstance(instance);
631
649
  if (!computedAddress.equals(instance.address)) {
632
650
  throw new Error('Added a contract in which the address does not match the contract instance.');
633
651
  }
634
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
652
+
653
+ await this.contractStore.addContractArtifact(artifact, contractClass);
635
654
 
636
655
  const publicFunctionSignatures = artifact.functions
637
656
  .filter(fn => fn.functionType === FunctionType.PUBLIC)
@@ -680,15 +699,16 @@ export class PXE {
680
699
  throw new Error('Could not update contract to a class different from the current one.');
681
700
  }
682
701
 
683
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
684
-
685
702
  const publicFunctionSignatures = artifact.functions
686
703
  .filter(fn => fn.functionType === FunctionType.PUBLIC)
687
704
  .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
688
705
  await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
689
706
 
690
707
  currentInstance.currentContractClassId = contractClass.id;
691
- await this.contractStore.addContractInstance(currentInstance);
708
+ await Promise.all([
709
+ this.contractStore.addContractArtifact(artifact, contractClass),
710
+ this.contractStore.addContractInstance(currentInstance),
711
+ ]);
692
712
  this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
693
713
  });
694
714
  }
@@ -764,17 +784,17 @@ export class PXE {
764
784
  // transaction before this one is included in a block from this PXE, and that transaction contains a log with
765
785
  // a tag derived from the same secret, we would reuse the tag and the transactions would be linked. Hence
766
786
  // storing the tags here prevents linkage of txs sent from the same PXE.
767
- const preTagsUsedInTheTx = privateExecutionResult.entrypoint.preTags;
768
- if (preTagsUsedInTheTx.length > 0) {
787
+ const taggingIndexRangesUsedInTheTx = privateExecutionResult.entrypoint.taggingIndexRanges;
788
+ if (taggingIndexRangesUsedInTheTx.length > 0) {
769
789
  // TODO(benesjan): The following is an expensive operation. Figure out a way to avoid it.
770
790
  const txHash = (await txProvingResult.toTx()).txHash;
771
791
 
772
- await this.senderTaggingStore.storePendingIndexes(preTagsUsedInTheTx, txHash, jobId);
773
- this.log.debug(`Stored used pre-tags as sender for the tx`, {
774
- preTagsUsedInTheTx,
792
+ await this.senderTaggingStore.storePendingIndexes(taggingIndexRangesUsedInTheTx, txHash, jobId);
793
+ this.log.debug(`Stored used tagging index ranges as sender for the tx`, {
794
+ taggingIndexRangesUsedInTheTx,
775
795
  });
776
796
  } else {
777
- this.log.debug(`No pre-tags used in the tx`);
797
+ this.log.debug(`No tagging index ranges used in the tx`);
778
798
  }
779
799
 
780
800
  return txProvingResult;
@@ -881,7 +901,14 @@ export class PXE {
881
901
  */
882
902
  public simulateTx(
883
903
  txRequest: TxExecutionRequest,
884
- { simulatePublic, skipTxValidation = false, skipFeeEnforcement = false, overrides, scopes }: SimulateTxOpts,
904
+ {
905
+ simulatePublic,
906
+ skipTxValidation = false,
907
+ skipFeeEnforcement = false,
908
+ skipKernels = true,
909
+ overrides,
910
+ scopes,
911
+ }: SimulateTxOpts,
885
912
  ): Promise<TxSimulationResult> {
886
913
  // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
887
914
  // to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
@@ -905,17 +932,20 @@ export class PXE {
905
932
  await this.blockStateSynchronizer.sync();
906
933
  const syncTime = syncTimer.ms();
907
934
 
908
- const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
909
- // Temporary: in case there are overrides, we have to skip the kernels or validations
910
- // will fail. Consider handing control to the user/wallet on whether they want to run them
911
- // or not.
912
935
  const overriddenContracts = overrides?.contracts ? new Set(Object.keys(overrides.contracts)) : undefined;
913
936
  const hasOverriddenContracts = overriddenContracts !== undefined && overriddenContracts.size > 0;
914
- const skipKernels = hasOverriddenContracts;
915
937
 
916
- // Set overridden contracts on the sync service so it knows to skip syncing them
938
+ if (hasOverriddenContracts && !skipKernels) {
939
+ throw new Error(
940
+ 'Simulating with overridden contracts is not compatible with kernel execution. Please set skipKernels to true when simulating with overridden contracts.',
941
+ );
942
+ }
943
+ const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
944
+
917
945
  if (hasOverriddenContracts) {
918
- this.contractSyncService.setOverriddenContracts(jobId, overriddenContracts);
946
+ // Overridden contracts don't have a sync function, so calling sync on them would fail.
947
+ // We exclude them so the sync service skips them entirely.
948
+ this.contractSyncService.setExcludedFromSync(jobId, overriddenContracts);
919
949
  }
920
950
 
921
951
  // Execution of private functions only; no proving, and no kernel logic.
@@ -947,6 +977,9 @@ export class PXE {
947
977
  const publicSimulationTimer = new Timer();
948
978
  publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
949
979
  publicSimulationTime = publicSimulationTimer.ms();
980
+ if (publicOutput?.debugLogs?.length) {
981
+ await displayDebugLogs(publicOutput.debugLogs, addr => this.contractStore.getDebugContractName(addr));
982
+ }
950
983
  }
951
984
 
952
985
  let validationTime: number | undefined;
@@ -955,7 +988,8 @@ export class PXE {
955
988
  const validationResult = await this.node.isValidTx(simulatedTx, { isSimulation: true, skipFeeEnforcement });
956
989
  validationTime = validationTimer.ms();
957
990
  if (validationResult.result === 'invalid') {
958
- throw new Error('The simulated transaction is unable to be added to state and is invalid.');
991
+ const reason = validationResult.reason.length > 0 ? ` Reason: ${validationResult.reason.join(', ')}` : '';
992
+ throw new Error(`The simulated transaction is unable to be added to state and is invalid.${reason}`);
959
993
  }
960
994
  }
961
995
 
@@ -1043,7 +1077,7 @@ export class PXE {
1043
1077
  scopes,
1044
1078
  );
1045
1079
 
1046
- const executionResult = await this.#executeUtility(
1080
+ const { result: executionResult, offchainEffects } = await this.#executeUtility(
1047
1081
  contractFunctionSimulator,
1048
1082
  call,
1049
1083
  authwits ?? [],
@@ -1064,7 +1098,12 @@ export class PXE {
1064
1098
  };
1065
1099
 
1066
1100
  const simulationStats = contractFunctionSimulator.getStats();
1067
- return { result: executionResult, stats: { timings, nodeRPCCalls: simulationStats.nodeRPCCalls } };
1101
+ return {
1102
+ result: executionResult,
1103
+ offchainEffects,
1104
+ anchorBlockTimestamp: anchorBlockHeader.globalVariables.timestamp,
1105
+ stats: { timings, nodeRPCCalls: simulationStats.nodeRPCCalls },
1106
+ };
1068
1107
  } catch (err: any) {
1069
1108
  const { to, name, args } = call;
1070
1109
  const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
@@ -1126,9 +1165,10 @@ export class PXE {
1126
1165
  }
1127
1166
 
1128
1167
  /**
1129
- * Stops the PXE's job queue.
1168
+ * Stops the PXE's job queue and closes the backing store.
1130
1169
  */
1131
- public stop(): Promise<void> {
1132
- return this.jobQueue.end();
1170
+ public async stop(): Promise<void> {
1171
+ await this.jobQueue.end();
1172
+ await this.db.close();
1133
1173
  }
1134
1174
  }