@aztec/pxe 0.0.1-commit.e558bd1c → 0.0.1-commit.e57c76e

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 (345) hide show
  1. package/dest/bin/check_oracle_version.js +43 -99
  2. package/dest/bin/index.d.ts +2 -0
  3. package/dest/bin/index.d.ts.map +1 -0
  4. package/dest/bin/index.js +1 -0
  5. package/dest/bin/oracle_version_helpers.d.ts +26 -0
  6. package/dest/bin/oracle_version_helpers.d.ts.map +1 -0
  7. package/dest/bin/oracle_version_helpers.js +93 -0
  8. package/dest/block_synchronizer/block_stream_source.d.ts +10 -0
  9. package/dest/block_synchronizer/block_stream_source.d.ts.map +1 -0
  10. package/dest/block_synchronizer/block_stream_source.js +62 -0
  11. package/dest/block_synchronizer/block_synchronizer.d.ts +6 -2
  12. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  13. package/dest/block_synchronizer/block_synchronizer.js +30 -10
  14. package/dest/config/index.d.ts +8 -2
  15. package/dest/config/index.d.ts.map +1 -1
  16. package/dest/config/index.js +13 -15
  17. package/dest/config/package_info.js +1 -1
  18. package/dest/contract_function_simulator/contract_function_simulator.d.ts +65 -30
  19. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  20. package/dest/contract_function_simulator/contract_function_simulator.js +215 -76
  21. package/dest/contract_function_simulator/ephemeral_array_service.d.ts +28 -0
  22. package/dest/contract_function_simulator/ephemeral_array_service.d.ts.map +1 -0
  23. package/dest/contract_function_simulator/ephemeral_array_service.js +78 -0
  24. package/dest/contract_function_simulator/execution_note_cache.d.ts +2 -2
  25. package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
  26. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +7 -11
  27. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
  28. package/dest/contract_function_simulator/execution_tagging_index_cache.js +19 -15
  29. package/dest/contract_function_simulator/index.d.ts +14 -2
  30. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  31. package/dest/contract_function_simulator/index.js +11 -0
  32. package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts +48 -0
  33. package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts.map +1 -0
  34. package/dest/contract_function_simulator/noir-structs/bounded_vec.js +45 -0
  35. package/dest/contract_function_simulator/noir-structs/ephemeral_array.d.ts +37 -0
  36. package/dest/contract_function_simulator/noir-structs/ephemeral_array.d.ts.map +1 -0
  37. package/dest/contract_function_simulator/noir-structs/ephemeral_array.js +59 -0
  38. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -4
  39. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  40. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +8 -9
  41. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +13 -3
  42. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -1
  43. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +35 -4
  44. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +2 -2
  45. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  46. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +2 -4
  47. package/dest/contract_function_simulator/noir-structs/note_data.d.ts +27 -0
  48. package/dest/contract_function_simulator/noir-structs/note_data.d.ts.map +1 -0
  49. package/dest/contract_function_simulator/noir-structs/note_data.js +3 -0
  50. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +3 -5
  51. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
  52. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +6 -10
  53. package/dest/contract_function_simulator/noir-structs/option.d.ts +61 -0
  54. package/dest/contract_function_simulator/noir-structs/option.d.ts.map +1 -0
  55. package/dest/contract_function_simulator/noir-structs/option.js +62 -0
  56. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts +11 -0
  57. package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts.map +1 -0
  58. package/dest/contract_function_simulator/noir-structs/provided_secret.js +24 -0
  59. package/dest/contract_function_simulator/oracle/interfaces.d.ts +16 -98
  60. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  61. package/dest/contract_function_simulator/oracle/interfaces.js +2 -2
  62. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +2 -2
  63. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
  64. package/dest/contract_function_simulator/oracle/note_packing_utils.js +2 -2
  65. package/dest/contract_function_simulator/oracle/oracle.d.ts +75 -46
  66. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  67. package/dest/contract_function_simulator/oracle/oracle.js +471 -287
  68. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +127 -0
  69. package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -0
  70. package/dest/contract_function_simulator/oracle/oracle_registry.js +786 -0
  71. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +139 -0
  72. package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -0
  73. package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +560 -0
  74. package/dest/contract_function_simulator/oracle/private_execution.js +5 -3
  75. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +68 -97
  76. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  77. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +140 -109
  78. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +146 -72
  79. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  80. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +433 -157
  81. package/dest/contract_function_simulator/pick_notes.d.ts +1 -1
  82. package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -1
  83. package/dest/contract_function_simulator/pick_notes.js +20 -3
  84. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +1 -1
  85. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +1 -1
  86. package/dest/contract_function_simulator/proxied_contract_data_source.js +35 -64
  87. package/dest/contract_logging.d.ts +27 -0
  88. package/dest/contract_logging.d.ts.map +1 -0
  89. package/dest/contract_logging.js +38 -0
  90. package/dest/contract_sync/contract_sync_service.d.ts +8 -7
  91. package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
  92. package/dest/contract_sync/contract_sync_service.js +93 -40
  93. package/dest/contract_sync/helpers.d.ts +2 -3
  94. package/dest/contract_sync/helpers.d.ts.map +1 -1
  95. package/dest/contract_sync/helpers.js +12 -14
  96. package/dest/debug/pxe_debug_utils.d.ts +5 -11
  97. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  98. package/dest/debug/pxe_debug_utils.js +4 -13
  99. package/dest/entrypoints/client/bundle/index.d.ts +3 -1
  100. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  101. package/dest/entrypoints/client/bundle/index.js +2 -0
  102. package/dest/entrypoints/client/bundle/utils.d.ts +2 -2
  103. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  104. package/dest/entrypoints/client/bundle/utils.js +21 -5
  105. package/dest/entrypoints/client/lazy/index.d.ts +3 -1
  106. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  107. package/dest/entrypoints/client/lazy/index.js +2 -0
  108. package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
  109. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  110. package/dest/entrypoints/client/lazy/utils.js +21 -5
  111. package/dest/entrypoints/pxe_creation_options.d.ts +9 -1
  112. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  113. package/dest/entrypoints/pxe_creation_options.js +3 -1
  114. package/dest/entrypoints/server/index.d.ts +4 -2
  115. package/dest/entrypoints/server/index.d.ts.map +1 -1
  116. package/dest/entrypoints/server/index.js +3 -1
  117. package/dest/entrypoints/server/utils.d.ts +4 -3
  118. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  119. package/dest/entrypoints/server/utils.js +21 -5
  120. package/dest/events/event_service.d.ts +15 -6
  121. package/dest/events/event_service.d.ts.map +1 -1
  122. package/dest/events/event_service.js +44 -11
  123. package/dest/events/private_event_filter_validator.d.ts +3 -2
  124. package/dest/events/private_event_filter_validator.d.ts.map +1 -1
  125. package/dest/events/private_event_filter_validator.js +15 -0
  126. package/dest/hooks/authorize_utility_call.d.ts +41 -0
  127. package/dest/hooks/authorize_utility_call.d.ts.map +1 -0
  128. package/dest/hooks/authorize_utility_call.js +4 -0
  129. package/dest/hooks/execution_hooks.d.ts +42 -0
  130. package/dest/hooks/execution_hooks.d.ts.map +1 -0
  131. package/dest/hooks/execution_hooks.js +9 -0
  132. package/dest/hooks/index.d.ts +4 -0
  133. package/dest/hooks/index.d.ts.map +1 -0
  134. package/dest/hooks/index.js +1 -0
  135. package/dest/logs/log_service.d.ts +9 -8
  136. package/dest/logs/log_service.d.ts.map +1 -1
  137. package/dest/logs/log_service.js +130 -81
  138. package/dest/messages/message_context_service.d.ts +17 -0
  139. package/dest/messages/message_context_service.d.ts.map +1 -0
  140. package/dest/messages/message_context_service.js +55 -0
  141. package/dest/notes/note_service.d.ts +27 -5
  142. package/dest/notes/note_service.d.ts.map +1 -1
  143. package/dest/notes/note_service.js +83 -58
  144. package/dest/notes_filter.d.ts +24 -0
  145. package/dest/notes_filter.d.ts.map +1 -0
  146. package/dest/notes_filter.js +4 -0
  147. package/dest/oracle_version.d.ts +4 -3
  148. package/dest/oracle_version.d.ts.map +1 -1
  149. package/dest/oracle_version.js +20 -10
  150. package/dest/private_kernel/batch_planner.d.ts +47 -0
  151. package/dest/private_kernel/batch_planner.d.ts.map +1 -0
  152. package/dest/private_kernel/batch_planner.js +104 -0
  153. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts +4 -0
  154. package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts.map +1 -0
  155. package/dest/private_kernel/hints/{compute_tx_include_by_timestamp.js → compute_tx_expiration_timestamp.js} +12 -12
  156. package/dest/private_kernel/hints/index.d.ts +1 -1
  157. package/dest/private_kernel/hints/index.js +1 -1
  158. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +4 -3
  159. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
  160. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +130 -69
  161. package/dest/private_kernel/hints/test_utils.d.ts +122 -0
  162. package/dest/private_kernel/hints/test_utils.d.ts.map +1 -0
  163. package/dest/private_kernel/hints/test_utils.js +202 -0
  164. package/dest/private_kernel/private_kernel_execution_prover.d.ts +6 -2
  165. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  166. package/dest/private_kernel/private_kernel_execution_prover.js +166 -65
  167. package/dest/private_kernel/private_kernel_oracle.d.ts +15 -11
  168. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  169. package/dest/private_kernel/private_kernel_oracle.js +31 -25
  170. package/dest/pxe.d.ts +119 -24
  171. package/dest/pxe.d.ts.map +1 -1
  172. package/dest/pxe.js +223 -137
  173. package/dest/storage/anchor_block_store/anchor_block_store.js +1 -1
  174. package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.d.ts +42 -0
  175. package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.d.ts.map +1 -0
  176. package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.js +93 -0
  177. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +15 -0
  178. package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -0
  179. package/dest/storage/backwards_compatibility_tests/schema_tests.js +591 -0
  180. package/dest/storage/backwards_compatibility_tests/store_spy.d.ts +19 -0
  181. package/dest/storage/backwards_compatibility_tests/store_spy.d.ts.map +1 -0
  182. package/dest/storage/backwards_compatibility_tests/store_spy.js +63 -0
  183. package/dest/storage/capsule_store/capsule_service.d.ts +21 -0
  184. package/dest/storage/capsule_store/capsule_service.d.ts.map +1 -0
  185. package/dest/storage/capsule_store/capsule_service.js +50 -0
  186. package/dest/storage/capsule_store/capsule_store.d.ts +9 -9
  187. package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
  188. package/dest/storage/capsule_store/capsule_store.js +36 -28
  189. package/dest/storage/capsule_store/index.d.ts +2 -1
  190. package/dest/storage/capsule_store/index.d.ts.map +1 -1
  191. package/dest/storage/capsule_store/index.js +1 -0
  192. package/dest/storage/contract_store/contract_store.d.ts +42 -15
  193. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  194. package/dest/storage/contract_store/contract_store.js +146 -87
  195. package/dest/storage/metadata.d.ts +1 -1
  196. package/dest/storage/metadata.js +1 -1
  197. package/dest/storage/note_store/note_store.d.ts +3 -3
  198. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  199. package/dest/storage/note_store/note_store.js +3 -4
  200. package/dest/storage/open_pxe_stores.d.ts +33 -0
  201. package/dest/storage/open_pxe_stores.d.ts.map +1 -0
  202. package/dest/storage/open_pxe_stores.js +27 -0
  203. package/dest/storage/private_event_store/private_event_store.d.ts +1 -1
  204. package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
  205. package/dest/storage/private_event_store/private_event_store.js +3 -0
  206. package/dest/storage/private_event_store/stored_private_event.js +1 -1
  207. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
  208. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  209. package/dest/storage/tagging_store/sender_tagging_store.d.ts +29 -28
  210. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  211. package/dest/storage/tagging_store/sender_tagging_store.js +141 -115
  212. package/dest/tagging/get_all_logs_by_tags.d.ts +34 -10
  213. package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
  214. package/dest/tagging/get_all_logs_by_tags.js +45 -32
  215. package/dest/tagging/index.d.ts +6 -5
  216. package/dest/tagging/index.d.ts.map +1 -1
  217. package/dest/tagging/index.js +4 -3
  218. package/dest/tagging/persist_sender_tagging_index_ranges.d.ts +29 -0
  219. package/dest/tagging/persist_sender_tagging_index_ranges.d.ts.map +1 -0
  220. package/dest/tagging/persist_sender_tagging_index_ranges.js +42 -0
  221. package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts +56 -0
  222. package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts.map +1 -0
  223. package/dest/tagging/recipient_sync/sync_tagged_private_logs.js +163 -0
  224. package/dest/tagging/recipient_sync/utils/find_highest_indexes.d.ts +3 -3
  225. package/dest/tagging/recipient_sync/utils/find_highest_indexes.d.ts.map +1 -1
  226. package/dest/tagging/recipient_sync/utils/find_highest_indexes.js +2 -2
  227. package/dest/tagging/reconcile_tagging_index_ranges.d.ts +36 -0
  228. package/dest/tagging/reconcile_tagging_index_ranges.d.ts.map +1 -0
  229. package/dest/tagging/reconcile_tagging_index_ranges.js +74 -0
  230. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -9
  231. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  232. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +32 -14
  233. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +13 -7
  234. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  235. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +41 -10
  236. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -7
  237. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  238. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +37 -25
  239. package/package.json +20 -17
  240. package/src/bin/check_oracle_version.ts +49 -122
  241. package/src/bin/index.ts +1 -0
  242. package/src/bin/oracle_version_helpers.ts +121 -0
  243. package/src/block_synchronizer/block_stream_source.ts +81 -0
  244. package/src/block_synchronizer/block_synchronizer.ts +33 -11
  245. package/src/config/index.ts +15 -9
  246. package/src/config/package_info.ts +1 -1
  247. package/src/contract_function_simulator/contract_function_simulator.ts +390 -138
  248. package/src/contract_function_simulator/ephemeral_array_service.ts +110 -0
  249. package/src/contract_function_simulator/execution_note_cache.ts +1 -1
  250. package/src/contract_function_simulator/execution_tagging_index_cache.ts +19 -18
  251. package/src/contract_function_simulator/index.ts +51 -1
  252. package/src/contract_function_simulator/noir-structs/bounded_vec.ts +55 -0
  253. package/src/contract_function_simulator/noir-structs/ephemeral_array.ts +66 -0
  254. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +9 -8
  255. package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +36 -3
  256. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +2 -5
  257. package/src/contract_function_simulator/noir-structs/note_data.ts +27 -0
  258. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +4 -9
  259. package/src/contract_function_simulator/noir-structs/option.ts +69 -0
  260. package/src/contract_function_simulator/noir-structs/provided_secret.ts +27 -0
  261. package/src/contract_function_simulator/oracle/interfaces.ts +12 -176
  262. package/src/contract_function_simulator/oracle/note_packing_utils.ts +3 -3
  263. package/src/contract_function_simulator/oracle/oracle.ts +559 -485
  264. package/src/contract_function_simulator/oracle/oracle_registry.ts +585 -0
  265. package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +553 -0
  266. package/src/contract_function_simulator/oracle/private_execution.ts +4 -4
  267. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +170 -203
  268. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +646 -236
  269. package/src/contract_function_simulator/pick_notes.ts +22 -3
  270. package/src/contract_function_simulator/proxied_contract_data_source.ts +41 -64
  271. package/src/contract_logging.ts +52 -0
  272. package/src/contract_sync/contract_sync_service.ts +125 -65
  273. package/src/contract_sync/helpers.ts +13 -20
  274. package/src/debug/pxe_debug_utils.ts +11 -22
  275. package/src/entrypoints/client/bundle/index.ts +2 -0
  276. package/src/entrypoints/client/bundle/utils.ts +19 -6
  277. package/src/entrypoints/client/lazy/index.ts +2 -0
  278. package/src/entrypoints/client/lazy/utils.ts +19 -6
  279. package/src/entrypoints/pxe_creation_options.ts +14 -0
  280. package/src/entrypoints/server/index.ts +3 -1
  281. package/src/entrypoints/server/utils.ts +22 -13
  282. package/src/events/event_service.ts +69 -21
  283. package/src/events/private_event_filter_validator.ts +21 -1
  284. package/src/hooks/authorize_utility_call.ts +44 -0
  285. package/src/hooks/execution_hooks.ts +48 -0
  286. package/src/hooks/index.ts +7 -0
  287. package/src/logs/log_service.ts +160 -143
  288. package/src/messages/message_context_service.ts +62 -0
  289. package/src/notes/note_service.ts +120 -85
  290. package/src/notes_filter.ts +24 -0
  291. package/src/oracle_version.ts +20 -10
  292. package/src/private_kernel/batch_planner.ts +169 -0
  293. package/src/private_kernel/hints/{compute_tx_include_by_timestamp.ts → compute_tx_expiration_timestamp.ts} +13 -13
  294. package/src/private_kernel/hints/index.ts +1 -1
  295. package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +165 -118
  296. package/src/private_kernel/hints/test_utils.ts +318 -0
  297. package/src/private_kernel/private_kernel_execution_prover.ts +254 -89
  298. package/src/private_kernel/private_kernel_oracle.ts +42 -32
  299. package/src/pxe.ts +393 -178
  300. package/src/storage/anchor_block_store/anchor_block_store.ts +1 -1
  301. package/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +22 -0
  302. package/src/storage/backwards_compatibility_tests/__snapshots__/AnchorBlockStore.json +3 -0
  303. package/src/storage/backwards_compatibility_tests/__snapshots__/CapsuleStore.json +16 -0
  304. package/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +28 -0
  305. package/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +52 -0
  306. package/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json +46 -0
  307. package/src/storage/backwards_compatibility_tests/__snapshots__/NoteStore.json +36 -0
  308. package/src/storage/backwards_compatibility_tests/__snapshots__/PrivateEventStore.json +44 -0
  309. package/src/storage/backwards_compatibility_tests/__snapshots__/RecipientTaggingStore.json +18 -0
  310. package/src/storage/backwards_compatibility_tests/__snapshots__/SenderAddressBookStore.json +16 -0
  311. package/src/storage/backwards_compatibility_tests/__snapshots__/SenderTaggingStore.json +22 -0
  312. package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +97 -0
  313. package/src/storage/backwards_compatibility_tests/kv_store_snapshot.ts +122 -0
  314. package/src/storage/backwards_compatibility_tests/schema_tests.ts +712 -0
  315. package/src/storage/backwards_compatibility_tests/store_spy.ts +73 -0
  316. package/src/storage/capsule_store/capsule_service.ts +90 -0
  317. package/src/storage/capsule_store/capsule_store.ts +44 -26
  318. package/src/storage/capsule_store/index.ts +1 -0
  319. package/src/storage/contract_store/contract_store.ts +182 -104
  320. package/src/storage/metadata.ts +1 -1
  321. package/src/storage/note_store/note_store.ts +5 -5
  322. package/src/storage/open_pxe_stores.ts +49 -0
  323. package/src/storage/private_event_store/private_event_store.ts +4 -0
  324. package/src/storage/private_event_store/stored_private_event.ts +1 -1
  325. package/src/storage/tagging_store/recipient_tagging_store.ts +5 -5
  326. package/src/storage/tagging_store/sender_tagging_store.ts +185 -138
  327. package/src/tagging/get_all_logs_by_tags.ts +87 -35
  328. package/src/tagging/index.ts +5 -4
  329. package/src/tagging/persist_sender_tagging_index_ranges.ts +57 -0
  330. package/src/tagging/recipient_sync/sync_tagged_private_logs.ts +240 -0
  331. package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +4 -4
  332. package/src/tagging/reconcile_tagging_index_ranges.ts +102 -0
  333. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +52 -17
  334. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +44 -14
  335. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +27 -27
  336. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +0 -4
  337. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +0 -1
  338. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +0 -15
  339. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +0 -1
  340. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +0 -99
  341. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +0 -15
  342. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +0 -1
  343. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +0 -32
  344. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +0 -143
  345. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +0 -49
