@aztec/pxe 0.0.1-commit.96bb3f7 → 0.0.1-commit.a072138

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 (226) hide show
  1. package/dest/bin/check_oracle_version.js +1 -1
  2. package/dest/block_synchronizer/block_synchronizer.d.ts +9 -5
  3. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
  4. package/dest/block_synchronizer/block_synchronizer.js +66 -21
  5. package/dest/config/index.d.ts +3 -1
  6. package/dest/config/index.d.ts.map +1 -1
  7. package/dest/config/index.js +17 -0
  8. package/dest/contract_function_simulator/benchmarked_node.d.ts +9 -0
  9. package/dest/contract_function_simulator/benchmarked_node.d.ts.map +1 -0
  10. package/dest/contract_function_simulator/benchmarked_node.js +77 -0
  11. package/dest/contract_function_simulator/contract_function_simulator.d.ts +6 -10
  12. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  13. package/dest/contract_function_simulator/contract_function_simulator.js +33 -25
  14. package/dest/contract_function_simulator/execution_note_cache.d.ts +18 -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 +45 -28
  17. package/dest/contract_function_simulator/index.d.ts +2 -2
  18. package/dest/contract_function_simulator/index.d.ts.map +1 -1
  19. package/dest/contract_function_simulator/index.js +1 -1
  20. package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +1 -1
  21. package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
  22. package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +1 -1
  23. package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
  24. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts +4 -10
  25. package/dest/contract_function_simulator/noir-structs/utility_context.d.ts.map +1 -1
  26. package/dest/contract_function_simulator/noir-structs/utility_context.js +7 -18
  27. package/dest/contract_function_simulator/oracle/interfaces.d.ts +15 -11
  28. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  29. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts +3 -1
  30. package/dest/contract_function_simulator/oracle/message_load_oracle_inputs.d.ts.map +1 -1
  31. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +6 -6
  32. package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
  33. package/dest/contract_function_simulator/oracle/note_packing_utils.js +8 -8
  34. package/dest/contract_function_simulator/oracle/oracle.d.ts +10 -8
  35. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  36. package/dest/contract_function_simulator/oracle/oracle.js +44 -33
  37. package/dest/contract_function_simulator/oracle/private_execution.d.ts +2 -26
  38. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
  39. package/dest/contract_function_simulator/oracle/private_execution.js +0 -35
  40. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +11 -3
  41. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  42. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +22 -10
  43. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +33 -20
  44. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  45. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +78 -76
  46. package/dest/contract_sync/index.d.ts +23 -0
  47. package/dest/contract_sync/index.d.ts.map +1 -0
  48. package/dest/contract_sync/index.js +54 -0
  49. package/dest/debug/pxe_debug_utils.d.ts +16 -6
  50. package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
  51. package/dest/debug/pxe_debug_utils.js +20 -10
  52. package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
  53. package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
  54. package/dest/entrypoints/client/bundle/utils.js +12 -6
  55. package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
  56. package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
  57. package/dest/entrypoints/client/lazy/utils.js +13 -7
  58. package/dest/entrypoints/pxe_creation_options.d.ts +3 -2
  59. package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
  60. package/dest/entrypoints/server/index.d.ts +3 -1
  61. package/dest/entrypoints/server/index.d.ts.map +1 -1
  62. package/dest/entrypoints/server/index.js +2 -0
  63. package/dest/entrypoints/server/utils.d.ts +1 -1
  64. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  65. package/dest/entrypoints/server/utils.js +19 -8
  66. package/dest/events/event_service.d.ts +6 -6
  67. package/dest/events/event_service.d.ts.map +1 -1
  68. package/dest/events/event_service.js +19 -22
  69. package/dest/events/private_event_filter_validator.d.ts +5 -5
  70. package/dest/events/private_event_filter_validator.d.ts.map +1 -1
  71. package/dest/events/private_event_filter_validator.js +5 -6
  72. package/dest/job_coordinator/job_coordinator.d.ts +3 -2
  73. package/dest/job_coordinator/job_coordinator.d.ts.map +1 -1
  74. package/dest/job_coordinator/job_coordinator.js +3 -2
  75. package/dest/logs/log_service.d.ts +6 -4
  76. package/dest/logs/log_service.d.ts.map +1 -1
  77. package/dest/logs/log_service.js +21 -16
  78. package/dest/notes/note_service.d.ts +7 -7
  79. package/dest/notes/note_service.d.ts.map +1 -1
  80. package/dest/notes/note_service.js +31 -36
  81. package/dest/oracle_version.d.ts +3 -3
  82. package/dest/oracle_version.d.ts.map +1 -1
  83. package/dest/oracle_version.js +4 -3
  84. package/dest/private_kernel/hints/index.d.ts +2 -2
  85. package/dest/private_kernel/hints/index.d.ts.map +1 -1
  86. package/dest/private_kernel/hints/index.js +1 -1
  87. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +28 -0
  88. package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -0
  89. package/dest/private_kernel/hints/{build_private_kernel_reset_private_inputs.js → private_kernel_reset_private_inputs_builder.js} +12 -6
  90. package/dest/private_kernel/private_kernel_execution_prover.d.ts +3 -2
  91. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
  92. package/dest/private_kernel/private_kernel_execution_prover.js +3 -3
  93. package/dest/private_kernel/private_kernel_oracle.d.ts +23 -28
  94. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
  95. package/dest/private_kernel/private_kernel_oracle.js +90 -2
  96. package/dest/pxe.d.ts +7 -36
  97. package/dest/pxe.d.ts.map +1 -1
  98. package/dest/pxe.js +43 -83
  99. package/dest/storage/address_store/address_store.d.ts +1 -1
  100. package/dest/storage/address_store/address_store.d.ts.map +1 -1
  101. package/dest/storage/address_store/address_store.js +12 -11
  102. package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -1
  103. package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
  104. package/dest/storage/anchor_block_store/anchor_block_store.js +8 -1
  105. package/dest/storage/capsule_store/capsule_store.d.ts +24 -9
  106. package/dest/storage/capsule_store/capsule_store.d.ts.map +1 -1
  107. package/dest/storage/capsule_store/capsule_store.js +130 -23
  108. package/dest/storage/contract_store/contract_store.d.ts +1 -2
  109. package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
  110. package/dest/storage/contract_store/contract_store.js +22 -25
  111. package/dest/storage/metadata.d.ts +1 -1
  112. package/dest/storage/metadata.js +1 -1
  113. package/dest/storage/note_store/note_store.d.ts +51 -52
  114. package/dest/storage/note_store/note_store.d.ts.map +1 -1
  115. package/dest/storage/note_store/note_store.js +282 -263
  116. package/dest/storage/note_store/stored_note.d.ts +16 -0
  117. package/dest/storage/note_store/stored_note.d.ts.map +1 -0
  118. package/dest/storage/note_store/stored_note.js +43 -0
  119. package/dest/storage/private_event_store/private_event_store.d.ts +43 -8
  120. package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
  121. package/dest/storage/private_event_store/private_event_store.js +226 -111
  122. package/dest/storage/private_event_store/stored_private_event.d.ts +23 -0
  123. package/dest/storage/private_event_store/stored_private_event.d.ts.map +1 -0
  124. package/dest/storage/private_event_store/stored_private_event.js +56 -0
  125. package/dest/storage/tagging_store/recipient_tagging_store.d.ts +15 -8
  126. package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
  127. package/dest/storage/tagging_store/recipient_tagging_store.js +88 -19
  128. package/dest/storage/tagging_store/sender_address_book_store.d.ts +1 -1
  129. package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +1 -1
  130. package/dest/storage/tagging_store/sender_address_book_store.js +20 -14
  131. package/dest/storage/tagging_store/sender_tagging_store.d.ts +19 -9
  132. package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
  133. package/dest/storage/tagging_store/sender_tagging_store.js +252 -100
  134. package/dest/tagging/get_all_logs_by_tags.d.ts +24 -0
  135. package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -0
  136. package/dest/tagging/get_all_logs_by_tags.js +46 -0
  137. package/dest/tagging/index.d.ts +2 -1
  138. package/dest/tagging/index.d.ts.map +1 -1
  139. package/dest/tagging/index.js +1 -0
  140. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +3 -2
  141. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
  142. package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +6 -6
  143. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +3 -2
  144. package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
  145. package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +5 -2
  146. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +3 -2
  147. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
  148. package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +7 -7
  149. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +1 -1
  150. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
  151. package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +5 -8
  152. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -2
  153. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
  154. package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +10 -5
  155. package/package.json +18 -18
  156. package/src/bin/check_oracle_version.ts +1 -0
  157. package/src/block_synchronizer/block_synchronizer.ts +85 -33
  158. package/src/config/index.ts +14 -0
  159. package/src/contract_function_simulator/benchmarked_node.ts +103 -0
  160. package/src/contract_function_simulator/contract_function_simulator.ts +34 -28
  161. package/src/contract_function_simulator/execution_note_cache.ts +44 -25
  162. package/src/contract_function_simulator/index.ts +1 -1
  163. package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
  164. package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
  165. package/src/contract_function_simulator/noir-structs/utility_context.ts +6 -25
  166. package/src/contract_function_simulator/oracle/interfaces.ts +20 -10
  167. package/src/contract_function_simulator/oracle/note_packing_utils.ts +10 -10
  168. package/src/contract_function_simulator/oracle/oracle.ts +65 -40
  169. package/src/contract_function_simulator/oracle/private_execution.ts +1 -67
  170. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +35 -12
  171. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +100 -82
  172. package/src/contract_sync/index.ts +98 -0
  173. package/src/debug/pxe_debug_utils.ts +26 -11
  174. package/src/entrypoints/client/bundle/utils.ts +7 -14
  175. package/src/entrypoints/client/lazy/utils.ts +8 -14
  176. package/src/entrypoints/pxe_creation_options.ts +2 -1
  177. package/src/entrypoints/server/index.ts +2 -0
  178. package/src/entrypoints/server/utils.ts +15 -19
  179. package/src/events/event_service.ts +17 -25
  180. package/src/events/private_event_filter_validator.ts +3 -5
  181. package/src/job_coordinator/job_coordinator.ts +4 -3
  182. package/src/logs/log_service.ts +32 -14
  183. package/src/notes/note_service.ts +38 -43
  184. package/src/oracle_version.ts +4 -3
  185. package/src/private_kernel/hints/index.ts +1 -1
  186. package/src/private_kernel/hints/{build_private_kernel_reset_private_inputs.ts → private_kernel_reset_private_inputs_builder.ts} +32 -20
  187. package/src/private_kernel/private_kernel_execution_prover.ts +7 -4
  188. package/src/private_kernel/private_kernel_oracle.ts +116 -37
  189. package/src/pxe.ts +77 -118
  190. package/src/storage/address_store/address_store.ts +15 -15
  191. package/src/storage/anchor_block_store/anchor_block_store.ts +8 -0
  192. package/src/storage/capsule_store/capsule_store.ts +159 -23
  193. package/src/storage/contract_store/contract_store.ts +22 -31
  194. package/src/storage/metadata.ts +1 -1
  195. package/src/storage/note_store/note_store.ts +317 -318
  196. package/src/storage/note_store/stored_note.ts +48 -0
  197. package/src/storage/private_event_store/private_event_store.ts +292 -124
  198. package/src/storage/private_event_store/stored_private_event.ts +73 -0
  199. package/src/storage/tagging_store/recipient_tagging_store.ts +106 -20
  200. package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
  201. package/src/storage/tagging_store/sender_tagging_store.ts +293 -108
  202. package/src/tagging/get_all_logs_by_tags.ts +68 -0
  203. package/src/tagging/index.ts +1 -0
  204. package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +16 -5
  205. package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +7 -1
  206. package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +9 -6
  207. package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +5 -17
  208. package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +16 -4
  209. package/dest/contract_function_simulator/proxied_node.d.ts +0 -9
  210. package/dest/contract_function_simulator/proxied_node.d.ts.map +0 -1
  211. package/dest/contract_function_simulator/proxied_node.js +0 -27
  212. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +0 -28
  213. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
  214. package/dest/private_kernel/private_kernel_oracle_impl.d.ts +0 -46
  215. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +0 -1
  216. package/dest/private_kernel/private_kernel_oracle_impl.js +0 -85
  217. package/dest/public_storage/public_storage_service.d.ts +0 -24
  218. package/dest/public_storage/public_storage_service.d.ts.map +0 -1
  219. package/dest/public_storage/public_storage_service.js +0 -26
  220. package/dest/tree_membership/tree_membership_service.d.ts +0 -52
  221. package/dest/tree_membership/tree_membership_service.d.ts.map +0 -1
  222. package/dest/tree_membership/tree_membership_service.js +0 -84
  223. package/src/contract_function_simulator/proxied_node.ts +0 -33
  224. package/src/private_kernel/private_kernel_oracle_impl.ts +0 -127
  225. package/src/public_storage/public_storage_service.ts +0 -33
  226. package/src/tree_membership/tree_membership_service.ts +0 -112
