@aztec/pxe 3.0.0-canary.a9708bd → 3.0.0-devnet.20251212

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 (264) hide show
  1. package/README.md +5 -5
  2. package/dest/bin/check_oracle_version.d.ts +1 -1
  3. package/dest/bin/check_oracle_version.js +110 -10
  4. package/dest/config/index.d.ts +9 -17
  5. package/dest/config/index.d.ts.map +1 -1
  6. package/dest/config/index.js +10 -16
  7. package/dest/config/package_info.d.ts +1 -1
  8. package/dest/config/package_info.js +1 -1
  9. package/dest/contract_function_simulator/contract_function_simulator.d.ts +6 -6
  10. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  11. package/dest/contract_function_simulator/contract_function_simulator.js +97 -42
  12. package/dest/contract_function_simulator/execution_data_provider.d.ts +40 -57
  13. package/dest/contract_function_simulator/execution_data_provider.d.ts.map +1 -1
  14. package/dest/contract_function_simulator/execution_note_cache.d.ts +11 -9
  15. package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
  16. package/dest/contract_function_simulator/execution_note_cache.js +28 -17
  17. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +16 -0
  18. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -0
  19. package/dest/contract_function_simulator/execution_tagging_index_cache.js +26 -0
  20. package/dest/contract_function_simulator/hashed_values_cache.d.ts +2 -2
  21. package/dest/contract_function_simulator/hashed_values_cache.d.ts.map +1 -1
  22. package/dest/contract_function_simulator/index.d.ts +4 -2
  23. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  24. package/dest/contract_function_simulator/index.js +2 -1
  25. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +2 -2
  26. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
  27. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +2 -2
  28. package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -1
  29. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +3 -3
  30. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts.map +1 -1
  31. package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +8 -4
  32. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +6 -3
  33. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
  34. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +12 -3
  35. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +22 -0
  36. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -0
  37. package/dest/contract_function_simulator/noir-structs/utility_context.js +33 -0
  38. package/dest/contract_function_simulator/oracle/index.d.ts +2 -2
  39. package/dest/contract_function_simulator/oracle/index.d.ts.map +1 -1
  40. package/dest/contract_function_simulator/oracle/index.js +1 -1
  41. package/dest/contract_function_simulator/oracle/interfaces.d.ts +104 -0
  42. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -0
  43. package/dest/contract_function_simulator/oracle/interfaces.js +4 -0
  44. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +2 -4
  45. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
  46. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.js +1 -1
  47. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +10 -4
  48. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
  49. package/dest/contract_function_simulator/oracle/note_packing_utils.js +10 -5
  50. package/dest/contract_function_simulator/oracle/oracle.d.ts +17 -15
  51. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  52. package/dest/contract_function_simulator/oracle/oracle.js +101 -81
  53. package/dest/contract_function_simulator/oracle/private_execution.d.ts +6 -5
  54. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
  55. package/dest/contract_function_simulator/oracle/private_execution.js +7 -16
  56. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +34 -22
  57. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  58. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +89 -25
  59. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +23 -33
  60. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  61. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +38 -42
  62. package/dest/contract_function_simulator/pick_notes.d.ts +2 -2
  63. package/dest/contract_function_simulator/pick_notes.d.ts.map +1 -1
  64. package/dest/contract_function_simulator/pick_notes.js +1 -1
  65. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +1 -1
  66. package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +1 -1
  67. package/dest/contract_function_simulator/proxied_node.d.ts +1 -1
  68. package/dest/contract_function_simulator/proxied_node.d.ts.map +1 -1
  69. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts +34 -68
  70. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -1
  71. package/dest/contract_function_simulator/pxe_oracle_interface.js +220 -208
  72. package/dest/entrypoints/client/bundle/index.d.ts +4 -2
  73. package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
  74. package/dest/entrypoints/client/bundle/index.js +2 -1
  75. package/dest/entrypoints/client/bundle/utils.d.ts +9 -9
  76. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  77. package/dest/entrypoints/client/bundle/utils.js +12 -12
  78. package/dest/entrypoints/client/lazy/index.d.ts +4 -2
  79. package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
  80. package/dest/entrypoints/client/lazy/index.js +2 -1
  81. package/dest/entrypoints/client/lazy/utils.d.ts +8 -8
  82. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  83. package/dest/entrypoints/client/lazy/utils.js +11 -11
  84. package/dest/entrypoints/pxe_creation_options.d.ts +3 -1
  85. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  86. package/dest/entrypoints/server/index.d.ts +4 -2
  87. package/dest/entrypoints/server/index.d.ts.map +1 -1
  88. package/dest/entrypoints/server/index.js +2 -1
  89. package/dest/entrypoints/server/utils.d.ts +5 -24
  90. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  91. package/dest/entrypoints/server/utils.js +9 -41
  92. package/dest/error_enriching.d.ts +11 -0
  93. package/dest/error_enriching.d.ts.map +1 -0
  94. package/dest/{pxe_service/error_enriching.js → error_enriching.js} +3 -0
  95. package/dest/events/index.d.ts +2 -0
  96. package/dest/events/index.d.ts.map +1 -0
  97. package/dest/events/index.js +1 -0
  98. package/dest/events/private_event_filter_validator.d.ts +8 -0
  99. package/dest/events/private_event_filter_validator.d.ts.map +1 -0
  100. package/dest/events/private_event_filter_validator.js +39 -0
  101. package/dest/oracle_version.d.ts +3 -3
  102. package/dest/oracle_version.js +2 -2
  103. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +3 -3
  104. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
  105. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.js +7 -7
  106. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +1 -1
  107. package/dest/private_kernel/hints/compute_tx_include_by_timestamp.js +6 -6
  108. package/dest/private_kernel/hints/index.d.ts +1 -1
  109. package/dest/private_kernel/index.d.ts +1 -1
  110. package/dest/private_kernel/private_kernel_execution_prover.d.ts +9 -2
  111. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  112. package/dest/private_kernel/private_kernel_execution_prover.js +38 -32
  113. package/dest/private_kernel/private_kernel_oracle.d.ts +3 -2
  114. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  115. package/dest/private_kernel/private_kernel_oracle_impl.d.ts +8 -7
  116. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
  117. package/dest/pxe.d.ts +240 -0
  118. package/dest/pxe.d.ts.map +1 -0
  119. package/dest/{pxe_service/pxe_service.js → pxe.js} +227 -241
  120. package/dest/storage/address_data_provider/address_data_provider.d.ts +2 -4
  121. package/dest/storage/address_data_provider/address_data_provider.d.ts.map +1 -1
  122. package/dest/storage/address_data_provider/address_data_provider.js +0 -3
  123. package/dest/storage/address_data_provider/index.d.ts +1 -1
  124. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +3 -5
  125. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -1
  126. package/dest/storage/capsule_data_provider/capsule_data_provider.js +1 -5
  127. package/dest/storage/capsule_data_provider/index.d.ts +1 -1
  128. package/dest/storage/contract_data_provider/contract_data_provider.d.ts +6 -17
  129. package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
  130. package/dest/storage/contract_data_provider/contract_data_provider.js +0 -15
  131. package/dest/storage/contract_data_provider/index.d.ts +1 -1
  132. package/dest/storage/contract_data_provider/private_functions_tree.d.ts +1 -1
  133. package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
  134. package/dest/storage/contract_data_provider/private_functions_tree.js +1 -1
  135. package/dest/storage/index.d.ts +1 -2
  136. package/dest/storage/index.d.ts.map +1 -1
  137. package/dest/storage/index.js +0 -1
  138. package/dest/storage/metadata.d.ts +1 -1
  139. package/dest/storage/note_data_provider/index.d.ts +2 -2
  140. package/dest/storage/note_data_provider/index.d.ts.map +1 -1
  141. package/dest/storage/note_data_provider/index.js +1 -1
  142. package/dest/storage/note_data_provider/note_data_provider.d.ts +75 -11
  143. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
  144. package/dest/storage/note_data_provider/note_data_provider.js +143 -81
  145. package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts +31 -17
  146. package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts.map +1 -1
  147. package/dest/storage/private_event_data_provider/private_event_data_provider.js +47 -28
  148. package/dest/storage/sync_data_provider/index.d.ts +1 -1
  149. package/dest/storage/sync_data_provider/sync_data_provider.d.ts +4 -5
  150. package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +1 -1
  151. package/dest/storage/sync_data_provider/sync_data_provider.js +0 -3
  152. package/dest/storage/tagging_data_provider/index.d.ts +1 -1
  153. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +29 -7
  154. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +1 -1
  155. package/dest/storage/tagging_data_provider/tagging_data_provider.js +46 -39
  156. package/dest/synchronizer/index.d.ts +1 -1
  157. package/dest/synchronizer/synchronizer.d.ts +3 -2
  158. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  159. package/dest/synchronizer/synchronizer.js +4 -4
  160. package/dest/tagging/constants.d.ts +2 -0
  161. package/dest/tagging/constants.d.ts.map +1 -0
  162. package/dest/tagging/constants.js +2 -0
  163. package/dest/tagging/index.d.ts +7 -0
  164. package/dest/tagging/index.d.ts.map +1 -0
  165. package/dest/tagging/index.js +5 -0
  166. package/dest/tagging/siloed_tag.d.ts +14 -0
  167. package/dest/tagging/siloed_tag.d.ts.map +1 -0
  168. package/dest/tagging/siloed_tag.js +20 -0
  169. package/dest/tagging/tag.d.ts +12 -0
  170. package/dest/tagging/tag.d.ts.map +1 -0
  171. package/dest/tagging/tag.js +17 -0
  172. package/dest/tagging/utils.d.ts +18 -0
  173. package/dest/tagging/utils.d.ts.map +1 -0
  174. package/dest/tagging/utils.js +24 -0
  175. package/package.json +22 -24
  176. package/src/bin/check_oracle_version.ts +134 -10
  177. package/src/config/index.ts +18 -32
  178. package/src/config/package_info.ts +1 -1
  179. package/src/contract_function_simulator/contract_function_simulator.ts +151 -62
  180. package/src/contract_function_simulator/execution_data_provider.ts +47 -65
  181. package/src/contract_function_simulator/execution_note_cache.ts +33 -17
  182. package/src/contract_function_simulator/execution_tagging_index_cache.ts +32 -0
  183. package/src/contract_function_simulator/hashed_values_cache.ts +1 -1
  184. package/src/contract_function_simulator/index.ts +3 -1
  185. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
  186. package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +1 -1
  187. package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +10 -5
  188. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +14 -2
  189. package/src/contract_function_simulator/noir-structs/utility_context.ts +42 -0
  190. package/src/contract_function_simulator/oracle/index.ts +1 -1
  191. package/src/contract_function_simulator/oracle/interfaces.ts +176 -0
  192. package/src/contract_function_simulator/oracle/message_load_oracle_inputs.ts +1 -1
  193. package/src/contract_function_simulator/oracle/note_packing_utils.ts +21 -5
  194. package/src/contract_function_simulator/oracle/oracle.ts +135 -80
  195. package/src/contract_function_simulator/oracle/private_execution.ts +10 -17
  196. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +123 -49
  197. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +68 -80
  198. package/src/contract_function_simulator/pick_notes.ts +1 -1
  199. package/src/contract_function_simulator/pxe_oracle_interface.ts +291 -271
  200. package/src/entrypoints/client/bundle/index.ts +3 -1
  201. package/src/entrypoints/client/bundle/utils.ts +15 -23
  202. package/src/entrypoints/client/lazy/index.ts +3 -1
  203. package/src/entrypoints/client/lazy/utils.ts +14 -22
  204. package/src/entrypoints/pxe_creation_options.ts +2 -0
  205. package/src/entrypoints/server/index.ts +3 -1
  206. package/src/entrypoints/server/utils.ts +12 -56
  207. package/src/{pxe_service/error_enriching.ts → error_enriching.ts} +5 -1
  208. package/src/events/index.ts +1 -0
  209. package/src/events/private_event_filter_validator.ts +47 -0
  210. package/src/oracle_version.ts +2 -2
  211. package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +5 -9
  212. package/src/private_kernel/hints/compute_tx_include_by_timestamp.ts +6 -6
  213. package/src/private_kernel/private_kernel_execution_prover.ts +51 -43
  214. package/src/private_kernel/private_kernel_oracle.ts +2 -1
  215. package/src/private_kernel/private_kernel_oracle_impl.ts +4 -3
  216. package/src/{pxe_service/pxe_service.ts → pxe.ts} +256 -308
  217. package/src/storage/address_data_provider/address_data_provider.ts +1 -7
  218. package/src/storage/capsule_data_provider/capsule_data_provider.ts +2 -12
  219. package/src/storage/contract_data_provider/contract_data_provider.ts +4 -27
  220. package/src/storage/contract_data_provider/private_functions_tree.ts +1 -1
  221. package/src/storage/index.ts +0 -1
  222. package/src/storage/note_data_provider/index.ts +1 -1
  223. package/src/storage/note_data_provider/note_data_provider.ts +171 -109
  224. package/src/storage/private_event_data_provider/private_event_data_provider.ts +69 -41
  225. package/src/storage/sync_data_provider/sync_data_provider.ts +3 -8
  226. package/src/storage/tagging_data_provider/tagging_data_provider.ts +52 -55
  227. package/src/synchronizer/synchronizer.ts +4 -4
  228. package/src/tagging/constants.ts +2 -0
  229. package/src/tagging/index.ts +6 -0
  230. package/src/tagging/siloed_tag.ts +22 -0
  231. package/src/tagging/tag.ts +16 -0
  232. package/src/tagging/utils.ts +31 -0
  233. package/dest/bin/index.d.ts +0 -3
  234. package/dest/bin/index.d.ts.map +0 -1
  235. package/dest/bin/index.js +0 -48
  236. package/dest/contract_function_simulator/oracle/typed_oracle.d.ts +0 -87
  237. package/dest/contract_function_simulator/oracle/typed_oracle.d.ts.map +0 -1
  238. package/dest/contract_function_simulator/oracle/typed_oracle.js +0 -146
  239. package/dest/contract_function_simulator/tagging_utils.d.ts +0 -17
  240. package/dest/contract_function_simulator/tagging_utils.d.ts.map +0 -1
  241. package/dest/contract_function_simulator/tagging_utils.js +0 -23
  242. package/dest/pxe_service/error_enriching.d.ts +0 -11
  243. package/dest/pxe_service/error_enriching.d.ts.map +0 -1
  244. package/dest/pxe_service/index.d.ts +0 -3
  245. package/dest/pxe_service/index.d.ts.map +0 -1
  246. package/dest/pxe_service/index.js +0 -2
  247. package/dest/pxe_service/pxe_service.d.ts +0 -100
  248. package/dest/pxe_service/pxe_service.d.ts.map +0 -1
  249. package/dest/storage/data_provider.d.ts +0 -4
  250. package/dest/storage/data_provider.d.ts.map +0 -1
  251. package/dest/storage/data_provider.js +0 -1
  252. package/dest/storage/note_data_provider/note_dao.d.ts +0 -100
  253. package/dest/storage/note_data_provider/note_dao.d.ts.map +0 -1
  254. package/dest/storage/note_data_provider/note_dao.js +0 -102
  255. package/dest/test/pxe_test_suite.d.ts +0 -3
  256. package/dest/test/pxe_test_suite.d.ts.map +0 -1
  257. package/dest/test/pxe_test_suite.js +0 -97
  258. package/src/bin/index.ts +0 -62
  259. package/src/contract_function_simulator/oracle/typed_oracle.ts +0 -289
  260. package/src/contract_function_simulator/tagging_utils.ts +0 -32
  261. package/src/pxe_service/index.ts +0 -2
  262. package/src/storage/data_provider.ts +0 -3
  263. package/src/storage/note_data_provider/note_dao.ts +0 -154
  264. package/src/test/pxe_test_suite.ts +0 -113