package/src/pxe.ts CHANGED
@@ -6,7 +6,6 @@ import { SerialQueue } from '@aztec/foundation/queue';
6
6
  import { Timer } from '@aztec/foundation/timer';
7
7
  import { KeyStore } from '@aztec/key-store';
8
8
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
9
- import { L2TipsKVStore } from '@aztec/kv-store/stores';
10
9
  import { type ProtocolContractsProvider, protocolContractNames } from '@aztec/protocol-contracts';
11
10
  import type { CircuitSimulator } from '@aztec/simulator/client';
12
11
  import {
@@ -18,6 +17,7 @@ import {
18
17
  } from '@aztec/stdlib/abi';
19
18
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
20
19
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
20
+ import { GENESIS_BLOCK_HEADER_HASH, type L2TipsProvider } from '@aztec/stdlib/block';
21
21
  import {
22
22
  CompleteAddress,
23
23
  type ContractInstanceWithAddress,
@@ -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,12 +60,15 @@ 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';
63
+ import { displayDebugLogs } from './contract_logging.js';
62
64
  import { ContractSyncService } from './contract_sync/contract_sync_service.js';
63
65
  import { readCurrentClassId } from './contract_sync/helpers.js';
64
66
  import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
65
67
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
66
68
  import { PrivateEventFilterValidator } from './events/private_event_filter_validator.js';
69
+ import type { ExecutionHooks } from './hooks/index.js';
67
70
  import { JobCoordinator } from './job_coordinator/job_coordinator.js';
71
+ import { MessageContextService } from './messages/message_context_service.js';
68
72
  import {
69
73
  PrivateKernelExecutionProver,
70
74
  type PrivateKernelExecutionProverConfig,
@@ -75,16 +79,105 @@ import { AnchorBlockStore } from './storage/anchor_block_store/anchor_block_stor
75
79
  import { CapsuleStore } from './storage/capsule_store/capsule_store.js';
76
80
  import { ContractStore } from './storage/contract_store/contract_store.js';
77
81
  import { NoteStore } from './storage/note_store/note_store.js';
82
+ import { openPxeStores } from './storage/open_pxe_stores.js';
78
83
  import { PrivateEventStore } from './storage/private_event_store/private_event_store.js';
79
84
  import { RecipientTaggingStore } from './storage/tagging_store/recipient_tagging_store.js';
80
85
  import { SenderAddressBookStore } from './storage/tagging_store/sender_address_book_store.js';
81
86
  import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store.js';
87
+ import { persistSenderTaggingIndexRangesForTx } from './tagging/index.js';
82
88
 
83
89
  export type PackedPrivateEvent = InTx & {
84
90
  packedEvent: Fr[];
85
91
  eventSelector: EventSelector;
86
92
  };
87
93
 
94
+ /** Options for PXE.proveTx. */
95
+ export type ProveTxOpts = {
96
+ /** Addresses whose private state and keys are accessible during private execution. */
97
+ scopes: AztecAddress[];
98
+ /** Sender address used to derive discovery tags for private messages (notes, events, logs) this tx emits. */
99
+ senderForTags?: AztecAddress;
100
+ };
101
+
102
+ /** Options for PXE.profileTx. */
103
+ export type ProfileTxOpts = {
104
+ /** The profiling mode to use. */
105
+ profileMode: 'full' | 'execution-steps' | 'gates';
106
+ /** If true, proof generation is skipped during profiling. Defaults to true. */
107
+ skipProofGeneration?: boolean;
108
+ /** Addresses whose private state and keys are accessible during private execution. */
109
+ scopes: AztecAddress[];
110
+ /** Sender address used to derive discovery tags for private messages (notes, events, logs) this tx emits. */
111
+ senderForTags?: AztecAddress;
112
+ };
113
+
114
+ /** Options for PXE.simulateTx. */
115
+ export type SimulateTxOpts = {
116
+ /** Whether to simulate the public part of the transaction. */
117
+ simulatePublic: boolean;
118
+ /** If false, this function throws if the transaction is unable to be included in a block at the current state. */
119
+ skipTxValidation?: boolean;
120
+ /** If false, fees are enforced. */
121
+ skipFeeEnforcement?: boolean;
122
+ /** If true, kernel logic is emulated in TS for simulation */
123
+ skipKernels?: boolean;
124
+ /**
125
+ * Pre-simulation overrides applied to the ephemeral fork and contract DB. Bundles publicStorage
126
+ * writes (no skipKernels required) and per-address (instance, artifact?) overrides used by both
127
+ * AVM-side public dispatch and PXE-side ACIR private dispatch (requires skipKernels: true).
128
+ */
129
+ overrides?: SimulationOverrides;
130
+ /** Addresses whose private state and keys are accessible during private execution */
131
+ scopes: AztecAddress[];
132
+ /** Sender address used to derive discovery tags for private messages (notes, events, logs) this tx emits. */
133
+ senderForTags?: AztecAddress;
134
+ };
135
+
136
+ /** Options for PXE.executeUtility. */
137
+ export type ExecuteUtilityOpts = {
138
+ /** The authentication witnesses required for the function call. */
139
+ authwits?: AuthWitness[];
140
+ /** The accounts whose notes we can access in this call */
141
+ scopes: AztecAddress[];
142
+ };
143
+
144
+ /**
145
+ * Supplies the set of "nice to have" contracts that every PXE preloads regardless of which wallet
146
+ * drives it. Today this is just the standard multi-call entrypoint: the SDK's self-paid account
147
+ * deploy flow ({@link DeployAccountMethod} with `from = NO_FROM`) routes its payload through it, so a
148
+ * PXE that did not register it would fail contract sync with an opaque "no contract instance" error.
149
+ *
150
+ * Returning a list keeps this extensible: a wallet may supply its own provider that preloads
151
+ * additional contracts. Injected the same way as {@link ProtocolContractsProvider} so the PXE never
152
+ * statically imports the bundled artifacts, keeping the bundle/lazy split intact.
153
+ */
154
+ export type PreloadedContractsProvider = {
155
+ /** Returns the contract instances and artifacts the PXE should preload on startup. */
156
+ getPreloadedContracts: () => Promise<Array<{ instance: ContractInstanceWithAddress; artifact: ContractArtifact }>>;
157
+ };
158
+
159
+ /** Args for PXE.create. */
160
+ export type PXECreateArgs = {
161
+ /** The Aztec node to connect to. */
162
+ node: AztecNode;
163
+ /** The key-value store for persisting PXE state. */
164
+ store: AztecAsyncKVStore;
165
+ /** The prover for generating private kernel proofs. */
166
+ proofCreator: PrivateKernelProver;
167
+ /** The circuit simulator for executing ACIR circuits. */
168
+ simulator: CircuitSimulator;
169
+ /** Provider for protocol contract artifacts and instances. */
170
+ protocolContractsProvider: ProtocolContractsProvider;
171
+ /** Provider for the "nice to have" contracts the PXE preloads. */
172
+ preloadedContractsProvider: PreloadedContractsProvider;
173
+ /** PXE configuration options. */
174
+ config: PXEConfig;
175
+ /** Optional logger instance or string suffix for the logger name. */
176
+ loggerOrSuffix?: string | Logger;
177
+ /** Optional hooks to observe and influence contract execution. */
178
+ hooks?: ExecutionHooks;
179
+ };
180
+
88
181
  /**
89
182
  * Private eXecution Environment (PXE) is a library used by wallets to simulate private phase of transactions and to
90
183
  * manage private state of users.
@@ -92,6 +185,7 @@ export type PackedPrivateEvent = InTx & {
92
185
  export class PXE {
93
186
  private constructor(
94
187
  private node: AztecNode,
188
+ private db: AztecAsyncKVStore,
95
189
  private blockStateSynchronizer: BlockSynchronizer,
96
190
  private keyStore: KeyStore,
97
191
  private contractStore: ContractStore,
@@ -104,14 +198,19 @@ export class PXE {
104
198
  private addressStore: AddressStore,
105
199
  private privateEventStore: PrivateEventStore,
106
200
  private contractSyncService: ContractSyncService,
201
+ private messageContextService: MessageContextService,
202
+ private l2TipsStore: L2TipsProvider,
107
203
  private simulator: CircuitSimulator,
108
204
  private proverEnabled: boolean,
205
+ private autoSync: boolean,
109
206
  private proofCreator: PrivateKernelProver,
110
207
  private protocolContractsProvider: ProtocolContractsProvider,
208
+ private preloadedContractsProvider: PreloadedContractsProvider,
111
209
  private log: Logger,
112
210
  private jobQueue: SerialQueue,
113
211
  private jobCoordinator: JobCoordinator,
114
212
  public debug: PXEDebugUtils,
213
+ private hooks: ExecutionHooks | undefined,
115
214
  ) {}
116
215
 
117
216
  /**
@@ -121,15 +220,17 @@ export class PXE {
121
220
  *
122
221
  * @returns A promise that resolves PXE is ready to be used.
123
222
  */
124
- public static async create(
125
- node: AztecNode,
126
- store: AztecAsyncKVStore,
127
- proofCreator: PrivateKernelProver,
128
- simulator: CircuitSimulator,
129
- protocolContractsProvider: ProtocolContractsProvider,
130
- config: PXEConfig,
131
- loggerOrSuffix?: string | Logger,
132
- ) {
223
+ public static async create({
224
+ node,
225
+ store,
226
+ proofCreator,
227
+ simulator,
228
+ protocolContractsProvider,
229
+ preloadedContractsProvider,
230
+ config,
231
+ loggerOrSuffix,
232
+ hooks,
233
+ }: PXECreateArgs) {
133
234
  // Extract bindings from the logger, or use empty bindings if a string suffix is provided.
134
235
  const bindings: LoggerBindings | undefined =
135
236
  loggerOrSuffix && typeof loggerOrSuffix !== 'string' ? loggerOrSuffix.getBindings() : undefined;
@@ -139,31 +240,45 @@ export class PXE {
139
240
  ? createLogger(loggerOrSuffix ? `pxe:service:${loggerOrSuffix}` : `pxe:service`)
140
241
  : loggerOrSuffix;
141
242
 
142
- const proverEnabled = !!config.proverEnabled;
143
- const addressStore = new AddressStore(store);
144
- const privateEventStore = new PrivateEventStore(store);
145
- const contractStore = new ContractStore(store);
146
- const noteStore = new NoteStore(store);
147
- const anchorBlockStore = new AnchorBlockStore(store);
148
- const senderTaggingStore = new SenderTaggingStore(store);
149
- const senderAddressBookStore = new SenderAddressBookStore(store);
150
- const recipientTaggingStore = new RecipientTaggingStore(store);
151
- const capsuleStore = new CapsuleStore(store);
152
- const keyStore = new KeyStore(store);
153
- const tipsStore = new L2TipsKVStore(store, 'pxe');
243
+ const info = await node.getNodeInfo();
244
+
245
+ // Source the genesis block hash from the node so PXE's L2BlockStream agrees with the node's
246
+ // archiver on the dynamic initial header hash. Without this the tip store would fall back to
247
+ // the static `GENESIS_BLOCK_HEADER_HASH` constant, which only matches deployments with the
248
+ // default empty genesis (timestamp 0, no prefilled public data) and diverges otherwise — the
249
+ // sync at block 0 would then get stuck in `areBlockHashesEqualAt` and abort. If the node does
250
+ // not return a genesis block (older node or test fixture) we fall back to the static constant.
251
+ const initialBlockHash = (await node.getBlock(BlockNumber.ZERO))?.hash ?? GENESIS_BLOCK_HEADER_HASH;
252
+
253
+ const proverEnabled = config.proverEnabled !== undefined ? config.proverEnabled : info.realProofs;
254
+ const {
255
+ addressStore,
256
+ privateEventStore,
257
+ contractStore,
258
+ noteStore,
259
+ anchorBlockStore,
260
+ senderTaggingStore,
261
+ senderAddressBookStore,
262
+ recipientTaggingStore,
263
+ capsuleStore,
264
+ keyStore,
265
+ l2TipsStore,
266
+ } = openPxeStores(store, initialBlockHash);
154
267
  const contractSyncService = new ContractSyncService(
155
268
  node,
156
269
  contractStore,
157
270
  noteStore,
158
271
  createLogger('pxe:contract_sync', bindings),
159
272
  );
273
+ const messageContextService = new MessageContextService(node);
274
+
160
275
  const synchronizer = new BlockSynchronizer(
161
276
  node,
162
277
  store,
163
278
  anchorBlockStore,
164
279
  noteStore,
165
280
  privateEventStore,
166
- tipsStore,
281
+ l2TipsStore,
167
282
  contractSyncService,
168
283
  config,
169
284
  bindings,
@@ -185,6 +300,7 @@ export class PXE {
185
300
 
186
301
  const pxe = new PXE(
187
302
  node,
303
+ store,
188
304
  synchronizer,
189
305
  keyStore,
190
306
  contractStore,
@@ -197,26 +313,30 @@ export class PXE {
197
313
  addressStore,
198
314
  privateEventStore,
199
315
  contractSyncService,
316
+ messageContextService,
317
+ l2TipsStore,
200
318
  simulator,
201
319
  proverEnabled,
320
+ config.autoSync,
202
321
  proofCreator,
203
322
  protocolContractsProvider,
323
+ preloadedContractsProvider,
204
324
  log,
205
325
  jobQueue,
206
326
  jobCoordinator,
207
327
  debugUtils,
328
+ hooks,
208
329
  );
209
330
 
210
331
  debugUtils.setPXEHelpers(
211
332
  pxe.#putInJobQueue.bind(pxe),
212
333
  pxe.#getSimulatorForTx.bind(pxe),
213
- pxe.#simulateUtility.bind(pxe),
334
+ pxe.#executeUtility.bind(pxe),
214
335
  );
215
336
 
216
337
  pxe.jobQueue.start();
217
338
 
218
- await pxe.#registerProtocolContracts();
219
- const info = await node.getNodeInfo();
339
+ await Promise.all([pxe.#registerProtocolContracts(), pxe.#registerPreloadedContracts()]);
220
340
  log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.rollupVersion}`);
221
341
  return pxe;
222
342
  }
@@ -226,20 +346,23 @@ export class PXE {
226
346
  #getSimulatorForTx(overrides?: { contracts?: ContractOverrides }) {
227
347
  const proxyContractStore = ProxiedContractStoreFactory.create(this.contractStore, overrides?.contracts);
228
348
 
229
- return new ContractFunctionSimulator(
230
- proxyContractStore,
231
- this.noteStore,
232
- this.keyStore,
233
- this.addressStore,
234
- BenchmarkedNodeFactory.create(this.node),
235
- this.senderTaggingStore,
236
- this.recipientTaggingStore,
237
- this.senderAddressBookStore,
238
- this.capsuleStore,
239
- this.privateEventStore,
240
- this.simulator,
241
- this.contractSyncService,
242
- );
349
+ return new ContractFunctionSimulator({
350
+ contractStore: proxyContractStore,
351
+ noteStore: this.noteStore,
352
+ keyStore: this.keyStore,
353
+ addressStore: this.addressStore,
354
+ aztecNode: BenchmarkedNodeFactory.create(this.node),
355
+ l2TipsStore: this.l2TipsStore,
356
+ senderTaggingStore: this.senderTaggingStore,
357
+ recipientTaggingStore: this.recipientTaggingStore,
358
+ senderAddressBookStore: this.senderAddressBookStore,
359
+ capsuleStore: this.capsuleStore,
360
+ privateEventStore: this.privateEventStore,
361
+ simulator: this.simulator,
362
+ contractSyncService: this.contractSyncService,
363
+ messageContextService: this.messageContextService,
364
+ hooks: this.hooks,
365
+ });
243
366
  }
244
367
 
245
368
  #contextualizeError(err: Error, ...context: string[]): Error {
@@ -289,50 +412,66 @@ export class PXE {
289
412
  }
290
413
 
291
414
  async #registerProtocolContracts() {
292
- const registered: Record<string, string> = {};
293
- for (const name of protocolContractNames) {
294
- const { address, contractClass, instance, artifact } =
295
- await this.protocolContractsProvider.getProtocolContractArtifact(name);
296
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
297
- await this.contractStore.addContractInstance(instance);
298
- registered[name] = address.toString();
299
- }
415
+ const registered = Object.fromEntries(
416
+ await Promise.all(
417
+ protocolContractNames.map(async name => {
418
+ const { address, instance, artifact } =
419
+ await this.protocolContractsProvider.getProtocolContractArtifact(name);
420
+ await this.contractStore.addContractArtifact(artifact);
421
+ await this.contractStore.addContractInstance(instance);
422
+ return [name, address.toString()] as const;
423
+ }),
424
+ ),
425
+ );
300
426
  this.log.verbose(`Registered protocol contracts in pxe`, registered);
301
427
  }
302
428
 
429
+ async #registerPreloadedContracts() {
430
+ const contracts = await this.preloadedContractsProvider.getPreloadedContracts();
431
+ await Promise.all(contracts.map(({ instance, artifact }) => this.registerContract({ instance, artifact })));
432
+ this.log.verbose(`Registered preloaded contracts in pxe`, {
433
+ contracts: contracts.map(({ instance }) => instance.address.toString()),
434
+ });
435
+ }
436
+
303
437
  // Executes the entrypoint private function, as well as all nested private
304
438
  // functions that might arise.
305
- async #executePrivate(
306
- contractFunctionSimulator: ContractFunctionSimulator,
307
- txRequest: TxExecutionRequest,
308
- scopes: AztecAddress[] | undefined,
309
- jobId: string,
310
- ): Promise<PrivateExecutionResult> {
439
+ async #executePrivate({
440
+ contractFunctionSimulator,
441
+ txRequest,
442
+ anchorBlockHeader,
443
+ scopes,
444
+ jobId,
445
+ senderForTags,
446
+ }: {
447
+ contractFunctionSimulator: ContractFunctionSimulator;
448
+ txRequest: TxExecutionRequest;
449
+ anchorBlockHeader: BlockHeader;
450
+ scopes: AztecAddress[];
451
+ jobId: string;
452
+ senderForTags?: AztecAddress;
453
+ }): Promise<PrivateExecutionResult> {
311
454
  const { origin: contractAddress, functionSelector } = txRequest;
312
455
 
313
456
  try {
314
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
315
-
316
457
  await this.contractSyncService.ensureContractSynced(
317
458
  contractAddress,
318
459
  functionSelector,
319
- privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
460
+ (privateSyncCall, execScopes) =>
461
+ this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
320
462
  anchorBlockHeader,
321
463
  jobId,
464
+ scopes,
322
465
  );
323
466
 
324
- const result = await contractFunctionSimulator.run(
325
- txRequest,
467
+ const result = await contractFunctionSimulator.run(txRequest, {
326
468
  contractAddress,
327
- functionSelector,
328
- undefined,
469
+ selector: functionSelector,
329
470
  anchorBlockHeader,
330
- // The sender for tags is set by contracts, typically by an account
331
- // contract entrypoint
332
- undefined, // senderForTags
333
471
  scopes,
334
472
  jobId,
335
- );
473
+ senderForTags,
474
+ });
336
475
  this.log.debug(`Private simulation completed for ${contractAddress.toString()}:${functionSelector}`);
337
476
  return result;
338
477
  } catch (err) {
@@ -344,25 +483,32 @@ export class PXE {
344
483
  }
345
484
 
346
485
  /**
347
- * Simulate a utility function call on the given contract.
486
+ * Execute a utility function call on the given contract.
348
487
  * @param contractFunctionSimulator - The simulator to use for the function call.
349
488
  * @param call - The function call to execute.
350
489
  * @param authWitnesses - Authentication witnesses required for the function call.
351
490
  * @param scopes - Optional array of account addresses whose notes can be accessed in this call. Defaults to all
352
491
  * accounts if not specified.
353
492
  * @param jobId - The job ID for staged writes.
354
- * @returns The simulation result containing the outputs of the utility function.
493
+ * @returns The execution result containing the outputs of the utility function.
355
494
  */
356
- async #simulateUtility(
495
+ async #executeUtility(
357
496
  contractFunctionSimulator: ContractFunctionSimulator,
358
497
  call: FunctionCall,
359
498
  authWitnesses: AuthWitness[] | undefined,
360
- scopes: AztecAddress[] | undefined,
499
+ scopes: AztecAddress[],
361
500
  jobId: string,
362
501
  ) {
363
502
  try {
364
503
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
365
- return contractFunctionSimulator.runUtility(call, authWitnesses ?? [], anchorBlockHeader, scopes, jobId);
504
+ const { result, offchainEffects } = await contractFunctionSimulator.runUtility(
505
+ call,
506
+ authWitnesses ?? [],
507
+ anchorBlockHeader,
508
+ scopes,
509
+ jobId,
510
+ );
511
+ return { result, offchainEffects };
366
512
  } catch (err) {
367
513
  if (err instanceof SimulationError) {
368
514
  await enrichSimulationError(err, this.contractStore, this.log);
@@ -377,11 +523,11 @@ export class PXE {
377
523
  * It can also be used for estimating gas in the future.
378
524
  * @param tx - The transaction to be simulated.
379
525
  */
380
- async #simulatePublicCalls(tx: Tx, skipFeeEnforcement: boolean) {
526
+ async #simulatePublicCalls(tx: Tx, skipFeeEnforcement: boolean, overrides?: SimulationOverrides) {
381
527
  // Simulating public calls can throw if the TX fails in a phase that doesn't allow reverts (setup)
382
528
  // Or return as reverted if it fails in a phase that allows reverts (app logic, teardown)
383
529
  try {
384
- const result = await this.node.simulatePublicCalls(tx, skipFeeEnforcement);
530
+ const result = await this.node.simulatePublicCalls(tx, skipFeeEnforcement, overrides);
385
531
  if (result.revertReason) {
386
532
  throw result.revertReason;
387
533
  }
@@ -413,11 +559,10 @@ export class PXE {
413
559
  txExecutionRequest: TxExecutionRequest,
414
560
  proofCreator: PrivateKernelProver,
415
561
  privateExecutionResult: PrivateExecutionResult,
562
+ anchorBlockHeader: BlockHeader,
416
563
  config: PrivateKernelExecutionProverConfig,
417
564
  ): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
418
- const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
419
- const anchorBlockHash = await anchorBlockHeader.hash();
420
- const kernelOracle = new PrivateKernelOracle(this.contractStore, this.keyStore, this.node, anchorBlockHash);
565
+ const kernelOracle = new PrivateKernelOracle(this.contractStore, this.keyStore, this.node, anchorBlockHeader);
421
566
  const kernelTraceProver = new PrivateKernelExecutionProver(
422
567
  kernelOracle,
423
568
  proofCreator,
@@ -428,8 +573,43 @@ export class PXE {
428
573
  return await kernelTraceProver.proveWithKernels(txExecutionRequest.toTxRequest(), privateExecutionResult, config);
429
574
  }
430
575
 
576
+ /**
577
+ * Syncs with the node only when `autoSync` is enabled.
578
+ * When `autoSync` is disabled, callers (typically a wallet) are
579
+ * responsible for invoking `pxe.sync()` at the right granularity.
580
+ */
581
+ async #maybeSync(): Promise<void> {
582
+ if (this.autoSync) {
583
+ await this.blockStateSynchronizer.sync();
584
+ }
585
+ }
586
+
431
587
  // Public API
432
588
 
589
+ /**
590
+ * Triggers a sync of PXE state with the node, regardless of the `autoSync` config flag. Use this to
591
+ * batch syncs across composite flows when `autoSync` is disabled (e.g. one sync per simulate+send
592
+ * instead of one per inner PXE call). Serialized through the job queue.
593
+ */
594
+ public sync(): Promise<void> {
595
+ return this.#putInJobQueue(() => this.blockStateSynchronizer.sync());
596
+ }
597
+
598
+ /**
599
+ * Returns the block header up to which the PXE has synced.
600
+ * @returns The synced block header
601
+ */
602
+ public getSyncedBlockHeader(): Promise<BlockHeader> {
603
+ return this.#putInJobQueue(() => {
604
+ return this.anchorBlockStore.getBlockHeader();
605
+ });
606
+ }
607
+
608
+ /**
609
+ * Returns the contract instance for a given address, if it's registered in the PXE.
610
+ * @param address - The contract address.
611
+ * @returns The contract instance if found, undefined otherwise.
612
+ */
433
613
  public getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
434
614
  return this.contractStore.getContractInstance(address);
435
615
  }
@@ -456,7 +636,7 @@ export class PXE {
456
636
  public async registerAccount(secretKey: Fr, partialAddress: PartialAddress): Promise<CompleteAddress> {
457
637
  const accounts = await this.keyStore.getAccounts();
458
638
  const accountCompleteAddress = await this.keyStore.addAccount(secretKey, partialAddress);
459
- if (accounts.includes(accountCompleteAddress.address)) {
639
+ if (accounts.some(a => a.equals(accountCompleteAddress.address))) {
460
640
  this.log.info(`Account:\n "${accountCompleteAddress.address.toString()}"\n already registered.`);
461
641
  return accountCompleteAddress;
462
642
  } else {
@@ -479,8 +659,14 @@ export class PXE {
479
659
  * TODO: It's strange that we return the address here and I (benesjan) think we should drop the return value.
480
660
  */
481
661
  public async registerSender(sender: AztecAddress): Promise<AztecAddress> {
662
+ if (!(await sender.isValid())) {
663
+ throw new Error(
664
+ `Address ${sender} is not valid: it does not correspond to a point on the Grumpkin curve. Cannot register it as a sender.`,
665
+ );
666
+ }
667
+
482
668
  const accounts = await this.keyStore.getAccounts();
483
- if (accounts.includes(sender)) {
669
+ if (accounts.some(a => a.equals(sender))) {
484
670
  this.log.info(`Sender:\n "${sender.toString()}"\n already registered.`);
485
671
  return sender;
486
672
  }
@@ -489,6 +675,9 @@ export class PXE {
489
675
 
490
676
  if (wasAdded) {
491
677
  this.log.info(`Added sender:\n ${sender.toString()}`);
678
+ // Wipe the entire sync cache: the new sender's tagged logs could contain notes/events for any contract, so
679
+ // all contracts must re-sync to discover them. Queued to avoid wiping while a job is in flight.
680
+ await this.#putInJobQueue(() => Promise.resolve(this.contractSyncService.wipe()));
492
681
  } else {
493
682
  this.log.info(`Sender:\n "${sender.toString()}"\n already registered.`);
494
683
  }
@@ -538,8 +727,7 @@ export class PXE {
538
727
  * @param artifact - The build artifact for the contract class.
539
728
  */
540
729
  public async registerContractClass(artifact: ContractArtifact): Promise<void> {
541
- const { id: contractClassId } = await getContractClassFromArtifact(artifact);
542
- await this.contractStore.addContractArtifact(contractClassId, artifact);
730
+ const contractClassId = await this.contractStore.addContractArtifact(artifact);
543
731
  this.log.info(`Added contract class ${artifact.name} with id ${contractClassId}`);
544
732
  }
545
733
 
@@ -558,22 +746,24 @@ export class PXE {
558
746
  if (artifact) {
559
747
  // If the user provides an artifact, validate it against the expected class id and register it
560
748
  const contractClass = await getContractClassFromArtifact(artifact);
561
- const contractClassId = contractClass.id;
562
- if (!contractClassId.equals(instance.currentContractClassId)) {
749
+ if (!contractClass.id.equals(instance.currentContractClassId)) {
563
750
  throw new Error(
564
- `Artifact does not match expected class id (computed ${contractClassId} but instance refers to ${instance.currentContractClassId})`,
751
+ `Artifact does not match expected class id (computed ${contractClass.id} but instance refers to ${instance.currentContractClassId})`,
565
752
  );
566
753
  }
567
754
  const computedAddress = await computeContractAddressFromInstance(instance);
568
755
  if (!computedAddress.equals(instance.address)) {
569
756
  throw new Error('Added a contract in which the address does not match the contract instance.');
570
757
  }
571
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
758
+
759
+ await this.contractStore.addContractArtifact(artifact, contractClass);
572
760
 
573
761
  const publicFunctionSignatures = artifact.functions
574
762
  .filter(fn => fn.functionType === FunctionType.PUBLIC)
575
763
  .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
576
- await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
764
+ if (publicFunctionSignatures.length > 0) {
765
+ await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
766
+ }
577
767
  } else {
578
768
  // Otherwise, make sure there is an artifact already registered for that class id
579
769
  artifact = await this.contractStore.getContractArtifact(instance.currentContractClassId);
@@ -608,7 +798,7 @@ export class PXE {
608
798
  throw new Error(`Instance not found when updating a contract. Contract address: ${contractAddress}.`);
609
799
  }
610
800
  const contractClass = await getContractClassFromArtifact(artifact);
611
- await this.blockStateSynchronizer.sync();
801
+ await this.#maybeSync();
612
802
 
613
803
  const header = await this.anchorBlockStore.getBlockHeader();
614
804
 
@@ -617,15 +807,18 @@ export class PXE {
617
807
  throw new Error('Could not update contract to a class different from the current one.');
618
808
  }
619
809
 
620
- await this.contractStore.addContractArtifact(contractClass.id, artifact);
621
-
622
810
  const publicFunctionSignatures = artifact.functions
623
811
  .filter(fn => fn.functionType === FunctionType.PUBLIC)
624
812
  .map(fn => decodeFunctionSignature(fn.name, fn.parameters));
625
- await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
813
+ if (publicFunctionSignatures.length > 0) {
814
+ await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
815
+ }
626
816
 
627
817
  currentInstance.currentContractClassId = contractClass.id;
628
- await this.contractStore.addContractInstance(currentInstance);
818
+ await Promise.all([
819
+ this.contractStore.addContractArtifact(artifact, contractClass),
820
+ this.contractStore.addContractInstance(currentInstance),
821
+ ]);
629
822
  this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
630
823
  });
631
824
  }
@@ -643,11 +836,12 @@ export class PXE {
643
836
  * (where validators prove the public portion).
644
837
  *
645
838
  * @param txRequest - An authenticated tx request ready for proving
839
+ * @param scopes - Addresses whose private state and keys are accessible during private execution.
646
840
  * @returns A result containing the proof and public inputs of the tail circuit.
647
841
  * @throws If contract code not found, or public simulation reverts.
648
842
  * Also throws if simulatePublic is true and public simulation reverts.
649
843
  */
650
- public proveTx(txRequest: TxExecutionRequest): Promise<TxProvingResult> {
844
+ public proveTx(txRequest: TxExecutionRequest, { scopes, senderForTags }: ProveTxOpts): Promise<TxProvingResult> {
651
845
  let privateExecutionResult: PrivateExecutionResult;
652
846
  // We disable proving concurrently mostly out of caution, since it accesses some of our stores. Proving is so
653
847
  // computationally demanding that it'd be rare for someone to try to do it concurrently regardless.
@@ -655,17 +849,25 @@ export class PXE {
655
849
  const totalTimer = new Timer();
656
850
  try {
657
851
  const syncTimer = new Timer();
658
- await this.blockStateSynchronizer.sync();
852
+ await this.#maybeSync();
853
+ const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
659
854
  const syncTime = syncTimer.ms();
660
855
  const contractFunctionSimulator = this.#getSimulatorForTx();
661
- privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, undefined, jobId);
856
+ privateExecutionResult = await this.#executePrivate({
857
+ contractFunctionSimulator,
858
+ txRequest,
859
+ anchorBlockHeader,
860
+ scopes,
861
+ jobId,
862
+ senderForTags,
863
+ });
662
864
 
663
865
  const {
664
866
  publicInputs,
665
867
  chonkProof,
666
868
  executionSteps,
667
869
  timings: { proving } = {},
668
- } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
870
+ } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, anchorBlockHeader, {
669
871
  simulate: false,
670
872
  skipFeeEnforcement: false,
671
873
  profileMode: 'none',
@@ -695,23 +897,20 @@ export class PXE {
695
897
  nodeRPCCalls: contractFunctionSimulator?.getStats().nodeRPCCalls,
696
898
  });
697
899
 
698
- // While not strictly necessary to store tagging cache contents in the DB since we sync tagging indexes from
699
- // chain before sending new logs, the sync can only see logs already included in blocks. If we send another
700
- // transaction before this one is included in a block from this PXE, and that transaction contains a log with
701
- // a tag derived from the same secret, we would reuse the tag and the transactions would be linked. Hence
702
- // storing the tags here prevents linkage of txs sent from the same PXE.
703
- const preTagsUsedInTheTx = privateExecutionResult.entrypoint.preTags;
704
- if (preTagsUsedInTheTx.length > 0) {
705
- // TODO(benesjan): The following is an expensive operation. Figure out a way to avoid it.
706
- const txHash = (await txProvingResult.toTx()).txHash;
707
-
708
- await this.senderTaggingStore.storePendingIndexes(preTagsUsedInTheTx, txHash, jobId);
709
- this.log.debug(`Stored used pre-tags as sender for the tx`, {
710
- preTagsUsedInTheTx,
711
- });
712
- } else {
713
- this.log.debug(`No pre-tags used in the tx`);
714
- }
900
+ // We keep track of which tagging indices we've used in this tx so that we don't repeat them in future txs
901
+ // (which would link them) without having to rely on this tx being mined (and us seeing the indices being used
902
+ // onchain).
903
+ // Note that this must happen _after_ proving as it requires the proof's public inputs, from which the kernels
904
+ // may have removed some logs due to note-nullifier squashing - this may lead to range of tagging indices we've
905
+ // actually used to being reduced.
906
+ await persistSenderTaggingIndexRangesForTx(
907
+ this.senderTaggingStore,
908
+ privateExecutionResult.entrypoint.taggingIndexRanges,
909
+ publicInputs,
910
+ () => txProvingResult.getTxHash(),
911
+ jobId,
912
+ this.log,
913
+ );
715
914
 
716
915
  return txProvingResult;
717
916
  } catch (err: any) {
@@ -722,17 +921,13 @@ export class PXE {
722
921
 
723
922
  /**
724
923
  * Profiles a transaction, reporting gate counts (unless disabled) and returns an execution trace.
725
- *
726
- * @param txRequest - An authenticated tx request ready for simulation
727
- * @param msgSender - (Optional) The message sender to use for the simulation.
728
- * @param skipTxValidation - (Optional) If false, this function throws if the transaction is unable to be included in a block at the current state.
924
+ * @param txRequest - An authenticated tx request ready for simulation.
729
925
  * @returns A trace of the program execution with gate counts.
730
926
  * @throws If the code for the functions executed in this transaction have not been made available via `addContracts`.
731
927
  */
732
928
  public profileTx(
733
929
  txRequest: TxExecutionRequest,
734
- profileMode: 'full' | 'execution-steps' | 'gates',
735
- skipProofGeneration: boolean = true,
930
+ { profileMode, skipProofGeneration = true, scopes, senderForTags }: ProfileTxOpts,
736
931
  ): Promise<TxProfileResult> {
737
932
  // We disable concurrent profiles for consistency with simulateTx.
738
933
  return this.#putInJobQueue(async jobId => {
@@ -751,21 +946,25 @@ export class PXE {
751
946
  txInfo,
752
947
  );
753
948
  const syncTimer = new Timer();
754
- await this.blockStateSynchronizer.sync();
949
+ await this.#maybeSync();
950
+ const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
755
951
  const syncTime = syncTimer.ms();
756
952
 
757
953
  const contractFunctionSimulator = this.#getSimulatorForTx();
758
- const privateExecutionResult = await this.#executePrivate(
954
+ const privateExecutionResult = await this.#executePrivate({
759
955
  contractFunctionSimulator,
760
956
  txRequest,
761
- undefined,
957
+ anchorBlockHeader,
958
+ scopes,
762
959
  jobId,
763
- );
960
+ senderForTags,
961
+ });
764
962
 
765
963
  const { executionSteps, timings: { proving } = {} } = await this.#prove(
766
964
  txRequest,
767
965
  this.proofCreator,
768
966
  privateExecutionResult,
967
+ anchorBlockHeader,
769
968
  {
770
969
  simulate: skipProofGeneration,
771
970
  skipFeeEnforcement: false,
@@ -817,12 +1016,7 @@ export class PXE {
817
1016
  * In that case, the transaction returned is only potentially ready to be sent to the network for execution.
818
1017
  *
819
1018
  *
820
- * @param txRequest - An authenticated tx request ready for simulation
821
- * @param simulatePublic - Whether to simulate the public part of the transaction.
822
- * @param skipTxValidation - (Optional) If false, this function throws if the transaction is unable to be included in a block at the current state.
823
- * @param skipFeeEnforcement - (Optional) If false, fees are enforced.
824
- * @param overrides - (Optional) State overrides for the simulation, such as msgSender, contract instances and artifacts.
825
- * @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will default to all.
1019
+ * @param txRequest - An authenticated tx request ready for simulation.
826
1020
  * @returns A simulated transaction result object that includes public and private return values.
827
1021
  * @throws If the code for the functions executed in this transaction have not been made available via `addContracts`.
828
1022
  * Also throws if simulatePublic is true and public simulation reverts.
@@ -831,11 +1025,15 @@ export class PXE {
831
1025
  */
832
1026
  public simulateTx(
833
1027
  txRequest: TxExecutionRequest,
834
- simulatePublic: boolean,
835
- skipTxValidation: boolean = false,
836
- skipFeeEnforcement: boolean = false,
837
- overrides?: SimulationOverrides,
838
- scopes?: AztecAddress[],
1028
+ {
1029
+ simulatePublic,
1030
+ skipTxValidation = false,
1031
+ skipFeeEnforcement = false,
1032
+ skipKernels = true,
1033
+ overrides,
1034
+ scopes,
1035
+ senderForTags,
1036
+ }: SimulateTxOpts,
839
1037
  ): Promise<TxSimulationResult> {
840
1038
  // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
841
1039
  // to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
@@ -856,24 +1054,26 @@ export class PXE {
856
1054
  txInfo,
857
1055
  );
858
1056
  const syncTimer = new Timer();
859
- await this.blockStateSynchronizer.sync();
1057
+ await this.#maybeSync();
1058
+ const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
860
1059
  const syncTime = syncTimer.ms();
861
1060
 
862
- const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
863
- // Temporary: in case there are overrides, we have to skip the kernels or validations
864
- // will fail. Consider handing control to the user/wallet on whether they want to run them
865
- // or not.
866
- const overriddenContracts = overrides?.contracts ? new Set(Object.keys(overrides.contracts)) : undefined;
867
- const hasOverriddenContracts = overriddenContracts !== undefined && overriddenContracts.size > 0;
868
- const skipKernels = hasOverriddenContracts;
869
-
870
- // Set overridden contracts on the sync service so it knows to skip syncing them
871
- if (hasOverriddenContracts) {
872
- this.contractSyncService.setOverriddenContracts(jobId, overriddenContracts);
1061
+ if (overrides?.contracts && Object.keys(overrides.contracts).length > 0 && !skipKernels) {
1062
+ throw new Error(
1063
+ 'Simulating with overridden contracts is not compatible with kernel execution. Please set skipKernels to true when simulating with overridden contracts.',
1064
+ );
873
1065
  }
1066
+ const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
874
1067
 
875
1068
  // Execution of private functions only; no proving, and no kernel logic.
876
- const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, scopes, jobId);
1069
+ const privateExecutionResult = await this.#executePrivate({
1070
+ contractFunctionSimulator,
1071
+ txRequest,
1072
+ anchorBlockHeader,
1073
+ scopes,
1074
+ jobId,
1075
+ senderForTags,
1076
+ });
877
1077
 
878
1078
  let publicInputs: PrivateKernelTailCircuitPublicInputs | undefined;
879
1079
  let executionSteps: PrivateExecutionStep[] = [];
@@ -881,15 +1081,22 @@ export class PXE {
881
1081
  if (skipKernels) {
882
1082
  ({ publicInputs, executionSteps } = await generateSimulatedProvingResult(
883
1083
  privateExecutionResult,
884
- this.contractStore,
1084
+ (addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
1085
+ this.node,
885
1086
  ));
886
1087
  } else {
887
1088
  // Kernel logic, plus proving of all private functions and kernels.
888
- ({ publicInputs, executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
889
- simulate: true,
890
- skipFeeEnforcement,
891
- profileMode: 'none',
892
- }));
1089
+ ({ publicInputs, executionSteps } = await this.#prove(
1090
+ txRequest,
1091
+ this.proofCreator,
1092
+ privateExecutionResult,
1093
+ anchorBlockHeader,
1094
+ {
1095
+ simulate: true,
1096
+ skipFeeEnforcement,
1097
+ profileMode: 'none',
1098
+ },
1099
+ ));
893
1100
  }
894
1101
 
895
1102
  const privateSimulationResult = new PrivateSimulationResult(privateExecutionResult, publicInputs);
@@ -898,8 +1105,11 @@ export class PXE {
898
1105
  let publicOutput: PublicSimulationOutput | undefined;
899
1106
  if (simulatePublic && publicInputs.forPublic) {
900
1107
  const publicSimulationTimer = new Timer();
901
- publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
1108
+ publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement, overrides);
902
1109
  publicSimulationTime = publicSimulationTimer.ms();
1110
+ if (publicOutput?.debugLogs?.length) {
1111
+ await displayDebugLogs(publicOutput.debugLogs, addr => this.contractStore.getDebugContractName(addr));
1112
+ }
903
1113
  }
904
1114
 
905
1115
  let validationTime: number | undefined;
@@ -908,7 +1118,8 @@ export class PXE {
908
1118
  const validationResult = await this.node.isValidTx(simulatedTx, { isSimulation: true, skipFeeEnforcement });
909
1119
  validationTime = validationTimer.ms();
910
1120
  if (validationResult.result === 'invalid') {
911
- throw new Error('The simulated transaction is unable to be added to state and is invalid.');
1121
+ const reason = validationResult.reason.length > 0 ? ` Reason: ${validationResult.reason.join(', ')}` : '';
1122
+ throw new Error(`The simulated transaction is unable to be added to state and is invalid.${reason}`);
912
1123
  }
913
1124
  }
914
1125
 
@@ -959,34 +1170,28 @@ export class PXE {
959
1170
  inspect(txRequest),
960
1171
  `simulatePublic=${simulatePublic}`,
961
1172
  `skipTxValidation=${skipTxValidation}`,
962
- `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
1173
+ `scopes=${scopes.map(s => s.toString()).join(', ')}`,
963
1174
  );
964
1175
  }
965
1176
  });
966
1177
  }
967
1178
 
968
1179
  /**
969
- * Simulate the execution of a contract utility function.
970
- *
1180
+ * Executes a contract utility function.
971
1181
  * @param call - The function call containing the function details, arguments, and target contract address.
972
- * @param authwits - (Optional) The authentication witnesses required for the function call.
973
- * @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will
974
- * default to all.
975
- * @returns The result of the utility function call, structured based on the function ABI.
976
1182
  */
977
- public simulateUtility(
1183
+ public executeUtility(
978
1184
  call: FunctionCall,
979
- authwits?: AuthWitness[],
980
- scopes?: AztecAddress[],
981
- ): Promise<UtilitySimulationResult> {
982
- // We disable concurrent simulations since those might execute oracles which read and write to the PXE stores (e.g.
1185
+ { authwits, scopes }: ExecuteUtilityOpts = { scopes: [] },
1186
+ ): Promise<UtilityExecutionResult> {
1187
+ // We disable concurrent executions since those might execute oracles which read and write to the PXE stores (e.g.
983
1188
  // to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
984
- // delete the same read value, or reading values that another simulation is currently modifying).
1189
+ // delete the same read value, or reading values that another execution is currently modifying).
985
1190
  return this.#putInJobQueue(async jobId => {
986
1191
  try {
987
1192
  const totalTimer = new Timer();
988
1193
  const syncTimer = new Timer();
989
- await this.blockStateSynchronizer.sync();
1194
+ await this.#maybeSync();
990
1195
  const syncTime = syncTimer.ms();
991
1196
  const functionTimer = new Timer();
992
1197
  const contractFunctionSimulator = this.#getSimulatorForTx();
@@ -995,12 +1200,14 @@ export class PXE {
995
1200
  await this.contractSyncService.ensureContractSynced(
996
1201
  call.to,
997
1202
  call.selector,
998
- privateSyncCall => this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
1203
+ (privateSyncCall, execScopes) =>
1204
+ this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
999
1205
  anchorBlockHeader,
1000
1206
  jobId,
1207
+ scopes,
1001
1208
  );
1002
1209
 
1003
- const executionResult = await this.#simulateUtility(
1210
+ const { result: executionResult, offchainEffects } = await this.#executeUtility(
1004
1211
  contractFunctionSimulator,
1005
1212
  call,
1006
1213
  authwits ?? [],
@@ -1021,14 +1228,19 @@ export class PXE {
1021
1228
  };
1022
1229
 
1023
1230
  const simulationStats = contractFunctionSimulator.getStats();
1024
- return { result: executionResult, stats: { timings, nodeRPCCalls: simulationStats.nodeRPCCalls } };
1231
+ return {
1232
+ result: executionResult,
1233
+ offchainEffects,
1234
+ anchorBlockTimestamp: anchorBlockHeader.globalVariables.timestamp,
1235
+ stats: { timings, nodeRPCCalls: simulationStats.nodeRPCCalls },
1236
+ };
1025
1237
  } catch (err: any) {
1026
1238
  const { to, name, args } = call;
1027
1239
  const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
1028
1240
  throw this.#contextualizeError(
1029
1241
  err,
1030
- `simulateUtility ${to}:${name}(${stringifiedArgs})`,
1031
- `scopes=${scopes?.map(s => s.toString()).join(', ') ?? 'undefined'}`,
1242
+ `executeUtility ${to}:${name}(${stringifiedArgs})`,
1243
+ `scopes=${scopes.map(s => s.toString()).join(', ')}`,
1032
1244
  );
1033
1245
  }
1034
1246
  });
@@ -1054,7 +1266,7 @@ export class PXE {
1054
1266
  let anchorBlockNumber: BlockNumber;
1055
1267
 
1056
1268
  await this.#putInJobQueue(async jobId => {
1057
- await this.blockStateSynchronizer.sync();
1269
+ await this.#maybeSync();
1058
1270
 
1059
1271
  const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
1060
1272
  anchorBlockNumber = anchorBlockHeader.getBlockNumber();
@@ -1064,10 +1276,11 @@ export class PXE {
1064
1276
  await this.contractSyncService.ensureContractSynced(
1065
1277
  filter.contractAddress,
1066
1278
  null,
1067
- async privateSyncCall =>
1068
- await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
1279
+ async (privateSyncCall, execScopes) =>
1280
+ await this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
1069
1281
  anchorBlockHeader,
1070
1282
  jobId,
1283
+ filter.scopes,
1071
1284
  );
1072
1285
  });
1073
1286
 
@@ -1082,9 +1295,11 @@ export class PXE {
1082
1295
  }
1083
1296
 
1084
1297
  /**
1085
- * Stops the PXE's job queue.
1298
+ * Stops the PXE's job queue and closes the backing store.
1086
1299
  */
1087
- public stop(): Promise<void> {
1088
- return this.jobQueue.end();
1300
+ public async stop(): Promise<void> {
1301
+ await this.jobQueue.end();
1302
+ await this.blockStateSynchronizer.stop();
1303
+ await this.db.close();
1089
1304
  }
1090
1305
  }