@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.
Files changed (100) hide show
  1. package/dest/config/index.d.ts +2 -3
  2. package/dest/config/index.d.ts.map +1 -1
  3. package/dest/config/index.js +4 -5
  4. package/dest/contract_data_oracle/index.d.ts +1 -0
  5. package/dest/contract_data_oracle/index.d.ts.map +1 -1
  6. package/dest/contract_data_oracle/index.js +5 -1
  7. package/dest/database/incoming_note_dao.d.ts +1 -1
  8. package/dest/database/incoming_note_dao.d.ts.map +1 -1
  9. package/dest/database/kv_pxe_database.d.ts +5 -12
  10. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  11. package/dest/database/kv_pxe_database.js +31 -62
  12. package/dest/database/outgoing_note_dao.d.ts +1 -1
  13. package/dest/database/outgoing_note_dao.d.ts.map +1 -1
  14. package/dest/database/pxe_database.d.ts +17 -25
  15. package/dest/database/pxe_database.d.ts.map +1 -1
  16. package/dest/kernel_oracle/index.d.ts +3 -3
  17. package/dest/kernel_oracle/index.d.ts.map +1 -1
  18. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
  19. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +12 -4
  20. package/dest/kernel_prover/kernel_prover.d.ts +3 -1
  21. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  22. package/dest/kernel_prover/kernel_prover.js +39 -7
  23. package/dest/kernel_prover/test/test_circuit_prover.d.ts +1 -0
  24. package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
  25. package/dest/kernel_prover/test/test_circuit_prover.js +5 -1
  26. package/dest/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.d.ts +1 -1
  27. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +1 -0
  28. package/dest/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.js +1 -1
  29. package/dest/note_decryption_utils/brute_force_note_info.d.ts.map +1 -0
  30. package/dest/{note_processor/utils → note_decryption_utils}/brute_force_note_info.js +1 -1
  31. package/dest/note_decryption_utils/index.d.ts.map +1 -0
  32. package/dest/{note_processor/utils → note_decryption_utils}/index.js +1 -1
  33. package/dest/{note_processor/utils → note_decryption_utils}/produce_note_daos.d.ts +5 -8
  34. package/dest/note_decryption_utils/produce_note_daos.d.ts.map +1 -0
  35. package/dest/note_decryption_utils/produce_note_daos.js +47 -0
  36. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts +8 -0
  37. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts.map +1 -0
  38. package/dest/note_decryption_utils/produce_note_daos_for_key.js +17 -0
  39. package/dest/pxe_http/pxe_http_server.d.ts +1 -2
  40. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  41. package/dest/pxe_http/pxe_http_server.js +5 -51
  42. package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
  43. package/dest/pxe_service/create_pxe_service.js +7 -4
  44. package/dest/pxe_service/error_enriching.d.ts.map +1 -1
  45. package/dest/pxe_service/error_enriching.js +7 -6
  46. package/dest/pxe_service/pxe_service.d.ts +11 -25
  47. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  48. package/dest/pxe_service/pxe_service.js +45 -48
  49. package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
  50. package/dest/pxe_service/test/pxe_test_suite.js +4 -3
  51. package/dest/simulator_oracle/index.d.ts +15 -16
  52. package/dest/simulator_oracle/index.d.ts.map +1 -1
  53. package/dest/simulator_oracle/index.js +195 -65
  54. package/dest/synchronizer/synchronizer.d.ts +0 -48
  55. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  56. package/dest/synchronizer/synchronizer.js +3 -201
  57. package/package.json +14 -14
  58. package/src/config/index.ts +4 -7
  59. package/src/contract_data_oracle/index.ts +5 -0
  60. package/src/database/incoming_note_dao.ts +1 -1
  61. package/src/database/kv_pxe_database.ts +33 -70
  62. package/src/database/outgoing_note_dao.ts +1 -1
  63. package/src/database/pxe_database.ts +19 -28
  64. package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +13 -3
  65. package/src/kernel_prover/kernel_prover.ts +49 -5
  66. package/src/kernel_prover/test/test_circuit_prover.ts +8 -4
  67. package/src/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.ts +1 -1
  68. package/src/{note_processor/utils → note_decryption_utils}/produce_note_daos.ts +6 -16
  69. package/src/{note_processor/utils → note_decryption_utils}/produce_note_daos_for_key.ts +6 -15
  70. package/src/pxe_http/pxe_http_server.ts +5 -84
  71. package/src/pxe_service/create_pxe_service.ts +9 -3
  72. package/src/pxe_service/error_enriching.ts +12 -5
  73. package/src/pxe_service/pxe_service.ts +61 -78
  74. package/src/pxe_service/test/pxe_test_suite.ts +6 -2
  75. package/src/simulator_oracle/index.ts +280 -60
  76. package/src/synchronizer/synchronizer.ts +3 -253
  77. package/dest/database/deferred_note_dao.d.ts +0 -40
  78. package/dest/database/deferred_note_dao.d.ts.map +0 -1
  79. package/dest/database/deferred_note_dao.js +0 -38
  80. package/dest/note_processor/index.d.ts +0 -2
  81. package/dest/note_processor/index.d.ts.map +0 -1
  82. package/dest/note_processor/index.js +0 -2
  83. package/dest/note_processor/note_processor.d.ts +0 -83
  84. package/dest/note_processor/note_processor.d.ts.map +0 -1
  85. package/dest/note_processor/note_processor.js +0 -231
  86. package/dest/note_processor/utils/add_public_values_to_payload.d.ts.map +0 -1
  87. package/dest/note_processor/utils/brute_force_note_info.d.ts.map +0 -1
  88. package/dest/note_processor/utils/index.d.ts.map +0 -1
  89. package/dest/note_processor/utils/produce_note_daos.d.ts.map +0 -1
  90. package/dest/note_processor/utils/produce_note_daos.js +0 -51
  91. package/dest/note_processor/utils/produce_note_daos_for_key.d.ts +0 -9
  92. package/dest/note_processor/utils/produce_note_daos_for_key.d.ts.map +0 -1
  93. package/dest/note_processor/utils/produce_note_daos_for_key.js +0 -26
  94. package/src/database/deferred_note_dao.ts +0 -47
  95. package/src/note_processor/index.ts +0 -1
  96. package/src/note_processor/note_processor.ts +0 -358
  97. /package/dest/{note_processor/utils → note_decryption_utils}/brute_force_note_info.d.ts +0 -0
  98. /package/dest/{note_processor/utils → note_decryption_utils}/index.d.ts +0 -0
  99. /package/src/{note_processor/utils → note_decryption_utils}/brute_force_note_info.ts +0 -0
  100. /package/src/{note_processor/utils → note_decryption_utils}/index.ts +0 -0