@@ -1,22 +1,20 @@
1
1
  import { timesParallel } from '@aztec/foundation/collection';
2
- import { Fr } from '@aztec/foundation/fields';
3
2
  import { createLogger } from '@aztec/foundation/log';
4
- import { getFunctionArtifact } from '@aztec/stdlib/abi';
5
3
  import { computeUniqueNoteHash, siloNoteHash, siloNullifier, siloPrivateLog } from '@aztec/stdlib/hash';
6
4
  import { MAX_RPC_LEN } from '@aztec/stdlib/interfaces/client';
7
- import { computeAddressSecret, computeAppTaggingSecret } from '@aztec/stdlib/keys';
8
- import { IndexedTaggingSecret, PendingTaggedLog, PrivateLogWithTxData, PublicLogWithTxData, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
5
+ import { computeAddressSecret } from '@aztec/stdlib/keys';
6
+ import { PendingTaggedLog, PrivateLogWithTxData, PublicLogWithTxData, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
9
7
  import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
10
8
  import { Note } from '@aztec/stdlib/note';
9
+ import { NoteDao } from '@aztec/stdlib/note';
11
10
  import { MerkleTreeId } from '@aztec/stdlib/trees';
12
11
  import { MessageLoadOracleInputs } from '../contract_function_simulator/oracle/message_load_oracle_inputs.js';
13
12
  import { ORACLE_VERSION } from '../oracle_version.js';
14
- import { NoteDao } from '../storage/note_data_provider/note_dao.js';
13
+ import { DirectionalAppTaggingSecret, SiloedTag, Tag, WINDOW_HALF_SIZE, getInitialIndexesMap, getPreTagsForTheWindow } from '../tagging/index.js';
15
14
  import { EventValidationRequest } from './noir-structs/event_validation_request.js';
16
15
  import { LogRetrievalRequest } from './noir-structs/log_retrieval_request.js';
17
16
  import { LogRetrievalResponse } from './noir-structs/log_retrieval_response.js';
18
17
  import { NoteValidationRequest } from './noir-structs/note_validation_request.js';
19
- import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
20
18
  /**
21
19
  * A data layer that provides and stores information needed for simulating/proving a transaction.
22
20
  */ export class PXEOracleInterface {
@@ -49,7 +47,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
49
47
  const completeAddress = await this.addressDataProvider.getCompleteAddress(account);
50
48
  if (!completeAddress) {
51
49
  throw new Error(`No public key registered for address ${account}.
52
- Register it by calling pxe.addAccount(...).\nSee docs for context: https://docs.aztec.network/developers/reference/debugging/aztecnr-errors#simulation-error-no-public-key-registered-for-address-0x0-register-it-by-calling-pxeregisterrecipient-or-pxeregisteraccount`);
50
+ Register it by calling pxe.addAccount(...).\nSee docs for context: https://docs.aztec.network/developers/resources/debugging/aztecnr-errors#simulation-error-no-public-key-registered-for-address-0x0-register-it-by-calling-pxeregisterrecipient-or-pxeregisteraccount`);
53
51
  }
54
52
  return completeAddress;
55
53
  }
@@ -60,16 +58,19 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
60
58
  }
61
59
  return instance;
62
60
  }
