@aztec/pxe 0.42.0 → 0.43.0

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 (47) hide show
  1. package/dest/database/deferred_note_dao.d.ts +2 -2
  2. package/dest/database/deferred_note_dao.d.ts.map +1 -1
  3. package/dest/database/deferred_note_dao.js +2 -2
  4. package/dest/database/incoming_note_dao.d.ts +73 -0
  5. package/dest/database/incoming_note_dao.d.ts.map +1 -0
  6. package/dest/database/incoming_note_dao.js +92 -0
  7. package/dest/database/kv_pxe_database.d.ts +10 -7
  8. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  9. package/dest/database/kv_pxe_database.js +149 -78
  10. package/dest/database/{note_dao.d.ts → outgoing_note_dao.d.ts} +7 -12
  11. package/dest/database/outgoing_note_dao.d.ts.map +1 -0
  12. package/dest/database/outgoing_note_dao.js +83 -0
  13. package/dest/database/pxe_database.d.ts +21 -9
  14. package/dest/database/pxe_database.d.ts.map +1 -1
  15. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  16. package/dest/database/pxe_database_test_suite.js +71 -24
  17. package/dest/kernel_oracle/index.d.ts +1 -1
  18. package/dest/note_processor/note_processor.d.ts +23 -20
  19. package/dest/note_processor/note_processor.d.ts.map +1 -1
  20. package/dest/note_processor/note_processor.js +123 -76
  21. package/dest/note_processor/produce_note_dao.d.ts +13 -4
  22. package/dest/note_processor/produce_note_dao.d.ts.map +1 -1
  23. package/dest/note_processor/produce_note_dao.js +88 -31
  24. package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
  25. package/dest/pxe_service/create_pxe_service.js +3 -1
  26. package/dest/pxe_service/pxe_service.d.ts +9 -4
  27. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  28. package/dest/pxe_service/pxe_service.js +106 -28
  29. package/dest/simulator_oracle/index.js +2 -2
  30. package/dest/synchronizer/synchronizer.d.ts +2 -2
  31. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  32. package/dest/synchronizer/synchronizer.js +37 -36
  33. package/package.json +14 -14
  34. package/src/database/deferred_note_dao.ts +1 -1
  35. package/src/database/{note_dao.ts → incoming_note_dao.ts} +10 -7
  36. package/src/database/kv_pxe_database.ts +127 -29
  37. package/src/database/outgoing_note_dao.ts +90 -0
  38. package/src/database/pxe_database.ts +23 -9
  39. package/src/database/pxe_database_test_suite.ts +93 -29
  40. package/src/note_processor/note_processor.ts +191 -121
  41. package/src/note_processor/produce_note_dao.ts +164 -50
  42. package/src/pxe_service/create_pxe_service.ts +2 -0
  43. package/src/pxe_service/pxe_service.ts +170 -42
  44. package/src/simulator_oracle/index.ts +1 -1
  45. package/src/synchronizer/synchronizer.ts +48 -52
  46. package/dest/database/note_dao.d.ts.map +0 -1
  47. package/dest/database/note_dao.js +0 -89
@@ -1,6 +1,6 @@
1
- var _Synchronizer_instances, _Synchronizer_reprocessDeferredNotesForContract;
1
+ var _Synchronizer_instances, _Synchronizer_reprocessDeferredNotesForContract, _Synchronizer_removeNullifiedNotes;
2
2
  import { __classPrivateFieldGet } from "tslib";
3
- import { L2BlockL2Logs, MerkleTreeId } from '@aztec/circuit-types';
3
+ import { MerkleTreeId } from '@aztec/circuit-types';
4
4
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
5
5
  import { createDebugLogger } from '@aztec/foundation/log';
6
6
  import { RunningPromise } from '@aztec/foundation/running-promise';
@@ -89,15 +89,12 @@ export class Synchronizer {
89
89
  if (blocks.length === 0) {
90
90
  return false;
91
91
  }
92
- const noteEncryptedLogs = blocks.flatMap(block => block.body.noteEncryptedLogs);
93
92
  // Update latest tree roots from the most recent block
94
93
  const latestBlock = blocks[blocks.length - 1];
95
94
  await this.setHeaderFromBlock(latestBlock);
96
- const logCount = L2BlockL2Logs.getTotalLogCount(noteEncryptedLogs);
97
- this.log.debug(`Forwarding ${logCount} encrypted logs and blocks to ${this.noteProcessors.length} note processors`);
95
+ this.log.debug(`Forwarding ${blocks.length} blocks to ${this.noteProcessors.length} note processors`);
98
96
  for (const noteProcessor of this.noteProcessors) {
99
- // TODO(#6830): pass in only the blocks
100
- await noteProcessor.process(blocks, noteEncryptedLogs);
97
+ await noteProcessor.process(blocks);
101
98
  }
102
99
  return true;
103
100
  }
