@aztec/pxe 0.61.0 → 0.63.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 (109) 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 +4 -4
  8. package/dest/database/incoming_note_dao.d.ts.map +1 -1
  9. package/dest/database/incoming_note_dao.js +6 -6
  10. package/dest/database/kv_pxe_database.d.ts +10 -14
  11. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  12. package/dest/database/kv_pxe_database.js +82 -94
  13. package/dest/database/outgoing_note_dao.d.ts +2 -2
  14. package/dest/database/outgoing_note_dao.d.ts.map +1 -1
  15. package/dest/database/outgoing_note_dao.js +2 -2
  16. package/dest/database/pxe_database.d.ts +42 -20
  17. package/dest/database/pxe_database.d.ts.map +1 -1
  18. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  19. package/dest/database/pxe_database_test_suite.js +11 -11
  20. package/dest/index.d.ts +1 -1
  21. package/dest/index.d.ts.map +1 -1
  22. package/dest/index.js +1 -1
  23. package/dest/kernel_oracle/index.d.ts +3 -3
  24. package/dest/kernel_oracle/index.d.ts.map +1 -1
  25. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
  26. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +12 -4
  27. package/dest/kernel_prover/kernel_prover.d.ts +3 -1
  28. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  29. package/dest/kernel_prover/kernel_prover.js +39 -7
  30. package/dest/kernel_prover/test/test_circuit_prover.d.ts +1 -0
  31. package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
  32. package/dest/kernel_prover/test/test_circuit_prover.js +5 -1
  33. package/dest/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.d.ts +1 -1
  34. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +1 -0
  35. package/dest/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.js +1 -1
  36. package/dest/note_decryption_utils/brute_force_note_info.d.ts.map +1 -0
  37. package/dest/{note_processor/utils → note_decryption_utils}/brute_force_note_info.js +1 -1
  38. package/dest/note_decryption_utils/index.d.ts.map +1 -0
  39. package/dest/{note_processor/utils → note_decryption_utils}/index.js +1 -1
  40. package/dest/{note_processor/utils → note_decryption_utils}/produce_note_daos.d.ts +6 -9
  41. package/dest/note_decryption_utils/produce_note_daos.d.ts.map +1 -0
  42. package/dest/note_decryption_utils/produce_note_daos.js +47 -0
  43. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts +8 -0
  44. package/dest/note_decryption_utils/produce_note_daos_for_key.d.ts.map +1 -0
  45. package/dest/note_decryption_utils/produce_note_daos_for_key.js +17 -0
  46. package/dest/pxe_http/pxe_http_server.d.ts +1 -2
  47. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  48. package/dest/pxe_http/pxe_http_server.js +5 -49
  49. package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
  50. package/dest/pxe_service/create_pxe_service.js +7 -4
  51. package/dest/pxe_service/error_enriching.d.ts.map +1 -1
  52. package/dest/pxe_service/error_enriching.js +7 -6
  53. package/dest/pxe_service/pxe_service.d.ts +13 -19
  54. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  55. package/dest/pxe_service/pxe_service.js +79 -79
  56. package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
  57. package/dest/pxe_service/test/pxe_test_suite.js +5 -34
  58. package/dest/simulator_oracle/index.d.ts +32 -10
  59. package/dest/simulator_oracle/index.d.ts.map +1 -1
  60. package/dest/simulator_oracle/index.js +223 -30
  61. package/dest/synchronizer/synchronizer.d.ts +0 -48
  62. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  63. package/dest/synchronizer/synchronizer.js +3 -201
  64. package/package.json +16 -14
  65. package/src/config/index.ts +4 -7
  66. package/src/contract_data_oracle/index.ts +5 -0
  67. package/src/database/incoming_note_dao.ts +5 -5
  68. package/src/database/kv_pxe_database.ts +95 -106
  69. package/src/database/outgoing_note_dao.ts +3 -3
  70. package/src/database/pxe_database.ts +47 -22
  71. package/src/database/pxe_database_test_suite.ts +12 -20
  72. package/src/index.ts +1 -1
  73. package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +13 -3
  74. package/src/kernel_prover/kernel_prover.ts +49 -5
  75. package/src/kernel_prover/test/test_circuit_prover.ts +8 -4
  76. package/src/{note_processor/utils → note_decryption_utils}/add_public_values_to_payload.ts +1 -1
  77. package/src/{note_processor/utils → note_decryption_utils}/produce_note_daos.ts +12 -22
  78. package/src/{note_processor/utils → note_decryption_utils}/produce_note_daos_for_key.ts +6 -15
  79. package/src/pxe_http/pxe_http_server.ts +5 -81
  80. package/src/pxe_service/create_pxe_service.ts +9 -3
  81. package/src/pxe_service/error_enriching.ts +12 -5
  82. package/src/pxe_service/pxe_service.ts +102 -113
  83. package/src/pxe_service/test/pxe_test_suite.ts +7 -55
  84. package/src/simulator_oracle/index.ts +322 -23
  85. package/src/synchronizer/synchronizer.ts +3 -253
  86. package/dest/database/deferred_note_dao.d.ts +0 -40
  87. package/dest/database/deferred_note_dao.d.ts.map +0 -1
  88. package/dest/database/deferred_note_dao.js +0 -38
  89. package/dest/note_processor/index.d.ts +0 -2
  90. package/dest/note_processor/index.d.ts.map +0 -1
  91. package/dest/note_processor/index.js +0 -2
  92. package/dest/note_processor/note_processor.d.ts +0 -83
  93. package/dest/note_processor/note_processor.d.ts.map +0 -1
  94. package/dest/note_processor/note_processor.js +0 -230
  95. package/dest/note_processor/utils/add_public_values_to_payload.d.ts.map +0 -1
  96. package/dest/note_processor/utils/brute_force_note_info.d.ts.map +0 -1
  97. package/dest/note_processor/utils/index.d.ts.map +0 -1
  98. package/dest/note_processor/utils/produce_note_daos.d.ts.map +0 -1
  99. package/dest/note_processor/utils/produce_note_daos.js +0 -51
  100. package/dest/note_processor/utils/produce_note_daos_for_key.d.ts +0 -9
  101. package/dest/note_processor/utils/produce_note_daos_for_key.d.ts.map +0 -1
  102. package/dest/note_processor/utils/produce_note_daos_for_key.js +0 -26
  103. package/src/database/deferred_note_dao.ts +0 -47
  104. package/src/note_processor/index.ts +0 -1
  105. package/src/note_processor/note_processor.ts +0 -355
  106. /package/dest/{note_processor/utils → note_decryption_utils}/brute_force_note_info.d.ts +0 -0
  107. /package/dest/{note_processor/utils → note_decryption_utils}/index.d.ts +0 -0
  108. /package/src/{note_processor/utils → note_decryption_utils}/brute_force_note_info.ts +0 -0
  109. /package/src/{note_processor/utils → note_decryption_utils}/index.ts +0 -0