@@ -1,16 +1,18 @@
1
- import { toArray } from '@aztec/foundation/iterable';
2
1
  import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
3
2
  import type { DirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs';
4
3
  import { TxHash } from '@aztec/stdlib/tx';
5
4
 
5
+ import type { StagedStore } from '../../job_coordinator/job_coordinator.js';
6
6
  import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../../tagging/constants.js';
7
7
 
8
8
  /**
9
9
  * Data provider of tagging data used when syncing the sender tagging indexes. The recipient counterpart of this class
10
- * is called RecipientTaggingStore. We have the providers separate for the sender and recipient because
10
+ * is called RecipientTaggingStore. We have the data stores separate for sender and recipient because
11
11
  * the algorithms are completely disjoint and there is not data reuse between the two.
12
12
  */
13
- export class SenderTaggingStore {
13
+ export class SenderTaggingStore implements StagedStore {
14
+ readonly storeName = 'sender_tagging';
15
+
14
16
  #store: AztecAsyncKVStore;
15
17
 
16
18
  // Stores the pending indexes for each directional app tagging secret. Pending here means that the tx that contained
@@ -21,18 +23,106 @@ export class SenderTaggingStore {
21
23
  // the smaller ones are irrelevant due to tx atomicity.
22
24
  //
23
25
  // TODO(#17615): This assumes no logs are used in the non-revertible phase.
26
+ //
27
+ // directional app tagging secret => { pending index, txHash }[]
24
28
  #pendingIndexes: AztecAsyncMap<string, { index: number; txHash: string }[]>;
25
29
 
30
+ // jobId => directional app tagging secret => { pending index, txHash }[]
31
+ #pendingIndexesForJob: Map<string, Map<string, { index: number; txHash: string }[]>>;
32
+
26
33
  // Stores the last (highest) finalized index for each directional app tagging secret. We care only about the last
27
34
  // index because unlike the pending indexes, it will never happen that a finalized index would be removed and hence
28
35
  // we don't need to store the history.
36
+ //
37
+ // directional app tagging secret => highest finalized index
29
38
  #lastFinalizedIndexes: AztecAsyncMap<string, number>;
30
39
 
40
+ // jobId => directional app tagging secret => highest finalized index
41
+ #lastFinalizedIndexesForJob: Map<string, Map<string, number>>;
42
+
31
43
  constructor(store: AztecAsyncKVStore) {
32
44
  this.#store = store;
33
45
 
34
46
  this.#pendingIndexes = this.#store.openMap('pending_indexes');
35
47
  this.#lastFinalizedIndexes = this.#store.openMap('last_finalized_indexes');
48
+
49
+ this.#pendingIndexesForJob = new Map();
50
+ this.#lastFinalizedIndexesForJob = new Map();
51
+ }
52
+
53
+ #getPendingIndexesForJob(jobId: string): Map<string, { index: number; txHash: string }[]> {
54
+ let pendingIndexesForJob = this.#pendingIndexesForJob.get(jobId);
55
+ if (!pendingIndexesForJob) {
56
+ pendingIndexesForJob = new Map();
57
+ this.#pendingIndexesForJob.set(jobId, pendingIndexesForJob);
58
+ }
59
+ return pendingIndexesForJob;
60
+ }
61
+
62
+ #getLastFinalizedIndexesForJob(jobId: string): Map<string, number> {
63
+ let jobStagedLastFinalizedIndexes = this.#lastFinalizedIndexesForJob.get(jobId);
64
+ if (!jobStagedLastFinalizedIndexes) {
65
+ jobStagedLastFinalizedIndexes = new Map();
66
+ this.#lastFinalizedIndexesForJob.set(jobId, jobStagedLastFinalizedIndexes);
67
+ }
68
+ return jobStagedLastFinalizedIndexes;
69
+ }
70
+
71
+ async #readPendingIndexes(jobId: string, secret: string): Promise<{ index: number; txHash: string }[]> {
72
+ // Always issue DB read to keep IndexedDB transaction alive (they auto-commit when a new micro-task starts and there
73
+ // are no pending read requests). The staged value still takes precedence if it exists.
74
+ const dbValue = await this.#pendingIndexes.getAsync(secret);
75
+ const staged = this.#getPendingIndexesForJob(jobId).get(secret);
76
+ return staged !== undefined ? staged : (dbValue ?? []);
77
+ }
78
+
79
+ #writePendingIndexes(jobId: string, secret: string, pendingIndexes: { index: number; txHash: string }[]) {
80
+ this.#getPendingIndexesForJob(jobId).set(secret, pendingIndexes);
81
+ }
82
+
83
+ async #readLastFinalizedIndex(jobId: string, secret: string): Promise<number | undefined> {
84
+ // Always issue DB read to keep IndexedDB transaction alive (they auto-commit when a new micro-task starts and there
85
+ // are no pending read requests). The staged value still takes precedence if it exists.
86
+ const dbValue = await this.#lastFinalizedIndexes.getAsync(secret);
87
+ const staged = this.#getLastFinalizedIndexesForJob(jobId).get(secret);
88
+ return staged ?? dbValue;
89
+ }
90
+
91
+ #writeLastFinalizedIndex(jobId: string, secret: string, lastFinalizedIndex: number) {
92
+ this.#getLastFinalizedIndexesForJob(jobId).set(secret, lastFinalizedIndex);
93
+ }
94
+
95
+ /**
96
+ * Writes all job-specific in-memory data to persistent storage.
97
+ *
98
+ * @remark This method must run in a DB transaction context. It's designed to be called from JobCoordinator#commitJob.
99
+ */
100
+ async commit(jobId: string): Promise<void> {
101
+ const pendingIndexesForJob = this.#pendingIndexesForJob.get(jobId);
102
+ if (pendingIndexesForJob) {
103
+ for (const [secret, pendingIndexes] of pendingIndexesForJob.entries()) {
104
+ if (pendingIndexes.length === 0) {
105
+ await this.#pendingIndexes.delete(secret);
106
+ } else {
107
+ await this.#pendingIndexes.set(secret, pendingIndexes);
108
+ }
109
+ }
110
+ }
111
+
112
+ const lastFinalizedIndexesForJob = this.#lastFinalizedIndexesForJob.get(jobId);
113
+ if (lastFinalizedIndexesForJob) {
114
+ for (const [secret, lastFinalizedIndex] of lastFinalizedIndexesForJob.entries()) {
115
+ await this.#lastFinalizedIndexes.set(secret, lastFinalizedIndex);
116
+ }
117
+ }
118
+
119
+ return this.discardStaged(jobId);
120
+ }
121
+
122
+ discardStaged(jobId: string): Promise<void> {
123
+ this.#pendingIndexesForJob.delete(jobId);
124
+ this.#lastFinalizedIndexesForJob.delete(jobId);
125
+ return Promise.resolve();
36
126
  }
