@aztec/pxe 0.0.1-commit.e6bd8901 → 0.0.1-commit.f146247c
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.
- package/dest/block_synchronizer/block_synchronizer.d.ts +3 -3
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +5 -5
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +2 -4
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +7 -9
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +8 -8
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.d.ts +3 -3
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +15 -15
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +2 -3
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +5 -7
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +20 -16
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +23 -19
- package/dest/contract_sync/index.d.ts +1 -1
- package/dest/contract_sync/index.d.ts.map +1 -1
- package/dest/contract_sync/index.js +1 -3
- package/dest/debug/pxe_debug_utils.d.ts +16 -6
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +17 -8
- package/dest/entrypoints/client/bundle/utils.d.ts +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +12 -6
- package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +13 -7
- package/dest/entrypoints/pxe_creation_options.d.ts +3 -2
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.d.ts +1 -1
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +19 -8
- package/dest/events/event_service.d.ts +4 -5
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +5 -6
- package/dest/job_coordinator/job_coordinator.d.ts +3 -2
- package/dest/job_coordinator/job_coordinator.d.ts.map +1 -1
- package/dest/job_coordinator/job_coordinator.js +3 -2
- package/dest/logs/log_service.d.ts +5 -4
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +8 -12
- package/dest/notes/note_service.d.ts +4 -5
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +6 -8
- package/dest/oracle_version.d.ts +3 -3
- package/dest/oracle_version.d.ts.map +1 -1
- package/dest/oracle_version.js +2 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +3 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +2 -2
- package/dest/private_kernel/private_kernel_oracle.d.ts +3 -3
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/pxe.d.ts +1 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +9 -8
- package/dest/storage/address_store/address_store.d.ts +1 -1
- package/dest/storage/address_store/address_store.d.ts.map +1 -1
- package/dest/storage/address_store/address_store.js +12 -11
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -1
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
- package/dest/storage/anchor_block_store/anchor_block_store.js +8 -1
- package/dest/storage/capsule_store/capsule_store.js +6 -8
- package/dest/storage/contract_store/contract_store.d.ts +1 -1
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +22 -13
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/note_store/note_store.d.ts +11 -1
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +143 -105
- package/dest/storage/private_event_store/private_event_store.d.ts +1 -1
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +84 -61
- package/dest/storage/private_event_store/stored_private_event.d.ts +4 -4
- package/dest/storage/private_event_store/stored_private_event.d.ts.map +1 -1
- package/dest/storage/private_event_store/stored_private_event.js +2 -2
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.js +31 -19
- package/dest/storage/tagging_store/sender_address_book_store.d.ts +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.js +20 -14
- package/dest/storage/tagging_store/sender_tagging_store.d.ts +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +183 -113
- package/dest/tagging/get_all_logs_by_tags.d.ts +4 -4
- package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +3 -3
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +3 -3
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +3 -3
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +3 -3
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/block_synchronizer/block_synchronizer.ts +17 -19
- package/src/contract_function_simulator/contract_function_simulator.ts +6 -6
- package/src/contract_function_simulator/oracle/interfaces.ts +10 -10
- package/src/contract_function_simulator/oracle/oracle.ts +27 -17
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +2 -8
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +32 -26
- package/src/contract_sync/index.ts +1 -3
- package/src/debug/pxe_debug_utils.ts +23 -9
- package/src/entrypoints/client/bundle/utils.ts +7 -14
- package/src/entrypoints/client/lazy/utils.ts +8 -14
- package/src/entrypoints/pxe_creation_options.ts +2 -1
- package/src/entrypoints/server/utils.ts +15 -19
- package/src/events/event_service.ts +4 -6
- package/src/job_coordinator/job_coordinator.ts +4 -3
- package/src/logs/log_service.ts +12 -13
- package/src/notes/note_service.ts +5 -8
- package/src/oracle_version.ts +2 -2
- package/src/private_kernel/private_kernel_execution_prover.ts +6 -3
- package/src/private_kernel/private_kernel_oracle.ts +2 -2
- package/src/pxe.ts +16 -9
- package/src/storage/address_store/address_store.ts +15 -15
- package/src/storage/anchor_block_store/anchor_block_store.ts +8 -0
- package/src/storage/capsule_store/capsule_store.ts +8 -8
- package/src/storage/contract_store/contract_store.ts +22 -11
- package/src/storage/metadata.ts +1 -1
- package/src/storage/note_store/note_store.ts +159 -129
- package/src/storage/private_event_store/private_event_store.ts +102 -81
- package/src/storage/private_event_store/stored_private_event.ts +3 -3
- package/src/storage/tagging_store/recipient_tagging_store.ts +31 -21
- package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
- package/src/storage/tagging_store/sender_tagging_store.ts +210 -126
- package/src/tagging/get_all_logs_by_tags.ts +3 -3
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +2 -2
- package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +2 -2
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +2 -2
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +3 -3
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
-
import { toArray } from '@aztec/foundation/iterable';
|
|
4
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
4
|
import { Semaphore } from '@aztec/foundation/queue';
|
|
6
5
|
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
|
|
@@ -81,43 +80,45 @@ export class PrivateEventStore implements StagedStore {
|
|
|
81
80
|
metadata: PrivateEventMetadata,
|
|
82
81
|
jobId: string,
|
|
83
82
|
) {
|
|
84
|
-
return this.#withJobLock(jobId,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.logger.verbose('storing private event log (job stage)', {
|
|
89
|
-
eventId,
|
|
90
|
-
contractAddress,
|
|
91
|
-
scope,
|
|
92
|
-
msgContent,
|
|
93
|
-
l2BlockNumber,
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const existing = await this.#readEvent(eventId, jobId);
|
|
83
|
+
return this.#withJobLock(jobId, () =>
|
|
84
|
+
this.#store.transactionAsync(async () => {
|
|
85
|
+
const { contractAddress, scope, txHash, l2BlockNumber, l2BlockHash, txIndexInBlock, eventIndexInTx } = metadata;
|
|
86
|
+
const eventId = siloedEventCommitment.toString();
|
|
97
87
|
|
|
98
|
-
|
|
99
|
-
// If we already stored this event, we still want to make sure to track it for the given scope
|
|
100
|
-
existing.addScope(scope.toString());
|
|
101
|
-
this.#writeEvent(eventId, existing, jobId);
|
|
102
|
-
} else {
|
|
103
|
-
this.#writeEvent(
|
|
88
|
+
this.logger.verbose('storing private event log (job stage)', {
|
|
104
89
|
eventId,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
90
|
+
contractAddress,
|
|
91
|
+
scope,
|
|
92
|
+
msgContent,
|
|
93
|
+
l2BlockNumber,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const existing = await this.#readEvent(eventId, jobId);
|
|
97
|
+
|
|
98
|
+
if (existing) {
|
|
99
|
+
// If we already stored this event, we still want to make sure to track it for the given scope
|
|
100
|
+
existing.addScope(scope.toString());
|
|
101
|
+
this.#writeEvent(eventId, existing, jobId);
|
|
102
|
+
} else {
|
|
103
|
+
this.#writeEvent(
|
|
104
|
+
eventId,
|
|
105
|
+
new StoredPrivateEvent(
|
|
106
|
+
randomness,
|
|
107
|
+
msgContent,
|
|
108
|
+
l2BlockNumber,
|
|
109
|
+
l2BlockHash,
|
|
110
|
+
txHash,
|
|
111
|
+
txIndexInBlock,
|
|
112
|
+
eventIndexInTx,
|
|
113
|
+
contractAddress,
|
|
114
|
+
eventSelector,
|
|
115
|
+
new Set([scope.toString()]),
|
|
116
|
+
),
|
|
117
|
+
jobId,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}),
|
|
121
|
+
);
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
/**
|
|
@@ -136,6 +137,20 @@ export class PrivateEventStore implements StagedStore {
|
|
|
136
137
|
filter: PrivateEventStoreFilter,
|
|
137
138
|
): Promise<PackedPrivateEvent[]> {
|
|
138
139
|
return this.#store.transactionAsync(async () => {
|
|
140
|
+
const key = this.#keyFor(filter.contractAddress, eventSelector);
|
|
141
|
+
const targetScopes = new Set(filter.scopes.map(s => s.toString()));
|
|
142
|
+
|
|
143
|
+
// Map from eventId to the promise that reads the event buffer.
|
|
144
|
+
// We start reads during iteration to keep DB requests pending and avoid IndexedDB auto-commit.
|
|
145
|
+
const eventReadPromises: Map<string, Promise<Buffer | undefined>> = new Map();
|
|
146
|
+
|
|
147
|
+
for await (const eventId of this.#eventsByContractAndEventSelector.getValuesAsync(key)) {
|
|
148
|
+
eventReadPromises.set(eventId, this.#events.getAsync(eventId));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const eventIds = [...eventReadPromises.keys()];
|
|
152
|
+
const eventBuffers = await Promise.all(eventReadPromises.values());
|
|
153
|
+
|
|
139
154
|
const events: Array<{
|
|
140
155
|
l2BlockNumber: number;
|
|
141
156
|
txIndexInBlock: number;
|
|
@@ -143,13 +158,9 @@ export class PrivateEventStore implements StagedStore {
|
|
|
143
158
|
event: PackedPrivateEvent;
|
|
144
159
|
}> = [];
|
|
145
160
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const eventIds: string[] = await toArray(this.#eventsByContractAndEventSelector.getValuesAsync(key));
|
|
150
|
-
|
|
151
|
-
for (const eventId of eventIds) {
|
|
152
|
-
const eventBuffer = await this.#events.getAsync(eventId);
|
|
161
|
+
for (let i = 0; i < eventIds.length; i++) {
|
|
162
|
+
const eventId = eventIds[i];
|
|
163
|
+
const eventBuffer = eventBuffers[i];
|
|
153
164
|
|
|
154
165
|
// Defensive, if it happens, there's a problem with how we're handling #eventsByContractAndEventSelector
|
|
155
166
|
if (!eventBuffer) {
|
|
@@ -223,29 +234,39 @@ export class PrivateEventStore implements StagedStore {
|
|
|
223
234
|
* IMPORTANT: This method must be called within a transaction to ensure atomicity.
|
|
224
235
|
*/
|
|
225
236
|
public async rollback(blockNumber: number, synchedBlockNumber: number): Promise<void> {
|
|
226
|
-
|
|
237
|
+
// First pass: collect all event IDs for all blocks, starting reads during iteration to keep tx alive.
|
|
238
|
+
const eventsByBlock: Map<number, { eventId: string; eventReadPromise: Promise<Buffer | undefined> }[]> = new Map();
|
|
227
239
|
|
|
228
240
|
for (let block = blockNumber + 1; block <= synchedBlockNumber; block++) {
|
|
229
|
-
const
|
|
241
|
+
const blockEvents: { eventId: string; eventReadPromise: Promise<Buffer | undefined> }[] = [];
|
|
242
|
+
for await (const eventId of this.#eventsByBlockNumber.getValuesAsync(block)) {
|
|
243
|
+
// Start read immediately during iteration to keep IndexedDB transaction alive
|
|
244
|
+
blockEvents.push({ eventId, eventReadPromise: this.#events.getAsync(eventId) });
|
|
245
|
+
}
|
|
246
|
+
if (blockEvents.length > 0) {
|
|
247
|
+
eventsByBlock.set(block, blockEvents);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
230
250
|
|
|
231
|
-
|
|
232
|
-
|
|
251
|
+
// Second pass: await reads and perform deletes
|
|
252
|
+
let removedCount = 0;
|
|
253
|
+
for (const [block, events] of eventsByBlock) {
|
|
254
|
+
await this.#eventsByBlockNumber.delete(block);
|
|
233
255
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
256
|
+
for (const { eventId, eventReadPromise } of events) {
|
|
257
|
+
const buffer = await eventReadPromise;
|
|
258
|
+
if (!buffer) {
|
|
259
|
+
throw new Error(`Event not found for eventId ${eventId}`);
|
|
260
|
+
}
|
|
239
261
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
262
|
+
const entry = StoredPrivateEvent.fromBuffer(buffer);
|
|
263
|
+
await this.#events.delete(eventId);
|
|
264
|
+
await this.#eventsByContractAndEventSelector.deleteValue(
|
|
265
|
+
this.#keyFor(entry.contractAddress, entry.eventSelector),
|
|
266
|
+
eventId,
|
|
267
|
+
);
|
|
246
268
|
|
|
247
|
-
|
|
248
|
-
}
|
|
269
|
+
removedCount++;
|
|
249
270
|
}
|
|
250
271
|
}
|
|
251
272
|
|
|
@@ -262,28 +283,30 @@ export class PrivateEventStore implements StagedStore {
|
|
|
262
283
|
*
|
|
263
284
|
* @param jobId - The jobId identifying which staged data to commit
|
|
264
285
|
*/
|
|
265
|
-
commit(jobId: string): Promise<void> {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
286
|
+
async commit(jobId: string): Promise<void> {
|
|
287
|
+
// Note: Don't use #withJobLock here - commit runs within JobCoordinator's transactionAsync,
|
|
288
|
+
// and awaiting the lock would create a microtask boundary with no pending DB request,
|
|
289
|
+
// causing IndexedDB to auto-commit the transaction.
|
|
290
|
+
for (const [eventId, entry] of this.#getEventsForJob(jobId).entries()) {
|
|
291
|
+
const lookupKey = this.#keyFor(entry.contractAddress, entry.eventSelector);
|
|
292
|
+
this.logger.verbose('storing private event log', { eventId, lookupKey });
|
|
293
|
+
|
|
294
|
+
await Promise.all([
|
|
295
|
+
this.#events.set(eventId, entry.toBuffer()),
|
|
296
|
+
this.#eventsByContractAndEventSelector.set(lookupKey, eventId),
|
|
297
|
+
this.#eventsByBlockNumber.set(entry.l2BlockNumber, eventId),
|
|
298
|
+
]);
|
|
299
|
+
}
|
|
277
300
|
|
|
278
|
-
|
|
279
|
-
});
|
|
301
|
+
this.#clearJobData(jobId);
|
|
280
302
|
}
|
|
281
303
|
|
|
282
304
|
/**
|
|
283
305
|
* Discards in memory job data without persisting it.
|
|
284
306
|
*/
|
|
285
307
|
discardStaged(jobId: string): Promise<void> {
|
|
286
|
-
|
|
308
|
+
this.#clearJobData(jobId);
|
|
309
|
+
return Promise.resolve();
|
|
287
310
|
}
|
|
288
311
|
|
|
289
312
|
/**
|
|
@@ -292,13 +315,11 @@ export class PrivateEventStore implements StagedStore {
|
|
|
292
315
|
* Returns undefined if the event does not exist in the store overall.
|
|
293
316
|
*/
|
|
294
317
|
async #readEvent(eventId: string, jobId: string): Promise<StoredPrivateEvent | undefined> {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return eventForJob;
|
|
298
|
-
}
|
|
299
|
-
|
|
318
|
+
// Always issue DB read to keep IndexedDB transaction alive (they auto-commit when a new micro-task starts and there
|
|
319
|
+
// are no pending read requests). The staged value still takes precedence if it exists.
|
|
300
320
|
const buffer = await this.#events.getAsync(eventId);
|
|
301
|
-
|
|
321
|
+
const eventForJob = this.#getEventsForJob(jobId).get(eventId);
|
|
322
|
+
return eventForJob ?? (buffer ? StoredPrivateEvent.fromBuffer(buffer) : undefined);
|
|
302
323
|
}
|
|
303
324
|
|
|
304
325
|
/**
|
|
@@ -2,7 +2,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
2
2
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
3
|
import { EventSelector } from '@aztec/stdlib/abi';
|
|
4
4
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
|
-
import {
|
|
5
|
+
import { BlockHash } from '@aztec/stdlib/block';
|
|
6
6
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
7
7
|
|
|
8
8
|
/** Serializable private event entry with scope tracking. */
|
|
@@ -11,7 +11,7 @@ export class StoredPrivateEvent {
|
|
|
11
11
|
readonly randomness: Fr,
|
|
12
12
|
readonly msgContent: Fr[],
|
|
13
13
|
readonly l2BlockNumber: number,
|
|
14
|
-
readonly l2BlockHash:
|
|
14
|
+
readonly l2BlockHash: BlockHash,
|
|
15
15
|
readonly txHash: TxHash,
|
|
16
16
|
readonly txIndexInBlock: number,
|
|
17
17
|
readonly eventIndexInTx: number,
|
|
@@ -49,7 +49,7 @@ export class StoredPrivateEvent {
|
|
|
49
49
|
const msgContentLength = reader.readNumber();
|
|
50
50
|
const msgContent = reader.readArray(msgContentLength, Fr);
|
|
51
51
|
const l2BlockNumber = reader.readNumber();
|
|
52
|
-
const l2BlockHash =
|
|
52
|
+
const l2BlockHash = new BlockHash(Fr.fromBuffer(reader));
|
|
53
53
|
const txHash = TxHash.fromBuffer(reader);
|
|
54
54
|
const txIndexInBlock = reader.readNumber();
|
|
55
55
|
const eventIndexInTx = reader.readNumber();
|
|
@@ -45,7 +45,11 @@ export class RecipientTaggingStore implements StagedStore {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
async #readHighestAgedIndex(jobId: string, secret: string): Promise<number | undefined> {
|
|
48
|
-
|
|
48
|
+
// Always issue DB read to keep IndexedDB transaction alive (they auto-commit when a new micro-task starts and there
|
|
49
|
+
// are no pending read requests). The staged value still takes precedence if it exists.
|
|
50
|
+
const dbValue = await this.#highestAgedIndex.getAsync(secret);
|
|
51
|
+
const staged = this.#getHighestAgedIndexForJob(jobId).get(secret);
|
|
52
|
+
return staged ?? dbValue;
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
#writeHighestAgedIndex(jobId: string, secret: string, index: number) {
|
|
@@ -62,9 +66,11 @@ export class RecipientTaggingStore implements StagedStore {
|
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
async #readHighestFinalizedIndex(jobId: string, secret: string): Promise<number | undefined> {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
);
|
|
69
|
+
// Always issue DB read to keep IndexedDB transaction alive (they auto-commit when a new micro-task starts and there
|
|
70
|
+
// are no pending read requests). The staged value still takes precedence if it exists.
|
|
71
|
+
const dbValue = await this.#highestFinalizedIndex.getAsync(secret);
|
|
72
|
+
const staged = this.#getHighestFinalizedIndexForJob(jobId).get(secret);
|
|
73
|
+
return staged ?? dbValue;
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
#writeHighestFinalizedIndex(jobId: string, secret: string, index: number) {
|
|
@@ -101,29 +107,33 @@ export class RecipientTaggingStore implements StagedStore {
|
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
getHighestAgedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
104
|
-
return this.#readHighestAgedIndex(jobId, secret.toString());
|
|
110
|
+
return this.#store.transactionAsync(() => this.#readHighestAgedIndex(jobId, secret.toString()));
|
|
105
111
|
}
|
|
106
112
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
updateHighestAgedIndex(secret: DirectionalAppTaggingSecret, index: number, jobId: string): Promise<void> {
|
|
114
|
+
return this.#store.transactionAsync(async () => {
|
|
115
|
+
const currentIndex = await this.#readHighestAgedIndex(jobId, secret.toString());
|
|
116
|
+
if (currentIndex !== undefined && index <= currentIndex) {
|
|
117
|
+
// Log sync should never set a lower highest aged index.
|
|
118
|
+
throw new Error(`New highest aged index (${index}) must be higher than the current one (${currentIndex})`);
|
|
119
|
+
}
|
|
120
|
+
this.#writeHighestAgedIndex(jobId, secret.toString(), index);
|
|
121
|
+
});
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
getHighestFinalizedIndex(secret: DirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
117
|
-
return this.#readHighestFinalizedIndex(jobId, secret.toString());
|
|
125
|
+
return this.#store.transactionAsync(() => this.#readHighestFinalizedIndex(jobId, secret.toString()));
|
|
118
126
|
}
|
|
119
127
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
updateHighestFinalizedIndex(secret: DirectionalAppTaggingSecret, index: number, jobId: string): Promise<void> {
|
|
129
|
+
return this.#store.transactionAsync(async () => {
|
|
130
|
+
const currentIndex = await this.#readHighestFinalizedIndex(jobId, secret.toString());
|
|
131
|
+
if (currentIndex !== undefined && index < currentIndex) {
|
|
132
|
+
// Log sync should never set a lower highest finalized index but it can happen that it would try to set the same
|
|
133
|
+
// one because we are loading logs from highest aged index + 1 and not from the highest finalized index.
|
|
134
|
+
throw new Error(`New highest finalized index (${index}) must be higher than the current one (${currentIndex})`);
|
|
135
|
+
}
|
|
136
|
+
this.#writeHighestFinalizedIndex(jobId, secret.toString(), index);
|
|
137
|
+
});
|
|
128
138
|
}
|
|
129
139
|
}
|
|
@@ -16,27 +16,33 @@ export class SenderAddressBookStore {
|
|
|
16
16
|
this.#addressBook = this.#store.openMap('address_book');
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
addSender(address: AztecAddress): Promise<boolean> {
|
|
20
|
+
return this.#store.transactionAsync(async () => {
|
|
21
|
+
if (await this.#addressBook.hasAsync(address.toString())) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
await this.#addressBook.set(address.toString(), true);
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
return true;
|
|
28
|
+
});
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
return
|
|
31
|
+
getSenders(): Promise<AztecAddress[]> {
|
|
32
|
+
return this.#store.transactionAsync(async () => {
|
|
33
|
+
return (await toArray(this.#addressBook.keysAsync())).map(AztecAddress.fromString);
|
|
34
|
+
});
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
removeSender(address: AztecAddress): Promise<boolean> {
|
|
38
|
+
return this.#store.transactionAsync(async () => {
|
|
39
|
+
if (!(await this.#addressBook.hasAsync(address.toString()))) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
await this.#addressBook.delete(address.toString());
|
|
39
44
|
|
|
40
|
-
|
|
45
|
+
return true;
|
|
46
|
+
});
|
|
41
47
|
}
|
|
42
48
|
}
|