@aztec/pxe 0.0.1-commit.29c6b1a3 → 0.0.1-commit.2d9cb6034

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 (237) hide show
  1. package/dest/block_synchronizer/block_synchronizer.d.ts +5 -3
  2. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  3. package/dest/block_synchronizer/block_synchronizer.js +15 -3
  4. package/dest/config/index.d.ts +2 -2
  5. package/dest/config/index.d.ts.map +1 -1
  6. package/dest/config/index.js +1 -1
  7. package/dest/config/package_info.js +1 -1
  8. package/dest/contract_function_simulator/contract_function_simulator.d.ts +60 -31
  9. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  10. package/dest/contract_function_simulator/contract_function_simulator.js +201 -74
  11. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +7 -7
  12. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/execution_tagging_index_cache.js +19 -11
  14. package/dest/contract_function_simulator/index.d.ts +2 -1
  15. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  16. package/dest/contract_function_simulator/index.js +1 -0
  17. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -5
  18. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  19. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +7 -9
  20. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
  21. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  22. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -3
  23. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +3 -6
  24. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
  25. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +5 -10
  26. package/dest/contract_function_simulator/oracle/interfaces.d.ts +50 -45
  27. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  28. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts +9 -0
  29. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts.map +1 -0
  30. package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.js +38 -0
  31. package/dest/contract_function_simulator/oracle/oracle.d.ts +64 -44
  32. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  33. package/dest/contract_function_simulator/oracle/oracle.js +211 -109
  34. package/dest/contract_function_simulator/oracle/private_execution.js +5 -3
  35. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +53 -79
  36. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  37. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +109 -87
  38. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +100 -57
  39. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  40. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +243 -128
  41. package/dest/contract_logging.d.ts +27 -0
  42. package/dest/contract_logging.d.ts.map +1 -0
  43. package/dest/contract_logging.js +38 -0
  44. package/dest/contract_sync/contract_sync_service.d.ts +44 -0
  45. package/dest/contract_sync/contract_sync_service.d.ts.map +1 -0
  46. package/dest/contract_sync/contract_sync_service.js +104 -0
  47. package/dest/contract_sync/helpers.d.ts +28 -0
  48. package/dest/contract_sync/helpers.d.ts.map +1 -0
  49. package/dest/contract_sync/{index.js → helpers.js} +19 -13
  50. package/dest/debug/pxe_debug_utils.d.ts +14 -10
  51. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  52. package/dest/debug/pxe_debug_utils.js +16 -15
  53. package/dest/entrypoints/client/bundle/index.d.ts +3 -1
  54. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  55. package/dest/entrypoints/client/bundle/index.js +2 -0
  56. package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
  57. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  58. package/dest/entrypoints/client/bundle/utils.js +21 -7
  59. package/dest/entrypoints/client/lazy/index.d.ts +3 -1
  60. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  61. package/dest/entrypoints/client/lazy/index.js +2 -0
  62. package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
  63. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  64. package/dest/entrypoints/client/lazy/utils.js +22 -8
  65. package/dest/entrypoints/pxe_creation_options.d.ts +3 -2
  66. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  67. package/dest/entrypoints/server/index.d.ts +3 -2
  68. package/dest/entrypoints/server/index.d.ts.map +1 -1
  69. package/dest/entrypoints/server/index.js +2 -1
  70. package/dest/entrypoints/server/utils.d.ts +1 -1
  71. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  72. package/dest/entrypoints/server/utils.js +28 -9
  73. package/dest/events/event_service.d.ts +5 -5
  74. package/dest/events/event_service.d.ts.map +1 -1
  75. package/dest/events/event_service.js +20 -9
  76. package/dest/job_coordinator/job_coordinator.d.ts +3 -2
  77. package/dest/job_coordinator/job_coordinator.d.ts.map +1 -1
  78. package/dest/job_coordinator/job_coordinator.js +3 -2
  79. package/dest/logs/log_service.d.ts +9 -8
  80. package/dest/logs/log_service.d.ts.map +1 -1
  81. package/dest/logs/log_service.js +46 -54
  82. package/dest/messages/message_context_service.d.ts +17 -0
  83. package/dest/messages/message_context_service.d.ts.map +1 -0
  84. package/dest/messages/message_context_service.js +36 -0
  85. package/dest/notes/note_service.d.ts +7 -8
  86. package/dest/notes/note_service.d.ts.map +1 -1
  87. package/dest/notes/note_service.js +23 -14
  88. package/dest/notes_filter.d.ts +24 -0
  89. package/dest/notes_filter.d.ts.map +1 -0
  90. package/dest/notes_filter.js +4 -0
  91. package/dest/oracle_version.d.ts +3 -3
  92. package/dest/oracle_version.d.ts.map +1 -1
  93. package/dest/oracle_version.js +3 -3
  94. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts +4 -0
  95. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts.map +1 -0
  96. package/dest/private_kernel/hints/{compute_tx_include_by_timestamp.js → compute_tx_expiration_timestamp.js} +12 -12
  97. package/dest/private_kernel/hints/index.d.ts +1 -1
  98. package/dest/private_kernel/hints/index.js +1 -1
  99. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +4 -3
  100. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  101. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +129 -68
  102. package/dest/private_kernel/hints/test_utils.d.ts +122 -0
  103. package/dest/private_kernel/hints/test_utils.d.ts.map +1 -0
  104. package/dest/private_kernel/hints/test_utils.js +203 -0
  105. package/dest/private_kernel/private_kernel_execution_prover.d.ts +3 -2
  106. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  107. package/dest/private_kernel/private_kernel_execution_prover.js +21 -13
  108. package/dest/private_kernel/private_kernel_oracle.d.ts +6 -2
  109. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  110. package/dest/private_kernel/private_kernel_oracle.js +7 -3
  111. package/dest/pxe.d.ts +73 -24
  112. package/dest/pxe.d.ts.map +1 -1
  113. package/dest/pxe.js +130 -76
  114. package/dest/storage/address_store/address_store.d.ts +1 -1
  115. package/dest/storage/address_store/address_store.d.ts.map +1 -1
  116. package/dest/storage/address_store/address_store.js +12 -11
  117. package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -1
  118. package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
  119. package/dest/storage/anchor_block_store/anchor_block_store.js +8 -1
  120. package/dest/storage/capsule_store/capsule_service.d.ts +21 -0
  121. package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -0
  122. package/dest/storage/capsule_store/capsule_service.js +50 -0
  123. package/dest/storage/capsule_store/capsule_store.d.ts +9 -9
  124. package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
  125. package/dest/storage/capsule_store/capsule_store.js +39 -36
  126. package/dest/storage/capsule_store/index.d.ts +2 -1
  127. package/dest/storage/capsule_store/index.d.ts.map +1 -1
  128. package/dest/storage/capsule_store/index.js +1 -0
  129. package/dest/storage/contract_store/contract_store.d.ts +42 -15
  130. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  131. package/dest/storage/contract_store/contract_store.js +157 -72
  132. package/dest/storage/metadata.d.ts +1 -1
  133. package/dest/storage/metadata.js +1 -1
  134. package/dest/storage/note_store/note_store.d.ts +13 -3
  135. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  136. package/dest/storage/note_store/note_store.js +147 -107
  137. package/dest/storage/private_event_store/private_event_store.d.ts +1 -1
  138. package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
  139. package/dest/storage/private_event_store/private_event_store.js +84 -61
  140. package/dest/storage/private_event_store/stored_private_event.js +1 -1
  141. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
  142. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  143. package/dest/storage/tagging_store/recipient_tagging_store.js +31 -19
  144. package/dest/storage/tagging_store/sender_address_book_store.d.ts +1 -1
  145. package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +1 -1
  146. package/dest/storage/tagging_store/sender_address_book_store.js +20 -14
  147. package/dest/storage/tagging_store/sender_tagging_store.d.ts +29 -28
  148. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  149. package/dest/storage/tagging_store/sender_tagging_store.js +233 -137
  150. package/dest/tagging/get_all_logs_by_tags.d.ts +1 -1
  151. package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
  152. package/dest/tagging/get_all_logs_by_tags.js +17 -3
  153. package/dest/tagging/index.d.ts +3 -3
  154. package/dest/tagging/index.d.ts.map +1 -1
  155. package/dest/tagging/index.js +1 -1
  156. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +4 -5
  157. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
  158. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +7 -7
  159. package/dest/tagging/recipient_sync/utils/find_highest_indexes.js +2 -2
  160. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +6 -7
  161. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
  162. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +12 -11
  163. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -8
  164. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  165. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +13 -7
  166. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +4 -3
  167. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  168. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +20 -10
  169. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -7
  170. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  171. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +36 -24
  172. package/package.json +25 -16
  173. package/src/block_synchronizer/block_synchronizer.ts +27 -12
  174. package/src/config/index.ts +1 -1
  175. package/src/config/package_info.ts +1 -1
  176. package/src/contract_function_simulator/contract_function_simulator.ts +360 -133
  177. package/src/contract_function_simulator/execution_tagging_index_cache.ts +19 -14
  178. package/src/contract_function_simulator/index.ts +1 -0
  179. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +8 -8
  180. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -4
  181. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +3 -9
  182. package/src/contract_function_simulator/oracle/interfaces.ts +69 -60
  183. package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +98 -0
  184. package/src/contract_function_simulator/oracle/oracle.ts +245 -144
  185. package/src/contract_function_simulator/oracle/private_execution.ts +4 -4
  186. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +135 -184
  187. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +410 -145
  188. package/src/contract_logging.ts +52 -0
  189. package/src/contract_sync/contract_sync_service.ts +170 -0
  190. package/src/contract_sync/{index.ts → helpers.ts} +22 -22
  191. package/src/debug/pxe_debug_utils.ts +48 -18
  192. package/src/entrypoints/client/bundle/index.ts +2 -0
  193. package/src/entrypoints/client/bundle/utils.ts +16 -15
  194. package/src/entrypoints/client/lazy/index.ts +2 -0
  195. package/src/entrypoints/client/lazy/utils.ts +17 -15
  196. package/src/entrypoints/pxe_creation_options.ts +2 -1
  197. package/src/entrypoints/server/index.ts +2 -1
  198. package/src/entrypoints/server/utils.ts +22 -26
  199. package/src/events/event_service.ts +21 -10
  200. package/src/job_coordinator/job_coordinator.ts +4 -3
  201. package/src/logs/log_service.ts +87 -79
  202. package/src/messages/message_context_service.ts +44 -0
  203. package/src/notes/note_service.ts +24 -15
  204. package/src/notes_filter.ts +24 -0
  205. package/src/oracle_version.ts +3 -3
  206. package/src/private_kernel/hints/{compute_tx_include_by_timestamp.ts → compute_tx_expiration_timestamp.ts} +13 -13
  207. package/src/private_kernel/hints/index.ts +1 -1
  208. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +164 -117
  209. package/src/private_kernel/hints/test_utils.ts +325 -0
  210. package/src/private_kernel/private_kernel_execution_prover.ts +25 -15
  211. package/src/private_kernel/private_kernel_oracle.ts +7 -7
  212. package/src/pxe.ts +242 -129
  213. package/src/storage/address_store/address_store.ts +15 -15
  214. package/src/storage/anchor_block_store/anchor_block_store.ts +8 -0
  215. package/src/storage/capsule_store/capsule_service.ts +90 -0
  216. package/src/storage/capsule_store/capsule_store.ts +42 -34
  217. package/src/storage/capsule_store/index.ts +1 -0
  218. package/src/storage/contract_store/contract_store.ts +186 -76
  219. package/src/storage/metadata.ts +1 -1
  220. package/src/storage/note_store/note_store.ts +166 -132
  221. package/src/storage/private_event_store/private_event_store.ts +102 -81
  222. package/src/storage/private_event_store/stored_private_event.ts +1 -1
  223. package/src/storage/tagging_store/recipient_tagging_store.ts +38 -24
  224. package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
  225. package/src/storage/tagging_store/sender_tagging_store.ts +287 -156
  226. package/src/tagging/get_all_logs_by_tags.ts +28 -4
  227. package/src/tagging/index.ts +2 -2
  228. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +7 -10
  229. package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
  230. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +10 -15
  231. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +23 -10
  232. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +26 -11
  233. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +27 -26
  234. package/dest/contract_sync/index.d.ts +0 -23
  235. package/dest/contract_sync/index.d.ts.map +0 -1
  236. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +0 -4
  237. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +0 -1
