@aztec/pxe 0.62.0 → 0.63.1
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/config/index.d.ts +2 -3
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +4 -5
- package/dest/contract_data_oracle/index.d.ts +1 -0
- package/dest/contract_data_oracle/index.d.ts.map +1 -1
- package/dest/contract_data_oracle/index.js +5 -1
- package/dest/database/incoming_note_dao.d.ts +1 -1
- package/dest/database/incoming_note_dao.d.ts.map +1 -1
- package/dest/database/kv_pxe_database.d.ts +5 -12
- package/dest/database/kv_pxe_database.d.ts.map +1 -1
- package/dest/database/kv_pxe_database.js +31 -62
- package/dest/database/outgoing_note_dao.d.ts +1 -1
- package/dest/database/outgoing_note_dao.d.ts.map +1 -1
- package/dest/database/pxe_database.d.ts +17 -25
- package/dest/database/pxe_database.d.ts.map +1 -1
- package/dest/kernel_oracle/index.d.ts +3 -3
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +12 -4
- package/dest/kernel_prover/kernel_prover.d.ts +3 -1
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +39 -7
- package/dest/kernel_prover/test/test_circuit_prover.d.ts +1 -0
- package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/kernel_prover/test/test_circuit_prover.js +5 -1
- package/dest/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.d.ts +1 -1
- package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +1 -0
- package/dest/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.js +1 -1
- package/dest/note_decryption_utils/brute_force_note_info.d.ts.map +1 -0
- package/dest/{note_processor/utils → note_decryption_utils}/brute_force_note_info.js +1 -1
- package/dest/note_decryption_utils/index.d.ts.map +1 -0
- package/dest/{note_processor/utils → note_decryption_utils}/index.js +1 -1
- package/dest/{note_processor/utils → note_decryption_utils}/produce_note_daos.d.ts +5 -8
- package/dest/note_decryption_utils/produce_note_daos.d.ts.map +1 -0
- package/dest/note_decryption_utils/produce_note_daos.js +47 -0
- package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts +8 -0
- package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts.map +1 -0
- package/dest/note_decryption_utils/produce_note_daos_for_key.js +17 -0
- package/dest/pxe_http/pxe_http_server.d.ts +1 -2
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.js +5 -51
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +7 -4
- package/dest/pxe_service/error_enriching.d.ts.map +1 -1
- package/dest/pxe_service/error_enriching.js +7 -6
- package/dest/pxe_service/pxe_service.d.ts +11 -25
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +45 -48
- package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
- package/dest/pxe_service/test/pxe_test_suite.js +4 -3
- package/dest/simulator_oracle/index.d.ts +15 -16
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +195 -65
- package/dest/synchronizer/synchronizer.d.ts +0 -48
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +3 -201
- package/package.json +14 -14
- package/src/config/index.ts +4 -7
- package/src/contract_data_oracle/index.ts +5 -0
- package/src/database/incoming_note_dao.ts +1 -1
- package/src/database/kv_pxe_database.ts +33 -70
- package/src/database/outgoing_note_dao.ts +1 -1
- package/src/database/pxe_database.ts +19 -28
- package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +13 -3
- package/src/kernel_prover/kernel_prover.ts +49 -5
- package/src/kernel_prover/test/test_circuit_prover.ts +8 -4
- package/src/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.ts +1 -1
- package/src/{note_processor/utils → note_decryption_utils}/produce_note_daos.ts +6 -16
- package/src/{note_processor/utils → note_decryption_utils}/produce_note_daos_for_key.ts +6 -15
- package/src/pxe_http/pxe_http_server.ts +5 -84
- package/src/pxe_service/create_pxe_service.ts +9 -3
- package/src/pxe_service/error_enriching.ts +12 -5
- package/src/pxe_service/pxe_service.ts +61 -78
- package/src/pxe_service/test/pxe_test_suite.ts +6 -2
- package/src/simulator_oracle/index.ts +280 -60
- package/src/synchronizer/synchronizer.ts +3 -253
- package/dest/database/deferred_note_dao.d.ts +0 -40
- package/dest/database/deferred_note_dao.d.ts.map +0 -1
- package/dest/database/deferred_note_dao.js +0 -38
- package/dest/note_processor/index.d.ts +0 -2
- package/dest/note_processor/index.d.ts.map +0 -1
- package/dest/note_processor/index.js +0 -2
- package/dest/note_processor/note_processor.d.ts +0 -83
- package/dest/note_processor/note_processor.d.ts.map +0 -1
- package/dest/note_processor/note_processor.js +0 -231
- package/dest/note_processor/utils/add_public_values_to_payload.d.ts.map +0 -1
- package/dest/note_processor/utils/brute_force_note_info.d.ts.map +0 -1
- package/dest/note_processor/utils/index.d.ts.map +0 -1
- package/dest/note_processor/utils/produce_note_daos.d.ts.map +0 -1
- package/dest/note_processor/utils/produce_note_daos.js +0 -51
- package/dest/note_processor/utils/produce_note_daos_for_key.d.ts +0 -9
- package/dest/note_processor/utils/produce_note_daos_for_key.d.ts.map +0 -1
- package/dest/note_processor/utils/produce_note_daos_for_key.js +0 -26
- package/src/database/deferred_note_dao.ts +0 -47
- package/src/note_processor/index.ts +0 -1
- package/src/note_processor/note_processor.ts +0 -358
- /package/dest/{note_processor/utils → note_decryption_utils}/brute_force_note_info.d.ts +0 -0
- /package/dest/{note_processor/utils → note_decryption_utils}/index.d.ts +0 -0
- /package/src/{note_processor/utils → note_decryption_utils}/brute_force_note_info.ts +0 -0
- /package/src/{note_processor/utils → note_decryption_utils}/index.ts +0 -0
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
-
import { MerkleTreeId } from '@aztec/circuit-types';
|
|
4
|
-
import { INITIAL_L2_BLOCK_NUM, } from '@aztec/circuits.js';
|
|
1
|
+
import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
5
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
3
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
|
-
import { NoteProcessor } from '../note_processor/index.js';
|
|
8
4
|
/**
|
|
9
5
|
* The Synchronizer class manages the synchronization of note processors and interacts with the Aztec node
|
|
10
6
|
* to obtain encrypted logs, blocks, and other necessary information for the accounts.
|
|
@@ -14,14 +10,11 @@ import { NoteProcessor } from '../note_processor/index.js';
|
|
|
14
10
|
*/
|
|
15
11
|
export class Synchronizer {
|
|
16
12
|
constructor(node, db, jobQueue, logSuffix = '') {
|
|
17
|
-
_Synchronizer_instances.add(this);
|
|
18
13
|
this.node = node;
|
|
19
14
|
this.db = db;
|
|
20
15
|
this.jobQueue = jobQueue;
|
|
21
|
-
this.noteProcessors = [];
|
|
22
16
|
this.running = false;
|
|
23
17
|
this.initialSyncBlockNumber = INITIAL_L2_BLOCK_NUM - 1;
|
|
24
|
-
this.noteProcessorsToCatchUp = [];
|
|
25
18
|
this.log = createDebugLogger(logSuffix ? `aztec:pxe_synchronizer_${logSuffix}` : 'aztec:pxe_synchronizer');
|
|
26
19
|
}
|
|
27
20
|
/**
|
|
@@ -65,14 +58,7 @@ export class Synchronizer {
|
|
|
65
58
|
let moreWork = true;
|
|
66
59
|
// keep external this.running flag to interrupt greedy sync
|
|
67
60
|
while (moreWork && this.running) {
|
|
68
|
-
|
|
69
|
-
// There is a note processor that needs to catch up. We hijack the main loop to catch up the note processor.
|
|
70
|
-
moreWork = await this.workNoteProcessorCatchUp(limit);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
// No note processor needs to catch up. We continue with the normal flow.
|
|
74
|
-
moreWork = await this.work(limit);
|
|
75
|
-
}
|
|
61
|
+
moreWork = await this.work(limit);
|
|
76
62
|
}
|
|
77
63
|
});
|
|
78
64
|
}
|
|
@@ -92,10 +78,6 @@ export class Synchronizer {
|
|
|
92
78
|
// Update latest tree roots from the most recent block
|
|
93
79
|
const latestBlock = blocks[blocks.length - 1];
|
|
94
80
|
await this.setHeaderFromBlock(latestBlock);
|
|
95
|
-
this.log.debug(`Forwarding ${blocks.length} blocks to ${this.noteProcessors.length} note processors`);
|
|
96
|
-
for (const noteProcessor of this.noteProcessors) {
|
|
97
|
-
await noteProcessor.process(blocks);
|
|
98
|
-
}
|
|
99
81
|
return true;
|
|
100
82
|
}
|
|
101
83
|
catch (err) {
|
|
@@ -103,86 +85,6 @@ export class Synchronizer {
|
|
|
103
85
|
return false;
|
|
104
86
|
}
|
|
105
87
|
}
|
|
106
|
-
/**
|
|
107
|
-
* Catch up note processors that are lagging behind the main sync.
|
|
108
|
-
* e.g. because we just added a new account.
|
|
109
|
-
*
|
|
110
|
-
* @param limit - the maximum number of encrypted, unencrypted logs and blocks to fetch in each iteration.
|
|
111
|
-
* @returns true if there could be more work, false if there was an error which allows a retry with delay.
|
|
112
|
-
*/
|
|
113
|
-
async workNoteProcessorCatchUp(limit = 1) {
|
|
114
|
-
const toBlockNumber = this.getSynchedBlockNumber();
|
|
115
|
-
// filter out note processors that are already caught up
|
|
116
|
-
// and sort them by the block number they are lagging behind in ascending order
|
|
117
|
-
const noteProcessorsToCatchUp = [];
|
|
118
|
-
this.noteProcessorsToCatchUp.forEach(noteProcessor => {
|
|
119
|
-
if (noteProcessor.status.syncedToBlock >= toBlockNumber) {
|
|
120
|
-
// Note processor is ahead of main sync, nothing to do
|
|
121
|
-
this.noteProcessors.push(noteProcessor);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
noteProcessorsToCatchUp.push(noteProcessor);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
this.noteProcessorsToCatchUp = noteProcessorsToCatchUp;
|
|
128
|
-
if (!this.noteProcessorsToCatchUp.length) {
|
|
129
|
-
// No note processors to catch up, nothing to do here,
|
|
130
|
-
// but we return true to continue with the normal flow.
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
// create a copy so that:
|
|
134
|
-
// 1. we can modify the original array while iterating over it
|
|
135
|
-
// 2. we don't need to serialize insertions into the array
|
|
136
|
-
const catchUpGroup = this.noteProcessorsToCatchUp
|
|
137
|
-
.slice()
|
|
138
|
-
// sort by the block number they are lagging behind
|
|
139
|
-
.sort((a, b) => a.status.syncedToBlock - b.status.syncedToBlock);
|
|
140
|
-
// grab the note processor that is lagging behind the most
|
|
141
|
-
const from = catchUpGroup[0].status.syncedToBlock + 1;
|
|
142
|
-
// Ensuring that the note processor does not sync further than the main sync.
|
|
143
|
-
limit = Math.min(limit, toBlockNumber - from + 1);
|
|
144
|
-
// this.log(`Catching up ${catchUpGroup.length} note processors by up to ${limit} blocks starting at block ${from}`);
|
|
145
|
-
if (limit < 1) {
|
|
146
|
-
throw new Error(`Unexpected limit ${limit} for note processor catch up`);
|
|
147
|
-
}
|
|
148
|
-
try {
|
|
149
|
-
const blocks = await this.node.getBlocks(from, limit);
|
|
150
|
-
if (!blocks.length) {
|
|
151
|
-
// This should never happen because this function should only be called when the note processor is lagging
|
|
152
|
-
// behind main sync.
|
|
153
|
-
throw new Error('No blocks in processor catch up mode');
|
|
154
|
-
}
|
|
155
|
-
for (const noteProcessor of catchUpGroup) {
|
|
156
|
-
// find the index of the first block that the note processor is not yet synced to
|
|
157
|
-
const index = blocks.findIndex(block => block.number > noteProcessor.status.syncedToBlock);
|
|
158
|
-
if (index === -1) {
|
|
159
|
-
// Due to the limit, we might not have fetched a new enough block for the note processor.
|
|
160
|
-
// And since the group is sorted, we break as soon as we find a note processor
|
|
161
|
-
// that needs blocks newer than the newest block we fetched.
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
this.log.debug(`Catching up note processor ${noteProcessor.account.toString()} by processing ${blocks.length - index} blocks`);
|
|
165
|
-
await noteProcessor.process(blocks.slice(index));
|
|
166
|
-
if (noteProcessor.status.syncedToBlock === toBlockNumber) {
|
|
167
|
-
// Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`.
|
|
168
|
-
this.log.debug(`Note processor for ${noteProcessor.account.toString()} has caught up`, {
|
|
169
|
-
eventName: 'note-processor-caught-up',
|
|
170
|
-
account: noteProcessor.account.toString(),
|
|
171
|
-
duration: noteProcessor.timer.ms(),
|
|
172
|
-
dbSize: await this.db.estimateSize(),
|
|
173
|
-
...noteProcessor.stats,
|
|
174
|
-
});
|
|
175
|
-
this.noteProcessorsToCatchUp = this.noteProcessorsToCatchUp.filter(np => !np.account.equals(noteProcessor.account));
|
|
176
|
-
this.noteProcessors.push(noteProcessor);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return true; // could be more work, immediately continue syncing
|
|
180
|
-
}
|
|
181
|
-
catch (err) {
|
|
182
|
-
this.log.error(`Error in synchronizer workNoteProcessorCatchUp`, err);
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
88
|
async setHeaderFromBlock(latestBlock) {
|
|
187
89
|
if (latestBlock.number < this.initialSyncBlockNumber) {
|
|
188
90
|
return;
|
|
@@ -201,40 +103,6 @@ export class Synchronizer {
|
|
|
201
103
|
await this.runningPromise?.stop();
|
|
202
104
|
this.log.info('Stopped');
|
|
203
105
|
}
|
|
204
|
-
/**
|
|
205
|
-
* Add a new account to the Synchronizer with the specified private key.
|
|
206
|
-
* Creates a NoteProcessor instance for the account and pushes it into the noteProcessors array.
|
|
207
|
-
* The method resolves immediately after pushing the new note processor.
|
|
208
|
-
*
|
|
209
|
-
* @param publicKey - The public key for the account.
|
|
210
|
-
* @param keyStore - The key store.
|
|
211
|
-
* @param startingBlock - The block where to start scanning for notes for this accounts.
|
|
212
|
-
* @returns A promise that resolves once the account is added to the Synchronizer.
|
|
213
|
-
*/
|
|
214
|
-
addAccount(account, keyStore, startingBlock) {
|
|
215
|
-
const predicate = (x) => x.account.equals(account);
|
|
216
|
-
const processor = this.noteProcessors.find(predicate) ?? this.noteProcessorsToCatchUp.find(predicate);
|
|
217
|
-
if (processor) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
this.noteProcessorsToCatchUp.push(NoteProcessor.create(account, keyStore, this.db, this.node, startingBlock));
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Checks if the specified account is synchronized.
|
|
224
|
-
* @param account - The aztec address for which to query the sync status.
|
|
225
|
-
* @returns True if the account is fully synched, false otherwise.
|
|
226
|
-
* @remarks Checks whether all the notes from all the blocks have been processed. If it is not the case, the
|
|
227
|
-
* retrieved information from contracts might be old/stale (e.g. old token balance).
|
|
228
|
-
* @throws If checking a sync status of account which is not registered.
|
|
229
|
-
*/
|
|
230
|
-
async isAccountStateSynchronized(account) {
|
|
231
|
-
const findByAccountAddress = (x) => x.account.address.equals(account);
|
|
232
|
-
const processor = this.noteProcessors.find(findByAccountAddress) ?? this.noteProcessorsToCatchUp.find(findByAccountAddress);
|
|
233
|
-
if (!processor) {
|
|
234
|
-
throw new Error(`Checking if account is synched is not possible for ${account} because it is only registered as a recipient.`);
|
|
235
|
-
}
|
|
236
|
-
return await processor.isSynchronized();
|
|
237
|
-
}
|
|
238
106
|
getSynchedBlockNumber() {
|
|
239
107
|
return this.db.getBlockNumber() ?? this.initialSyncBlockNumber;
|
|
240
108
|
}
|
|
@@ -256,73 +124,7 @@ export class Synchronizer {
|
|
|
256
124
|
const lastBlockNumber = this.getSynchedBlockNumber();
|
|
257
125
|
return {
|
|
258
126
|
blocks: lastBlockNumber,
|
|
259
|
-
notes: Object.fromEntries(this.noteProcessors.map(n => [n.account.address.toString(), n.status.syncedToBlock])),
|
|
260
127
|
};
|
|
261
128
|
}
|
|
262
|
-
/**
|
|
263
|
-
* Returns the note processor stats.
|
|
264
|
-
* @returns The note processor stats for notes for each public key being tracked.
|
|
265
|
-
*/
|
|
266
|
-
getSyncStats() {
|
|
267
|
-
return Object.fromEntries(this.noteProcessors.map(n => [n.account.address.toString(), n.stats]));
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Retry decoding any deferred notes for the specified contract address.
|
|
271
|
-
* @param contractAddress - the contract address that has just been added
|
|
272
|
-
*/
|
|
273
|
-
reprocessDeferredNotesForContract(contractAddress) {
|
|
274
|
-
return this.jobQueue.put(() => __classPrivateFieldGet(this, _Synchronizer_instances, "m", _Synchronizer_reprocessDeferredNotesForContract).call(this, contractAddress));
|
|
275
|
-
}
|
|
276
129
|
}
|
|
277
|
-
|
|
278
|
-
const deferredNotes = await this.db.getDeferredNotesByContract(contractAddress);
|
|
279
|
-
// group deferred notes by txHash to properly deal with possible duplicates
|
|
280
|
-
const txHashToDeferredNotes = new Map();
|
|
281
|
-
for (const note of deferredNotes) {
|
|
282
|
-
const notesForTx = txHashToDeferredNotes.get(note.txHash) ?? [];
|
|
283
|
-
notesForTx.push(note);
|
|
284
|
-
txHashToDeferredNotes.set(note.txHash, notesForTx);
|
|
285
|
-
}
|
|
286
|
-
// keep track of decoded notes
|
|
287
|
-
const incomingNotes = [];
|
|
288
|
-
// now process each txHash
|
|
289
|
-
for (const deferredNotes of txHashToDeferredNotes.values()) {
|
|
290
|
-
// to be safe, try each note processor in case the deferred notes are for different accounts.
|
|
291
|
-
for (const processor of this.noteProcessors) {
|
|
292
|
-
const { incomingNotes: inNotes, outgoingNotes: outNotes } = await processor.decodeDeferredNotes(deferredNotes);
|
|
293
|
-
incomingNotes.push(...inNotes);
|
|
294
|
-
await this.db.addNotes(inNotes, outNotes, processor.account.address);
|
|
295
|
-
inNotes.forEach(noteDao => {
|
|
296
|
-
this.log.debug(`Decoded deferred incoming note under account ${processor.account.toString()} for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot} with nullifier ${noteDao.siloedNullifier.toString()}`);
|
|
297
|
-
});
|
|
298
|
-
outNotes.forEach(noteDao => {
|
|
299
|
-
this.log.debug(`Decoded deferred outgoing note under account ${processor.account.toString()} for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`);
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
// now drop the deferred notes, and add the decoded notes
|
|
304
|
-
await this.db.removeDeferredNotesByContract(contractAddress);
|
|
305
|
-
await __classPrivateFieldGet(this, _Synchronizer_instances, "m", _Synchronizer_removeNullifiedNotes).call(this, incomingNotes);
|
|
306
|
-
}, _Synchronizer_removeNullifiedNotes = async function _Synchronizer_removeNullifiedNotes(notes) {
|
|
307
|
-
// now group the decoded incoming notes by public key
|
|
308
|
-
const addressPointToIncomingNotes = new Map();
|
|
309
|
-
for (const noteDao of notes) {
|
|
310
|
-
const notesForAddressPoint = addressPointToIncomingNotes.get(noteDao.addressPoint) ?? [];
|
|
311
|
-
notesForAddressPoint.push(noteDao);
|
|
312
|
-
addressPointToIncomingNotes.set(noteDao.addressPoint, notesForAddressPoint);
|
|
313
|
-
}
|
|
314
|
-
// now for each group, look for the nullifiers in the nullifier tree
|
|
315
|
-
for (const [publicKey, notes] of addressPointToIncomingNotes.entries()) {
|
|
316
|
-
const nullifiers = notes.map(n => n.siloedNullifier);
|
|
317
|
-
const relevantNullifiers = [];
|
|
318
|
-
for (const nullifier of nullifiers) {
|
|
319
|
-
// NOTE: this leaks information about the nullifiers I'm interested in to the node.
|
|
320
|
-
const found = await this.node.findLeafIndex('latest', MerkleTreeId.NULLIFIER_TREE, nullifier);
|
|
321
|
-
if (found) {
|
|
322
|
-
relevantNullifiers.push(nullifier);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
await this.db.removeNullifiedNotes(relevantNullifiers, publicKey);
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXplci9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQWdDLFlBQVksRUFBZSxNQUFNLHNCQUFzQixDQUFDO0FBRS9GLE9BQU8sRUFJTCxvQkFBb0IsR0FFckIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQW9CLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFNUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBTW5FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUUzRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQVF2QixZQUFvQixJQUFlLEVBQVUsRUFBZSxFQUFVLFFBQXFCLEVBQUUsU0FBUyxHQUFHLEVBQUU7O1FBQXZGLFNBQUksR0FBSixJQUFJLENBQVc7UUFBVSxPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBYTtRQU5uRixtQkFBYyxHQUFvQixFQUFFLENBQUM7UUFDckMsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNoQiwyQkFBc0IsR0FBRyxvQkFBb0IsR0FBRyxDQUFDLENBQUM7UUFFbEQsNEJBQXVCLEdBQW9CLEVBQUUsQ0FBQztRQUdwRCxJQUFJLENBQUMsR0FBRyxHQUFHLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsMEJBQTBCLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzdHLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLGFBQWEsR0FBRyxJQUFJO1FBQ2hELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLE9BQU87UUFDVCxDQUFDO1FB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
|
|
130
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXplci9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUQsT0FBTyxFQUFvQixpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTVFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUluRTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQU12QixZQUFvQixJQUFlLEVBQVUsRUFBZSxFQUFVLFFBQXFCLEVBQUUsU0FBUyxHQUFHLEVBQUU7UUFBdkYsU0FBSSxHQUFKLElBQUksQ0FBVztRQUFVLE9BQUUsR0FBRixFQUFFLENBQWE7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFhO1FBSm5GLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsMkJBQXNCLEdBQUcsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO1FBSXhELElBQUksQ0FBQyxHQUFHLEdBQUcsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQywwQkFBMEIsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDN0csQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsYUFBYSxHQUFHLElBQUk7UUFDaEQsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUVwQixNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxHQUFHLENBQUMsSUFB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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"bin": "./dest/bin/index.js",
|
|
@@ -59,19 +59,19 @@
|
|
|
59
59
|
]
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@aztec/bb-prover": "0.
|
|
63
|
-
"@aztec/bb.js": "0.
|
|
64
|
-
"@aztec/builder": "0.
|
|
65
|
-
"@aztec/circuit-types": "0.
|
|
66
|
-
"@aztec/circuits.js": "0.
|
|
67
|
-
"@aztec/ethereum": "0.
|
|
68
|
-
"@aztec/foundation": "0.
|
|
69
|
-
"@aztec/key-store": "0.
|
|
70
|
-
"@aztec/kv-store": "0.
|
|
71
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
72
|
-
"@aztec/protocol-contracts": "0.
|
|
73
|
-
"@aztec/simulator": "0.
|
|
74
|
-
"@aztec/types": "0.
|
|
62
|
+
"@aztec/bb-prover": "0.63.1",
|
|
63
|
+
"@aztec/bb.js": "0.63.1",
|
|
64
|
+
"@aztec/builder": "0.63.1",
|
|
65
|
+
"@aztec/circuit-types": "0.63.1",
|
|
66
|
+
"@aztec/circuits.js": "0.63.1",
|
|
67
|
+
"@aztec/ethereum": "0.63.1",
|
|
68
|
+
"@aztec/foundation": "0.63.1",
|
|
69
|
+
"@aztec/key-store": "0.63.1",
|
|
70
|
+
"@aztec/kv-store": "0.63.1",
|
|
71
|
+
"@aztec/noir-protocol-circuits-types": "0.63.1",
|
|
72
|
+
"@aztec/protocol-contracts": "0.63.1",
|
|
73
|
+
"@aztec/simulator": "0.63.1",
|
|
74
|
+
"@aztec/types": "0.63.1",
|
|
75
75
|
"@msgpack/msgpack": "^3.0.0-beta2",
|
|
76
76
|
"@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi",
|
|
77
77
|
"@noir-lang/types": "workspace:*",
|
package/src/config/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
getConfigFromMappings,
|
|
6
6
|
numberConfigHelper,
|
|
7
7
|
} from '@aztec/foundation/config';
|
|
8
|
+
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
8
9
|
import { type Network } from '@aztec/types/network';
|
|
9
10
|
|
|
10
11
|
import { readFileSync } from 'fs';
|
|
@@ -35,11 +36,9 @@ export interface PXEConfig {
|
|
|
35
36
|
l2BlockPollingIntervalMS: number;
|
|
36
37
|
/** L2 block to start scanning from for new accounts */
|
|
37
38
|
l2StartingBlock: number;
|
|
38
|
-
/** Where to store PXE data. If not set, will store in memory */
|
|
39
|
-
dataDirectory?: string;
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
export type PXEServiceConfig = PXEConfig & KernelProverConfig & BBProverConfig;
|
|
41
|
+
export type PXEServiceConfig = PXEConfig & KernelProverConfig & BBProverConfig & DataStoreConfig;
|
|
43
42
|
|
|
44
43
|
export type CliPXEOptions = {
|
|
45
44
|
/** External Aztec network to connect to. e.g. devnet */
|
|
@@ -51,6 +50,7 @@ export type CliPXEOptions = {
|
|
|
51
50
|
};
|
|
52
51
|
|
|
53
52
|
export const pxeConfigMappings: ConfigMappingsType<PXEServiceConfig> = {
|
|
53
|
+
...dataConfigMappings,
|
|
54
54
|
l2BlockPollingIntervalMS: {
|
|
55
55
|
env: 'PXE_BLOCK_POLLING_INTERVAL_MS',
|
|
56
56
|
description: 'The interval to wait between polling for new blocks.',
|
|
@@ -61,10 +61,6 @@ export const pxeConfigMappings: ConfigMappingsType<PXEServiceConfig> = {
|
|
|
61
61
|
...numberConfigHelper(INITIAL_L2_BLOCK_NUM),
|
|
62
62
|
description: 'L2 block to start scanning from for new accounts',
|
|
63
63
|
},
|
|
64
|
-
dataDirectory: {
|
|
65
|
-
env: 'PXE_DATA_DIRECTORY',
|
|
66
|
-
description: 'Where to store PXE data. If not set, will store in memory',
|
|
67
|
-
},
|
|
68
64
|
bbBinaryPath: {
|
|
69
65
|
env: 'BB_BINARY_PATH',
|
|
70
66
|
description: 'Path to the BB binary',
|
|
@@ -111,6 +107,7 @@ export const pxeCliConfigMappings: ConfigMappingsType<CliPXEOptions> = {
|
|
|
111
107
|
export const allPxeConfigMappings: ConfigMappingsType<CliPXEOptions & PXEServiceConfig> = {
|
|
112
108
|
...pxeConfigMappings,
|
|
113
109
|
...pxeCliConfigMappings,
|
|
110
|
+
...dataConfigMappings,
|
|
114
111
|
proverEnabled: {
|
|
115
112
|
env: 'PXE_PROVER_ENABLED',
|
|
116
113
|
parseEnv: (val: string) => ['1', 'true', 'TRUE'].includes(val) || !!process.env.NETWORK,
|
|
@@ -130,6 +130,11 @@ export class ContractDataOracle {
|
|
|
130
130
|
return tree.getFunctionMembershipWitness(selector);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
public async getDebugContractName(contractAddress: AztecAddress) {
|
|
134
|
+
const tree = await this.getTreeForAddress(contractAddress);
|
|
135
|
+
return tree.getArtifact().name;
|
|
136
|
+
}
|
|
137
|
+
|
|
133
138
|
public async getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector) {
|
|
134
139
|
const tree = await this.getTreeForAddress(contractAddress);
|
|
135
140
|
const { name: contractName } = tree.getArtifact();
|
|
@@ -5,7 +5,7 @@ import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
|
|
|
5
5
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
6
6
|
import { type NoteData } from '@aztec/simulator';
|
|
7
7
|
|
|
8
|
-
import { type NoteInfo } from '../
|
|
8
|
+
import { type NoteInfo } from '../note_decryption_utils/index.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A note with contextual data which was decrypted as incoming.
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
CompleteAddress,
|
|
5
5
|
type ContractInstanceWithAddress,
|
|
6
6
|
Header,
|
|
7
|
+
type IndexedTaggingSecret,
|
|
7
8
|
type PublicKey,
|
|
8
9
|
SerializableContractInstance,
|
|
9
|
-
type TaggingSecret,
|
|
10
10
|
computePoint,
|
|
11
11
|
} from '@aztec/circuits.js';
|
|
12
12
|
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
} from '@aztec/kv-store';
|
|
23
23
|
import { contractArtifactFromBuffer, contractArtifactToBuffer } from '@aztec/types/abi';
|
|
24
24
|
|
|
25
|
-
import { DeferredNoteDao } from './deferred_note_dao.js';
|
|
26
25
|
import { IncomingNoteDao } from './incoming_note_dao.js';
|
|
27
26
|
import { OutgoingNoteDao } from './outgoing_note_dao.js';
|
|
28
27
|
import { type PxeDatabase } from './pxe_database.js';
|
|
@@ -45,8 +44,6 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
45
44
|
#nullifiedNotesByStorageSlot: AztecMultiMap<string, string>;
|
|
46
45
|
#nullifiedNotesByTxHash: AztecMultiMap<string, string>;
|
|
47
46
|
#nullifiedNotesByAddressPoint: AztecMultiMap<string, string>;
|
|
48
|
-
#deferredNotes: AztecArray<Buffer | null>;
|
|
49
|
-
#deferredNotesByContract: AztecMultiMap<string, number>;
|
|
50
47
|
#syncedBlockPerPublicKey: AztecMap<string, number>;
|
|
51
48
|
#contractArtifacts: AztecMap<string, Buffer>;
|
|
52
49
|
#contractInstances: AztecMap<string, Buffer>;
|
|
@@ -64,7 +61,11 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
64
61
|
#notesByTxHashAndScope: Map<string, AztecMultiMap<string, string>>;
|
|
65
62
|
#notesByAddressPointAndScope: Map<string, AztecMultiMap<string, string>>;
|
|
66
63
|
|
|
67
|
-
|
|
64
|
+
// Stores the last index used for each tagging secret, taking direction into account
|
|
65
|
+
// This is necessary to avoid reusing the same index for the same secret, which happens if
|
|
66
|
+
// sender and recipient are the same
|
|
67
|
+
#taggingSecretIndexesForSenders: AztecMap<string, number>;
|
|
68
|
+
#taggingSecretIndexesForRecipients: AztecMap<string, number>;
|
|
68
69
|
|
|
69
70
|
constructor(private db: AztecKVStore) {
|
|
70
71
|
this.#db = db;
|
|
@@ -92,9 +93,6 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
92
93
|
this.#nullifiedNotesByTxHash = db.openMultiMap('nullified_notes_by_tx_hash');
|
|
93
94
|
this.#nullifiedNotesByAddressPoint = db.openMultiMap('nullified_notes_by_address_point');
|
|
94
95
|
|
|
95
|
-
this.#deferredNotes = db.openArray('deferred_notes');
|
|
96
|
-
this.#deferredNotesByContract = db.openMultiMap('deferred_notes_by_contract');
|
|
97
|
-
|
|
98
96
|
this.#outgoingNotes = db.openMap('outgoing_notes');
|
|
99
97
|
this.#outgoingNotesByContract = db.openMultiMap('outgoing_notes_by_contract');
|
|
100
98
|
this.#outgoingNotesByStorageSlot = db.openMultiMap('outgoing_notes_by_storage_slot');
|
|
@@ -114,7 +112,8 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
114
112
|
this.#notesByAddressPointAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_address_point`));
|
|
115
113
|
}
|
|
116
114
|
|
|
117
|
-
this.#
|
|
115
|
+
this.#taggingSecretIndexesForSenders = db.openMap('tagging_secret_indexes_for_senders');
|
|
116
|
+
this.#taggingSecretIndexesForRecipients = db.openMap('tagging_secret_indexes_for_recipients');
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
public async getContract(
|
|
@@ -215,56 +214,6 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
215
214
|
});
|
|
216
215
|
}
|
|
217
216
|
|
|
218
|
-
async addDeferredNotes(deferredNotes: DeferredNoteDao[]): Promise<void> {
|
|
219
|
-
const newLength = await this.#deferredNotes.push(...deferredNotes.map(note => note.toBuffer()));
|
|
220
|
-
for (const [index, note] of deferredNotes.entries()) {
|
|
221
|
-
const noteId = newLength - deferredNotes.length + index;
|
|
222
|
-
await this.#deferredNotesByContract.set(note.payload.contractAddress.toString(), noteId);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
getDeferredNotesByContract(contractAddress: AztecAddress): Promise<DeferredNoteDao[]> {
|
|
227
|
-
const noteIds = this.#deferredNotesByContract.getValues(contractAddress.toString());
|
|
228
|
-
const notes: DeferredNoteDao[] = [];
|
|
229
|
-
for (const noteId of noteIds) {
|
|
230
|
-
const serializedNote = this.#deferredNotes.at(noteId);
|
|
231
|
-
if (!serializedNote) {
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const note = DeferredNoteDao.fromBuffer(serializedNote);
|
|
236
|
-
notes.push(note);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return Promise.resolve(notes);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Removes all deferred notes for a given contract address.
|
|
244
|
-
* @param contractAddress - the contract address to remove deferred notes for
|
|
245
|
-
* @returns an array of the removed deferred notes
|
|
246
|
-
*/
|
|
247
|
-
removeDeferredNotesByContract(contractAddress: AztecAddress): Promise<DeferredNoteDao[]> {
|
|
248
|
-
return this.#db.transaction(() => {
|
|
249
|
-
const deferredNotes: DeferredNoteDao[] = [];
|
|
250
|
-
const indices = Array.from(this.#deferredNotesByContract.getValues(contractAddress.toString()));
|
|
251
|
-
|
|
252
|
-
for (const index of indices) {
|
|
253
|
-
const deferredNoteBuffer = this.#deferredNotes.at(index);
|
|
254
|
-
if (!deferredNoteBuffer) {
|
|
255
|
-
continue;
|
|
256
|
-
} else {
|
|
257
|
-
deferredNotes.push(DeferredNoteDao.fromBuffer(deferredNoteBuffer));
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
void this.#deferredNotesByContract.deleteValue(contractAddress.toString(), index);
|
|
261
|
-
void this.#deferredNotes.setAt(index, null);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return deferredNotes;
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
|
|
268
217
|
getIncomingNotes(filter: IncomingNotesFilter): Promise<IncomingNoteDao[]> {
|
|
269
218
|
const publicKey: PublicKey | undefined = filter.owner ? computePoint(filter.owner) : undefined;
|
|
270
219
|
|
|
@@ -599,23 +548,37 @@ export class KVPxeDatabase implements PxeDatabase {
|
|
|
599
548
|
return incomingNotesSize + outgoingNotesSize + treeRootsSize + authWitsSize + addressesSize;
|
|
600
549
|
}
|
|
601
550
|
|
|
602
|
-
async
|
|
603
|
-
|
|
551
|
+
async incrementTaggingSecretsIndexesAsSender(appTaggingSecrets: Fr[]): Promise<void> {
|
|
552
|
+
await this.#incrementTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForSenders);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
async #incrementTaggingSecretsIndexes(appTaggingSecrets: Fr[], storageMap: AztecMap<string, number>): Promise<void> {
|
|
556
|
+
const indexes = await this.#getTaggingSecretsIndexes(appTaggingSecrets, storageMap);
|
|
604
557
|
await this.db.transaction(() => {
|
|
605
558
|
indexes.forEach((taggingSecretIndex, listIndex) => {
|
|
606
559
|
const nextIndex = taggingSecretIndex + 1;
|
|
607
|
-
|
|
608
|
-
const key = `${secret.toString()}-${recipient.toString()}`;
|
|
609
|
-
void this.#taggingSecretIndexes.set(key, nextIndex);
|
|
560
|
+
void storageMap.set(appTaggingSecrets[listIndex].toString(), nextIndex);
|
|
610
561
|
});
|
|
611
562
|
});
|
|
612
563
|
}
|
|
613
564
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
)
|
|
619
|
-
);
|
|
565
|
+
async setTaggingSecretsIndexesAsRecipient(indexedSecrets: IndexedTaggingSecret[]): Promise<void> {
|
|
566
|
+
await this.db.transaction(() => {
|
|
567
|
+
indexedSecrets.forEach(indexedSecret => {
|
|
568
|
+
void this.#taggingSecretIndexesForRecipients.set(indexedSecret.secret.toString(), indexedSecret.index);
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
async getTaggingSecretsIndexesAsRecipient(appTaggingSecrets: Fr[]) {
|
|
574
|
+
return await this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForRecipients);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
async getTaggingSecretsIndexesAsSender(appTaggingSecrets: Fr[]) {
|
|
578
|
+
return await this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForSenders);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
#getTaggingSecretsIndexes(appTaggingSecrets: Fr[], storageMap: AztecMap<string, number>): Promise<number[]> {
|
|
582
|
+
return this.db.transaction(() => appTaggingSecrets.map(secret => storageMap.get(`${secret.toString()}`) ?? 0));
|
|
620
583
|
}
|
|
621
584
|
}
|
|
@@ -4,7 +4,7 @@ import { NoteSelector } from '@aztec/foundation/abi';
|
|
|
4
4
|
import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
|
|
5
5
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
6
6
|
|
|
7
|
-
import { type NoteInfo } from '../
|
|
7
|
+
import { type NoteInfo } from '../note_decryption_utils/index.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* A note with contextual data which was decrypted as outgoing.
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
type CompleteAddress,
|
|
4
4
|
type ContractInstanceWithAddress,
|
|
5
5
|
type Header,
|
|
6
|
+
type IndexedTaggingSecret,
|
|
6
7
|
type PublicKey,
|
|
7
|
-
type TaggingSecret,
|
|
8
8
|
} from '@aztec/circuits.js';
|
|
9
9
|
import { type ContractArtifact } from '@aztec/foundation/abi';
|
|
10
10
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
@@ -12,7 +12,6 @@ import { type Fr } from '@aztec/foundation/fields';
|
|
|
12
12
|
|
|
13
13
|
import { type ContractArtifactDatabase } from './contracts/contract_artifact_db.js';
|
|
14
14
|
import { type ContractInstanceDatabase } from './contracts/contract_instance_db.js';
|
|
15
|
-
import { type DeferredNoteDao } from './deferred_note_dao.js';
|
|
16
15
|
import { type IncomingNoteDao } from './incoming_note_dao.js';
|
|
17
16
|
import { type OutgoingNoteDao } from './outgoing_note_dao.js';
|
|
18
17
|
|
|
@@ -90,25 +89,6 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD
|
|
|
90
89
|
*/
|
|
91
90
|
addNotes(incomingNotes: IncomingNoteDao[], outgoingNotes: OutgoingNoteDao[], scope?: AztecAddress): Promise<void>;
|
|
92
91
|
|
|
93
|
-
/**
|
|
94
|
-
* Add notes to the database that are intended for us, but we don't yet have the contract.
|
|
95
|
-
* @param deferredNotes - An array of deferred notes.
|
|
96
|
-
*/
|
|
97
|
-
addDeferredNotes(deferredNotes: DeferredNoteDao[]): Promise<void>;
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Get deferred notes for a given contract address.
|
|
101
|
-
* @param contractAddress - The contract address to get the deferred notes for.
|
|
102
|
-
*/
|
|
103
|
-
getDeferredNotesByContract(contractAddress: AztecAddress): Promise<DeferredNoteDao[]>;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Remove deferred notes for a given contract address.
|
|
107
|
-
* @param contractAddress - The contract address to remove the deferred notes for.
|
|
108
|
-
* @returns an array of the removed deferred notes
|
|
109
|
-
*/
|
|
110
|
-
removeDeferredNotesByContract(contractAddress: AztecAddress): Promise<DeferredNoteDao[]>;
|
|
111
|
-
|
|
112
92
|
/**
|
|
113
93
|
* Remove nullified notes associated with the given account and nullifiers.
|
|
114
94
|
*
|
|
@@ -209,18 +189,29 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD
|
|
|
209
189
|
|
|
210
190
|
/**
|
|
211
191
|
* Returns the last seen indexes for the provided app siloed tagging secrets or 0 if they've never been seen.
|
|
212
|
-
* The recipient must also be provided to convey "directionality" of the secret and index pair, or in other words
|
|
213
|
-
* whether the index was used to tag a sent or received note.
|
|
214
192
|
* @param appTaggingSecrets - The app siloed tagging secrets.
|
|
215
193
|
* @returns The indexes for the provided secrets, 0 if they've never been seen.
|
|
216
194
|
*/
|
|
217
|
-
|
|
195
|
+
getTaggingSecretsIndexesAsRecipient(appTaggingSecrets: Fr[]): Promise<number[]>;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Returns the last seen indexes for the provided app siloed tagging secrets or 0 if they've never been used
|
|
199
|
+
* @param appTaggingSecrets - The app siloed tagging secrets.
|
|
200
|
+
* @returns The indexes for the provided secrets, 0 if they've never been seen.
|
|
201
|
+
*/
|
|
202
|
+
getTaggingSecretsIndexesAsSender(appTaggingSecrets: Fr[]): Promise<number[]>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Increments the index for the provided app siloed tagging secrets in the senders database
|
|
206
|
+
* To be used when the generated tags have been used as sender
|
|
207
|
+
* @param appTaggingSecrets - The app siloed tagging secrets.
|
|
208
|
+
*/
|
|
209
|
+
incrementTaggingSecretsIndexesAsSender(appTaggingSecrets: Fr[]): Promise<void>;
|
|
218
210
|
|
|
219
211
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* whether the index was used to tag a sent or received note.
|
|
212
|
+
* Sets the index for the provided app siloed tagging secrets
|
|
213
|
+
* To be used when the generated tags have been "seen" as a recipient
|
|
223
214
|
* @param appTaggingSecrets - The app siloed tagging secrets.
|
|
224
215
|
*/
|
|
225
|
-
|
|
216
|
+
setTaggingSecretsIndexesAsRecipient(indexedTaggingSecrets: IndexedTaggingSecret[]): Promise<void>;
|
|
226
217
|
}
|