@@ -1,16 +1,13 @@
1
- import {
2
- type IncomingNotesFilter,
3
- MerkleTreeId,
4
- NoteStatus,
5
- type OutgoingNotesFilter,
6
- type PublicKey,
7
- } from '@aztec/circuit-types';
1
+ import { type IncomingNotesFilter, MerkleTreeId, NoteStatus, type OutgoingNotesFilter } from '@aztec/circuit-types';
8
2
  import {
9
3
  AztecAddress,
10
4
  CompleteAddress,
11
5
  type ContractInstanceWithAddress,
12
6
  Header,
7
+ type IndexedTaggingSecret,
8
+ type PublicKey,
13
9
  SerializableContractInstance,
10
+ computePoint,
14
11
  } from '@aztec/circuits.js';
15
12
  import { type ContractArtifact } from '@aztec/foundation/abi';
16
13
  import { toBufferBE } from '@aztec/foundation/bigint-buffer';
@@ -25,7 +22,6 @@ import {
25
22
  } from '@aztec/kv-store';
26
23
  import { contractArtifactFromBuffer, contractArtifactToBuffer } from '@aztec/types/abi';
27
24
 
28
- import { DeferredNoteDao } from './deferred_note_dao.js';
29
25
  import { IncomingNoteDao } from './incoming_note_dao.js';
30
26
  import { OutgoingNoteDao } from './outgoing_note_dao.js';
31
27
  import { type PxeDatabase } from './pxe_database.js';
@@ -35,8 +31,9 @@ import { type PxeDatabase } from './pxe_database.js';
35
31
  */