package/src/pxe.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { PrivateEventFilter } from '@aztec/aztec.js/wallet';
2
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
- import { type Logger, createLogger } from '@aztec/foundation/log';
4
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
5
5
  import { SerialQueue } from '@aztec/foundation/queue';
6
6
  import { Timer } from '@aztec/foundation/timer';
7
7
  import { KeyStore } from '@aztec/key-store';
@@ -33,6 +33,7 @@ import type {
33
33
  PrivateKernelTailCircuitPublicInputs,
34
34
  } from '@aztec/stdlib/kernel';
35
35
  import {
36
+ BlockHeader,
36
37
  type ContractOverrides,
37
38
  type InTx,
38
39
  PrivateExecutionResult,
@@ -46,7 +47,7 @@ import {
46
47
  TxProfileResult,
47
48
  TxProvingResult,
48
49
  TxSimulationResult,
49
- UtilitySimulationResult,
50
+ UtilityExecutionResult,
50
51
  } from '@aztec/stdlib/tx';
51
52
 
52
53
  import { inspect } from 'util';
@@ -59,11 +60,14 @@ import {
59
60
  generateSimulatedProvingResult,
60
61
  } from './contract_function_simulator/contract_function_simulator.js';
61
62
  import { ProxiedContractStoreFactory } from './contract_function_simulator/proxied_contract_data_source.js';
62
- import { ensureContractSynced, readCurrentClassId } from './contract_sync/index.js';
63
+ import { displayDebugLogs } from './contract_logging.js';
64
+ import { ContractSyncService } from './contract_sync/contract_sync_service.js';
65
+ import { readCurrentClassId } from './contract_sync/helpers.js';
63
66
  import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
64
67
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
65
68
  import { PrivateEventFilterValidator } from './events/private_event_filter_validator.js';
66
69
  import { JobCoordinator } from './job_coordinator/job_coordinator.js';
70
+ import { MessageContextService } from './messages/message_context_service.js';
67
71
  import {
68
72
  PrivateKernelExecutionProver,
69
73
  type PrivateKernelExecutionProverConfig,
@@ -84,6 +88,58 @@ export type PackedPrivateEvent = InTx & {
84
88
  eventSelector: EventSelector;
85
89
  };
86
90
 
91
+ /** Options for PXE.profileTx. */
92
+ export type ProfileTxOpts = {
93
+ /** The profiling mode to use. */
94
+ profileMode: 'full' | 'execution-steps' | 'gates';
95
+ /** If true, proof generation is skipped during profiling. Defaults to true. */
96
+ skipProofGeneration?: boolean;
97
+ /** Addresses whose private state and keys are accessible during private execution. */
98
+ scopes: AztecAddress[];
99
+ };
100
+
101
+ /** Options for PXE.simulateTx. */
102
+ export type SimulateTxOpts = {
103
+ /** Whether to simulate the public part of the transaction. */
104
+ simulatePublic: boolean;
105
+ /** If false, this function throws if the transaction is unable to be included in a block at the current state. */
106
+ skipTxValidation?: boolean;
107
+ /** If false, fees are enforced. */
108
+ skipFeeEnforcement?: boolean;
109
+ /** If true, kernel logic is emulated in TS for simulation */
110
+ skipKernels?: boolean;
111
+ /** State overrides for the simulation, such as contract instances and artifacts. Requires skipKernels: true */
112
+ overrides?: SimulationOverrides;
113
+ /** Addresses whose private state and keys are accessible during private execution */
114
+ scopes: AztecAddress[];
115
+ };
116
+
117
+ /** Options for PXE.executeUtility. */
118
+ export type ExecuteUtilityOpts = {
119
+ /** The authentication witnesses required for the function call. */
120
+ authwits?: AuthWitness[];
121
+ /** The accounts whose notes we can access in this call */
122
+ scopes: AztecAddress[];
123
+ };
124
+
125
+ /** Args for PXE.create. */
126
+ export type PXECreateArgs = {
127
+ /** The Aztec node to connect to. */
128
+ node: AztecNode;
129
+ /** The key-value store for persisting PXE state. */
130
+ store: AztecAsyncKVStore;
131
+ /** The prover for generating private kernel proofs. */
132
+ proofCreator: PrivateKernelProver;
133
+ /** The circuit simulator for executing ACIR circuits. */
134
+ simulator: CircuitSimulator;
135
+ /** Provider for protocol contract artifacts and instances. */
136
+ protocolContractsProvider: ProtocolContractsProvider;
137
+ /** PXE configuration options. */
138
+ config: PXEConfig;
139
+ /** Optional logger instance or string suffix for the logger name. */
140
+ loggerOrSuffix?: string | Logger;
141
+ };
142
+
87
143
  /**
88
144
  * Private eXecution Environment (PXE) is a library used by wallets to simulate private phase of transactions and to
89
145
  * manage private state of users.
@@ -91,6 +147,7 @@ export type PackedPrivateEvent = InTx & {
91
147
  export class PXE {
92
148
  private constructor(
93
149
  private node: AztecNode,
150
+ private db: AztecAsyncKVStore,
94
151
  private blockStateSynchronizer: BlockSynchronizer,
95
152
  private keyStore: KeyStore,
96
153
  private contractStore: ContractStore,
@@ -102,6 +159,8 @@ export class PXE {
102
159
  private recipientTaggingStore: RecipientTaggingStore,
103
160
  private addressStore: AddressStore,
104
161
  private privateEventStore: PrivateEventStore,
162
+ private contractSyncService: ContractSyncService,
163
+ private messageContextService: MessageContextService,
105
164
  private simulator: CircuitSimulator,
106
165
  private proverEnabled: boolean,
107
166
  private proofCreator: PrivateKernelProver,
@@ -119,21 +178,27 @@ export class PXE {
119
178
  *
120
179
  * @returns A promise that resolves PXE is ready to be used.
121
180
  */
122
- public static async create(
123
- node: AztecNode,
124
- store: AztecAsyncKVStore,
125
- proofCreator: PrivateKernelProver,
126
- simulator: CircuitSimulator,
127
- protocolContractsProvider: ProtocolContractsProvider,
128
- config: PXEConfig,
129
- loggerOrSuffix?: string | Logger,
130
- ) {
181
+ public static async create({
182
+ node,
183
+ store,
184
+ proofCreator,
185
+ simulator,
186
+ protocolContractsProvider,
187
+ config,
188
+ loggerOrSuffix,
189
+ }: PXECreateArgs) {
190
+ // Extract bindings from the logger, or use empty bindings if a string suffix is provided.
191
+ const bindings: LoggerBindings | undefined =
192
+ loggerOrSuffix && typeof loggerOrSuffix !== 'string' ? loggerOrSuffix.getBindings() : undefined;
193
+
131
194
  const log =
132
195
  !loggerOrSuffix || typeof loggerOrSuffix === 'string'
133
196
  ? createLogger(loggerOrSuffix ? `pxe:service:${loggerOrSuffix}` : `pxe:service`)
134
197
  : loggerOrSuffix;
135
198
 
136
- const proverEnabled = !!config.proverEnabled;
199
+ const info = await node.getNodeInfo();
200
+
201
+ const proverEnabled = config.proverEnabled !== undefined ? config.proverEnabled : info.realProofs;
137
202
  const addressStore = new AddressStore(store);
138
203
  const privateEventStore = new PrivateEventStore(store);
139
204
  const contractStore = new ContractStore(store);
@@ -145,6 +210,14 @@ export class PXE {
145
210
  const capsuleStore = new CapsuleStore(store);
146
211
  const keyStore = new KeyStore(store);
147
212
  const tipsStore = new L2TipsKVStore(store, 'pxe');
213
+ const contractSyncService = new ContractSyncService(
214
+ node,
215
+ contractStore,
216
+ noteStore,
217
+ createLogger('pxe:contract_sync', bindings),
218
+ );
219
+ const messageContextService = new MessageContextService(node);
220
+
148
221
  const synchronizer = new BlockSynchronizer(
149
222
  node,
150
223
  store,
@@ -152,25 +225,28 @@ export class PXE {
152
225
  noteStore,
153
226
  privateEventStore,
154
227
  tipsStore,
228
+ contractSyncService,
155
229
  config,
156
- loggerOrSuffix,
230
+ bindings,
157
231
  );
158
232
 
159
- const jobCoordinator = new JobCoordinator(store);
233
+ const jobCoordinator = new JobCoordinator(store, bindings);
160
234
  jobCoordinator.registerStores([
161
235
  capsuleStore,
162
236
  senderTaggingStore,
163
237
  recipientTaggingStore,
164
238
  privateEventStore,
165
239
  noteStore,
240
+ contractSyncService,
166
241
  ]);
167
242
 
168
- const debugUtils = new PXEDebugUtils(contractStore, noteStore, synchronizer, anchorBlockStore);
243
+ const debugUtils = new PXEDebugUtils(contractSyncService, noteStore, synchronizer, anchorBlockStore);
169
244
 
170
245
  const jobQueue = new SerialQueue();
171
246
 
172
247
  const pxe = new PXE(
173
248
  node,
249
+ store,
174
250
  synchronizer,
175
251
  keyStore,
176
252
  contractStore,
@@ -182,6 +258,8 @@ export class PXE {
182
258
  recipientTaggingStore,
183
259
  addressStore,
184
260
  privateEventStore,
261
+ contractSyncService,
262
+ messageContextService,
185
263
  simulator,
186
264
  proverEnabled,
187
265
  proofCreator,
@@ -192,12 +270,15 @@ export class PXE {
192
270
  debugUtils,
193
271
  );
194
272
 
195
- debugUtils.setPXE(pxe, pxe.#putInJobQueue.bind(pxe));
273
+ debugUtils.setPXEHelpers(
274
+ pxe.#putInJobQueue.bind(pxe),
275
+ pxe.#getSimulatorForTx.bind(pxe),
276
+ pxe.#executeUtility.bind(pxe),
277
+ );
196
278
 
197
279
  pxe.jobQueue.start();
198
280
 
199
281
  await pxe.#registerProtocolContracts();
200
- const info = await node.getNodeInfo();
201
282
  log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.rollupVersion}`);
202
283
  return pxe;
203
284
  }
@@ -207,20 +288,21 @@ export class PXE {
207
288
  #getSimulatorForTx(overrides?: { contracts?: ContractOverrides }) {
208
289
  const proxyContractStore = ProxiedContractStoreFactory.create(this.contractStore, overrides?.contracts);
209
290
 
210
- return new ContractFunctionSimulator(
211
- proxyContractStore,
212
- this.noteStore,
213
- this.keyStore,
214
- this.addressStore,
215
- BenchmarkedNodeFactory.create(this.node),
216
- this.anchorBlockStore,
217
- this.senderTaggingStore,
218
- this.recipientTaggingStore,
219
- this.senderAddressBookStore,
220
- this.capsuleStore,
221
- this.privateEventStore,
222
- this.simulator,
223
- );
291
+ return new ContractFunctionSimulator({
292
+ contractStore: proxyContractStore,
293
+ noteStore: this.noteStore,
294
+ keyStore: this.keyStore,
295
+ addressStore: this.addressStore,
296
+ aztecNode: BenchmarkedNodeFactory.create(this.node),
297
+ senderTaggingStore: this.senderTaggingStore,
298
+ recipientTaggingStore: this.recipientTaggingStore,
299
+ senderAddressBookStore: this.senderAddressBookStore,
300
+ capsuleStore: this.capsuleStore,
301
+ privateEventStore: this.privateEventStore,
302
+ simulator: this.simulator,
303
+ contractSyncService: this.contractSyncService,
304
+ messageContextService: this.messageContextService,
305
+ });
224
306
  }
225
307
 
226
308
  #contextualizeError(err: Error, ...context: string[]): Error {
@@ -272,9 +354,8 @@ export class PXE {
272
354
  async #registerProtocolContracts() {
273
355
  const registered: Record<string, string> = {};
274
356
  for (const name of protocolContractNames) {
275
- const { address, contractClass, instance, artifact } =
276
- await this.protocolContractsProvider.getProtocolContractArtifact(name);
277
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
357
+ const { address, instance, artifact } = await this.protocolContractsProvider.getProtocolContractArtifact(name);
358
+ await this.contractStore.addContractArtifact(artifact);
278
359
  await this.contractStore.addContractInstance(instance);
279
360
  registered[name] = address.toString();
280
361
  }
@@ -286,7 +367,7 @@ export class PXE {
286
367
  async #executePrivate(
287
368
  contractFunctionSimulator: ContractFunctionSimulator,
288
369
  txRequest: TxExecutionRequest,
289
- scopes: AztecAddress[] | undefined,
370
+ scopes: AztecAddress[],
290
371
  jobId: string,
291
372
  ): Promise<PrivateExecutionResult> {
292
373
  const { origin: contractAddress, functionSelector } = txRequest;
@@ -294,27 +375,23 @@ export class PXE {
294
375
  try {
295
376
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
296
377
 
297
- await ensureContractSynced(
378
+ await this.contractSyncService.ensureContractSynced(
298
379
  contractAddress,
299
380
  functionSelector,
300
- privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
301
- this.node,
302
- this.contractStore,
381
+ (privateSyncCall, execScopes) =>
382
+ this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
303
383
  anchorBlockHeader,
384
+ jobId,
385
+ scopes,
304
386
  );
305
387
 
306
- const result = await contractFunctionSimulator.run(
307
- txRequest,
388
+ const result = await contractFunctionSimulator.run(txRequest, {
308
389
  contractAddress,
309
- functionSelector,
310
- undefined,
390
+ selector: functionSelector,
311
391
  anchorBlockHeader,
312
- // The sender for tags is set by contracts, typically by an account
313
- // contract entrypoint
314
- undefined, // senderForTags
315
392
  scopes,
316
393
  jobId,
317
- );
394
+ });
318
395
  this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
319
396
  return result;
320
397
  } catch (err) {
@@ -326,25 +403,32 @@ export class PXE {
326
403
  }
327
404
 
328
405
  /**
329
- * Simulate a utility function call on the given contract.
406
+ * Execute a utility function call on the given contract.
330
407
  * @param contractFunctionSimulator - The simulator to use for the function call.
331
408
  * @param call - The function call to execute.
332
409
  * @param authWitnesses - Authentication witnesses required for the function call.
333
410
  * @param scopes - Optional array of account addresses whose notes can be accessed in this call. Defaults to all
334
411
  * accounts if not specified.
335
412
  * @param jobId - The job ID for staged writes.
336
- * @returns The simulation result containing the outputs of the utility function.
413
+ * @returns The execution result containing the outputs of the utility function.
337
414
  */
338
- async #simulateUtility(
415
+ async #executeUtility(
339
416
  contractFunctionSimulator: ContractFunctionSimulator,
340
417
  call: FunctionCall,
341
418
  authWitnesses: AuthWitness[] | undefined,
342
- scopes: AztecAddress[] | undefined,
419
+ scopes: AztecAddress[],
343
420
  jobId: string,
344
421
  ) {
345
422
  try {
346
423
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
347
- return contractFunctionSimulator.runUtility(call, authWitnesses ?? [], anchorBlockHeader, scopes, jobId);
424
+ const { result, offchainEffects } = await contractFunctionSimulator.runUtility(
425
+ call,
426
+ authWitnesses ?? [],
427
+ anchorBlockHeader,
428
+ scopes,
429
+ jobId,
430
+ );
431
+ return { result, offchainEffects };
348
432
  } catch (err) {
349
433
  if (err instanceof SimulationError) {
350
434
  await enrichSimulationError(err, this.contractStore, this.log);
@@ -400,13 +484,33 @@ export class PXE {
400
484
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
401
485
  const anchorBlockHash = await anchorBlockHeader.hash();
402
486
  const kernelOracle = new PrivateKernelOracle(this.contractStore, this.keyStore, this.node, anchorBlockHash);
403
- const kernelTraceProver = new PrivateKernelExecutionProver(kernelOracle, proofCreator, !this.proverEnabled);
487
+ const kernelTraceProver = new PrivateKernelExecutionProver(
488
+ kernelOracle,
489
+ proofCreator,
490
+ !this.proverEnabled,
491
+ this.log.getBindings(),
492
+ );
404
493
  this.log.debug(`Executing kernel trace prover (${JSON.stringify(config)})...`);
405
494
  return await kernelTraceProver.proveWithKernels(txExecutionRequest.toTxRequest(), privateExecutionResult, config);
406
495
  }
407
496
 
408
497
  // Public API
409
498
 
499
+ /**
500
+ * Returns the block header up to which the PXE has synced.
501
+ * @returns The synced block header
502
+ */
503
+ public getSyncedBlockHeader(): Promise<BlockHeader> {
504
+ return this.#putInJobQueue(() => {
505
+ return this.anchorBlockStore.getBlockHeader();
506
+ });
507
+ }
508
+
509
+ /**
510
+ * Returns the contract instance for a given address, if it's registered in the PXE.
511
+ * @param address - The contract address.
512
+ * @returns The contract instance if found, undefined otherwise.
513
+ */
410
514
  public getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
411
515
  return this.contractStore.getContractInstance(address);
412
516
  }
@@ -466,6 +570,9 @@ export class PXE {
466
570
 
467
571
  if (wasAdded) {
468
572
  this.log.info(`Added sender:\n ${sender.toString()}`);
573
+ // Wipe the entire sync cache: the new sender's tagged logs could contain notes/events for any contract, so
574
+ // all contracts must re-sync to discover them.
575
+ this.contractSyncService.wipe();
469
576
  } else {
470
577
  this.log.info(`Sender:\n "${sender.toString()}"\n already registered.`);
471
578
  }
@@ -515,8 +622,7 @@ export class PXE {
515
622
  * @param artifact - The build artifact for the contract class.
516
623
  */
517
624
  public async registerContractClass(artifact: ContractArtifact): Promise<void> {
518
- const { id: contractClassId } = await getContractClassFromArtifact(artifact);
519
- await this.contractStore.addContractArtifact(contractClassId, artifact);
625
+ const contractClassId = await this.contractStore.addContractArtifact(artifact);
520
626
  this.log.info(`Added contract class ${artifact.name} with id ${contractClassId}`);
521
627
  }
522
628
 
@@ -535,17 +641,17 @@ export class PXE {
535
641
  if (artifact) {
536
642
  // If the user provides an artifact, validate it against the expected class id and register it
537
643
  const contractClass = await getContractClassFromArtifact(artifact);
538
- const contractClassId = contractClass.id;
539
- if (!contractClassId.equals(instance.currentContractClassId)) {
644
+ if (!contractClass.id.equals(instance.currentContractClassId)) {
540
645
  throw new Error(
541
- `Artifact does not match expected class id (computed ${contractClassId} but instance refers to ${instance.currentContractClassId})`,
646
+ `Artifact does not match expected class id (computed ${contractClass.id} but instance refers to ${instance.currentContractClassId})`,
542
647
  );
543
648
  }
544
649
  const computedAddress = await computeContractAddressFromInstance(instance);
545
650
  if (!computedAddress.equals(instance.address)) {
546
651
  throw new Error('Added a contract in which the address does not match the contract instance.');
547
652
  }
548
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
653
+
654
+ await this.contractStore.addContractArtifact(artifact, contractClass);
549
655
 
550
656
  const publicFunctionSignatures = artifact.functions
551
657
  .filter(fn => fn.functionType === FunctionType.PUBLIC)
@@ -594,15 +700,16 @@ export class PXE {
594
700
  throw new Error('Could not update contract to a class different from the current one.');
595
701
  }
596
702
 
597
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
598
-
599
703
  const publicFunctionSignatures = artifact.functions
600
704
  .filter(fn => fn.functionType === FunctionType.PUBLIC)
601
705
  .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
602
706
  await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
603
707
 
604
708
  currentInstance.currentContractClassId = contractClass.id;
605
- await this.contractStore.addContractInstance(currentInstance);
709
+ await Promise.all([
710
+ this.contractStore.addContractArtifact(artifact, contractClass),
711
+ this.contractStore.addContractInstance(currentInstance),
712
+ ]);
606
713
  this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
607
714
  });
608
715
  }
@@ -620,11 +727,12 @@ export class PXE {
620
727
  * (where validators prove the public portion).
621
728
  *
622
729
  * @param txRequest - An authenticated tx request ready for proving
730
+ * @param scopes - Addresses whose private state and keys are accessible during private execution.
623
731
  * @returns A result containing the proof and public inputs of the tail circuit.
624
732
  * @throws If contract code not found, or public simulation reverts.
625
733
  * Also throws if simulatePublic is true and public simulation reverts.
626
734
  */
627
- public proveTx(txRequest: TxExecutionRequest): Promise<TxProvingResult> {
735
+ public proveTx(txRequest: TxExecutionRequest, scopes: AztecAddress[]): Promise<TxProvingResult> {
628
736
  let privateExecutionResult: PrivateExecutionResult;
629
737
  // We disable proving concurrently mostly out of caution, since it accesses some of our stores. Proving is so
630
738
  // computationally demanding that it'd be rare for someone to try to do it concurrently regardless.
@@ -635,7 +743,7 @@ export class PXE {
635
743
  await this.blockStateSynchronizer.sync();
636
744
  const syncTime = syncTimer.ms();
637
745
  const contractFunctionSimulator = this.#getSimulatorForTx();
638
- privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, undefined, jobId);
746
+ privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, scopes, jobId);
639
747
 
640
748
  const {
641
749
  publicInputs,
@@ -677,17 +785,17 @@ export class PXE {
677
785
  // transaction before this one is included in a block from this PXE, and that transaction contains a log with
678
786
  // a tag derived from the same secret, we would reuse the tag and the transactions would be linked. Hence
679
787
  // storing the tags here prevents linkage of txs sent from the same PXE.
680
- const preTagsUsedInTheTx = privateExecutionResult.entrypoint.preTags;
681
- if (preTagsUsedInTheTx.length > 0) {
788
+ const taggingIndexRangesUsedInTheTx = privateExecutionResult.entrypoint.taggingIndexRanges;
789
+ if (taggingIndexRangesUsedInTheTx.length > 0) {
682
790
  // TODO(benesjan): The following is an expensive operation. Figure out a way to avoid it.
683
791
  const txHash = (await txProvingResult.toTx()).txHash;
684
792
 
685
- await this.senderTaggingStore.storePendingIndexes(preTagsUsedInTheTx, txHash, jobId);
686
- this.log.debug(`Stored used pre-tags as sender for the tx`, {
687
- preTagsUsedInTheTx,
793
+ await this.senderTaggingStore.storePendingIndexes(taggingIndexRangesUsedInTheTx, txHash, jobId);
794
+ this.log.debug(`Stored used tagging index ranges as sender for the tx`, {
795
+ taggingIndexRangesUsedInTheTx,
688
796
  });
689
797
  } else {
690
- this.log.debug(`No pre-tags used in the tx`);
798
+ this.log.debug(`No tagging index ranges used in the tx`);
691
799
  }
692
800
 
693
801
  return txProvingResult;
@@ -699,17 +807,13 @@ export class PXE {
699
807
 
700
808
  /**
701
809
  * Profiles a transaction, reporting gate counts (unless disabled) and returns an execution trace.
702
- *
703
- * @param txRequest - An authenticated tx request ready for simulation
704
- * @param msgSender - (Optional) The message sender to use for the simulation.
705
- * @param skipTxValidation - (Optional) If false, this function throws if the transaction is unable to be included in a block at the current state.
810
+ * @param txRequest - An authenticated tx request ready for simulation.
706
811
  * @returns A trace of the program execution with gate counts.
707
812
  * @throws If the code for the functions executed in this transaction have not been made available via `addContracts`.
708
813
  */
709
814
  public profileTx(
710
815
  txRequest: TxExecutionRequest,
711
- profileMode: 'full' | 'execution-steps' | 'gates',
712
- skipProofGeneration: boolean = true,
816
+ { profileMode, skipProofGeneration = true, scopes }: ProfileTxOpts,
713
817
  ): Promise<TxProfileResult> {
714
818
  // We disable concurrent profiles for consistency with simulateTx.
715
819
  return this.#putInJobQueue(async jobId => {
@@ -732,12 +836,7 @@ export class PXE {
732
836
  const syncTime = syncTimer.ms();
733
837
 
734
838
  const contractFunctionSimulator = this.#getSimulatorForTx();
735
- const privateExecutionResult = await this.#executePrivate(
736
- contractFunctionSimulator,
737
- txRequest,
738
- undefined,
739
- jobId,
740
- );
839
+ const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, scopes, jobId);
741
840
 
742
841
  const { executionSteps, timings: { proving } = {} } = await this.#prove(
743
842
  txRequest,
@@ -794,12 +893,7 @@ export class PXE {
794
893
  * In that case, the transaction returned is only potentially ready to be sent to the network for execution.
795
894
  *
796
895
  *
797
- * @param txRequest - An authenticated tx request ready for simulation
798
- * @param simulatePublic - Whether to simulate the public part of the transaction.
799
- * @param skipTxValidation - (Optional) If false, this function throws if the transaction is unable to be included in a block at the current state.
800
- * @param skipFeeEnforcement - (Optional) If false, fees are enforced.
801
- * @param overrides - (Optional) State overrides for the simulation, such as msgSender, contract instances and artifacts.
802
- * @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will default to all.
896
+ * @param txRequest - An authenticated tx request ready for simulation.
803
897
  * @returns A simulated transaction result object that includes public and private return values.
804
898
  * @throws If the code for the functions executed in this transaction have not been made available via `addContracts`.
805
899
  * Also throws if simulatePublic is true and public simulation reverts.
@@ -808,11 +902,14 @@ export class PXE {
808
902
  */
809
903
  public simulateTx(
810
904
  txRequest: TxExecutionRequest,
811
- simulatePublic: boolean,
812
- skipTxValidation: boolean = false,
813
- skipFeeEnforcement: boolean = false,
814
- overrides?: SimulationOverrides,
815
- scopes?: AztecAddress[],
905
+ {
906
+ simulatePublic,
907
+ skipTxValidation = false,
908
+ skipFeeEnforcement = false,
909
+ skipKernels = true,
910
+ overrides,
911
+ scopes,
912
+ }: SimulateTxOpts,
816
913
  ): Promise<TxSimulationResult> {
817
914
  // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
818
915
  // to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
@@ -836,11 +933,21 @@ export class PXE {
836
933
  await this.blockStateSynchronizer.sync();
837
934
  const syncTime = syncTimer.ms();
838
935
 
936
+ const overriddenContracts = overrides?.contracts ? new Set(Object.keys(overrides.contracts)) : undefined;
937
+ const hasOverriddenContracts = overriddenContracts !== undefined && overriddenContracts.size > 0;
938
+
939
+ if (hasOverriddenContracts && !skipKernels) {
940
+ throw new Error(
941
+ 'Simulating with overridden contracts is not compatible with kernel execution. Please set skipKernels to true when simulating with overridden contracts.',
942
+ );
943
+ }
839
944
  const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
840
- // Temporary: in case there are overrides, we have to skip the kernels or validations
841
- // will fail. Consider handing control to the user/wallet on whether they want to run them
842
- // or not.
843
- const skipKernels = overrides?.contracts !== undefined && Object.keys(overrides.contracts ?? {}).length > 0;
945
+
946
+ if (hasOverriddenContracts) {
947
+ // Overridden contracts don't have a sync function, so calling sync on them would fail.
948
+ // We exclude them so the sync service skips them entirely.
949
+ this.contractSyncService.setExcludedFromSync(jobId, overriddenContracts);
950
+ }
844
951
 
845
952
  // Execution of private functions only; no proving, and no kernel logic.
846
953
  const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, scopes, jobId);
@@ -851,7 +958,8 @@ export class PXE {
851
958
  if (skipKernels) {
852
959
  ({ publicInputs, executionSteps } = await generateSimulatedProvingResult(
853
960
  privateExecutionResult,
854
- this.contractStore,
961
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
962
+ this.node,
855
963
  ));
856
964
  } else {
857
965
  // Kernel logic, plus proving of all private functions and kernels.
@@ -870,6 +978,9 @@ export class PXE {
870
978
  const publicSimulationTimer = new Timer();
871
979
  publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
872
980
  publicSimulationTime = publicSimulationTimer.ms();
981
+ if (publicOutput?.debugLogs?.length) {
982
+ await displayDebugLogs(publicOutput.debugLogs, addr => this.contractStore.getDebugContractName(addr));
983
+ }
873
984
  }
874
985
 
875
986
  let validationTime: number | undefined;
@@ -878,7 +989,8 @@ export class PXE {
878
989
  const validationResult = await this.node.isValidTx(simulatedTx, { isSimulation: true, skipFeeEnforcement });
879
990
  validationTime = validationTimer.ms();
880
991
  if (validationResult.result === 'invalid') {
881
- throw new Error('The simulated transaction is unable to be added to state and is invalid.');
992
+ const reason = validationResult.reason.length > 0 ? ` Reason: ${validationResult.reason.join(', ')}` : '';
993
+ throw new Error(`The simulated transaction is unable to be added to state and is invalid.${reason}`);
882
994
  }
883
995
  }
884
996
 
@@ -929,29 +1041,23 @@ export class PXE {
929
1041
  inspect(txRequest),
930
1042
  `simulatePublic=${simulatePublic}`,
931
1043
  `skipTxValidation=${skipTxValidation}`,
932
- `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
1044
+ `scopes=${scopes.map(s => s.toString()).join(', ')}`,
933
1045
  );
934
1046
  }
935
1047
  });
936
1048
  }
937
1049
 
938
1050
  /**
939
- * Simulate the execution of a contract utility function.
940
- *
1051
+ * Executes a contract utility function.
941
1052
  * @param call - The function call containing the function details, arguments, and target contract address.
942
- * @param authwits - (Optional) The authentication witnesses required for the function call.
943
- * @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will
944
- * default to all.
945
- * @returns The result of the utility function call, structured based on the function ABI.
946
1053
  */
947
- public simulateUtility(
1054
+ public executeUtility(
948
1055
  call: FunctionCall,
949
- authwits?: AuthWitness[],
950
- scopes?: AztecAddress[],
951
- ): Promise<UtilitySimulationResult> {
952
- // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
1056
+ { authwits, scopes }: ExecuteUtilityOpts = { scopes: [] },
1057
+ ): Promise<UtilityExecutionResult> {
1058
+ // We disable concurrent executions since those might execute oracles which read and write to the PXE stores (e.g.
953
1059
  // to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
954
- // delete the same read value, or reading values that another simulation is currently modifying).
1060
+ // delete the same read value, or reading values that another execution is currently modifying).
955
1061
  return this.#putInJobQueue(async jobId => {
956
1062
  try {
957
1063
  const totalTimer = new Timer();
@@ -962,16 +1068,17 @@ export class PXE {
962
1068
  const contractFunctionSimulator = this.#getSimulatorForTx();
963
1069
 
964
1070
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
965
- await ensureContractSynced(
1071
+ await this.contractSyncService.ensureContractSynced(
966
1072
  call.to,
967
1073
  call.selector,
968
- privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
969
- this.node,
970
- this.contractStore,
1074
+ (privateSyncCall, execScopes) =>
1075
+ this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
971
1076
  anchorBlockHeader,
1077
+ jobId,
1078
+ scopes,
972
1079
  );
973
1080
 
974
- const executionResult = await this.#simulateUtility(
1081
+ const { result: executionResult, offchainEffects } = await this.#executeUtility(
975
1082
  contractFunctionSimulator,
976
1083
  call,
977
1084
  authwits ?? [],
@@ -992,14 +1099,19 @@ export class PXE {
992
1099
  };
993
1100
 
994
1101
  const simulationStats = contractFunctionSimulator.getStats();
995
- return { result: executionResult, stats: { timings, nodeRPCCalls: simulationStats.nodeRPCCalls } };
1102
+ return {
1103
+ result: executionResult,
1104
+ offchainEffects,
1105
+ anchorBlockTimestamp: anchorBlockHeader.globalVariables.timestamp,
1106
+ stats: { timings, nodeRPCCalls: simulationStats.nodeRPCCalls },
1107
+ };
996
1108
  } catch (err: any) {
997
1109
  const { to, name, args } = call;
998
1110
  const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
999
1111
  throw this.#contextualizeError(
1000
1112
  err,
1001
- `simulateUtility ${to}:${name}(${stringifiedArgs})`,
1002
- `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
1113
+ `executeUtility ${to}:${name}(${stringifiedArgs})`,
1114
+ `scopes=${scopes.map(s => s.toString()).join(', ')}`,
1003
1115
  );
1004
1116
  }
1005
1117
  });
@@ -1032,14 +1144,14 @@ export class PXE {
1032
1144
 
1033
1145
  const contractFunctionSimulator = this.#getSimulatorForTx();
1034
1146
 
1035
- await ensureContractSynced(
1147
+ await this.contractSyncService.ensureContractSynced(
1036
1148
  filter.contractAddress,
1037
1149
  null,
1038
- async privateSyncCall =>
1039
- await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
1040
- this.node,
1041
- this.contractStore,
1150
+ async (privateSyncCall, execScopes) =>
1151
+ await this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
1042
1152
  anchorBlockHeader,
1153
+ jobId,
1154
+ filter.scopes,
1043
1155
  );
1044
1156
  });
1045
1157
 
@@ -1054,9 +1166,10 @@ export class PXE {
1054
1166
  }
1055
1167
 
1056
1168
  /**
1057
- * Stops the PXE's job queue.
1169
+ * Stops the PXE's job queue and closes the backing store.
1058
1170
  */
1059
- public stop(): Promise<void> {
1060
- return this.jobQueue.end();
1171
+ public async stop(): Promise<void> {
1172
+ await this.jobQueue.end();
1173
+ await this.db.close();
1061
1174
  }
1062
1175
  }