@aztec/pxe 0.0.1-commit.54489865 → 0.0.1-commit.592b9384
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/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 +3 -5
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +7 -7
- 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 +9 -9
- 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 +4 -4
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +15 -11
- 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/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 +2 -1
- package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +2 -1
- 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/logs/log_service.d.ts +4 -4
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +7 -10
- 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 -7
- 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/pxe.d.ts +1 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +1 -1
- 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 +169 -129
- 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 +126 -101
- 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/package.json +16 -16
- package/src/contract_function_simulator/contract_function_simulator.ts +0 -4
- package/src/contract_function_simulator/oracle/interfaces.ts +8 -8
- package/src/contract_function_simulator/oracle/oracle.ts +21 -11
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +1 -5
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +24 -20
- package/src/entrypoints/client/bundle/utils.ts +3 -1
- package/src/entrypoints/client/lazy/utils.ts +3 -1
- package/src/events/event_service.ts +4 -6
- package/src/logs/log_service.ts +6 -9
- package/src/notes/note_service.ts +5 -7
- package/src/oracle_version.ts +2 -2
- package/src/pxe.ts +0 -1
- 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 +185 -150
- package/src/storage/private_event_store/private_event_store.ts +151 -128
- 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
|
@@ -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
|
/**
|
|
@@ -131,76 +132,88 @@ export class PrivateEventStore implements StagedStore {
|
|
|
131
132
|
* @returns - The event log contents, augmented with metadata about the transaction and block in which the event was
|
|
132
133
|
* included.
|
|
133
134
|
*/
|
|
134
|
-
public
|
|
135
|
+
public getPrivateEvents(
|
|
135
136
|
eventSelector: EventSelector,
|
|
136
137
|
filter: PrivateEventStoreFilter,
|
|
137
138
|
): Promise<PackedPrivateEvent[]> {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
eventIndexInTx: number;
|
|
142
|
-
event: PackedPrivateEvent;
|
|
143
|
-
}> = [];
|
|
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()));
|
|
144
142
|
|
|
145
|
-
|
|
146
|
-
|
|
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();
|
|
147
146
|
|
|
148
|
-
|
|
147
|
+
for await (const eventId of this.#eventsByContractAndEventSelector.getValuesAsync(key)) {
|
|
148
|
+
eventReadPromises.set(eventId, this.#events.getAsync(eventId));
|
|
149
|
+
}
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
const
|
|
151
|
+
const eventIds = [...eventReadPromises.keys()];
|
|
152
|
+
const eventBuffers = await Promise.all(eventReadPromises.values());
|
|
152
153
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
154
|
+
const events: Array<{
|
|
155
|
+
l2BlockNumber: number;
|
|
156
|
+
txIndexInBlock: number;
|
|
157
|
+
eventIndexInTx: number;
|
|
158
|
+
event: PackedPrivateEvent;
|
|
159
|
+
}> = [];
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
for (let i = 0; i < eventIds.length; i++) {
|
|
162
|
+
const eventId = eventIds[i];
|
|
163
|
+
const eventBuffer = eventBuffers[i];
|
|
162
164
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
// Defensive, if it happens, there's a problem with how we're handling #eventsByContractAndEventSelector
|
|
166
|
+
if (!eventBuffer) {
|
|
167
|
+
this.logger.verbose(
|
|
168
|
+
`EventId ${eventId} does not exist in main index but it is referenced from contract event selector index`,
|
|
169
|
+
);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
167
172
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
const storedPrivateEvent = StoredPrivateEvent.fromBuffer(eventBuffer);
|
|
174
|
+
|
|
175
|
+
// Filter by block range
|
|
176
|
+
if (storedPrivateEvent.l2BlockNumber < filter.fromBlock || storedPrivateEvent.l2BlockNumber >= filter.toBlock) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
172
179
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
180
|
+
// Filter by scopes
|
|
181
|
+
if (storedPrivateEvent.scopes.intersection(targetScopes).size === 0) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Filter by txHash
|
|
186
|
+
if (filter.txHash && !storedPrivateEvent.txHash.equals(filter.txHash)) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
events.push({
|
|
191
|
+
l2BlockNumber: storedPrivateEvent.l2BlockNumber,
|
|
192
|
+
txIndexInBlock: storedPrivateEvent.txIndexInBlock,
|
|
193
|
+
eventIndexInTx: storedPrivateEvent.eventIndexInTx,
|
|
194
|
+
event: {
|
|
195
|
+
packedEvent: storedPrivateEvent.msgContent,
|
|
196
|
+
l2BlockNumber: BlockNumber(storedPrivateEvent.l2BlockNumber),
|
|
197
|
+
txHash: storedPrivateEvent.txHash,
|
|
198
|
+
l2BlockHash: storedPrivateEvent.l2BlockHash,
|
|
199
|
+
eventSelector,
|
|
200
|
+
},
|
|
201
|
+
});
|
|
176
202
|
}
|
|
177
203
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
eventSelector,
|
|
188
|
-
},
|
|
204
|
+
// Sort by block number, then by tx index within block, then by event index within tx
|
|
205
|
+
events.sort((a, b) => {
|
|
206
|
+
if (a.l2BlockNumber !== b.l2BlockNumber) {
|
|
207
|
+
return a.l2BlockNumber - b.l2BlockNumber;
|
|
208
|
+
}
|
|
209
|
+
if (a.txIndexInBlock !== b.txIndexInBlock) {
|
|
210
|
+
return a.txIndexInBlock - b.txIndexInBlock;
|
|
211
|
+
}
|
|
212
|
+
return a.eventIndexInTx - b.eventIndexInTx;
|
|
189
213
|
});
|
|
190
|
-
}
|
|
191
214
|
|
|
192
|
-
|
|
193
|
-
events.sort((a, b) => {
|
|
194
|
-
if (a.l2BlockNumber !== b.l2BlockNumber) {
|
|
195
|
-
return a.l2BlockNumber - b.l2BlockNumber;
|
|
196
|
-
}
|
|
197
|
-
if (a.txIndexInBlock !== b.txIndexInBlock) {
|
|
198
|
-
return a.txIndexInBlock - b.txIndexInBlock;
|
|
199
|
-
}
|
|
200
|
-
return a.eventIndexInTx - b.eventIndexInTx;
|
|
215
|
+
return events.map(ev => ev.event);
|
|
201
216
|
});
|
|
202
|
-
|
|
203
|
-
return events.map(ev => ev.event);
|
|
204
217
|
}
|
|
205
218
|
|
|
206
219
|
/**
|
|
@@ -221,29 +234,39 @@ export class PrivateEventStore implements StagedStore {
|
|
|
221
234
|
* IMPORTANT: This method must be called within a transaction to ensure atomicity.
|
|
222
235
|
*/
|
|
223
236
|
public async rollback(blockNumber: number, synchedBlockNumber: number): Promise<void> {
|
|
224
|
-
|
|
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();
|
|
225
239
|
|
|
226
240
|
for (let block = blockNumber + 1; block <= synchedBlockNumber; block++) {
|
|
227
|
-
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
|
+
}
|
|
228
250
|
|
|
229
|
-
|
|
230
|
-
|
|
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);
|
|
231
255
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
+
}
|
|
237
261
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
+
);
|
|
244
268
|
|
|
245
|
-
|
|
246
|
-
}
|
|
269
|
+
removedCount++;
|
|
247
270
|
}
|
|
248
271
|
}
|
|
249
272
|
|
|
@@ -260,28 +283,30 @@ export class PrivateEventStore implements StagedStore {
|
|
|
260
283
|
*
|
|
261
284
|
* @param jobId - The jobId identifying which staged data to commit
|
|
262
285
|
*/
|
|
263
|
-
commit(jobId: string): Promise<void> {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
+
}
|
|
275
300
|
|
|
276
|
-
|
|
277
|
-
});
|
|
301
|
+
this.#clearJobData(jobId);
|
|
278
302
|
}
|
|
279
303
|
|
|
280
304
|
/**
|
|
281
305
|
* Discards in memory job data without persisting it.
|
|
282
306
|
*/
|
|
283
307
|
discardStaged(jobId: string): Promise<void> {
|
|
284
|
-
|
|
308
|
+
this.#clearJobData(jobId);
|
|
309
|
+
return Promise.resolve();
|
|
285
310
|
}
|
|
286
311
|
|
|
287
312
|
/**
|
|
@@ -290,13 +315,11 @@ export class PrivateEventStore implements StagedStore {
|
|
|
290
315
|
* Returns undefined if the event does not exist in the store overall.
|
|
291
316
|
*/
|
|
292
317
|
async #readEvent(eventId: string, jobId: string): Promise<StoredPrivateEvent | undefined> {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return eventForJob;
|
|
296
|
-
}
|
|
297
|
-
|
|
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.
|
|
298
320
|
const buffer = await this.#events.getAsync(eventId);
|
|
299
|
-
|
|
321
|
+
const eventForJob = this.#getEventsForJob(jobId).get(eventId);
|
|
322
|
+
return eventForJob ?? (buffer ? StoredPrivateEvent.fromBuffer(buffer) : undefined);
|
|
300
323
|
}
|
|
301
324
|
|
|
302
325
|
/**
|
|
@@ -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
|
}
|