63
- async getNotes(contractAddress, storageSlot, status, scopes) {
61
+ async getNotes(contractAddress, owner, storageSlot, status, scopes) {
64
62
  const noteDaos = await this.noteDataProvider.getNotes({
65
63
  contractAddress,
64
+ owner,
66
65
  storageSlot,
67
66
  status,
68
67
  scopes
69
68
  });
70
- return noteDaos.map(({ contractAddress, storageSlot, noteNonce, note, noteHash, siloedNullifier, index })=>({
69
+ return noteDaos.map(({ contractAddress, owner, storageSlot, randomness, noteNonce, note, noteHash, siloedNullifier, index })=>({
71
70
  contractAddress,
71
+ owner,
72
72
  storageSlot,
73
+ randomness,
73
74
  noteNonce,
74
75
  note,
75
76
  noteHash,
@@ -89,14 +90,6 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
89
90
  debug
90
91
  };
91
92
  }
92
- async getFunctionArtifactByName(contractAddress, functionName) {
93
- const instance = await this.contractDataProvider.getContractInstance(contractAddress);
94
- if (!instance) {
95
- return;
96
- }
97
- const artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
98
- return artifact && getFunctionArtifact(artifact, functionName);
99
- }
100
93
  /**
101
94
  * Fetches a message from the db, given its key.
102
95
  * @param contractAddress - Address of a contract by which the message was emitted.
@@ -140,30 +133,41 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
140
133
  }
141
134
  }
142
135
  async getNullifierMembershipWitnessAtLatestBlock(nullifier) {
143
- return this.getNullifierMembershipWitness(await this.getBlockNumber(), nullifier);
136
+ const blockNumber = (await this.getAnchorBlockHeader()).globalVariables.blockNumber;
137
+ return this.getNullifierMembershipWitness(blockNumber, nullifier);
144
138
  }
145
139
  getNullifierMembershipWitness(blockNumber, nullifier) {
146
140
  return this.aztecNode.getNullifierMembershipWitness(blockNumber, nullifier);
147
141
  }
148
- getLowNullifierMembershipWitness(blockNumber, nullifier) {
142
+ async getLowNullifierMembershipWitness(blockNumber, nullifier) {
143
+ const header = await this.getAnchorBlockHeader();
144
+ if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
145
+ throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
146
+ }
149
147
  return this.aztecNode.getLowNullifierMembershipWitness(blockNumber, nullifier);
150
148
  }
151
149
  async getBlock(blockNumber) {
150
+ const header = await this.getAnchorBlockHeader();
151
+ if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
152
+ throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
153
+ }
152
154
  return await this.aztecNode.getBlock(blockNumber);
153
155
  }
154
156
  async getPublicDataWitness(blockNumber, leafSlot) {
157
+ const header = await this.getAnchorBlockHeader();
158
+ if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
159
+ throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
160
+ }
155
161
  return await this.aztecNode.getPublicDataWitness(blockNumber, leafSlot);
156
162
  }
157
163
  async getPublicStorageAt(blockNumber, contract, slot) {
164
+ const header = await this.getAnchorBlockHeader();
165
+ if (blockNumber !== 'latest' && blockNumber > header.globalVariables.blockNumber) {
166
+ throw new Error(`Block number ${blockNumber} is higher than current block ${header.globalVariables.blockNumber}`);
167
+ }
158
168
  return await this.aztecNode.getPublicStorageAt(blockNumber, contract, slot);
159
169
  }
160
- /**
161
- * Retrieve the latest block header synchronized by the PXE.
162
- * @dev This structure is fed into the circuits simulator and is used to prove against certain historical roots.
163
- * @returns The BlockHeader object.
164
- * TODO: I think this naming is bad as it's not the latest block header synched by the node, but the latest block
165
- * header synchronized by the PXE. Would rename this to something like getSynchronizedBlockHeader().
166
- */ getBlockHeader() {
170
+ getAnchorBlockHeader() {
167
171
  return this.syncDataProvider.getBlockHeader();
168
172
  }
169
173
  assertCompatibleOracleVersion(version) {
@@ -171,34 +175,6 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
171
175
  throw new Error(`Incompatible oracle version. Expected version ${ORACLE_VERSION}, got ${version}.`);
172
176
  }
173
177
  }
174
- /**
175
- * Fetches the latest block number synchronized by the node.
176
- * @returns The block number.
177
- */ async getBlockNumber() {
178
- return await this.aztecNode.getBlockNumber();
179
- }
180
- /**
181
- * Fetches the timestamp of the latest block synchronized by the node.
182
- * @returns The timestamp.
183
- */ async getTimestamp() {
184
- const latestBlockHeader = await this.aztecNode.getBlockHeader();
185
- if (!latestBlockHeader) {
186
- throw new Error('Latest block header not found when getting timestamp');
187
- }
188
- return latestBlockHeader.globalVariables.timestamp;
189
- }
190
- /**
191
- * Fetches the current chain id.
192
- * @returns The chain id.
193
- */ async getChainId() {
194
- return await this.aztecNode.getChainId();
195
- }
196
- /**
197
- * Fetches the current version.
198
- * @returns The version.
199
- */ async getVersion() {
200
- return await this.aztecNode.getVersion();
201
- }
202
178
  getDebugFunctionName(contractAddress, selector) {
203
179
  return this.contractDataProvider.getDebugFunctionName(contractAddress, selector);
204
180
  }
@@ -210,57 +186,27 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
210
186
  */ getSenders() {
211
187
  return this.taggingDataProvider.getSenderAddresses();
212
188
  }
213
- /**
214
- * Returns the tagging secret for a given sender and recipient pair. For this to work, the ivsk_m of the sender must be known.
215
- * Includes the next index to be used used for tagging with this secret.
216
- * @param contractAddress - The contract address to silo the secret for
217
- * @param sender - The address sending the note
218
- * @param recipient - The address receiving the note
219
- * @returns An indexed tagging secret that can be used to tag notes.
220
- */ async getIndexedTaggingSecretAsSender(contractAddress, sender, recipient) {
221
- await this.syncTaggedLogsAsSender(contractAddress, sender, recipient);
222
- const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
223
- const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([
224
- appTaggingSecret
225
- ], sender);
226
- return new IndexedTaggingSecret(appTaggingSecret, index);
189
+ getLastUsedIndexAsSender(secret) {
190
+ return this.taggingDataProvider.getLastUsedIndexesAsSender(secret);
227
191
  }
228
- /**
229
- * Increments the tagging secret for a given sender and recipient pair. For this to work, the ivsk_m of the sender must be known.
230
- * @param contractAddress - The contract address to silo the secret for
231
- * @param sender - The address sending the note
232
- * @param recipient - The address receiving the note
233
- */ async incrementAppTaggingSecretIndexAsSender(contractAddress, sender, recipient) {
234
- const secret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
235
- const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
236
- this.log.debug(`Incrementing app tagging secret at ${contractName}(${contractAddress})`, {
237
- secret,
238
- sender,
239
- recipient,
240
- contractName,
241
- contractAddress
242
- });
243
- const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([
244
- secret
245
- ], sender);
246
- await this.taggingDataProvider.setTaggingSecretsIndexesAsSender([
247
- new IndexedTaggingSecret(secret, index + 1)
248
- ], sender);
249
- }
250
- async #calculateAppTaggingSecret(contractAddress, sender, recipient) {
192
+ async calculateDirectionalAppTaggingSecret(contractAddress, sender, recipient) {
251
193
  const senderCompleteAddress = await this.getCompleteAddress(sender);
252
194
  const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
253
- return computeAppTaggingSecret(senderCompleteAddress, senderIvsk, recipient, contractAddress);
195
+ return DirectionalAppTaggingSecret.compute(senderCompleteAddress, senderIvsk, recipient, contractAddress, recipient);
254
196
  }
255
197
  /**
256
- * Returns the indexed tagging secrets for a given recipient and all the senders in the address book
198
+ * Returns the last used tagging indexes along with the directional app tagging secrets for a given recipient and all
199
+ * the senders in the address book.
257
200
  * This method should be exposed as an oracle call to allow aztec.nr to perform the orchestration
258
201
  * of the syncTaggedLogs and processTaggedLogs methods. However, it is not possible to do so at the moment,
259
202
  * so we're keeping it private for now.
260
203
  * @param contractAddress - The contract address to silo the secret for
261
204
  * @param recipient - The address receiving the notes
262
- * @returns A list of indexed tagging secrets
263
- */ async #getIndexedTaggingSecretsForSenders(contractAddress, recipient) {
205
+ * @returns A list of directional app tagging secrets along with the last used tagging indexes. If the corresponding
206
+ * secret was never used, the index is undefined.
207
+ * TODO(benesjan): The naming here is broken as the function name does not reflect the return type. Fix when associating
208
+ * indexes with tx hash.
209
+ */ async #getLastUsedTaggingIndexesForSenders(contractAddress, recipient) {
264
210
  const recipientCompleteAddress = await this.getCompleteAddress(recipient);
265
211
  const recipientIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(recipient);
266
212
  // We implicitly add all PXE accounts as senders, this helps us decrypt tags on notes that we send to ourselves
@@ -269,21 +215,23 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
269
215
  ...await this.taggingDataProvider.getSenderAddresses(),
270
216
  ...await this.keyStore.getAccounts()
271
217
  ].filter((address, index, self)=>index === self.findIndex((otherAddress)=>otherAddress.equals(address)));
272
- const appTaggingSecrets = await Promise.all(senders.map((contact)=>computeAppTaggingSecret(recipientCompleteAddress, recipientIvsk, contact, contractAddress)));
273
- const indexes = await this.taggingDataProvider.getTaggingSecretsIndexesAsRecipient(appTaggingSecrets, recipient);
274
- return appTaggingSecrets.map((secret, i)=>new IndexedTaggingSecret(secret, indexes[i]));
218
+ const secrets = await Promise.all(senders.map((contact)=>{
219
+ return DirectionalAppTaggingSecret.compute(recipientCompleteAddress, recipientIvsk, contact, contractAddress, recipient);
220
+ }));
221
+ const indexes = await this.taggingDataProvider.getLastUsedIndexesAsRecipient(secrets);
222
+ if (indexes.length !== secrets.length) {
223
+ throw new Error('Indexes and directional app tagging secrets have different lengths');
224
+ }
225
+ return secrets.map((secret, i)=>({
226
+ secret,
227
+ index: indexes[i]
228
+ }));
275
229
  }
276
- /**
277
- * Updates the local index of the shared tagging secret of a sender / recipient pair
278
- * if a log with a larger index is found from the node.
279
- * @param contractAddress - The address of the contract that the logs are tagged for
280
- * @param sender - The address of the sender, we must know the sender's ivsk_m.
281
- * @param recipient - The address of the recipient.
282
- */ async syncTaggedLogsAsSender(contractAddress, sender, recipient) {
283
- const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
284
- const [oldIndex] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([
285
- appTaggingSecret
286
- ], sender);
230
+ async syncTaggedLogsAsSender(secret, contractAddress) {
231
+ const lastUsedIndex = await this.taggingDataProvider.getLastUsedIndexesAsSender(secret);
232
+ // If lastUsedIndex is undefined, we've never used this secret, so start from 0
233
+ // Otherwise, start from one past the last used index
234
+ const startIndex = lastUsedIndex === undefined ? 0 : lastUsedIndex + 1;
287
235
  // This algorithm works such that:
288
236
  // 1. If we find minimum consecutive empty logs in a window of logs we set the index to the index of the last log
289
237
  // we found and quit.
@@ -293,40 +241,50 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
293
241
  const WINDOW_SIZE = MIN_CONSECUTIVE_EMPTY_LOGS * 2;
294
242
  let [numConsecutiveEmptyLogs, currentIndex] = [
295
243
  0,
296
- oldIndex
244
+ startIndex
297
245
  ];
246
+ let lastFoundLogIndex = undefined;
298
247
  do {
299
248
  // We compute the tags for the current window of indexes
300
- const currentTags = await timesParallel(WINDOW_SIZE, (i)=>{
301
- const indexedAppTaggingSecret = new IndexedTaggingSecret(appTaggingSecret, currentIndex + i);
302
- return indexedAppTaggingSecret.computeSiloedTag(recipient, contractAddress);
249
+ const currentTags = await timesParallel(WINDOW_SIZE, async (i)=>{
250
+ return SiloedTag.compute(await Tag.compute({
251
+ secret,
252
+ index: currentIndex + i
253
+ }), contractAddress);
303
254
  });
304
255
  // We fetch the logs for the tags
305
- const possibleLogs = await this.#getPrivateLogsByTags(currentTags);
256
+ // TODO: The following conversion is unfortunate and we should most likely just type the #getPrivateLogsByTags
257
+ // to accept SiloedTag[] instead of Fr[]. That would result in a large change so I didn't do it yet.
258
+ const tagsAsFr = currentTags.map((tag)=>tag.value);
259
+ const possibleLogs = await this.#getPrivateLogsByTags(tagsAsFr);
306
260
  // We find the index of the last log in the window that is not empty
307
- const indexOfLastLog = possibleLogs.findLastIndex((possibleLog)=>possibleLog.length !== 0);
308
- if (indexOfLastLog === -1) {
261
+ const indexOfLastLogWithinArray = possibleLogs.findLastIndex((possibleLog)=>possibleLog.length !== 0);
262
+ if (indexOfLastLogWithinArray === -1) {
309
263
  break;
310
264
  }
311
- // We move the current index to that of the last log we found
312
- currentIndex += indexOfLastLog + 1;
265
+ // We've found logs so we update the last found log index
266
+ lastFoundLogIndex = (lastFoundLogIndex ?? 0) + indexOfLastLogWithinArray;
267
+ // We move the current index to that of the log right after the last found log
268
+ currentIndex = lastFoundLogIndex + 1;
313
269
  // We compute the number of consecutive empty logs we found and repeat the process if we haven't found enough.
314
- numConsecutiveEmptyLogs = WINDOW_SIZE - indexOfLastLog - 1;
270
+ numConsecutiveEmptyLogs = WINDOW_SIZE - indexOfLastLogWithinArray - 1;
315
271
  }while (numConsecutiveEmptyLogs < MIN_CONSECUTIVE_EMPTY_LOGS)
316
272
  const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
317
- if (currentIndex !== oldIndex) {
318
- await this.taggingDataProvider.setTaggingSecretsIndexesAsSender([
319
- new IndexedTaggingSecret(appTaggingSecret, currentIndex)
320
- ], sender);
321
- this.log.debug(`Syncing logs for sender ${sender} at contract ${contractName}(${contractAddress})`, {
322
- sender,
323
- secret: appTaggingSecret,
273
+ if (lastFoundLogIndex !== undefined) {
274
+ // Last found index is defined meaning we have actually found logs so we update the last used index
275
+ await this.taggingDataProvider.setLastUsedIndexesAsSender([
276
+ {
277
+ secret,
278
+ index: lastFoundLogIndex
279
+ }
280
+ ]);
281
+ this.log.debug(`Syncing logs for secret ${secret.toString()} at contract ${contractName}(${contractAddress})`, {
324
282
  index: currentIndex,
325
283
  contractName,
326
284
  contractAddress
327
285
  });
328
286
  } else {
329
- this.log.debug(`No new logs found for sender ${sender} at contract ${contractName}(${contractAddress})`);
287
+ this.log.debug(`No new logs found for secret ${secret.toString()} at contract ${contractName}(${contractAddress})`);
330
288
  }
331
289
  }
332
290
  /**
@@ -351,7 +309,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
351
309
  const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
352
310
  for (const recipient of recipients){
353
311
  // Get all the secrets for the recipient and sender pairs (#9365)
354
- const secrets = await this.#getIndexedTaggingSecretsForSenders(contractAddress, recipient);
312
+ const indexedSecrets = await this.#getLastUsedTaggingIndexesForSenders(contractAddress, recipient);
355
313
  // We fetch logs for a window of indexes in a range:
356
314
  // <latest_log_index - WINDOW_HALF_SIZE, latest_log_index + WINDOW_HALF_SIZE>.
357
315
  //
@@ -360,25 +318,39 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
360
318
  // for logs the first time we don't receive any logs for a tag, we might never receive anything from that sender again.
361
319
  // Also there's a possibility that we have advanced our index, but the sender has reused it, so we might have missed
362
320
  // some logs. For these reasons, we have to look both back and ahead of the stored index.
363
- let secretsAndWindows = secrets.map((secret)=>{
364
- return {
365
- appTaggingSecret: secret.appTaggingSecret,
366
- leftMostIndex: Math.max(0, secret.index - WINDOW_HALF_SIZE),
367
- rightMostIndex: secret.index + WINDOW_HALF_SIZE
368
- };
321
+ let secretsAndWindows = indexedSecrets.map((indexedSecret)=>{
322
+ if (indexedSecret.index === undefined) {
323
+ return {
324
+ secret: indexedSecret.secret,
325
+ leftMostIndex: 0,
326
+ rightMostIndex: WINDOW_HALF_SIZE
327
+ };
328
+ } else {
329
+ return {
330
+ secret: indexedSecret.secret,
331
+ leftMostIndex: Math.max(0, indexedSecret.index - WINDOW_HALF_SIZE),
332
+ rightMostIndex: indexedSecret.index + WINDOW_HALF_SIZE
333
+ };
334
+ }
369
335
  });
370
336
  // As we iterate we store the largest index we have seen for a given secret to later on store it in the db.
371
337
  const newLargestIndexMapToStore = {};
372
- // The initial/unmodified indexes of the secrets stored in a key-value map where key is the app tagging secret.
373
- const initialIndexesMap = getInitialIndexesMap(secrets);
338
+ // The initial/unmodified indexes of the secrets stored in a key-value map where key is the directional app
339
+ // tagging secret.
340
+ const initialIndexesMap = getInitialIndexesMap(indexedSecrets);
374
341
  while(secretsAndWindows.length > 0){
375
- const secretsForTheWholeWindow = getIndexedTaggingSecretsForTheWindow(secretsAndWindows);
376
- const tagsForTheWholeWindow = await Promise.all(secretsForTheWholeWindow.map((secret)=>secret.computeSiloedTag(recipient, contractAddress)));
342
+ const preTagsForTheWholeWindow = getPreTagsForTheWindow(secretsAndWindows);
343
+ const tagsForTheWholeWindow = await Promise.all(preTagsForTheWholeWindow.map(async (preTag)=>{
344
+ return SiloedTag.compute(await Tag.compute(preTag), contractAddress);
345
+ }));
377
346
  // We store the new largest indexes we find in the iteration in the following map to later on construct
378
347
  // a new set of secrets and windows to fetch logs for.
379
348
  const newLargestIndexMapForIteration = {};
380
349
  // Fetch the private logs for the tags and iterate over them
381
- const logsByTags = await this.#getPrivateLogsByTags(tagsForTheWholeWindow);
350
+ // TODO: The following conversion is unfortunate and we should most likely just type the #getPrivateLogsByTags
351
+ // to accept SiloedTag[] instead of Fr[]. That would result in a large change so I didn't do it yet.
352
+ const tagsForTheWholeWindowAsFr = tagsForTheWholeWindow.map((tag)=>tag.value);
353
+ const logsByTags = await this.#getPrivateLogsByTags(tagsForTheWholeWindowAsFr);
382
354
  this.log.debug(`Found ${logsByTags.filter((logs)=>logs.length > 0).length} logs as recipient ${recipient}`, {
383
355
  recipient,
384
356
  contractName,
@@ -387,19 +359,19 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
387
359
  for(let logIndex = 0; logIndex < logsByTags.length; logIndex++){
388
360
  const logsByTag = logsByTags[logIndex];
389
361
  if (logsByTag.length > 0) {
390
- // We filter out the logs that are newer than the historical block number of the tx currently being constructed
362
+ // We filter out the logs that are newer than the anchor block number of the tx currently being constructed
391
363
  const filteredLogsByBlockNumber = logsByTag.filter((l)=>l.blockNumber <= maxBlockNumber);
392
364
  // We store the logs in capsules (to later be obtained in Noir)
393
365
  await this.#storePendingTaggedLogs(contractAddress, pendingTaggedLogArrayBaseSlot, recipient, filteredLogsByBlockNumber);
394
- // We retrieve the indexed tagging secret corresponding to the log as I need that to evaluate whether
366
+ // We retrieve the pre tag corresponding to the log as I need that to evaluate whether
395
367
  // a new largest index have been found.
396
- const secretCorrespondingToLog = secretsForTheWholeWindow[logIndex];
397
- const initialIndex = initialIndexesMap[secretCorrespondingToLog.appTaggingSecret.toString()];
398
- if (secretCorrespondingToLog.index >= initialIndex && (newLargestIndexMapForIteration[secretCorrespondingToLog.appTaggingSecret.toString()] === undefined || secretCorrespondingToLog.index >= newLargestIndexMapForIteration[secretCorrespondingToLog.appTaggingSecret.toString()])) {
368
+ const preTagCorrespondingToLog = preTagsForTheWholeWindow[logIndex];
369
+ const initialIndex = initialIndexesMap[preTagCorrespondingToLog.secret.toString()];
370
+ if (preTagCorrespondingToLog.index >= initialIndex && (newLargestIndexMapForIteration[preTagCorrespondingToLog.secret.toString()] === undefined || preTagCorrespondingToLog.index >= newLargestIndexMapForIteration[preTagCorrespondingToLog.secret.toString()])) {
399
371
  // We have found a new largest index so we store it for later processing (storing it in the db + fetching
400
372
  // the difference of the window sets of current and the next iteration)
401
- newLargestIndexMapForIteration[secretCorrespondingToLog.appTaggingSecret.toString()] = secretCorrespondingToLog.index + 1;
402
- this.log.debug(`Incrementing index to ${secretCorrespondingToLog.index + 1} at contract ${contractName}(${contractAddress})`);
373
+ newLargestIndexMapForIteration[preTagCorrespondingToLog.secret.toString()] = preTagCorrespondingToLog.index + 1;
374
+ this.log.debug(`Incrementing index to ${preTagCorrespondingToLog.index + 1} at contract ${contractName}(${contractAddress})`);
403
375
  }
404
376
  }
405
377
  }
@@ -407,26 +379,31 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
407
379
  // for. Note that it's very unlikely that a new log from the current window would appear between the iterations
408
380
  // so we fetch the logs only for the difference of the window sets.
409
381
  const newSecretsAndWindows = [];
410
- for (const [appTaggingSecret, newIndex] of Object.entries(newLargestIndexMapForIteration)){
411
- const secret = secrets.find((secret)=>secret.appTaggingSecret.toString() === appTaggingSecret);
412
- if (secret) {
382
+ for (const [directionalAppTaggingSecret, newIndex] of Object.entries(newLargestIndexMapForIteration)){
383
+ const maybeIndexedSecret = indexedSecrets.find((indexedSecret)=>indexedSecret.secret.toString() === directionalAppTaggingSecret);
384
+ if (maybeIndexedSecret) {
413
385
  newSecretsAndWindows.push({
414
- appTaggingSecret: secret.appTaggingSecret,
386
+ secret: maybeIndexedSecret.secret,
415
387
  // We set the left most index to the new index to avoid fetching the same logs again
416
388
  leftMostIndex: newIndex,
417
389
  rightMostIndex: newIndex + WINDOW_HALF_SIZE
418
390
  });
419
391
  // We store the new largest index in the map to later store it in the db.
420
- newLargestIndexMapToStore[appTaggingSecret] = newIndex;
392
+ newLargestIndexMapToStore[directionalAppTaggingSecret] = newIndex;
421
393
  } else {
422
- throw new Error(`Secret not found for appTaggingSecret ${appTaggingSecret}. This is a bug as it should never happen!`);
394
+ throw new Error(`Secret not found for directionalAppTaggingSecret ${directionalAppTaggingSecret}. This is a bug as it should never happen!`);
423
395
  }
424
396
  }
425
397
  // Now we set the new secrets and windows and proceed to the next iteration.
426
398
  secretsAndWindows = newSecretsAndWindows;
427
399
  }
428
- // At this point we have processed all the logs for the recipient so we store the new largest indexes in the db.
429
- await this.taggingDataProvider.setTaggingSecretsIndexesAsRecipient(Object.entries(newLargestIndexMapToStore).map(([appTaggingSecret, index])=>new IndexedTaggingSecret(Fr.fromHexString(appTaggingSecret), index)), recipient);
400
+ // At this point we have processed all the logs for the recipient so we store the last used indexes in the db.
401
+ // newLargestIndexMapToStore contains "next" indexes to look for (one past the last found), so subtract 1 to get
402
+ // last used.
403
+ await this.taggingDataProvider.setLastUsedIndexesAsRecipient(Object.entries(newLargestIndexMapToStore).map(([directionalAppTaggingSecret, index])=>({
404
+ secret: DirectionalAppTaggingSecret.fromString(directionalAppTaggingSecret),
405
+ index: index - 1
406
+ })));
430
407
  }
431
408
  }
432
409
  async #storePendingTaggedLogs(contractAddress, capsuleArrayBaseSlot, recipient, privateLogs) {
@@ -447,7 +424,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
447
424
  // faster as we don't need to wait for the network round-trip.
448
425
  const noteValidationRequests = (await this.capsuleDataProvider.readCapsuleArray(contractAddress, noteValidationRequestsArrayBaseSlot)).map(NoteValidationRequest.fromFields);
449
426
  const eventValidationRequests = (await this.capsuleDataProvider.readCapsuleArray(contractAddress, eventValidationRequestsArrayBaseSlot)).map(EventValidationRequest.fromFields);
450
- const noteDeliveries = noteValidationRequests.map((request)=>this.deliverNote(request.contractAddress, request.storageSlot, request.noteNonce, request.content, request.noteHash, request.nullifier, request.txHash, request.recipient));
427
+ const noteDeliveries = noteValidationRequests.map((request)=>this.deliverNote(request.contractAddress, request.owner, request.storageSlot, request.randomness, request.noteNonce, request.content, request.noteHash, request.nullifier, request.txHash, request.recipient));
451
428
  const eventDeliveries = eventValidationRequests.map((request)=>this.deliverEvent(request.contractAddress, request.eventTypeId, request.serializedEvent, request.eventCommitment, request.txHash, request.recipient));
452
429
  await Promise.all([
453
430
  ...noteDeliveries,
@@ -457,7 +434,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
457
434
  await this.capsuleDataProvider.setCapsuleArray(contractAddress, noteValidationRequestsArrayBaseSlot, []);
458
435
  await this.capsuleDataProvider.setCapsuleArray(contractAddress, eventValidationRequestsArrayBaseSlot, []);
459
436
  }
460
- async deliverNote(contractAddress, storageSlot, noteNonce, content, noteHash, nullifier, txHash, recipient) {
437
+ async deliverNote(contractAddress, owner, storageSlot, randomness, noteNonce, content, noteHash, nullifier, txHash, recipient) {
461
438
  // We are going to store the new note in the NoteDataProvider, which will let us later return it via `getNotes`.
462
439
  // There's two things we need to check before we do this however:
463
440
  // - we must make sure the note does actually exist in the note hash tree
@@ -481,6 +458,17 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
481
458
  // of other contracts, which would constitute a security breach.
482
459
  const uniqueNoteHash = await computeUniqueNoteHash(noteNonce, await siloNoteHash(contractAddress, noteHash));
483
460
  const siloedNullifier = await siloNullifier(contractAddress, nullifier);
461
+ const txEffect = await this.aztecNode.getTxEffect(txHash);
462
+ if (!txEffect) {
463
+ throw new Error(`Could not find tx effect for tx hash ${txHash}`);
464
+ }
465
+ if (txEffect.l2BlockNumber > syncedBlockNumber) {
466
+ throw new Error(`Could not find tx effect for tx hash ${txHash} as of block number ${syncedBlockNumber}`);
467
+ }
468
+ const noteInTx = txEffect.data.noteHashes.some((nh)=>nh.equals(uniqueNoteHash));
469
+ if (!noteInTx) {
470
+ throw new Error(`Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present in tx ${txHash}`);
471
+ }
484
472
  // We store notes by their index in the global note hash tree, which has the convenient side effect of validating
485
473
  // note existence in said tree. We concurrently also check if the note's nullifier exists, performing all node
486
474
  // queries in a single round-trip.
@@ -495,7 +483,8 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
495
483
  if (uniqueNoteHashTreeIndexInBlock === undefined) {
496
484
  throw new Error(`Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present on the tree at block ${syncedBlockNumber} (from tx ${txHash})`);
497
485
  }
498
- const noteDao = new NoteDao(new Note(content), contractAddress, storageSlot, noteNonce, noteHash, siloedNullifier, txHash, uniqueNoteHashTreeIndexInBlock?.l2BlockNumber, uniqueNoteHashTreeIndexInBlock?.l2BlockHash.toString(), uniqueNoteHashTreeIndexInBlock?.data, recipient);
486
+ const noteDao = new NoteDao(new Note(content), contractAddress, owner, storageSlot, randomness, noteNonce, noteHash, siloedNullifier, txHash, uniqueNoteHashTreeIndexInBlock.l2BlockNumber, uniqueNoteHashTreeIndexInBlock.l2BlockHash.toString(), uniqueNoteHashTreeIndexInBlock.data);
487
+ // The note was found by `recipient`, so we use that as the scope when storing the note.
499
488
  await this.noteDataProvider.addNotes([
500
489
  noteDao
501
490
  ], recipient);
@@ -508,12 +497,12 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
508
497
  });
509
498
  if (nullifierIndex !== undefined) {
510
499
  const { data: _, ...blockHashAndNum } = nullifierIndex;
511
- await this.noteDataProvider.removeNullifiedNotes([
500
+ await this.noteDataProvider.applyNullifiers([
512
501
  {
513
502
  data: siloedNullifier,
514
503
  ...blockHashAndNum
515
504
  }
516
- ], recipient);
505
+ ]);
517
506
  this.log.verbose(`Removed just-added note`, {
518
507
  contract: contractAddress,
519
508
  slot: storageSlot,
@@ -540,7 +529,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
540
529
  } else if (privateLog !== null) {
541
530
  return new LogRetrievalResponse(privateLog.logPayload, privateLog.txHash, privateLog.uniqueNoteHashesInTx, privateLog.firstNullifierInTx);
542
531
  } else {
543
- null;
532
+ return null;
544
533
  }
545
534
  }));
546
535
  // Requests are cleared once we're done.
@@ -548,20 +537,39 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
548
537
  // The responses are stored as Option<LogRetrievalResponse> in a second CapsuleArray.
549
538
  await this.capsuleDataProvider.setCapsuleArray(contractAddress, logRetrievalResponsesArrayBaseSlot, maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption));
550
539
  }
551
- async deliverEvent(contractAddress, selector, content, eventCommitment, txHash, recipient) {
540
+ async deliverEvent(contractAddress, selector, content, eventCommitment, txHash, scope) {
552
541
  // While using 'latest' block number would be fine for private events since they cannot be accessed from Aztec.nr
553
542
  // (and thus we're less concerned about being ahead of the synced block), we use the synced block number to
554
543
  // maintain consistent behavior in the PXE. Additionally, events should never be ahead of the synced block here
555
544
  // since `fetchTaggedLogs` only processes logs up to the synced block.
556
- const syncedBlockNumber = await this.syncDataProvider.getBlockNumber();
557
- const siloedEventCommitment = await siloNullifier(contractAddress, eventCommitment);
545
+ const [syncedBlockNumber, siloedEventCommitment, txEffect] = await Promise.all([
546
+ this.syncDataProvider.getBlockNumber(),
547
+ siloNullifier(contractAddress, eventCommitment),
548
+ this.aztecNode.getTxEffect(txHash)
549
+ ]);
550
+ if (!txEffect) {
551
+ throw new Error(`Could not find tx effect for tx hash ${txHash}`);
552
+ }
553
+ if (txEffect.l2BlockNumber > syncedBlockNumber) {
554
+ throw new Error(`Could not find tx effect for tx hash ${txHash} as of block number ${syncedBlockNumber}`);
555
+ }
556
+ const eventInTx = txEffect.data.nullifiers.some((n)=>n.equals(siloedEventCommitment));
557
+ if (!eventInTx) {
558
+ throw new Error(`Event commitment ${eventCommitment} (siloed as ${siloedEventCommitment}) is not present in tx ${txHash}`);
559
+ }
558
560
  const [nullifierIndex] = await this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, [
559
561
  siloedEventCommitment
560
562
  ]);
561
563
  if (nullifierIndex === undefined) {
562
564
  throw new Error(`Event commitment ${eventCommitment} (siloed as ${siloedEventCommitment}) is not present on the nullifier tree at block ${syncedBlockNumber} (from tx ${txHash})`);
563
565
  }
564
- return this.privateEventDataProvider.storePrivateEventLog(contractAddress, recipient, selector, content, txHash, Number(nullifierIndex.data), nullifierIndex.l2BlockNumber);
566
+ return this.privateEventDataProvider.storePrivateEventLog(selector, content, Number(nullifierIndex.data), {
567
+ contractAddress,
568
+ scope,
569
+ txHash,
570
+ l2BlockNumber: nullifierIndex.l2BlockNumber,
571
+ l2BlockHash: nullifierIndex.l2BlockHash
572
+ });
565
573
  }
566
574
  // TODO(#14555): delete this function and implement this behavior in the node instead
567
575
  async getPublicLogByTag(tag, contractAddress) {
@@ -609,56 +617,60 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
609
617
  }
610
618
  return new PrivateLogWithTxData(scopedLog.log.getEmittedFieldsWithoutTag(), scopedLog.txHash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
611
619
  }
612
- async removeNullifiedNotes(contractAddress) {
620
+ /**
621
+ * Looks for nullifiers of active contract notes and marks them as nullified if a nullifier is found.
622
+ *
623
+ * Fetches notes from the NoteDataProvider and checks which nullifiers are present in the
624
+ * onchain nullifier Merkle tree - up to the latest locally synced block. We use the
625
+ * locally synced block instead of querying the chain's 'latest' block to ensure correctness:
626
+ * notes are only marked nullified once their corresponding nullifier has been included in a
627
+ * block up to which the PXE has synced.
628
+ * This allows recent nullifications to be processed even if the node is not an archive node.
629
+ *
630
+ * @param contractAddress - The contract whose notes should be checked and nullified.
631
+ */ async syncNoteNullifiers(contractAddress) {
613
632
  this.log.verbose('Searching for nullifiers of known notes', {
614
633
  contract: contractAddress
615
634
  });
616
- // We avoid making node queries at 'latest' since we mark notes as nullified only if the corresponding nullifier
617
- // has been included in a block up to which PXE has synced. Note that while this technically results in historical
618
- // queries, we perform it at the latest locally synced block number which *should* be recent enough to be
619
- // available, even for non-archive nodes.
620
635
  const syncedBlockNumber = await this.syncDataProvider.getBlockNumber();
621
- for (const recipient of (await this.keyStore.getAccounts())){
622
- const currentNotesForRecipient = await this.noteDataProvider.getNotes({
623
- contractAddress,
624
- recipient
625
- });
626
- if (currentNotesForRecipient.length === 0) {
627
- continue;
636
+ const contractNotes = await this.noteDataProvider.getNotes({
637
+ contractAddress
638
+ });
639
+ if (contractNotes.length === 0) {
640
+ return;
641
+ }
642
+ const nullifiersToCheck = contractNotes.map((note)=>note.siloedNullifier);
643
+ const nullifierBatches = nullifiersToCheck.reduce((acc, nullifier)=>{
644
+ if (acc[acc.length - 1].length < MAX_RPC_LEN) {
645
+ acc[acc.length - 1].push(nullifier);
646
+ } else {
647
+ acc.push([
648
+ nullifier
649
+ ]);
628
650
  }
629
- const nullifiersToCheck = currentNotesForRecipient.map((note)=>note.siloedNullifier);
630
- const nullifierBatches = nullifiersToCheck.reduce((acc, nullifier)=>{
631
- if (acc[acc.length - 1].length < MAX_RPC_LEN) {
632
- acc[acc.length - 1].push(nullifier);
633
- } else {
634
- acc.push([
635
- nullifier
636
- ]);
637
- }
638
- return acc;
639
- }, [
640
- []
641
- ]);
642
- const nullifierIndexes = (await Promise.all(nullifierBatches.map((batch)=>this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, batch)))).flat();
643
- const foundNullifiers = nullifiersToCheck.map((nullifier, i)=>{
644
- if (nullifierIndexes[i] !== undefined) {
645
- return {
646
- ...nullifierIndexes[i],
647
- ...{
648
- data: nullifier
649
- }
650
- };
651
- }
652
- }).filter((nullifier)=>nullifier !== undefined);
653
- const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(foundNullifiers, recipient);
654
- nullifiedNotes.forEach((noteDao)=>{
655
- this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
656
- contract: noteDao.contractAddress,
657
- slot: noteDao.storageSlot,
658
- nullifier: noteDao.siloedNullifier.toString()
659
- });
651
+ return acc;
652
+ }, [
653
+ []
654
+ ]);
655
+ const nullifierIndexes = (await Promise.all(nullifierBatches.map((batch)=>this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, batch)))).flat();
656
+ const foundNullifiers = nullifiersToCheck.map((nullifier, i)=>{
657
+ if (nullifierIndexes[i] !== undefined) {
658
+ return {
659
+ ...nullifierIndexes[i],
660
+ ...{
661
+ data: nullifier
662
+ }
663
+ };
664
+ }
665
+ }).filter((nullifier)=>nullifier !== undefined);
666
+ const nullifiedNotes = await this.noteDataProvider.applyNullifiers(foundNullifiers);
667
+ nullifiedNotes.forEach((noteDao)=>{
668
+ this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
669
+ contract: noteDao.contractAddress,
670
+ slot: noteDao.storageSlot,
671
+ nullifier: noteDao.siloedNullifier.toString()
660
672
  });
661
- }
673
+ });
662
674
  }
663
675
  storeCapsule(contractAddress, slot, capsule) {
664
676
  return this.capsuleDataProvider.storeCapsule(contractAddress, slot, capsule);