@@ -155,9 +152,6 @@ export class Synchronizer {
155
152
  // behind main sync.
156
153
  throw new Error('No blocks in processor catch up mode');
157
154
  }
158
- const noteEncryptedLogs = blocks.flatMap(block => block.body.noteEncryptedLogs);
159
- const logCount = L2BlockL2Logs.getTotalLogCount(noteEncryptedLogs);
160
- this.log.debug(`Forwarding ${logCount} encrypted logs and blocks to note processors in catch up mode`);
161
155
  for (const noteProcessor of catchUpGroup) {
162
156
  // find the index of the first block that the note processor is not yet synced to
163
157
  const index = blocks.findIndex(block => block.number > noteProcessor.status.syncedToBlock);
@@ -167,18 +161,18 @@ export class Synchronizer {
167
161
  // that needs blocks newer than the newest block we fetched.
168
162
  break;
169
163
  }
170
- this.log.debug(`Catching up note processor ${noteProcessor.masterIncomingViewingPublicKey.toString()} by processing ${blocks.length - index} blocks`);
171
- await noteProcessor.process(blocks.slice(index), noteEncryptedLogs.slice(index));
164
+ this.log.debug(`Catching up note processor ${noteProcessor.account.toString()} by processing ${blocks.length - index} blocks`);
165
+ await noteProcessor.process(blocks.slice(index));
172
166
  if (noteProcessor.status.syncedToBlock === toBlockNumber) {
173
167
  // Note processor caught up, move it to `noteProcessors` from `noteProcessorsToCatchUp`.
174
- this.log.debug(`Note processor for ${noteProcessor.masterIncomingViewingPublicKey.toString()} has caught up`, {
168
+ this.log.debug(`Note processor for ${noteProcessor.account.toString()} has caught up`, {
175
169
  eventName: 'note-processor-caught-up',
176
- publicKey: noteProcessor.masterIncomingViewingPublicKey.toString(),
170
+ account: noteProcessor.account.toString(),
177
171
  duration: noteProcessor.timer.ms(),
178
- dbSize: this.db.estimateSize(),
172
+ dbSize: await this.db.estimateSize(),
179
173
  ...noteProcessor.stats,
180
174
  });
181
- this.noteProcessorsToCatchUp = this.noteProcessorsToCatchUp.filter(np => !np.masterIncomingViewingPublicKey.equals(noteProcessor.masterIncomingViewingPublicKey));
175
+ this.noteProcessorsToCatchUp = this.noteProcessorsToCatchUp.filter(np => !np.account.equals(noteProcessor.account));
182
176
  this.noteProcessors.push(noteProcessor);
183
177
  }
184
178
  }
@@ -217,13 +211,13 @@ export class Synchronizer {
217
211
  * @param startingBlock - The block where to start scanning for notes for this accounts.
218
212
  * @returns A promise that resolves once the account is added to the Synchronizer.
219
213
  */
220
- addAccount(publicKey, keyStore, startingBlock) {
221
- const predicate = (x) => x.masterIncomingViewingPublicKey.equals(publicKey);
214
+ async addAccount(account, keyStore, startingBlock) {
215
+ const predicate = (x) => x.account.equals(account);
222
216
  const processor = this.noteProcessors.find(predicate) ?? this.noteProcessorsToCatchUp.find(predicate);
223
217
  if (processor) {
224
218
  return;
225
219
  }
226
- this.noteProcessorsToCatchUp.push(new NoteProcessor(publicKey, keyStore, this.db, this.node, startingBlock));
220
+ this.noteProcessorsToCatchUp.push(await NoteProcessor.create(account, keyStore, this.db, this.node, startingBlock));
227
221
  }
228
222
  /**
229
223
  * Checks if the specified account is synchronized.
@@ -238,8 +232,8 @@ export class Synchronizer {
238
232
  if (!completeAddress) {
239
233
  throw new Error(`Checking if account is synched is not possible for ${account} because it is not registered.`);
240
234
  }
241
- const findByPublicKey = (x) => x.masterIncomingViewingPublicKey.equals(completeAddress.publicKeys.masterIncomingViewingPublicKey);
242
- const processor = this.noteProcessors.find(findByPublicKey) ?? this.noteProcessorsToCatchUp.find(findByPublicKey);
235
+ const findByAccountAddress = (x) => x.account.equals(completeAddress.address);
236
+ const processor = this.noteProcessors.find(findByAccountAddress) ?? this.noteProcessorsToCatchUp.find(findByAccountAddress);
243
237
  if (!processor) {
244
238
  throw new Error(`Checking if account is synched is not possible for ${account} because it is only registered as a recipient.`);
245
239
  }
@@ -266,7 +260,7 @@ export class Synchronizer {
266
260
  const lastBlockNumber = this.getSynchedBlockNumber();
267
261
  return {
268
262
  blocks: lastBlockNumber,
269
- notes: Object.fromEntries(this.noteProcessors.map(n => [n.masterIncomingViewingPublicKey.toString(), n.status.syncedToBlock])),
263
+ notes: Object.fromEntries(this.noteProcessors.map(n => [n.account.toString(), n.status.syncedToBlock])),
270
264
  };
271
265
  }
272
266
  /**
@@ -274,7 +268,7 @@ export class Synchronizer {
274
268
  * @returns The note processor stats for notes for each public key being tracked.
275
269
  */
276
270
  getSyncStats() {
277
- return Object.fromEntries(this.noteProcessors.map(n => [n.masterIncomingViewingPublicKey.toString(), n.stats]));
271
+ return Object.fromEntries(this.noteProcessors.map(n => [n.account.toString(), n.stats]));
278
272
  }
279
273
  /**
280
274
  * Retry decoding any deferred notes for the specified contract address.
@@ -294,30 +288,37 @@ _Synchronizer_instances = new WeakSet(), _Synchronizer_reprocessDeferredNotesFor
294
288
  txHashToDeferredNotes.set(note.txHash, notesForTx);
295
289
  }
296
290
  // keep track of decoded notes
297
- const newNotes = [];
291
+ const incomingNotes = [];
292
+ const outgoingNotes = [];
298
293
  // now process each txHash
299
294
  for (const deferredNotes of txHashToDeferredNotes.values()) {
300
295
  // to be safe, try each note processor in case the deferred notes are for different accounts.
301
296
  for (const processor of this.noteProcessors) {
302
- const decodedNotes = await processor.decodeDeferredNotes(deferredNotes.filter(n => n.publicKey.equals(processor.masterIncomingViewingPublicKey)));
303
- newNotes.push(...decodedNotes);
297
+ const { incomingNotes: inNotes, outgoingNotes: outNotes } = await processor.decodeDeferredNotes(deferredNotes);
298
+ incomingNotes.push(...inNotes);
299
+ outgoingNotes.push(...outNotes);
304
300
  }
305
301
  }
306
302
  // now drop the deferred notes, and add the decoded notes
307
303
  await this.db.removeDeferredNotesByContract(contractAddress);
308
- await this.db.addNotes(newNotes);
309
- newNotes.forEach(noteDao => {
310
- this.log.debug(`Decoded deferred note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot} with nullifier ${noteDao.siloedNullifier.toString()}`);
304
+ await this.db.addNotes(incomingNotes, outgoingNotes);
305
+ incomingNotes.forEach(noteDao => {
306
+ this.log.debug(`Decoded deferred incoming note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot} with nullifier ${noteDao.siloedNullifier.toString()}`);
311
307
  });
312
- // now group the decoded notes by public key
313
- const publicKeyToNotes = new Map();
314
- for (const noteDao of newNotes) {
315
- const notesForPublicKey = publicKeyToNotes.get(noteDao.publicKey) ?? [];
308
+ outgoingNotes.forEach(noteDao => {
309
+ this.log.debug(`Decoded deferred outgoing note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`);
310
+ });
311
+ await __classPrivateFieldGet(this, _Synchronizer_instances, "m", _Synchronizer_removeNullifiedNotes).call(this, incomingNotes);
312
+ }, _Synchronizer_removeNullifiedNotes = async function _Synchronizer_removeNullifiedNotes(notes) {
313
+ // now group the decoded incoming notes by public key
314
+ const publicKeyToIncomingNotes = new Map();
315
+ for (const noteDao of notes) {
316
+ const notesForPublicKey = publicKeyToIncomingNotes.get(noteDao.ivpkM) ?? [];
316
317
  notesForPublicKey.push(noteDao);
317
- publicKeyToNotes.set(noteDao.publicKey, notesForPublicKey);
318
+ publicKeyToIncomingNotes.set(noteDao.ivpkM, notesForPublicKey);
318
319
  }
319
320
  // now for each group, look for the nullifiers in the nullifier tree
320
- for (const [publicKey, notes] of publicKeyToNotes.entries()) {
321
+ for (const [publicKey, notes] of publicKeyToIncomingNotes.entries()) {
321
322
  const nullifiers = notes.map(n => n.siloedNullifier);
322
323
  const relevantNullifiers = [];
323
324
  for (const nullifier of nullifiers) {
@@ -330,4 +331,4 @@ _Synchronizer_instances = new WeakSet(), _Synchronizer_reprocessDeferredNotesFor
330
331
  await this.db.removeNullifiedNotes(relevantNullifiers, publicKey);
331
332
  }
332
333
  };
333
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXplci9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQWdDLGFBQWEsRUFBRSxZQUFZLEVBQWUsTUFBTSxzQkFBc0IsQ0FBQztBQUU5RyxPQUFPLEVBQThCLG9CQUFvQixFQUFrQixNQUFNLG9CQUFvQixDQUFDO0FBRXRHLE9BQU8sRUFBb0IsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFNbkUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRTNEOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBUXZCLFlBQW9CLElBQWUsRUFBVSxFQUFlLEVBQVUsUUFBcUIsRUFBRSxTQUFTLEdBQUcsRUFBRTs7UUFBdkYsU0FBSSxHQUFKLElBQUksQ0FBVztRQUFVLE9BQUUsR0FBRixFQUFFLENBQWE7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFhO1FBTm5GLG1CQUFjLEdBQW9CLEVBQUUsQ0FBQztRQUNyQyxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLDJCQUFzQixHQUFHLG9CQUFvQixHQUFHLENBQUMsQ0FBQztRQUVsRCw0QkFBdUIsR0FBb0IsRUFBRSxDQUFDO1FBR3BELElBQUksQ0FBQyxHQUFHLEdBQUcsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQywwQkFBMEIsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDN0csQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsYUFBYSxHQUFHLElBQUk7UUFDaEQsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsT0FBTztR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
334
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luY2hyb25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXplci9zeW5jaHJvbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQWdDLFlBQVksRUFBZSxNQUFNLHNCQUFzQixDQUFDO0FBRS9GLE9BQU8sRUFBOEIsb0JBQW9CLEVBQWtCLE1BQU0sb0JBQW9CLENBQUM7QUFFdEcsT0FBTyxFQUFvQixpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzVFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQU9uRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFM0Q7Ozs7OztHQU1HO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFRdkIsWUFBb0IsSUFBZSxFQUFVLEVBQWUsRUFBVSxRQUFxQixFQUFFLFNBQVMsR0FBRyxFQUFFOztRQUF2RixTQUFJLEdBQUosSUFBSSxDQUFXO1FBQVUsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUFVLGFBQVEsR0FBUixRQUFRLENBQWE7UUFObkYsbUJBQWMsR0FBb0IsRUFBRSxDQUFDO1FBQ3JDLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsMkJBQXNCLEdBQUcsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO1FBRWxELDRCQUF1QixHQUFvQixFQUFFLENBQUM7UUFHcEQsSUFBSSxDQUFDLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLDBCQUEwQixTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUM3RyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxhQUFhLEdBQUcsSUFBSTtRQUNoRCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixPQUFPO1FBQ1QsQ0FBQztR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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/pxe",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "bin": "./dest/bin/index.js",
@@ -48,19 +48,19 @@
48
48
  ]
49
49
  },
50
50
  "dependencies": {
51
- "@aztec/bb-prover": "0.42.0",
52
- "@aztec/bb.js": "0.42.0",
53
- "@aztec/builder": "0.42.0",
54
- "@aztec/circuit-types": "0.42.0",
55
- "@aztec/circuits.js": "0.42.0",
56
- "@aztec/ethereum": "0.42.0",
57
- "@aztec/foundation": "0.42.0",
58
- "@aztec/key-store": "0.42.0",
59
- "@aztec/kv-store": "0.42.0",
60
- "@aztec/noir-protocol-circuits-types": "0.42.0",
61
- "@aztec/protocol-contracts": "0.42.0",
62
- "@aztec/simulator": "0.42.0",
63
- "@aztec/types": "0.42.0",
51
+ "@aztec/bb-prover": "0.43.0",
52
+ "@aztec/bb.js": "0.43.0",
53
+ "@aztec/builder": "0.43.0",
54
+ "@aztec/circuit-types": "0.43.0",
55
+ "@aztec/circuits.js": "0.43.0",
56
+ "@aztec/ethereum": "0.43.0",
57
+ "@aztec/foundation": "0.43.0",
58
+ "@aztec/key-store": "0.43.0",
59
+ "@aztec/kv-store": "0.43.0",
60
+ "@aztec/noir-protocol-circuits-types": "0.43.0",
61
+ "@aztec/protocol-contracts": "0.43.0",
62
+ "@aztec/simulator": "0.43.0",
63
+ "@aztec/types": "0.43.0",
64
64
  "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi",
65
65
  "koa": "^2.14.2",
66
66
  "koa-router": "^12.0.0",
@@ -9,7 +9,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
9
9
  */
10
10
  export class DeferredNoteDao {
11
11
  constructor(
12
- /** The public key associated with this note */
12
+ /** IvpkM or OvpkM (depending on if incoming or outgoing) the note was encrypted with. */
13
13
  public publicKey: PublicKey,
14
14
  /** The note as emitted from the Noir contract. */
15
15
  public note: Note,
@@ -5,9 +5,9 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
5
5
  import { type NoteData } from '@aztec/simulator';
6
6
 
7
7
  /**
8
- * A note with contextual data.
8
+ * A note with contextual data which was decrypted as incoming.
9
9
  */
10
- export class NoteDao implements NoteData {
10
+ export class IncomingNoteDao implements NoteData {
11
11
  constructor(
12
12
  /** The note as emitted from the Noir contract. */
13
13
  public note: Note,
@@ -26,12 +26,15 @@ export class NoteDao implements NoteData {
26
26
  * We can use this value to compute siloedNoteHash and uniqueSiloedNoteHash.
27
27
  */
28
28
  public innerNoteHash: Fr,
29
- /** The nullifier of the note (siloed by contract address). */
29
+ /**
30
+ * The nullifier of the note (siloed by contract address).
31
+ * Note: Might be set as 0 if the note was added to PXE as nullified.
32
+ */
30
33
  public siloedNullifier: Fr,
31
34
  /** The location of the relevant note in the note hash tree. */
32
35
  public index: bigint,
33
36
  /** The public key with which the note was encrypted. */
34
- public publicKey: PublicKey,
37
+ public ivpkM: PublicKey,
35
38
  ) {}
36
39
 
37
40
  toBuffer(): Buffer {
@@ -45,7 +48,7 @@ export class NoteDao implements NoteData {
45
48
  this.innerNoteHash,
46
49
  this.siloedNullifier,
47
50
  this.index,
48
- this.publicKey,
51
+ this.ivpkM,
49
52
  ]);
50
53
  }
51
54
  static fromBuffer(buffer: Buffer | BufferReader) {
@@ -62,7 +65,7 @@ export class NoteDao implements NoteData {
62
65
  const index = toBigIntBE(reader.readBytes(32));
63
66
  const publicKey = Point.fromBuffer(reader);
64
67
 
65
- return new NoteDao(
68
+ return new IncomingNoteDao(
66
69
  note,
67
70
  contractAddress,
68
71
  storageSlot,
@@ -82,7 +85,7 @@ export class NoteDao implements NoteData {
82
85
 
83
86
  static fromString(str: string) {
84
87
  const hex = str.replace(/^0x/, '');
85
- return NoteDao.fromBuffer(Buffer.from(hex, 'hex'));
88
+ return IncomingNoteDao.fromBuffer(Buffer.from(hex, 'hex'));
86
89
  }
87
90
 
88
91
  /**
@@ -1,4 +1,10 @@
1
- import { MerkleTreeId, type NoteFilter, NoteStatus, type PublicKey } from '@aztec/circuit-types';
1
+ import {
2
+ type IncomingNotesFilter,
3
+ MerkleTreeId,
4
+ NoteStatus,
5
+ type OutgoingNotesFilter,
6
+ type PublicKey,
7
+ } from '@aztec/circuit-types';
2
8
  import { AztecAddress, CompleteAddress, Header } from '@aztec/circuits.js';
3
9
  import { type ContractArtifact } from '@aztec/foundation/abi';
4
10
  import { toBufferBE } from '@aztec/foundation/bigint-buffer';
@@ -14,7 +20,8 @@ import { contractArtifactFromBuffer, contractArtifactToBuffer } from '@aztec/typ
14
20
  import { type ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts';
15
21
 
16
22
  import { DeferredNoteDao } from './deferred_note_dao.js';
17
- import { NoteDao } from './note_dao.js';
23
+ import { IncomingNoteDao } from './incoming_note_dao.js';
24
+ import { OutgoingNoteDao } from './outgoing_note_dao.js';
18
25
  import { type PxeDatabase } from './pxe_database.js';
19
26
 
20
27
  /**
@@ -32,11 +39,11 @@ export class KVPxeDatabase implements PxeDatabase {
32
39
  #notesByContract: AztecMultiMap<string, string>;
33
40
  #notesByStorageSlot: AztecMultiMap<string, string>;
34
41
  #notesByTxHash: AztecMultiMap<string, string>;
35
- #notesByOwner: AztecMultiMap<string, string>;
42
+ #notesByIvpkM: AztecMultiMap<string, string>;
36
43
  #nullifiedNotesByContract: AztecMultiMap<string, string>;
37
44
  #nullifiedNotesByStorageSlot: AztecMultiMap<string, string>;
38
45
  #nullifiedNotesByTxHash: AztecMultiMap<string, string>;
39
- #nullifiedNotesByOwner: AztecMultiMap<string, string>;
46
+ #nullifiedNotesByIvpkM: AztecMultiMap<string, string>;
40
47
  #deferredNotes: AztecArray<Buffer | null>;
41
48
  #deferredNotesByContract: AztecMultiMap<string, number>;
42
49
  #syncedBlockPerPublicKey: AztecMap<string, number>;
@@ -44,6 +51,12 @@ export class KVPxeDatabase implements PxeDatabase {
44
51
  #contractInstances: AztecMap<string, Buffer>;
45
52
  #db: AztecKVStore;
46
53
 
54
+ #outgoingNotes: AztecMap<string, Buffer>;
55
+ #outgoingNotesByContract: AztecMultiMap<string, string>;
56
+ #outgoingNotesByStorageSlot: AztecMultiMap<string, string>;
57
+ #outgoingNotesByTxHash: AztecMultiMap<string, string>;
58
+ #outgoingNotesByOvpkM: AztecMultiMap<string, string>;
59
+
47
60
  constructor(private db: AztecKVStore) {
48
61
  this.#db = db;
49
62
 
@@ -66,15 +79,21 @@ export class KVPxeDatabase implements PxeDatabase {
66
79
  this.#notesByContract = db.openMultiMap('notes_by_contract');
67
80
  this.#notesByStorageSlot = db.openMultiMap('notes_by_storage_slot');
68
81
  this.#notesByTxHash = db.openMultiMap('notes_by_tx_hash');
69
- this.#notesByOwner = db.openMultiMap('notes_by_owner');
82
+ this.#notesByIvpkM = db.openMultiMap('notes_by_ivpk_m');
70
83
 
71
84
  this.#nullifiedNotesByContract = db.openMultiMap('nullified_notes_by_contract');
72
85
  this.#nullifiedNotesByStorageSlot = db.openMultiMap('nullified_notes_by_storage_slot');
73
86
  this.#nullifiedNotesByTxHash = db.openMultiMap('nullified_notes_by_tx_hash');
74
- this.#nullifiedNotesByOwner = db.openMultiMap('nullified_notes_by_owner');
87
+ this.#nullifiedNotesByIvpkM = db.openMultiMap('nullified_notes_by_ivpk_m');
75
88
 
76
89
  this.#deferredNotes = db.openArray('deferred_notes');
77
90
  this.#deferredNotesByContract = db.openMultiMap('deferred_notes_by_contract');
91
+
92
+ this.#outgoingNotes = db.openMap('outgoing_notes');
93
+ this.#outgoingNotesByContract = db.openMultiMap('outgoing_notes_by_contract');
94
+ this.#outgoingNotesByStorageSlot = db.openMultiMap('outgoing_notes_by_storage_slot');
95
+ this.#outgoingNotesByTxHash = db.openMultiMap('outgoing_notes_by_tx_hash');
96
+ this.#outgoingNotesByOvpkM = db.openMultiMap('outgoing_notes_by_ovpk_m');
78
97
  }
79
98
 
80
99
  public async getContract(
@@ -135,13 +154,13 @@ export class KVPxeDatabase implements PxeDatabase {
135
154
  return val?.map(b => Fr.fromBuffer(b));
136
155
  }
137
156
 
138
- async addNote(note: NoteDao): Promise<void> {
139
- await this.addNotes([note]);
157
+ async addNote(note: IncomingNoteDao): Promise<void> {
158
+ await this.addNotes([note], []);
140
159
  }
141
160
 
142
- addNotes(notes: NoteDao[]): Promise<void> {
161
+ addNotes(incomingNotes: IncomingNoteDao[], outgoingNotes: OutgoingNoteDao[]): Promise<void> {
143
162
  return this.db.transaction(() => {
144
- for (const dao of notes) {
163
+ for (const dao of incomingNotes) {
145
164
  // store notes by their index in the notes hash tree
146
165
  // this provides the uniqueness we need to store individual notes
147
166
  // and should also return notes in the order that they were created.
@@ -152,7 +171,16 @@ export class KVPxeDatabase implements PxeDatabase {
152
171
  void this.#notesByContract.set(dao.contractAddress.toString(), noteIndex);
153
172
  void this.#notesByStorageSlot.set(dao.storageSlot.toString(), noteIndex);
154
173
  void this.#notesByTxHash.set(dao.txHash.toString(), noteIndex);
155
- void this.#notesByOwner.set(dao.publicKey.toString(), noteIndex);
174
+ void this.#notesByIvpkM.set(dao.ivpkM.toString(), noteIndex);
175
+ }
176
+
177
+ for (const dao of outgoingNotes) {
178
+ const noteIndex = toBufferBE(dao.index, 32).toString('hex');
179
+ void this.#outgoingNotes.set(noteIndex, dao.toBuffer());
180
+ void this.#outgoingNotesByContract.set(dao.contractAddress.toString(), noteIndex);
181
+ void this.#outgoingNotesByStorageSlot.set(dao.storageSlot.toString(), noteIndex);
182
+ void this.#outgoingNotesByTxHash.set(dao.txHash.toString(), noteIndex);
183
+ void this.#outgoingNotesByOvpkM.set(dao.ovpkM.toString(), noteIndex);
156
184
  }
157
185
  });
158
186
  }
@@ -207,7 +235,7 @@ export class KVPxeDatabase implements PxeDatabase {
207
235
  });
208
236
  }
209
237
 
210
- #getNotes(filter: NoteFilter): NoteDao[] {
238
+ getIncomingNotes(filter: IncomingNotesFilter): Promise<IncomingNoteDao[]> {
211
239
  const publicKey: PublicKey | undefined = filter.owner
212
240
  ? this.#getCompleteAddress(filter.owner)?.publicKeys.masterIncomingViewingPublicKey
213
241
  : undefined;
@@ -218,7 +246,7 @@ export class KVPxeDatabase implements PxeDatabase {
218
246
 
219
247
  candidateNoteSources.push({
220
248
  ids: publicKey
221
- ? this.#notesByOwner.getValues(publicKey.toString())
249
+ ? this.#notesByIvpkM.getValues(publicKey.toString())
222
250
  : filter.txHash
223
251
  ? this.#notesByTxHash.getValues(filter.txHash.toString())
224
252
  : filter.contractAddress
@@ -232,7 +260,7 @@ export class KVPxeDatabase implements PxeDatabase {
232
260
  if (filter.status == NoteStatus.ACTIVE_OR_NULLIFIED) {
233
261
  candidateNoteSources.push({
234
262
  ids: publicKey
235
- ? this.#nullifiedNotesByOwner.getValues(publicKey.toString())
263
+ ? this.#nullifiedNotesByIvpkM.getValues(publicKey.toString())
236
264
  : filter.txHash
237
265
  ? this.#nullifiedNotesByTxHash.getValues(filter.txHash.toString())
238
266
  : filter.contractAddress
@@ -244,7 +272,7 @@ export class KVPxeDatabase implements PxeDatabase {
244
272
  });
245
273
  }
246
274
 
247
- const result: NoteDao[] = [];
275
+ const result: IncomingNoteDao[] = [];
248
276
  for (const { ids, notes } of candidateNoteSources) {
249
277
  for (const id of ids) {
250
278
  const serializedNote = notes.get(id);
@@ -252,7 +280,7 @@ export class KVPxeDatabase implements PxeDatabase {
252
280
  continue;
253
281
  }
254
282
 
255
- const note = NoteDao.fromBuffer(serializedNote);
283
+ const note = IncomingNoteDao.fromBuffer(serializedNote);
256
284
  if (filter.contractAddress && !note.contractAddress.equals(filter.contractAddress)) {
257
285
  continue;
258
286
  }
@@ -265,7 +293,11 @@ export class KVPxeDatabase implements PxeDatabase {
265
293
  continue;
266
294
  }
267
295
 
268
- if (publicKey && !note.publicKey.equals(publicKey)) {
296
+ if (publicKey && !note.ivpkM.equals(publicKey)) {
297
+ continue;
298
+ }
299
+
300
+ if (filter.siloedNullifier && !note.siloedNullifier.equals(filter.siloedNullifier)) {
269
301
  continue;
270
302
  }
271
303
 
@@ -273,20 +305,66 @@ export class KVPxeDatabase implements PxeDatabase {
273
305
  }
274
306
  }
275
307
 
276
- return result;
308
+ return Promise.resolve(result);
277
309
  }
278
310
 
279
- getNotes(filter: NoteFilter): Promise<NoteDao[]> {
280
- return Promise.resolve(this.#getNotes(filter));
311
+ getOutgoingNotes(filter: OutgoingNotesFilter): Promise<OutgoingNoteDao[]> {
312
+ const ovpkM: PublicKey | undefined = filter.owner
313
+ ? this.#getCompleteAddress(filter.owner)?.publicKeys.masterOutgoingViewingPublicKey
314
+ : undefined;
315
+
316
+ // Check if ovpkM is truthy
317
+ const ids = ovpkM
318
+ ? this.#outgoingNotesByOvpkM.getValues(ovpkM.toString())
319
+ : // If ovpkM is falsy, check if filter.txHash is truthy
320
+ filter.txHash
321
+ ? this.#outgoingNotesByTxHash.getValues(filter.txHash.toString())
322
+ : // If both ovpkM and filter.txHash are falsy, check if filter.contractAddress is truthy
323
+ filter.contractAddress
324
+ ? this.#outgoingNotesByContract.getValues(filter.contractAddress.toString())
325
+ : // If ovpkM, filter.txHash, and filter.contractAddress are all falsy, check if filter.storageSlot is truthy
326
+ filter.storageSlot
327
+ ? this.#outgoingNotesByStorageSlot.getValues(filter.storageSlot.toString())
328
+ : // If none of the above conditions are met, retrieve all keys from this.#outgoingNotes
329
+ this.#outgoingNotes.keys();
330
+
331
+ const notes: OutgoingNoteDao[] = [];
332
+ for (const id of ids) {
333
+ const serializedNote = this.#outgoingNotes.get(id);
334
+ if (!serializedNote) {
335
+ continue;
336
+ }
337
+
338
+ const note = OutgoingNoteDao.fromBuffer(serializedNote);
339
+ if (filter.contractAddress && !note.contractAddress.equals(filter.contractAddress)) {
340
+ continue;
341
+ }
342
+
343
+ if (filter.txHash && !note.txHash.equals(filter.txHash)) {
344
+ continue;
345
+ }
346
+
347
+ if (filter.storageSlot && !note.storageSlot.equals(filter.storageSlot!)) {
348
+ continue;
349
+ }
350
+
351
+ if (ovpkM && !note.ovpkM.equals(ovpkM)) {
352
+ continue;
353
+ }
354
+
355
+ notes.push(note);
356
+ }
357
+
358
+ return Promise.resolve(notes);
281
359
  }
282
360
 
283
- removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise<NoteDao[]> {
361
+ removeNullifiedNotes(nullifiers: Fr[], account: PublicKey): Promise<IncomingNoteDao[]> {
284
362
  if (nullifiers.length === 0) {
285
363
  return Promise.resolve([]);
286
364
  }
287
365
 
288
366
  return this.#db.transaction(() => {
289
- const nullifiedNotes: NoteDao[] = [];
367
+ const nullifiedNotes: IncomingNoteDao[] = [];
290
368
 
291
369
  for (const nullifier of nullifiers) {
292
370
  const noteIndex = this.#nullifierToNoteId.get(nullifier.toString());
@@ -301,8 +379,8 @@ export class KVPxeDatabase implements PxeDatabase {
301
379
  continue;
302
380
  }
303
381
 
304
- const note = NoteDao.fromBuffer(noteBuffer);
305
- if (!note.publicKey.equals(account)) {
382
+ const note = IncomingNoteDao.fromBuffer(noteBuffer);
383
+ if (!note.ivpkM.equals(account)) {
306
384
  // tried to nullify someone else's note
307
385
  continue;
308
386
  }
@@ -310,7 +388,7 @@ export class KVPxeDatabase implements PxeDatabase {
310
388
  nullifiedNotes.push(note);
311
389
 
312
390
  void this.#notes.delete(noteIndex);
313
- void this.#notesByOwner.deleteValue(account.toString(), noteIndex);
391
+ void this.#notesByIvpkM.deleteValue(account.toString(), noteIndex);
314
392
  void this.#notesByTxHash.deleteValue(note.txHash.toString(), noteIndex);
315
393
  void this.#notesByContract.deleteValue(note.contractAddress.toString(), noteIndex);
316
394
  void this.#notesByStorageSlot.deleteValue(note.storageSlot.toString(), noteIndex);
@@ -319,7 +397,7 @@ export class KVPxeDatabase implements PxeDatabase {
319
397
  void this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
320
398
  void this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
321
399
  void this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
322
- void this.#nullifiedNotesByOwner.set(note.publicKey.toString(), noteIndex);
400
+ void this.#nullifiedNotesByIvpkM.set(note.ivpkM.toString(), noteIndex);
323
401
 
324
402
  void this.#nullifierToNoteId.delete(nullifier.toString());
325
403
  }
@@ -328,6 +406,18 @@ export class KVPxeDatabase implements PxeDatabase {
328
406
  });
329
407
  }
330
408
 
409
+ async addNullifiedNote(note: IncomingNoteDao): Promise<void> {
410
+ const noteIndex = toBufferBE(note.index, 32).toString('hex');
411
+
412
+ await this.#nullifiedNotes.set(noteIndex, note.toBuffer());
413
+ await this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
414
+ await this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
415
+ await this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
416
+ await this.#nullifiedNotesByIvpkM.set(note.ivpkM.toString(), noteIndex);
417
+
418
+ return Promise.resolve();
419
+ }
420
+
331
421
  async setHeader(header: Header): Promise<void> {
332
422
  await this.#synchronizedBlock.set(header.toBuffer());
333
423
  }
@@ -401,8 +491,16 @@ export class KVPxeDatabase implements PxeDatabase {
401
491
  return this.#syncedBlockPerPublicKey.set(publicKey.toString(), blockNumber);
402
492
  }
403
493
 
404
- estimateSize(): number {
405
- const notesSize = Array.from(this.#getNotes({})).reduce((sum, note) => sum + note.getSize(), 0);
494
+ async estimateSize(): Promise<number> {
495
+ const incomingNotesSize = Array.from(await this.getIncomingNotes({})).reduce(
496
+ (sum, note) => sum + note.getSize(),
497
+ 0,
498
+ );
499
+ const outgoingNotesSize = Array.from(await this.getOutgoingNotes({})).reduce(
500
+ (sum, note) => sum + note.getSize(),
501
+ 0,
502
+ );
503
+
406
504
  const authWitsSize = Array.from(this.#authWitnesses.values()).reduce(
407
505
  (sum, value) => sum + value.length * Fr.SIZE_IN_BYTES,
408
506
  0,
@@ -410,6 +508,6 @@ export class KVPxeDatabase implements PxeDatabase {
410
508
  const addressesSize = this.#addresses.length * CompleteAddress.SIZE_IN_BYTES;
411
509
  const treeRootsSize = Object.keys(MerkleTreeId).length * Fr.SIZE_IN_BYTES;
412
510
 
413
- return notesSize + treeRootsSize + authWitsSize + addressesSize;
511
+ return incomingNotesSize + outgoingNotesSize + treeRootsSize + authWitsSize + addressesSize;
414
512
  }
415
513
  }