36
32
  export class KVPxeDatabase implements PxeDatabase {
37
33
  #synchronizedBlock: AztecSingleton<Buffer>;
38
- #addresses: AztecArray<Buffer>;
39
- #addressIndex: AztecMap<string, number>;
34
+ #completeAddresses: AztecArray<Buffer>;
35
+ #completeAddressIndex: AztecMap<string, number>;
36
+ #addressBook: AztecSet<string>;
40
37
  #authWitnesses: AztecMap<string, Buffer[]>;
41
38
  #capsules: AztecArray<Buffer[]>;
42
39
  #notes: AztecMap<string, Buffer>;
@@ -46,9 +43,7 @@ export class KVPxeDatabase implements PxeDatabase {
46
43
  #nullifiedNotesByContract: AztecMultiMap<string, string>;
47
44
  #nullifiedNotesByStorageSlot: AztecMultiMap<string, string>;
48
45
  #nullifiedNotesByTxHash: AztecMultiMap<string, string>;
49
- #nullifiedNotesByIvpkM: AztecMultiMap<string, string>;
50
- #deferredNotes: AztecArray<Buffer | null>;
51
- #deferredNotesByContract: AztecMultiMap<string, number>;
46
+ #nullifiedNotesByAddressPoint: AztecMultiMap<string, string>;
52
47
  #syncedBlockPerPublicKey: AztecMap<string, number>;
53
48
  #contractArtifacts: AztecMap<string, Buffer>;
54
49
  #contractInstances: AztecMap<string, Buffer>;
@@ -64,15 +59,21 @@ export class KVPxeDatabase implements PxeDatabase {
64
59
  #notesByContractAndScope: Map<string, AztecMultiMap<string, string>>;
65
60
  #notesByStorageSlotAndScope: Map<string, AztecMultiMap<string, string>>;
66
61
  #notesByTxHashAndScope: Map<string, AztecMultiMap<string, string>>;
67
- #notesByIvpkMAndScope: Map<string, AztecMultiMap<string, string>>;
62
+ #notesByAddressPointAndScope: Map<string, AztecMultiMap<string, string>>;
68
63
 
69
- #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>;
70
69
 
71
70
  constructor(private db: AztecKVStore) {
72
71
  this.#db = db;
73
72
 
74
- this.#addresses = db.openArray('addresses');
75
- this.#addressIndex = db.openMap('address_index');
73
+ this.#completeAddresses = db.openArray('complete_addresses');
74
+ this.#completeAddressIndex = db.openMap('complete_address_index');
75
+
76
+ this.#addressBook = db.openSet('address_book');
76
77
 
77
78
  this.#authWitnesses = db.openMap('auth_witnesses');
78
79
  this.#capsules = db.openArray('capsules');
@@ -90,10 +91,7 @@ export class KVPxeDatabase implements PxeDatabase {
90
91
  this.#nullifiedNotesByContract = db.openMultiMap('nullified_notes_by_contract');
91
92
  this.#nullifiedNotesByStorageSlot = db.openMultiMap('nullified_notes_by_storage_slot');
92
93
  this.#nullifiedNotesByTxHash = db.openMultiMap('nullified_notes_by_tx_hash');
93
- this.#nullifiedNotesByIvpkM = db.openMultiMap('nullified_notes_by_ivpk_m');
94
-
95
- this.#deferredNotes = db.openArray('deferred_notes');
96
- this.#deferredNotesByContract = db.openMultiMap('deferred_notes_by_contract');
94
+ this.#nullifiedNotesByAddressPoint = db.openMultiMap('nullified_notes_by_address_point');
97
95
 
98
96
  this.#outgoingNotes = db.openMap('outgoing_notes');
99
97
  this.#outgoingNotesByContract = db.openMultiMap('outgoing_notes_by_contract');
@@ -105,16 +103,17 @@ export class KVPxeDatabase implements PxeDatabase {
105
103
  this.#notesByContractAndScope = new Map<string, AztecMultiMap<string, string>>();
106
104
  this.#notesByStorageSlotAndScope = new Map<string, AztecMultiMap<string, string>>();
107
105
  this.#notesByTxHashAndScope = new Map<string, AztecMultiMap<string, string>>();
108
- this.#notesByIvpkMAndScope = new Map<string, AztecMultiMap<string, string>>();
106
+ this.#notesByAddressPointAndScope = new Map<string, AztecMultiMap<string, string>>();
109
107
 
110
108
  for (const scope of this.#scopes.entries()) {
111
109
  this.#notesByContractAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_contract`));
112
110
  this.#notesByStorageSlotAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_storage_slot`));
113
111
  this.#notesByTxHashAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_tx_hash`));
114
- this.#notesByIvpkMAndScope.set(scope, db.openMultiMap(`${scope}:notes_by_ivpk_m`));
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(
@@ -201,7 +200,7 @@ export class KVPxeDatabase implements PxeDatabase {
201
200
  void this.#notesByContractAndScope.get(scope.toString())!.set(dao.contractAddress.toString(), noteIndex);
202
201
  void this.#notesByStorageSlotAndScope.get(scope.toString())!.set(dao.storageSlot.toString(), noteIndex);
203
202
  void this.#notesByTxHashAndScope.get(scope.toString())!.set(dao.txHash.toString(), noteIndex);
204
- void this.#notesByIvpkMAndScope.get(scope.toString())!.set(dao.ivpkM.toString(), noteIndex);
203
+ void this.#notesByAddressPointAndScope.get(scope.toString())!.set(dao.addressPoint.toString(), noteIndex);
205
204
  }
206
205
 
207
206
  for (const dao of outgoingNotes) {
@@ -215,60 +214,8 @@ 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
- const publicKey: PublicKey | undefined = filter.owner
270
- ? this.#getCompleteAddress(filter.owner)?.publicKeys.masterIncomingViewingPublicKey
271
- : undefined;
218
+ const publicKey: PublicKey | undefined = filter.owner ? computePoint(filter.owner) : undefined;
272
219
 
273
220
  filter.status = filter.status ?? NoteStatus.ACTIVE;
274
221
 
@@ -286,14 +233,14 @@ export class KVPxeDatabase implements PxeDatabase {
286
233
 
287
234
  activeNoteIdsPerScope.push(
288
235
  publicKey
289
- ? this.#notesByIvpkMAndScope.get(formattedScopeString)!.getValues(publicKey.toString())
236
+ ? this.#notesByAddressPointAndScope.get(formattedScopeString)!.getValues(publicKey.toString())
290
237
  : filter.txHash
291
238
  ? this.#notesByTxHashAndScope.get(formattedScopeString)!.getValues(filter.txHash.toString())
292
239
  : filter.contractAddress
293
240
  ? this.#notesByContractAndScope.get(formattedScopeString)!.getValues(filter.contractAddress.toString())
294
241
  : filter.storageSlot
295
242
  ? this.#notesByStorageSlotAndScope.get(formattedScopeString)!.getValues(filter.storageSlot.toString())
296
- : this.#notesByIvpkMAndScope.get(formattedScopeString)!.values(),
243
+ : this.#notesByAddressPointAndScope.get(formattedScopeString)!.values(),
297
244
  );
298
245
  }
299
246
 
@@ -305,7 +252,7 @@ export class KVPxeDatabase implements PxeDatabase {
305
252
  if (filter.status == NoteStatus.ACTIVE_OR_NULLIFIED) {
306
253
  candidateNoteSources.push({
307
254
  ids: publicKey
308
- ? this.#nullifiedNotesByIvpkM.getValues(publicKey.toString())
255
+ ? this.#nullifiedNotesByAddressPoint.getValues(publicKey.toString())
309
256
  : filter.txHash
310
257
  ? this.#nullifiedNotesByTxHash.getValues(filter.txHash.toString())
311
258
  : filter.contractAddress
@@ -338,7 +285,7 @@ export class KVPxeDatabase implements PxeDatabase {
338
285
  continue;
339
286
  }
340
287
 
341
- if (publicKey && !note.ivpkM.equals(publicKey)) {
288
+ if (publicKey && !note.addressPoint.equals(publicKey)) {
342
289
  continue;
343
290
  }
344
291
 
@@ -403,7 +350,7 @@ export class KVPxeDatabase implements PxeDatabase {
403
350
  return Promise.resolve(notes);
404
351
  }
405
352
 
406
- removeNullifiedNotes(nullifiers: Fr[], accountIvpkM: PublicKey): Promise<IncomingNoteDao[]> {
353
+ removeNullifiedNotes(nullifiers: Fr[], accountAddressPoint: PublicKey): Promise<IncomingNoteDao[]> {
407
354
  if (nullifiers.length === 0) {
408
355
  return Promise.resolve([]);
409
356
  }
@@ -425,7 +372,7 @@ export class KVPxeDatabase implements PxeDatabase {
425
372
  }
426
373
 
427
374
  const note = IncomingNoteDao.fromBuffer(noteBuffer);
428
- if (!note.ivpkM.equals(accountIvpkM)) {
375
+ if (!note.addressPoint.equals(accountAddressPoint)) {
429
376
  // tried to nullify someone else's note
430
377
  continue;
431
378
  }
@@ -435,7 +382,7 @@ export class KVPxeDatabase implements PxeDatabase {
435
382
  void this.#notes.delete(noteIndex);
436
383
 
437
384
  for (const scope in this.#scopes.entries()) {
438
- void this.#notesByIvpkMAndScope.get(scope)!.deleteValue(accountIvpkM.toString(), noteIndex);
385
+ void this.#notesByAddressPointAndScope.get(scope)!.deleteValue(accountAddressPoint.toString(), noteIndex);
439
386
  void this.#notesByTxHashAndScope.get(scope)!.deleteValue(note.txHash.toString(), noteIndex);
440
387
  void this.#notesByContractAndScope.get(scope)!.deleteValue(note.contractAddress.toString(), noteIndex);
441
388
  void this.#notesByStorageSlotAndScope.get(scope)!.deleteValue(note.storageSlot.toString(), noteIndex);
@@ -445,7 +392,7 @@ export class KVPxeDatabase implements PxeDatabase {
445
392
  void this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
446
393
  void this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
447
394
  void this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
448
- void this.#nullifiedNotesByIvpkM.set(note.ivpkM.toString(), noteIndex);
395
+ void this.#nullifiedNotesByAddressPoint.set(note.addressPoint.toString(), noteIndex);
449
396
 
450
397
  void this.#nullifierToNoteId.delete(nullifier.toString());
451
398
  }
@@ -461,7 +408,7 @@ export class KVPxeDatabase implements PxeDatabase {
461
408
  await this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
462
409
  await this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
463
410
  await this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
464
- await this.#nullifiedNotesByIvpkM.set(note.ivpkM.toString(), noteIndex);
411
+ await this.#nullifiedNotesByAddressPoint.set(note.addressPoint.toString(), noteIndex);
465
412
 
466
413
  return Promise.resolve();
467
414
  }
@@ -499,7 +446,7 @@ export class KVPxeDatabase implements PxeDatabase {
499
446
  this.#notesByContractAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_contract`));
500
447
  this.#notesByStorageSlotAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_storage_slot`));
501
448
  this.#notesByTxHashAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_tx_hash`));
502
- this.#notesByIvpkMAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_ivpk_m`));
449
+ this.#notesByAddressPointAndScope.set(scopeString, this.#db.openMultiMap(`${scopeString}:notes_by_address_point`));
503
450
 
504
451
  return true;
505
452
  }
@@ -510,15 +457,15 @@ export class KVPxeDatabase implements PxeDatabase {
510
457
  return this.#db.transaction(() => {
511
458
  const addressString = completeAddress.address.toString();
512
459
  const buffer = completeAddress.toBuffer();
513
- const existing = this.#addressIndex.get(addressString);
460
+ const existing = this.#completeAddressIndex.get(addressString);
514
461
  if (typeof existing === 'undefined') {
515
- const index = this.#addresses.length;
516
- void this.#addresses.push(buffer);
517
- void this.#addressIndex.set(addressString, index);
462
+ const index = this.#completeAddresses.length;
463
+ void this.#completeAddresses.push(buffer);
464
+ void this.#completeAddressIndex.set(addressString, index);
518
465
 
519
466
  return true;
520
467
  } else {
521
- const existingBuffer = this.#addresses.at(existing);
468
+ const existingBuffer = this.#completeAddresses.at(existing);
522
469
 
523
470
  if (existingBuffer?.equals(buffer)) {
524
471
  return false;
@@ -532,12 +479,12 @@ export class KVPxeDatabase implements PxeDatabase {
532
479
  }
533
480
 
534
481
  #getCompleteAddress(address: AztecAddress): CompleteAddress | undefined {
535
- const index = this.#addressIndex.get(address.toString());
482
+ const index = this.#completeAddressIndex.get(address.toString());
536
483
  if (typeof index === 'undefined') {
537
484
  return undefined;
538
485
  }
539
486
 
540
- const value = this.#addresses.at(index);
487
+ const value = this.#completeAddresses.at(index);
541
488
  return value ? CompleteAddress.fromBuffer(value) : undefined;
542
489
  }
543
490
 
@@ -546,7 +493,31 @@ export class KVPxeDatabase implements PxeDatabase {
546
493
  }
547
494
 
548
495
  getCompleteAddresses(): Promise<CompleteAddress[]> {
549
- return Promise.resolve(Array.from(this.#addresses).map(v => CompleteAddress.fromBuffer(v)));
496
+ return Promise.resolve(Array.from(this.#completeAddresses).map(v => CompleteAddress.fromBuffer(v)));
497
+ }
498
+
499
+ async addContactAddress(address: AztecAddress): Promise<boolean> {
500
+ if (this.#addressBook.has(address.toString())) {
501
+ return false;
502
+ }
503
+
504
+ await this.#addressBook.add(address.toString());
505
+
506
+ return true;
507
+ }
508
+
509
+ getContactAddresses(): AztecAddress[] {
510
+ return [...this.#addressBook.entries()].map(AztecAddress.fromString);
511
+ }
512
+
513
+ async removeContactAddress(address: AztecAddress): Promise<boolean> {
514
+ if (!this.#addressBook.has(address.toString())) {
515
+ return false;
516
+ }
517
+
518
+ await this.#addressBook.delete(address.toString());
519
+
520
+ return true;
550
521
  }
551
522
 
552
523
  getSynchedBlockNumberForAccount(account: AztecAddress): number | undefined {
@@ -571,25 +542,43 @@ export class KVPxeDatabase implements PxeDatabase {
571
542
  (sum, value) => sum + value.length * Fr.SIZE_IN_BYTES,
572
543
  0,
573
544
  );
574
- const addressesSize = this.#addresses.length * CompleteAddress.SIZE_IN_BYTES;
545
+ const addressesSize = this.#completeAddresses.length * CompleteAddress.SIZE_IN_BYTES;
575
546
  const treeRootsSize = Object.keys(MerkleTreeId).length * Fr.SIZE_IN_BYTES;
576
547
 
577
548
  return incomingNotesSize + outgoingNotesSize + treeRootsSize + authWitsSize + addressesSize;
578
549
  }
579
550
 
580
- async incrementTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise<void> {
581
- const indexes = await this.getTaggingSecretsIndexes(appTaggingSecrets);
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);
582
557
  await this.db.transaction(() => {
583
- indexes.forEach(index => {
584
- const nextIndex = index ? index + 1 : 1;
585
- void this.#taggingSecretIndexes.set(appTaggingSecrets.toString(), nextIndex);
558
+ indexes.forEach((taggingSecretIndex, listIndex) => {
559
+ const nextIndex = taggingSecretIndex + 1;
560
+ void storageMap.set(appTaggingSecrets[listIndex].toString(), nextIndex);
586
561
  });
587
562
  });
588
563
  }
589
564
 
590
- getTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise<number[]> {
591
- return this.db.transaction(() =>
592
- appTaggingSecrets.map(secret => this.#taggingSecretIndexes.get(secret.toString()) ?? 0),
593
- );
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));
594
583
  }
595
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.
@@ -39,7 +39,7 @@ export class OutgoingNoteDao {
39
39
  payload: L1NotePayload,
40
40
  noteInfo: NoteInfo,
41
41
  dataStartIndexForTx: number,
42
- ivpkM: PublicKey,
42
+ ovpkM: PublicKey,
43
43
  ) {
44
44
  const noteHashIndexInTheWholeTree = BigInt(dataStartIndexForTx + noteInfo.noteHashIndex);
45
45
  return new OutgoingNoteDao(
@@ -51,7 +51,7 @@ export class OutgoingNoteDao {
51
51
  noteInfo.nonce,
52
52
  noteInfo.noteHash,
53
53
  noteHashIndexInTheWholeTree,
54
- ivpkM,
54
+ ovpkM,
55
55
  );
56
56
  }
57
57
 
@@ -3,6 +3,7 @@ import {
3
3
  type CompleteAddress,
4
4
  type ContractInstanceWithAddress,
5
5
  type Header,
6
+ type IndexedTaggingSecret,
6
7
  type PublicKey,
7
8
  } from '@aztec/circuits.js';
8
9
  import { type ContractArtifact } from '@aztec/foundation/abi';
@@ -11,7 +12,6 @@ import { type Fr } from '@aztec/foundation/fields';
11
12
 
12
13
  import { type ContractArtifactDatabase } from './contracts/contract_artifact_db.js';
13
14
  import { type ContractInstanceDatabase } from './contracts/contract_instance_db.js';
14
- import { type DeferredNoteDao } from './deferred_note_dao.js';
15
15
  import { type IncomingNoteDao } from './incoming_note_dao.js';
16
16
  import { type OutgoingNoteDao } from './outgoing_note_dao.js';
17
17
 
@@ -89,25 +89,6 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD
89
89
  */
90
90
  addNotes(incomingNotes: IncomingNoteDao[], outgoingNotes: OutgoingNoteDao[], scope?: AztecAddress): Promise<void>;
91
91
 
92
- /**
93
- * Add notes to the database that are intended for us, but we don't yet have the contract.
94
- * @param deferredNotes - An array of deferred notes.
95
- */
96
- addDeferredNotes(deferredNotes: DeferredNoteDao[]): Promise<void>;
97
-
98
- /**
99
- * Get deferred notes for a given contract address.
100
- * @param contractAddress - The contract address to get the deferred notes for.
101
- */
102
- getDeferredNotesByContract(contractAddress: AztecAddress): Promise<DeferredNoteDao[]>;
103
-
104
- /**
105
- * Remove deferred notes for a given contract address.
106
- * @param contractAddress - The contract address to remove the deferred notes for.
107
- * @returns an array of the removed deferred notes
108
- */
109
- removeDeferredNotesByContract(contractAddress: AztecAddress): Promise<DeferredNoteDao[]>;
110
-
111
92
  /**
112
93
  * Remove nullified notes associated with the given account and nullifiers.
113
94
  *
@@ -145,6 +126,26 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD
145
126
  */
146
127
  setHeader(header: Header): Promise<void>;
147
128
 
129
+ /**
130
+ * Adds contact address to the database.
131
+ * @param address - The address to add to the address book.
132
+ * @returns A promise resolving to true if the address was added, false if it already exists.
133
+ */
134
+ addContactAddress(address: AztecAddress): Promise<boolean>;
135
+
136
+ /**
137
+ * Retrieves the list of contact addresses in the address book.
138
+ * @returns An array of Aztec addresses.
139
+ */
140
+ getContactAddresses(): AztecAddress[];
141
+
142
+ /**
143
+ * Removes a contact address from the database.
144
+ * @param address - The address to remove from the address book.
145
+ * @returns A promise resolving to true if the address was removed, false if it does not exist.
146
+ */
147
+ removeContactAddress(address: AztecAddress): Promise<boolean>;
148
+
148
149
  /**
149
150
  * Adds complete address to the database.
150
151
  * @param address - The complete address to add.
@@ -186,7 +187,31 @@ export interface PxeDatabase extends ContractArtifactDatabase, ContractInstanceD
186
187
  */
187
188
  estimateSize(): Promise<number>;
188
189
 
189
- getTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise<number[]>;
190
+ /**
191
+ * Returns the last seen indexes for the provided app siloed tagging secrets or 0 if they've never been seen.
192
+ * @param appTaggingSecrets - The app siloed tagging secrets.
193
+ * @returns The indexes for the provided secrets, 0 if they've never been seen.
194
+ */
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[]>;
190
203
 
191
- incrementTaggingSecretsIndexes(appTaggingSecrets: Fr[]): Promise<void>;
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>;
210
+
211
+ /**
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
214
+ * @param appTaggingSecrets - The app siloed tagging secrets.
215
+ */
216
+ setTaggingSecretsIndexesAsRecipient(indexedTaggingSecrets: IndexedTaggingSecret[]): Promise<void>;
192
217
  }
@@ -5,6 +5,7 @@ import {
5
5
  INITIAL_L2_BLOCK_NUM,
6
6
  PublicKeys,
7
7
  SerializableContractInstance,
8
+ computePoint,
8
9
  } from '@aztec/circuits.js';
9
10
  import { makeHeader } from '@aztec/circuits.js/testing';
10
11
  import { randomInt } from '@aztec/foundation/crypto';
@@ -101,7 +102,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
101
102
 
102
103
  [
103
104
  () => ({ owner: owners[0].address }),
104
- () => notes.filter(note => note.ivpkM.equals(owners[0].publicKeys.masterIncomingViewingPublicKey)),
105
+ () => notes.filter(note => note.addressPoint.equals(computePoint(owners[0].address))),
105
106
  ],
106
107
 
107
108
  [
@@ -123,7 +124,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
123
124
  randomIncomingNoteDao({
124
125
  contractAddress: contractAddresses[i % contractAddresses.length],
125
126
  storageSlot: storageSlots[i % storageSlots.length],
126
- ivpkM: owners[i % owners.length].publicKeys.masterIncomingViewingPublicKey,
127
+ addressPoint: computePoint(owners[i % owners.length].address),
127
128
  index: BigInt(i),
128
129
  }),
129
130
  );
@@ -155,13 +156,11 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
155
156
 
156
157
  // Nullify all notes and use the same filter as other test cases
157
158
  for (const owner of owners) {
158
- const notesToNullify = notes.filter(note =>
159
- note.ivpkM.equals(owner.publicKeys.masterIncomingViewingPublicKey),
160
- );
159
+ const notesToNullify = notes.filter(note => note.addressPoint.equals(computePoint(owner.address)));
161
160
  const nullifiers = notesToNullify.map(note => note.siloedNullifier);
162
- await expect(
163
- database.removeNullifiedNotes(nullifiers, owner.publicKeys.masterIncomingViewingPublicKey),
164
- ).resolves.toEqual(notesToNullify);
161
+ await expect(database.removeNullifiedNotes(nullifiers, computePoint(owner.address))).resolves.toEqual(
162
+ notesToNullify,
163
+ );
165
164
  }
166
165
 
167
166
  await expect(
@@ -172,11 +171,9 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
172
171
  it('skips nullified notes by default or when requesting active', async () => {
173
172
  await database.addNotes(notes, []);
174
173
 
175
- const notesToNullify = notes.filter(note =>
176
- note.ivpkM.equals(owners[0].publicKeys.masterIncomingViewingPublicKey),
177
- );
174
+ const notesToNullify = notes.filter(note => note.addressPoint.equals(computePoint(owners[0].address)));
178
175
  const nullifiers = notesToNullify.map(note => note.siloedNullifier);
179
- await expect(database.removeNullifiedNotes(nullifiers, notesToNullify[0].ivpkM)).resolves.toEqual(
176
+ await expect(database.removeNullifiedNotes(nullifiers, notesToNullify[0].addressPoint)).resolves.toEqual(
180
177
  notesToNullify,
181
178
  );
182
179
 
@@ -190,11 +187,9 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
190
187
  it('returns active and nullified notes when requesting either', async () => {
191
188
  await database.addNotes(notes, []);
192
189
 
193
- const notesToNullify = notes.filter(note =>
194
- note.ivpkM.equals(owners[0].publicKeys.masterIncomingViewingPublicKey),
195
- );
190
+ const notesToNullify = notes.filter(note => note.addressPoint.equals(computePoint(owners[0].address)));
196
191
  const nullifiers = notesToNullify.map(note => note.siloedNullifier);
197
- await expect(database.removeNullifiedNotes(nullifiers, notesToNullify[0].ivpkM)).resolves.toEqual(
192
+ await expect(database.removeNullifiedNotes(nullifiers, notesToNullify[0].addressPoint)).resolves.toEqual(
198
193
  notesToNullify,
199
194
  );
200
195
 
@@ -251,10 +246,7 @@ export function describePxeDatabase(getDatabase: () => PxeDatabase) {
251
246
  ).resolves.toEqual([notes[0]]);
252
247
 
253
248
  await expect(
254
- database.removeNullifiedNotes(
255
- [notes[0].siloedNullifier],
256
- owners[0].publicKeys.masterIncomingViewingPublicKey,
257
- ),
249
+ database.removeNullifiedNotes([notes[0].siloedNullifier], computePoint(owners[0].address)),
258
250
  ).resolves.toEqual([notes[0]]);
259
251
 
260
252
  await expect(
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ export * from './config/index.js';
4
4
 
5
5
  export { Tx, TxHash } from '@aztec/circuit-types';
6
6
 
7
- export { TxRequest, PartialAddress } from '@aztec/circuits.js';
7
+ export { TxRequest } from '@aztec/circuits.js';
8
8
  export * from '@aztec/foundation/fields';
9
9
  export * from '@aztec/foundation/eth-address';
10
10
  export * from '@aztec/foundation/aztec-address';
@@ -424,7 +424,7 @@ export class PrivateKernelResetPrivateInputsBuilder {
424
424
  throw new Error('`needsResetTransientData` must be run before `needsSiloNoteHashes`.');
425
425
  }
426
426
 
427
- const numNoteHashes = this.previousKernel.end.noteHashes.filter(n => !n.contractAddress.isEmpty()).length;
427
+ const numNoteHashes = this.previousKernel.end.noteHashes.filter(n => !n.contractAddress.isZero()).length;
428
428
  const numToSilo = Math.max(0, numNoteHashes - this.numTransientData);
429
429
  this.requestedDimensions.NOTE_HASH_SILOING_AMOUNT = numToSilo;
430
430
 
@@ -436,7 +436,7 @@ export class PrivateKernelResetPrivateInputsBuilder {
436
436
  throw new Error('`needsResetTransientData` must be run before `needsSiloNullifiers`.');
437
437
  }
438
438
 
439
- const numNullifiers = this.previousKernel.end.nullifiers.filter(n => !n.contractAddress.isEmpty()).length;
439
+ const numNullifiers = this.previousKernel.end.nullifiers.filter(n => !n.contractAddress.isZero()).length;
440
440
  const numToSilo = Math.max(0, numNullifiers - this.numTransientData);
441
441
  // Include the first nullifier if there's something to silo.
442
442
  // The reset circuit checks that capped_size must be greater than or equal to all non-empty nullifiers.
@@ -454,7 +454,17 @@ export class PrivateKernelResetPrivateInputsBuilder {
454
454
 
455
455
  const numLogs = this.previousKernel.end.encryptedLogsHashes.filter(l => !l.logHash.randomness.isZero()).length;
456
456
  const numToSilo = Math.max(0, numLogs - this.numTransientData);
457
- this.requestedDimensions.ENCRYPTED_LOG_SILOING_AMOUNT = numToSilo;
457
+ // The reset circuit checks that capped_size must be greater than or equal to all non-empty logs.
458
+ // Since there is no current config with ENCRYPTED_LOG_SILOING_AMOUNT = 0 (only 1+), it defaults to 1,
459
+ // so the circuit fails when we have more than 1 log and require no siloing.
460
+ const numLogsNoSiloing = this.previousKernel.end.encryptedLogsHashes.filter(
461
+ l => !l.logHash.isEmpty() && l.logHash.randomness.isZero(),
462
+ ).length;
463
+ const cappedSize = !numToSilo && numLogsNoSiloing > 1 ? numLogsNoSiloing : numToSilo;
464
+ // NB: This is a little flimsy, and only works because we have either ENCRYPTED_LOG_SILOING_AMOUNT=1 or 8.
465
+ // e.g. if we have 2 logs that need siloing, and 2 that dont, then numLogs = ENCRYPTED_LOG_SILOING_AMOUNT = 2
466
+ // This would fail because the circuit thinks that cappedSize = 2, but we have 4 logs.
467
+ this.requestedDimensions.ENCRYPTED_LOG_SILOING_AMOUNT = cappedSize;
458
468
 
459
469
  return numToSilo > 0;
460
470
  }