@@ -1,10 +1,6 @@
1
- var _Synchronizer_instances, _Synchronizer_reprocessDeferredNotesForContract, _Synchronizer_removeNullifiedNotes;
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
- if (this.noteProcessorsToCatchUp.length > 0) {
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
- _Synchronizer_instances = new WeakSet(), _Synchronizer_reprocessDeferredNotesForContract = async function _Synchronizer_reprocessDeferredNotesForContract(contractAddress) {
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.62.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.62.0",
63
- "@aztec/bb.js": "0.62.0",
64
- "@aztec/builder": "0.62.0",
65
- "@aztec/circuit-types": "0.62.0",
66
- "@aztec/circuits.js": "0.62.0",
67
- "@aztec/ethereum": "0.62.0",
68
- "@aztec/foundation": "0.62.0",
69
- "@aztec/key-store": "0.62.0",
70
- "@aztec/kv-store": "0.62.0",
71
- "@aztec/noir-protocol-circuits-types": "0.62.0",
72
- "@aztec/protocol-contracts": "0.62.0",
73
- "@aztec/simulator": "0.62.0",
74
- "@aztec/types": "0.62.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:*",
@@ -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 '../note_processor/utils/index.js';
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
- #taggingSecretIndexes: AztecMap<string, number>;
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.#taggingSecretIndexes = db.openMap('tagging_secret_indices');
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 incrementTaggingSecretsIndexes(appTaggingSecretsWithRecipient: TaggingSecret[]): Promise<void> {
603
- const indexes = await this.getTaggingSecretsIndexes(appTaggingSecretsWithRecipient);
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
- const { secret, recipient } = appTaggingSecretsWithRecipient[listIndex];
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
- getTaggingSecretsIndexes(appTaggingSecretsWithRecipient: TaggingSecret[]): Promise<number[]> {
615
- return this.db.transaction(() =>
616
- appTaggingSecretsWithRecipient.map(
617
- ({ secret, recipient }) => this.#taggingSecretIndexes.get(`${secret.toString()}-${recipient.toString()}`) ?? 0,
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 '../note_processor/utils/index.js';
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
- getTaggingSecretsIndexes(appTaggingSecretsWithRecipient: TaggingSecret[]): Promise<number[]>;
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
- * Increments the index for the provided app siloed tagging secrets.
221
- * The recipient must also be provided to convey "directionality" of the secret and index pair, or in other words
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
- incrementTaggingSecretsIndexes(appTaggingSecretsWithRecipient: TaggingSecret[]): Promise<void>;
216
+ setTaggingSecretsIndexesAsRecipient(indexedTaggingSecrets: IndexedTaggingSecret[]): Promise<void>;
226
217
  }