37
127
 
38
128
  /**
@@ -43,6 +133,7 @@ export class SenderTaggingStore {
43
133
  * @param preTags - The pre-tags containing the directional app tagging secrets and the indexes that are to be
44
134
  * stored in the db.
45
135
  * @param txHash - The tx in which the pretags were used in private logs.
136
+ * @param jobId - job context for staged writes to this store. See `JobCoordinator` for more details.
46
137
  * @throws If any two pre-tags contain the same directional app tagging secret. This is enforced because we care
47
138
  * only about the highest index for a given secret that was used in the tx. Hence this check is a good way to catch
48
139
  * bugs.
@@ -56,55 +147,80 @@ export class SenderTaggingStore {
56
147
  * This is enforced because this should never happen if the syncing is done correctly as we look for logs from higher
57
148
  * indexes than finalized ones.
58
149
  */
59
- async storePendingIndexes(preTags: PreTag[], txHash: TxHash) {
150
+ storePendingIndexes(preTags: PreTag[], txHash: TxHash, jobId: string): Promise<void> {
151
+ if (preTags.length === 0) {
152
+ return Promise.resolve();
153
+ }
154
+
60
155
  // The secrets in pre-tags should be unique because we always store just the highest index per given secret-txHash
61
156
  // pair. Below we check that this is the case.
62
157
  const secretsSet = new Set(preTags.map(preTag => preTag.secret.toString()));
63
158
  if (secretsSet.size !== preTags.length) {
64
- throw new Error(`Duplicate secrets found when storing pending indexes`);
159
+ return Promise.reject(new Error(`Duplicate secrets found when storing pending indexes`));
65
160
  }
66
161
 
67
- for (const { secret, index } of preTags) {
68
- // First we check that for any secret the highest used index in tx is not further than window length from
69
- // the highest finalized index.
70
- const finalizedIndex = (await this.getLastFinalizedIndex(secret)) ?? 0;
71
- if (index > finalizedIndex + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN) {
72
- throw new Error(
73
- `Highest used index ${index} is further than window length from the highest finalized index ${finalizedIndex}.
74
- Tagging window length ${UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN} is configured too low. Contact the Aztec team
75
- to increase it!`,
76
- );
77
- }
162
+ const txHashStr = txHash.toString();
78
163
 
79
- // Throw if the new pending index is lower than or equal to the last finalized index
80
- const secretStr = secret.toString();
81
- const lastFinalizedIndex = await this.#lastFinalizedIndexes.getAsync(secretStr);
82
- if (lastFinalizedIndex !== undefined && index <= lastFinalizedIndex) {
83
- throw new Error(
84
- `Cannot store pending index ${index} for secret ${secretStr}: ` +
85
- `it is lower than or equal to the last finalized index ${lastFinalizedIndex}`,
86
- );
87
- }
164
+ return this.#store.transactionAsync(async () => {
165
+ // Prefetch all data, start reads during iteration to keep IndexedDB transaction alive
166
+ const preTagReadPromises = preTags.map(({ secret, index }) => {
167
+ const secretStr = secret.toString();
168
+ return {
169
+ secret,
170
+ secretStr,
171
+ index,
172
+ pending: this.#readPendingIndexes(jobId, secretStr),
173
+ finalized: this.#readLastFinalizedIndex(jobId, secretStr),
174
+ };
175
+ });
88
176
 
89
- // Check if this secret + txHash combination already exists
90
- const txHashStr = txHash.toString();
91
- const existingForSecret = (await this.#pendingIndexes.getAsync(secretStr)) ?? [];
92
- const existingForSecretAndTx = existingForSecret.find(entry => entry.txHash === txHashStr);
177
+ // Await all reads together
178
+ const preTagData = await Promise.all(
179
+ preTagReadPromises.map(async item => ({
180
+ ...item,
181
+ pendingData: await item.pending,
182
+ finalizedIndex: await item.finalized,
183
+ })),
184
+ );
93
185
 
94
- if (existingForSecretAndTx) {
95
- // If it exists with a different index, throw an error
96
- if (existingForSecretAndTx.index !== index) {
186
+ // Process in memory and validate
187
+ for (const { secretStr, index, pendingData, finalizedIndex } of preTagData) {
188
+ // First we check that for any secret the highest used index in tx is not further than window length from
189
+ // the highest finalized index.
190
+ if (index > (finalizedIndex ?? 0) + UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN) {
97
191
  throw new Error(
98
- `Cannot store index ${index} for secret ${secretStr} and txHash ${txHashStr}: ` +
99
- `a different index ${existingForSecretAndTx.index} already exists for this secret-txHash pair`,
192
+ `Highest used index ${index} is further than window length from the highest finalized index ${finalizedIndex ?? 0}.
193
+ Tagging window length ${UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN} is configured too low. Contact the Aztec team
194
+ to increase it!`,
100
195
  );
101
196
  }
102
- // If it exists with the same index, ignore the update (no-op)
103
- } else {
104
- // If it doesn't exist, add it
105
- await this.#pendingIndexes.set(secretStr, [...existingForSecret, { index, txHash: txHashStr }]);
197
+
198
+ // Throw if the new pending index is lower than or equal to the last finalized index
199
+ if (finalizedIndex !== undefined && index <= finalizedIndex) {
200
+ throw new Error(
201
+ `Cannot store pending index ${index} for secret ${secretStr}: ` +
202
+ `it is lower than or equal to the last finalized index ${finalizedIndex}`,
203
+ );
204
+ }
205
+
206
+ // Check if this secret + txHash combination already exists
207
+ const existingForSecretAndTx = pendingData.find(entry => entry.txHash === txHashStr);
208
+
209
+ if (existingForSecretAndTx) {
210
+ // If it exists with a different index, throw an error
211
+ if (existingForSecretAndTx.index !== index) {
212
+ throw new Error(
213
+ `Cannot store index ${index} for secret ${secretStr} and txHash ${txHashStr}: ` +
214
+ `a different index ${existingForSecretAndTx.index} already exists for this secret-txHash pair`,
215
+ );
216
+ }
217
+ // If it exists with the same index, ignore the update (no-op)
218
+ } else {
219
+ // If it doesn't exist, add it
220
+ this.#writePendingIndexes(jobId, secretStr, [...pendingData, { index, txHash: txHashStr }]);
221
+ }
106
222
  }
107
- }
223
+ });
108
224
  }
109
225
 
110
226
  /**
@@ -116,16 +232,19 @@ export class SenderTaggingStore {
116
232
  * @returns An array of unique transaction hashes for pending transactions that contain indexes in the range
117
233
  * [startIndex, endIndex). Returns an empty array if no pending indexes exist in the range.
118
234
  */
119
- async getTxHashesOfPendingIndexes(
235
+ getTxHashesOfPendingIndexes(
120
236
  secret: DirectionalAppTaggingSecret,
121
237
  startIndex: number,
122
238
  endIndex: number,
239
+ jobId: string,
123
240
  ): Promise<TxHash[]> {
124
- const existing = (await this.#pendingIndexes.getAsync(secret.toString())) ?? [];
125
- const txHashes = existing
126
- .filter(entry => entry.index >= startIndex && entry.index < endIndex)
127
- .map(entry => entry.txHash);
128
- return Array.from(new Set(txHashes)).map(TxHash.fromString);
241
+ return this.#store.transactionAsync(async () => {
242
+ const existing = await this.#readPendingIndexes(jobId, secret.toString());
243
+ const txHashes = existing
244
+ .filter(entry => entry.index >= startIndex && entry.index < endIndex)
245
+ .map(entry => entry.txHash);
246
+ return Array.from(new Set(txHashes)).map(TxHash.fromString);
247
+ });
129
248
  }
130
249
 
131
250
  /**
@@ -133,8 +252,8 @@ export class SenderTaggingStore {
133
252
  * @param secret - The secret to get the last finalized index for.
134
253
  * @returns The last (highest) finalized index for the given secret.
135
254
  */
136
- getLastFinalizedIndex(secret: DirectionalAppTaggingSecret): Promise<number | undefined> {
137
- return this.#lastFinalizedIndexes.getAsync(secret.toString());
255
+ getLastFinalizedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
256
+ return this.#store.transactionAsync(() => this.#readLastFinalizedIndex(jobId, secret.toString()));
138
257
  }
139
258
 
140
259
  /**
@@ -143,102 +262,168 @@ export class SenderTaggingStore {
143
262
  * @param secret - The directional app tagging secret to query the last used index for.
144
263
  * @returns The last used index.
145
264
  */
146
- async getLastUsedIndex(secret: DirectionalAppTaggingSecret): Promise<number | undefined> {
265
+ getLastUsedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
147
266
  const secretStr = secret.toString();
148
- const pendingTxScopedIndexes = (await this.#pendingIndexes.getAsync(secretStr)) ?? [];
149
- const pendingIndexes = pendingTxScopedIndexes.map(entry => entry.index);
150
267
 
151
- if (pendingTxScopedIndexes.length === 0) {
152
- return this.#lastFinalizedIndexes.getAsync(secretStr);
153
- }
268
+ return this.#store.transactionAsync(async () => {
269
+ const pendingPromise = this.#readPendingIndexes(jobId, secretStr);
270
+ const finalizedPromise = this.#readLastFinalizedIndex(jobId, secretStr);
271
+
272
+ const [pendingTxScopedIndexes, lastFinalized] = await Promise.all([pendingPromise, finalizedPromise]);
273
+ const pendingIndexes = pendingTxScopedIndexes.map(entry => entry.index);
154
274
 
155
- // As the last used index we return the highest one from the pending indexes. Note that this value will be always
156
- // higher than the last finalized index because we prune lower pending indexes when a tx is finalized.
157
- return Math.max(...pendingIndexes);
275
+ if (pendingTxScopedIndexes.length === 0) {
276
+ return lastFinalized;
277
+ }
278
+
279
+ // As the last used index we return the highest one from the pending indexes. Note that this value will be always
280
+ // higher than the last finalized index because we prune lower pending indexes when a tx is finalized.
281
+ return Math.max(...pendingIndexes);
282
+ });
158
283
  }
159
284
 
160
285
  /**
161
286
  * Drops all pending indexes corresponding to the given transaction hashes.
162
287
  */
163
- async dropPendingIndexes(txHashes: TxHash[]) {
288
+ dropPendingIndexes(txHashes: TxHash[], jobId: string): Promise<void> {
164
289
  if (txHashes.length === 0) {
165
- return;
290
+ return Promise.resolve();
166
291
  }
167
292
 
168
- const txHashStrs = new Set<string>(txHashes.map(txHash => txHash.toString()));
169
- const allSecrets = await toArray(this.#pendingIndexes.keysAsync());
293
+ const txHashStrings = new Set<string>(txHashes.map(txHash => txHash.toString()));
170
294
 
171
- for (const secret of allSecrets) {
172
- const pendingData = await this.#pendingIndexes.getAsync(secret);
173
- if (pendingData) {
174
- const filtered = pendingData.filter(item => !txHashStrs.has(item.txHash));
175
- if (filtered.length === 0) {
176
- await this.#pendingIndexes.delete(secret);
177
- } else if (filtered.length !== pendingData.length) {
178
- // Some items were filtered out, so update the pending data
179
- await this.#pendingIndexes.set(secret, filtered);
295
+ return this.#store.transactionAsync(async () => {
296
+ // Prefetch all data, start reads during iteration to keep IndexedDB transaction alive
297
+ const secretReadPromises: Map<string, Promise<{ index: number; txHash: string }[]>> = new Map();
298
+
299
+ for await (const secret of this.#pendingIndexes.keysAsync()) {
300
+ secretReadPromises.set(secret, this.#readPendingIndexes(jobId, secret));
301
+ }
302
+
303
+ // Add staged-only secrets (sync, no DB)
304
+ for (const secret of this.#getPendingIndexesForJob(jobId).keys()) {
305
+ if (!secretReadPromises.has(secret)) {
306
+ secretReadPromises.set(secret, Promise.resolve(this.#getPendingIndexesForJob(jobId).get(secret) ?? []));
180
307
  }
181
- // else: No items were filtered out (txHashes not found for this secret) --> no-op
182
308
  }
183
- }
309
+
310
+ // Await all reads together
311
+ const secrets = [...secretReadPromises.keys()];
312
+ const pendingDataResults = await Promise.all(secretReadPromises.values());
313
+
314
+ // Process in memory
315
+ for (let i = 0; i < secrets.length; i++) {
316
+ const secret = secrets[i];
317
+ const pendingData = pendingDataResults[i];
318
+
319
+ if (pendingData && pendingData.length > 0) {
320
+ const filtered = pendingData.filter(item => !txHashStrings.has(item.txHash));
321
+ if (filtered.length === 0) {
322
+ this.#writePendingIndexes(jobId, secret, []);
323
+ } else if (filtered.length !== pendingData.length) {
324
+ // Some items were filtered out, so update the pending data
325
+ this.#writePendingIndexes(jobId, secret, filtered);
326
+ }
327
+ // else: No items were filtered out (txHashes not found for this secret) --> no-op
328
+ }
329
+ }
330
+ });
184
331
  }
185
332
 
186
333
  /**
187
334
  * Updates pending indexes corresponding to the given transaction hashes to be finalized and prunes any lower pending
188
335
  * indexes.
189
336
  */
190
- async finalizePendingIndexes(txHashes: TxHash[]) {
337
+ finalizePendingIndexes(txHashes: TxHash[], jobId: string): Promise<void> {
191
338
  if (txHashes.length === 0) {
192
- return;
339
+ return Promise.resolve();
193
340
  }
194
341
 
195
- for (const txHash of txHashes) {
196
- const txHashStr = txHash.toString();
342
+ const txHashStrings = new Set(txHashes.map(tx => tx.toString()));
197
343
 
198
- const allSecrets = await toArray(this.#pendingIndexes.keysAsync());
344
+ return this.#store.transactionAsync(async () => {
345
+ // Prefetch all data, start reads during iteration to keep IndexedDB transaction alive
346
+ const secretDataPromises: Map<
347
+ string,
348
+ { pending: Promise<{ index: number; txHash: string }[]>; finalized: Promise<number | undefined> }
349
+ > = new Map();
199
350
 
200
- for (const secret of allSecrets) {
201
- const pendingData = await this.#pendingIndexes.getAsync(secret);
202
- if (!pendingData) {
203
- continue;
351
+ for await (const secret of this.#pendingIndexes.keysAsync()) {
352
+ secretDataPromises.set(secret, {
353
+ pending: this.#readPendingIndexes(jobId, secret),
354
+ finalized: this.#readLastFinalizedIndex(jobId, secret),
355
+ });
356
+ }
357
+
358
+ // Add staged-only secrets (sync, no DB)
359
+ for (const secret of this.#getPendingIndexesForJob(jobId).keys()) {
360
+ if (!secretDataPromises.has(secret)) {
361
+ secretDataPromises.set(secret, {
362
+ pending: Promise.resolve(this.#getPendingIndexesForJob(jobId).get(secret) ?? []),
363
+ finalized: Promise.resolve(this.#getLastFinalizedIndexesForJob(jobId).get(secret)),
364
+ });
204
365
  }
366
+ }
367
+
368
+ // Await all reads together
369
+ const secrets = [...secretDataPromises.keys()];
370
+ const dataResults = await Promise.all(
371
+ secrets.map(async secret => ({
372
+ secret,
373
+ pendingData: await secretDataPromises.get(secret)!.pending,
374
+ lastFinalized: await secretDataPromises.get(secret)!.finalized,
375
+ })),
376
+ );
205
377
 
206
- const matchingIndexes = pendingData.filter(item => item.txHash === txHashStr).map(item => item.index);
207
- if (matchingIndexes.length === 0) {
378
+ // Process all txHashes for each secret in memory
379
+ for (const { secret, pendingData, lastFinalized } of dataResults) {
380
+ if (!pendingData || pendingData.length === 0) {
208
381
  continue;
209
382
  }
210
383
 
211
- if (matchingIndexes.length > 1) {
212
- // We should always just store the highest pending index for a given tx hash and secret because the lower
213
- // values are irrelevant.
214
- throw new Error(`Multiple pending indexes found for tx hash ${txHashStr} and secret ${secret}`);
215
- }
384
+ let currentPending = pendingData;
385
+ let currentFinalized = lastFinalized;
216
386
 
217
- let lastFinalized = await this.#lastFinalizedIndexes.getAsync(secret);
218
- const newFinalized = matchingIndexes[0];
387
+ // Process all txHashes for this secret
388
+ for (const txHashStr of txHashStrings) {
389
+ const matchingIndexes = currentPending.filter(item => item.txHash === txHashStr).map(item => item.index);
390
+ if (matchingIndexes.length === 0) {
391
+ continue;
392
+ }
219
393
 
220
- if (newFinalized < (lastFinalized ?? 0)) {
221
- // This should never happen because when last finalized index was finalized we should have pruned the lower
222
- // pending indexes.
223
- throw new Error(
224
- `New finalized index ${newFinalized} is smaller than the current last finalized index ${lastFinalized}`,
225
- );
226
- }
394
+ if (matchingIndexes.length > 1) {
395
+ // We should always just store the highest pending index for a given tx hash and secret because the lower
396
+ // values are irrelevant.
397
+ throw new Error(`Multiple pending indexes found for tx hash ${txHashStr} and secret ${secret}`);
398
+ }
227
399
 
228
- await this.#lastFinalizedIndexes.set(secret, newFinalized);
229
- lastFinalized = newFinalized;
400
+ const newFinalized = matchingIndexes[0];
230
401
 
231
- // When we add pending indexes, we ensure they are higher than the last finalized index. However, because we
232
- // cannot control the order in which transactions are finalized, there may be pending indexes that are now
233
- // obsolete because they are lower than the most recently finalized index. For this reason, we prune these
234
- // outdated pending indexes.
235
- const remainingItemsOfHigherIndex = pendingData.filter(item => item.index > (lastFinalized ?? 0));
236
- if (remainingItemsOfHigherIndex.length === 0) {
237
- await this.#pendingIndexes.delete(secret);
238
- } else {
239
- await this.#pendingIndexes.set(secret, remainingItemsOfHigherIndex);
402
+ if (newFinalized < (currentFinalized ?? 0)) {
403
+ // This should never happen because when last finalized index was finalized we should have pruned the lower
404
+ // pending indexes.
405
+ throw new Error(
406
+ `New finalized index ${newFinalized} is smaller than the current last finalized index ${currentFinalized}`,
407
+ );
408
+ }
409
+
410
+ currentFinalized = newFinalized;
411
+
412
+ // When we add pending indexes, we ensure they are higher than the last finalized index. However, because we
413
+ // cannot control the order in which transactions are finalized, there may be pending indexes that are now
414
+ // obsolete because they are lower than the most recently finalized index. For this reason, we prune these
415
+ // outdated pending indexes.
416
+ currentPending = currentPending.filter(item => item.index > currentFinalized!);
417
+ }
418
+
419
+ // Write final state if changed
420
+ if (currentFinalized !== lastFinalized) {
421
+ this.#writeLastFinalizedIndex(jobId, secret, currentFinalized!);
422
+ }
423
+ if (currentPending !== pendingData) {
424
+ this.#writePendingIndexes(jobId, secret, currentPending);
240
425
  }
241
426
  }
242
- }
427
+ });
243
428
  }
244
429
  }
@@ -0,0 +1,68 @@
1
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
2
+ import type { BlockHash } from '@aztec/stdlib/block';
3
+ import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
4
+ import type { AztecNode } from '@aztec/stdlib/interfaces/client';
5
+ import type { SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
6
+
7
+ /**
8
+ * Generic pagination helper that fetches all pages of results.
9
+ * @param numTags - The number of tags being queried (determines result array size).
10
+ * @param fetchPage - Function that fetches a single page of results given a page number.
11
+ * @returns An array of arrays, one per tag, containing all results across all pages.
12
+ */
13
+ async function getAllPages<T>(numTags: number, fetchPage: (page: number) => Promise<T[][]>): Promise<T[][]> {
14
+ const allResultsPerTag: T[][] = Array.from({ length: numTags }, () => []);
15
+ let page = 0;
16
+ let hasMore = true;
17
+
18
+ while (hasMore) {
19
+ const resultsPage = await fetchPage(page);
20
+ hasMore = false;
21
+
22
+ for (let i = 0; i < resultsPage.length; i++) {
23
+ allResultsPerTag[i].push(...resultsPage[i]);
24
+ if (resultsPage[i].length === MAX_LOGS_PER_TAG) {
25
+ hasMore = true;
26
+ }
27
+ }
28
+ page++;
29
+ }
30
+
31
+ return allResultsPerTag;
32
+ }
33
+
34
+ /**
35
+ * Fetches all private logs for the given tags, automatically paginating through all pages.
36
+ * @param aztecNode - The Aztec node to query.
37
+ * @param tags - The siloed tags to search for.
38
+ * @param anchorBlockHash - reference block for the Aztec node query, throws if block is not found there (typically
39
+ * because of reorgs).
40
+ * @returns An array of log arrays, one per tag, containing all logs across all pages.
41
+ */
42
+ export function getAllPrivateLogsByTags(
43
+ aztecNode: AztecNode,
44
+ tags: SiloedTag[],
45
+ anchorBlockHash: BlockHash,
46
+ ): Promise<TxScopedL2Log[][]> {
47
+ return getAllPages(tags.length, page => aztecNode.getPrivateLogsByTags(tags, page, anchorBlockHash));
48
+ }
49
+
50
+ /**
51
+ * Fetches all public logs for the given tags from a contract, automatically paginating through all pages.
52
+ * @param aztecNode - The Aztec node to query.
53
+ * @param contractAddress - The contract address to search logs for.
54
+ * @param tags - The tags to search for.
55
+ * @param anchorBlockHash - reference block for the Aztec node query, throws if block is not found there (typically
56
+ * because of reorgs).
57
+ * @returns An array of log arrays, one per tag, containing all logs across all pages.
58
+ */
59
+ export function getAllPublicLogsByTagsFromContract(
60
+ aztecNode: AztecNode,
61
+ contractAddress: AztecAddress,
62
+ tags: Tag[],
63
+ anchorBlockHash: BlockHash,
64
+ ): Promise<TxScopedL2Log[][]> {
65
+ return getAllPages(tags.length, page =>
66
+ aztecNode.getPublicLogsByTagsFromContract(contractAddress, tags, page, anchorBlockHash),
67
+ );
68
+ }
@@ -12,6 +12,7 @@
12
12
  export { loadPrivateLogsForSenderRecipientPair } from './recipient_sync/load_private_logs_for_sender_recipient_pair.js';
13
13
  export { syncSenderTaggingIndexes } from './sender_sync/sync_sender_tagging_indexes.js';
14
14
  export { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from './constants.js';
15
+ export { getAllPrivateLogsByTags, getAllPublicLogsByTagsFromContract } from './get_all_logs_by_tags.js';
15
16
 
16
17
  // Re-export tagging-related types from stdlib
17
18
  export { DirectionalAppTaggingSecret, Tag, SiloedTag } from '@aztec/stdlib/logs';
@@ -1,5 +1,6 @@
1
1
  import type { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
3
+ import type { BlockHash } from '@aztec/stdlib/block';
3
4
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
4
5
  import type { DirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs';
5
6
 
@@ -21,6 +22,8 @@ export async function loadPrivateLogsForSenderRecipientPair(
21
22
  aztecNode: AztecNode,
22
23
  taggingStore: RecipientTaggingStore,
23
24
  anchorBlockNumber: BlockNumber,
25
+ anchorBlockHash: BlockHash,
26
+ jobId: string,
24
27
  ): Promise<TxScopedL2Log[]> {
25
28
  // # Explanation of how the algorithm works
26
29
  // When we perform the sync we will look at logs that correspond to the tagging index range
@@ -76,8 +79,8 @@ export async function loadPrivateLogsForSenderRecipientPair(
76
79
 
77
80
  let start: number, end: number;
78
81
  {
79
- const currentHighestAgedIndex = await taggingStore.getHighestAgedIndex(secret);
80
- const currentHighestFinalizedIndex = await taggingStore.getHighestFinalizedIndex(secret);
82
+ const currentHighestAgedIndex = await taggingStore.getHighestAgedIndex(secret, jobId);
83
+ const currentHighestFinalizedIndex = await taggingStore.getHighestFinalizedIndex(secret, jobId);
81
84
 
82
85
  // We don't want to include the highest aged index so we start from `currentHighestAgedIndex + 1` (or 0 if not set)
83
86
  start = currentHighestAgedIndex === undefined ? 0 : currentHighestAgedIndex + 1;
@@ -91,7 +94,15 @@ export async function loadPrivateLogsForSenderRecipientPair(
91
94
 
92
95
  while (true) {
93
96
  // Get private logs with their block timestamps and corresponding tagging indexes
94
- const privateLogsWithIndexes = await loadLogsForRange(secret, app, aztecNode, start, end, anchorBlockNumber);
97
+ const privateLogsWithIndexes = await loadLogsForRange(
98
+ secret,
99
+ app,
100
+ aztecNode,
101
+ start,
102
+ end,
103
+ anchorBlockNumber,
104
+ anchorBlockHash,
105
+ );
95
106
 
96
107
  if (privateLogsWithIndexes.length === 0) {
97
108
  break;
@@ -107,7 +118,7 @@ export async function loadPrivateLogsForSenderRecipientPair(
107
118
 
108
119
  // Store updates in data provider and update local variables
109
120
  if (highestAgedIndex !== undefined) {
110
- await taggingStore.updateHighestAgedIndex(secret, highestAgedIndex);
121
+ await taggingStore.updateHighestAgedIndex(secret, highestAgedIndex, jobId);
111
122
  }
112
123
 
113
124
  if (highestFinalizedIndex === undefined) {
@@ -120,7 +131,7 @@ export async function loadPrivateLogsForSenderRecipientPair(
120
131
  throw new Error('Highest aged index lower than highest finalized index invariant violated');
121
132
  }
122
133
 
123
- await taggingStore.updateHighestFinalizedIndex(secret, highestFinalizedIndex);
134
+ await taggingStore.updateHighestFinalizedIndex(secret, highestFinalizedIndex, jobId);
124
135
 
125
136
  // For the next iteration we want to look only at indexes for which we have not attempted to load logs yet while
126
137
  // ensuring that we do not look further than WINDOW_LEN ahead of the highest finalized index.