@aztec/pxe 3.0.0-nightly.20251214 → 3.0.0-nightly.20251217

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 (121) hide show
  1. package/dest/block_synchronizer/block_synchronizer.d.ts +39 -0
  2. package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -0
  3. package/dest/{synchronizer/synchronizer.js → block_synchronizer/block_synchronizer.js} +22 -17
  4. package/dest/block_synchronizer/index.d.ts +2 -0
  5. package/dest/block_synchronizer/index.d.ts.map +1 -0
  6. package/dest/block_synchronizer/index.js +1 -0
  7. package/dest/config/index.d.ts +4 -4
  8. package/dest/config/index.d.ts.map +1 -1
  9. package/dest/contract_function_simulator/contract_function_simulator.d.ts +6 -4
  10. package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
  11. package/dest/contract_function_simulator/contract_function_simulator.js +7 -6
  12. package/dest/contract_function_simulator/execution_data_provider.d.ts +6 -26
  13. package/dest/contract_function_simulator/execution_data_provider.d.ts.map +1 -1
  14. package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +1 -1
  15. package/dest/contract_function_simulator/execution_tagging_index_cache.js +1 -1
  16. package/dest/contract_function_simulator/oracle/interfaces.d.ts +2 -2
  17. package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
  18. package/dest/contract_function_simulator/oracle/oracle.d.ts +1 -1
  19. package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
  20. package/dest/contract_function_simulator/oracle/oracle.js +3 -3
  21. package/dest/contract_function_simulator/oracle/private_execution.d.ts +2 -2
  22. package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
  23. package/dest/contract_function_simulator/oracle/private_execution.js +0 -1
  24. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +2 -3
  25. package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
  26. package/dest/contract_function_simulator/oracle/private_execution_oracle.js +8 -4
  27. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +4 -3
  28. package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
  29. package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +8 -7
  30. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts +9 -20
  31. package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -1
  32. package/dest/contract_function_simulator/pxe_oracle_interface.js +41 -106
  33. package/dest/debug/pxe_debug_utils.d.ts +30 -0
  34. package/dest/debug/pxe_debug_utils.d.ts.map +1 -0
  35. package/dest/debug/pxe_debug_utils.js +37 -0
  36. package/dest/events/private_event_filter_validator.d.ts +4 -4
  37. package/dest/events/private_event_filter_validator.d.ts.map +1 -1
  38. package/dest/events/private_event_filter_validator.js +4 -4
  39. package/dest/pxe.d.ts +19 -28
  40. package/dest/pxe.d.ts.map +1 -1
  41. package/dest/pxe.js +70 -86
  42. package/dest/storage/anchor_block_data_provider/anchor_block_data_provider.d.ts +9 -0
  43. package/dest/storage/anchor_block_data_provider/anchor_block_data_provider.d.ts.map +1 -0
  44. package/dest/storage/{sync_data_provider/sync_data_provider.js → anchor_block_data_provider/anchor_block_data_provider.js} +2 -9
  45. package/dest/storage/anchor_block_data_provider/index.d.ts +2 -0
  46. package/dest/storage/anchor_block_data_provider/index.d.ts.map +1 -0
  47. package/dest/storage/anchor_block_data_provider/index.js +1 -0
  48. package/dest/storage/contract_data_provider/contract_data_provider.d.ts +3 -2
  49. package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
  50. package/dest/storage/contract_data_provider/contract_data_provider.js +21 -1
  51. package/dest/storage/index.d.ts +2 -2
  52. package/dest/storage/index.d.ts.map +1 -1
  53. package/dest/storage/index.js +1 -1
  54. package/dest/storage/tagging_data_provider/index.d.ts +3 -2
  55. package/dest/storage/tagging_data_provider/index.d.ts.map +1 -1
  56. package/dest/storage/tagging_data_provider/index.js +2 -1
  57. package/dest/storage/tagging_data_provider/recipient_tagging_data_provider.d.ts +31 -0
  58. package/dest/storage/tagging_data_provider/recipient_tagging_data_provider.d.ts.map +1 -0
  59. package/dest/storage/tagging_data_provider/recipient_tagging_data_provider.js +65 -0
  60. package/dest/storage/tagging_data_provider/sender_tagging_data_provider.d.ts +67 -0
  61. package/dest/storage/tagging_data_provider/sender_tagging_data_provider.d.ts.map +1 -0
  62. package/dest/storage/tagging_data_provider/sender_tagging_data_provider.js +196 -0
  63. package/dest/tagging/constants.d.ts +1 -1
  64. package/dest/tagging/constants.d.ts.map +1 -1
  65. package/dest/tagging/constants.js +1 -0
  66. package/dest/tagging/sync/sync_sender_tagging_indexes.d.ts +21 -0
  67. package/dest/tagging/sync/sync_sender_tagging_indexes.d.ts.map +1 -0
  68. package/dest/tagging/sync/sync_sender_tagging_indexes.js +89 -0
  69. package/dest/tagging/sync/utils/get_status_change_of_pending.d.ts +11 -0
  70. package/dest/tagging/sync/utils/get_status_change_of_pending.d.ts.map +1 -0
  71. package/dest/tagging/sync/utils/get_status_change_of_pending.js +32 -0
  72. package/dest/tagging/sync/utils/load_and_store_new_tagging_indexes.d.ts +18 -0
  73. package/dest/tagging/sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -0
  74. package/dest/tagging/sync/utils/load_and_store_new_tagging_indexes.js +57 -0
  75. package/dest/tagging/utils.d.ts +2 -2
  76. package/dest/tagging/utils.d.ts.map +1 -1
  77. package/dest/tagging/utils.js +3 -2
  78. package/package.json +16 -16
  79. package/src/{synchronizer/synchronizer.ts → block_synchronizer/block_synchronizer.ts} +21 -17
  80. package/src/block_synchronizer/index.ts +1 -0
  81. package/src/config/index.ts +3 -3
  82. package/src/contract_function_simulator/contract_function_simulator.ts +21 -5
  83. package/src/contract_function_simulator/execution_data_provider.ts +7 -28
  84. package/src/contract_function_simulator/execution_tagging_index_cache.ts +1 -1
  85. package/src/contract_function_simulator/oracle/interfaces.ts +1 -1
  86. package/src/contract_function_simulator/oracle/oracle.ts +3 -3
  87. package/src/contract_function_simulator/oracle/private_execution.ts +1 -3
  88. package/src/contract_function_simulator/oracle/private_execution_oracle.ts +11 -5
  89. package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +6 -6
  90. package/src/contract_function_simulator/pxe_oracle_interface.ts +41 -114
  91. package/src/debug/pxe_debug_utils.ts +47 -0
  92. package/src/events/private_event_filter_validator.ts +3 -3
  93. package/src/pxe.ts +74 -96
  94. package/src/storage/{sync_data_provider/sync_data_provider.ts → anchor_block_data_provider/anchor_block_data_provider.ts} +2 -12
  95. package/src/storage/anchor_block_data_provider/index.ts +1 -0
  96. package/src/storage/contract_data_provider/contract_data_provider.ts +27 -0
  97. package/src/storage/index.ts +1 -1
  98. package/src/storage/tagging_data_provider/index.ts +2 -1
  99. package/src/storage/tagging_data_provider/recipient_tagging_data_provider.ts +86 -0
  100. package/src/storage/tagging_data_provider/sender_tagging_data_provider.ts +244 -0
  101. package/src/tagging/constants.ts +1 -0
  102. package/src/tagging/sync/sync_sender_tagging_indexes.ts +112 -0
  103. package/src/tagging/sync/utils/get_status_change_of_pending.ts +44 -0
  104. package/src/tagging/sync/utils/load_and_store_new_tagging_indexes.ts +74 -0
  105. package/src/tagging/utils.ts +3 -2
  106. package/dest/storage/sync_data_provider/index.d.ts +0 -2
  107. package/dest/storage/sync_data_provider/index.d.ts.map +0 -1
  108. package/dest/storage/sync_data_provider/index.js +0 -1
  109. package/dest/storage/sync_data_provider/sync_data_provider.d.ts +0 -11
  110. package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +0 -1
  111. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +0 -40
  112. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +0 -1
  113. package/dest/storage/tagging_data_provider/tagging_data_provider.js +0 -89
  114. package/dest/synchronizer/index.d.ts +0 -2
  115. package/dest/synchronizer/index.d.ts.map +0 -1
  116. package/dest/synchronizer/index.js +0 -1
  117. package/dest/synchronizer/synchronizer.d.ts +0 -36
  118. package/dest/synchronizer/synchronizer.d.ts.map +0 -1
  119. package/src/storage/sync_data_provider/index.ts +0 -1
  120. package/src/storage/tagging_data_provider/tagging_data_provider.ts +0 -120
  121. package/src/synchronizer/index.ts +0 -1
package/src/pxe.ts CHANGED
@@ -12,10 +12,8 @@ import {
12
12
  type ContractArtifact,
13
13
  EventSelector,
14
14
  FunctionCall,
15
- FunctionSelector,
16
15
  FunctionType,
17
16
  decodeFunctionSignature,
18
- encodeArguments,
19
17
  } from '@aztec/stdlib/abi';
20
18
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
21
19
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -35,8 +33,6 @@ import type {
35
33
  PrivateKernelExecutionProofOutput,
36
34
  PrivateKernelTailCircuitPublicInputs,
37
35
  } from '@aztec/stdlib/kernel';
38
- import type { NotesFilter } from '@aztec/stdlib/note';
39
- import { NoteDao } from '@aztec/stdlib/note';
40
36
  import {
41
37
  type ContractOverrides,
42
38
  type InTx,
@@ -56,6 +52,7 @@ import {
56
52
 
57
53
  import { inspect } from 'util';
58
54
 
55
+ import { BlockSynchronizer } from './block_synchronizer/index.js';
59
56
  import type { PXEConfig } from './config/index.js';
60
57
  import {
61
58
  ContractFunctionSimulator,
@@ -65,6 +62,7 @@ import { readCurrentClassId } from './contract_function_simulator/oracle/private
65
62
  import { ProxiedContractDataProviderFactory } from './contract_function_simulator/proxied_contract_data_source.js';
66
63
  import { ProxiedNodeFactory } from './contract_function_simulator/proxied_node.js';
67
64
  import { PXEOracleInterface } from './contract_function_simulator/pxe_oracle_interface.js';
65
+ import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
68
66
  import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
69
67
  import { PrivateEventFilterValidator } from './events/private_event_filter_validator.js';
70
68
  import {
@@ -73,13 +71,13 @@ import {
73
71
  } from './private_kernel/private_kernel_execution_prover.js';
74
72
  import { PrivateKernelOracleImpl } from './private_kernel/private_kernel_oracle_impl.js';
75
73
  import { AddressDataProvider } from './storage/address_data_provider/address_data_provider.js';
74
+ import { AnchorBlockDataProvider } from './storage/anchor_block_data_provider/anchor_block_data_provider.js';
76
75
  import { CapsuleDataProvider } from './storage/capsule_data_provider/capsule_data_provider.js';
77
76
  import { ContractDataProvider } from './storage/contract_data_provider/contract_data_provider.js';
78
77
  import { NoteDataProvider } from './storage/note_data_provider/note_data_provider.js';
79
78
  import { PrivateEventDataProvider } from './storage/private_event_data_provider/private_event_data_provider.js';
80
- import { SyncDataProvider } from './storage/sync_data_provider/sync_data_provider.js';
81
- import { TaggingDataProvider } from './storage/tagging_data_provider/tagging_data_provider.js';
82
- import { Synchronizer } from './synchronizer/index.js';
79
+ import { RecipientTaggingDataProvider } from './storage/tagging_data_provider/recipient_tagging_data_provider.js';
80
+ import { SenderTaggingDataProvider } from './storage/tagging_data_provider/sender_tagging_data_provider.js';
83
81
 
84
82
  export type PackedPrivateEvent = InTx & {
85
83
  packedEvent: Fr[];
@@ -93,13 +91,14 @@ export type PackedPrivateEvent = InTx & {
93
91
  export class PXE {
94
92
  private constructor(
95
93
  private node: AztecNode,
96
- private synchronizer: Synchronizer,
94
+ private blockStateSynchronizer: BlockSynchronizer,
97
95
  private keyStore: KeyStore,
98
96
  private contractDataProvider: ContractDataProvider,
99
97
  private noteDataProvider: NoteDataProvider,
100
98
  private capsuleDataProvider: CapsuleDataProvider,
101
- private syncDataProvider: SyncDataProvider,
102
- private taggingDataProvider: TaggingDataProvider,
99
+ private anchorBlockDataProvider: AnchorBlockDataProvider,
100
+ private senderTaggingDataProvider: SenderTaggingDataProvider,
101
+ private recipientTaggingDataProvider: RecipientTaggingDataProvider,
103
102
  private addressDataProvider: AddressDataProvider,
104
103
  private privateEventDataProvider: PrivateEventDataProvider,
105
104
  private simulator: CircuitSimulator,
@@ -108,6 +107,7 @@ export class PXE {
108
107
  private protocolContractsProvider: ProtocolContractsProvider,
109
108
  private log: Logger,
110
109
  private jobQueue: SerialQueue,
110
+ public debug: PXEDebugUtils,
111
111
  ) {}
112
112
 
113
113
  /**
@@ -136,21 +136,24 @@ export class PXE {
136
136
  const privateEventDataProvider = new PrivateEventDataProvider(store);
137
137
  const contractDataProvider = new ContractDataProvider(store);
138
138
  const noteDataProvider = await NoteDataProvider.create(store);
139
- const syncDataProvider = new SyncDataProvider(store);
140
- const taggingDataProvider = new TaggingDataProvider(store);
139
+ const anchorBlockDataProvider = new AnchorBlockDataProvider(store);
140
+ const senderTaggingDataProvider = new SenderTaggingDataProvider(store);
141
+ const recipientTaggingDataProvider = new RecipientTaggingDataProvider(store);
141
142
  const capsuleDataProvider = new CapsuleDataProvider(store);
142
143
  const keyStore = new KeyStore(store);
143
144
  const tipsStore = new L2TipsKVStore(store, 'pxe');
144
- const synchronizer = new Synchronizer(
145
+ const synchronizer = new BlockSynchronizer(
145
146
  node,
146
- syncDataProvider,
147
+ anchorBlockDataProvider,
147
148
  noteDataProvider,
148
- taggingDataProvider,
149
+ recipientTaggingDataProvider,
149
150
  tipsStore,
150
151
  config,
151
152
  loggerOrSuffix,
152
153
  );
153
154
 
155
+ const debugUtils = new PXEDebugUtils(contractDataProvider, noteDataProvider);
156
+
154
157
  const jobQueue = new SerialQueue();
155
158
 
156
159
  const pxe = new PXE(
@@ -160,8 +163,9 @@ export class PXE {
160
163
  contractDataProvider,
161
164
  noteDataProvider,
162
165
  capsuleDataProvider,
163
- syncDataProvider,
164
- taggingDataProvider,
166
+ anchorBlockDataProvider,
167
+ senderTaggingDataProvider,
168
+ recipientTaggingDataProvider,
165
169
  addressDataProvider,
166
170
  privateEventDataProvider,
167
171
  simulator,
@@ -170,8 +174,11 @@ export class PXE {
170
174
  protocolContractsProvider,
171
175
  log,
172
176
  jobQueue,
177
+ debugUtils,
173
178
  );
174
179
 
180
+ debugUtils.setPXE(pxe);
181
+
175
182
  pxe.jobQueue.start();
176
183
 
177
184
  await pxe.#registerProtocolContracts();
@@ -189,8 +196,9 @@ export class PXE {
189
196
  ProxiedContractDataProviderFactory.create(this.contractDataProvider, overrides?.contracts),
190
197
  this.noteDataProvider,
191
198
  this.capsuleDataProvider,
192
- this.syncDataProvider,
193
- this.taggingDataProvider,
199
+ this.anchorBlockDataProvider,
200
+ this.senderTaggingDataProvider,
201
+ this.recipientTaggingDataProvider,
194
202
  this.addressDataProvider,
195
203
  this.privateEventDataProvider,
196
204
  this.log,
@@ -254,31 +262,6 @@ export class PXE {
254
262
  return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
255
263
  }
256
264
 
257
- async #getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall> {
258
- const contract = await this.contractDataProvider.getContract(to);
259
- if (!contract) {
260
- throw new Error(
261
- `Unknown contract ${to}: add it to PXE by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/resources/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
262
- );
263
- }
264
-
265
- const functionDao = contract.functions.find(f => f.name === functionName);
266
- if (!functionDao) {
267
- throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
268
- }
269
-
270
- return {
271
- name: functionDao.name,
272
- args: encodeArguments(functionDao, args),
273
- selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
274
- type: functionDao.functionType,
275
- to,
276
- hideMsgSender: false,
277
- isStatic: functionDao.isStatic,
278
- returnTypes: functionDao.returnTypes,
279
- };
280
- }
281
-
282
265
  // Executes the entrypoint private function, as well as all nested private
283
266
  // functions that might arise.
284
267
  async #executePrivate(
@@ -289,11 +272,14 @@ export class PXE {
289
272
  const { origin: contractAddress, functionSelector } = txRequest;
290
273
 
291
274
  try {
275
+ const anchorBlockHeader = await this.anchorBlockDataProvider.getBlockHeader();
276
+
292
277
  const result = await contractFunctionSimulator.run(
293
278
  txRequest,
294
279
  contractAddress,
295
280
  functionSelector,
296
281
  undefined,
282
+ anchorBlockHeader,
297
283
  // The sender for tags is set by contracts, typically by an account
298
284
  // contract entrypoint
299
285
  undefined, // senderForTags
@@ -325,7 +311,8 @@ export class PXE {
325
311
  scopes?: AztecAddress[],
326
312
  ) {
327
313
  try {
328
- return contractFunctionSimulator.runUtility(call, authWitnesses ?? [], scopes);
314
+ const anchorBlockHeader = await this.anchorBlockDataProvider.getBlockHeader();
315
+ return contractFunctionSimulator.runUtility(call, authWitnesses ?? [], anchorBlockHeader, scopes);
329
316
  } catch (err) {
330
317
  if (err instanceof SimulationError) {
331
318
  await enrichSimulationError(err, this.contractDataProvider, this.log);
@@ -486,50 +473,52 @@ export class PXE {
486
473
  }
487
474
 
488
475
  /**
489
- * Registers a user contact in PXE.
476
+ * Registers a sender in this PXE.
490
477
  *
491
- * Once a new contact is registered, the PXE will be able to receive notes tagged from this contact.
492
- * Will do nothing if the account is already registered.
478
+ * After registering a new sender, the PXE will sync private logs that are tagged with this sender's address.
479
+ * Will do nothing if the address is already registered.
493
480
  *
494
- * @param address - Address of the user to add to the address book
495
- * @returns The address address of the account.
481
+ * @param sender - Address of the sender to register.
482
+ * @returns The address of the sender.
483
+ * TODO: It's strange that we return the address here and I (benesjan) think we should drop the return value.
496
484
  */
497
- public async registerSender(address: AztecAddress): Promise<AztecAddress> {
485
+ public async registerSender(sender: AztecAddress): Promise<AztecAddress> {
498
486
  const accounts = await this.keyStore.getAccounts();
499
- if (accounts.includes(address)) {
500
- this.log.info(`Sender:\n "${address.toString()}"\n already registered.`);
501
- return address;
487
+ if (accounts.includes(sender)) {
488
+ this.log.info(`Sender:\n "${sender.toString()}"\n already registered.`);
489
+ return sender;
502
490
  }
503
491
 
504
- const wasAdded = await this.taggingDataProvider.addSenderAddress(address);
492
+ const wasAdded = await this.recipientTaggingDataProvider.addSenderAddress(sender);
505
493
 
506
494
  if (wasAdded) {
507
- this.log.info(`Added sender:\n ${address.toString()}`);
495
+ this.log.info(`Added sender:\n ${sender.toString()}`);
508
496
  } else {
509
- this.log.info(`Sender:\n "${address.toString()}"\n already registered.`);
497
+ this.log.info(`Sender:\n "${sender.toString()}"\n already registered.`);
510
498
  }
511
499
 
512
- return address;
500
+ return sender;
513
501
  }
514
502
 
515
503
  /**
516
- * Retrieves the addresses stored as senders on this PXE.
517
- * @returns An array of the senders on this PXE.
504
+ * Retrieves senders registered in this PXE.
505
+ * @returns Senders registered in this PXE.
518
506
  */
519
507
  public getSenders(): Promise<AztecAddress[]> {
520
- return this.taggingDataProvider.getSenderAddresses();
508
+ return this.recipientTaggingDataProvider.getSenderAddresses();
521
509
  }
522
510
 
523
511
  /**
524
- * Removes a sender in the address book.
512
+ * Removes a sender registered in this PXE.
513
+ * @param sender - The address of the sender to remove.
525
514
  */
526
- public async removeSender(address: AztecAddress): Promise<void> {
527
- const wasRemoved = await this.taggingDataProvider.removeSenderAddress(address);
515
+ public async removeSender(sender: AztecAddress): Promise<void> {
516
+ const wasRemoved = await this.recipientTaggingDataProvider.removeSenderAddress(sender);
528
517
 
529
518
  if (wasRemoved) {
530
- this.log.info(`Removed sender:\n ${address.toString()}`);
519
+ this.log.info(`Removed sender:\n ${sender.toString()}`);
531
520
  } else {
532
- this.log.info(`Sender:\n "${address.toString()}"\n not in address book.`);
521
+ this.log.info(`Sender:\n "${sender.toString()}"\n not registered in PXE.`);
533
522
  }
534
523
  }
535
524
 
@@ -623,9 +612,9 @@ export class PXE {
623
612
  throw new Error(`Instance not found when updating a contract. Contract address: ${contractAddress}.`);
624
613
  }
625
614
  const contractClass = await getContractClassFromArtifact(artifact);
626
- await this.synchronizer.sync();
615
+ await this.blockStateSynchronizer.sync();
627
616
 
628
- const header = await this.syncDataProvider.getBlockHeader();
617
+ const header = await this.anchorBlockDataProvider.getBlockHeader();
629
618
 
630
619
  const currentClassId = await readCurrentClassId(
631
620
  contractAddress,
@@ -659,25 +648,6 @@ export class PXE {
659
648
  return this.contractDataProvider.getContractsAddresses();
660
649
  }
661
650
 
662
- /**
663
- * A debugging utility to get notes based on the provided filter.
664
- *
665
- * Note that this should not be used in production code because the structure of notes is considered to be
666
- * an implementation detail of contracts. This is only meant to be used for debugging purposes. If you need to obtain
667
- * note-related information in production code, please implement a custom utility function on your contract and call
668
- * that function instead (e.g. `get_balance(owner: AztecAddress) -> u128` utility function on a Token contract).
669
- *
670
- * @param filter - The filter to apply to the notes.
671
- * @returns The requested notes.
672
- */
673
- public async getNotes(filter: NotesFilter): Promise<NoteDao[]> {
674
- // We need to manually trigger private state sync to have a guarantee that all the notes are available.
675
- const call = await this.#getFunctionCall('sync_private_state', [], filter.contractAddress);
676
- await this.simulateUtility(call);
677
-
678
- return this.noteDataProvider.getNotes(filter);
679
- }
680
-
681
651
  /**
682
652
  * Proves the private portion of a simulated transaction, ready to send to the network
683
653
  * (where validators prove the public portion).
@@ -695,7 +665,7 @@ export class PXE {
695
665
  const totalTimer = new Timer();
696
666
  try {
697
667
  const syncTimer = new Timer();
698
- await this.synchronizer.sync();
668
+ await this.blockStateSynchronizer.sync();
699
669
  const syncTime = syncTimer.ms();
700
670
  const contractFunctionSimulator = this.#getSimulatorForTx();
701
671
  privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest);
@@ -735,14 +705,22 @@ export class PXE {
735
705
  nodeRPCCalls: contractFunctionSimulator?.getStats().nodeRPCCalls,
736
706
  });
737
707
 
708
+ // While not strictly necessary to store tagging cache contents in the DB since we sync tagging indexes from
709
+ // chain before sending new logs, the sync can only see logs already included in blocks. If we send another
710
+ // transaction before this one is included in a block from this PXE, and that transaction contains a log with
711
+ // a tag derived from the same secret, we would reuse the tag and the transactions would be linked. Hence
712
+ // storing the tags here prevents linkage of txs sent from the same PXE.
738
713
  const preTagsUsedInTheTx = privateExecutionResult.entrypoint.preTags;
739
714
  if (preTagsUsedInTheTx.length > 0) {
740
- await this.taggingDataProvider.setLastUsedIndexesAsSender(preTagsUsedInTheTx);
741
- this.log.debug(`Stored used pre tags as sender for the tx`, {
715
+ // TODO(benesjan): The following is an expensive operation. Figure out a way to avoid it.
716
+ const txHash = (await txProvingResult.toTx()).txHash;
717
+
718
+ await this.senderTaggingDataProvider.storePendingIndexes(preTagsUsedInTheTx, txHash);
719
+ this.log.debug(`Stored used pre-tags as sender for the tx`, {
742
720
  preTagsUsedInTheTx,
743
721
  });
744
722
  } else {
745
- this.log.debug(`No pre tags used in the tx`);
723
+ this.log.debug(`No pre-tags used in the tx`);
746
724
  }
747
725
 
748
726
  return txProvingResult;
@@ -783,7 +761,7 @@ export class PXE {
783
761
  txInfo,
784
762
  );
785
763
  const syncTimer = new Timer();
786
- await this.synchronizer.sync();
764
+ await this.blockStateSynchronizer.sync();
787
765
  const syncTime = syncTimer.ms();
788
766
 
789
767
  const contractFunctionSimulator = this.#getSimulatorForTx();
@@ -883,7 +861,7 @@ export class PXE {
883
861
  txInfo,
884
862
  );
885
863
  const syncTimer = new Timer();
886
- await this.synchronizer.sync();
864
+ await this.blockStateSynchronizer.sync();
887
865
  const syncTime = syncTimer.ms();
888
866
 
889
867
  const contractFunctionSimulator = this.#getSimulatorForTx(overrides);
@@ -1012,7 +990,7 @@ export class PXE {
1012
990
  try {
1013
991
  const totalTimer = new Timer();
1014
992
  const syncTimer = new Timer();
1015
- await this.synchronizer.sync();
993
+ await this.blockStateSynchronizer.sync();
1016
994
  const syncTime = syncTimer.ms();
1017
995
  const functionTimer = new Timer();
1018
996
  const contractFunctionSimulator = this.#getSimulatorForTx();
@@ -1062,10 +1040,10 @@ export class PXE {
1062
1040
  filter: PrivateEventFilter,
1063
1041
  ): Promise<PackedPrivateEvent[]> {
1064
1042
  // We need to manually trigger private state sync to have a guarantee that all the events are available.
1065
- const call = await this.#getFunctionCall('sync_private_state', [], filter.contractAddress);
1043
+ const call = await this.contractDataProvider.getFunctionCall('sync_private_state', [], filter.contractAddress);
1066
1044
  await this.simulateUtility(call);
1067
1045
 
1068
- const sanitizedFilter = await new PrivateEventFilterValidator(this.syncDataProvider).validate(filter);
1046
+ const sanitizedFilter = await new PrivateEventFilterValidator(this.anchorBlockDataProvider).validate(filter);
1069
1047
 
1070
1048
  this.log.error(
1071
1049
  `Getting private events for ${sanitizedFilter.contractAddress.toString()} from ${sanitizedFilter.fromBlock} to ${sanitizedFilter.toBlock}`,
@@ -1,8 +1,7 @@
1
- import type { BlockNumber } from '@aztec/foundation/branded-types';
2
1
  import type { AztecAsyncKVStore, AztecAsyncSingleton } from '@aztec/kv-store';
3
2
  import { BlockHeader } from '@aztec/stdlib/tx';
4
3
 
5
- export class SyncDataProvider {
4
+ export class AnchorBlockDataProvider {
6
5
  #store: AztecAsyncKVStore;
7
6
  #synchronizedHeader: AztecAsyncSingleton<Buffer>;
8
7
 
@@ -15,19 +14,10 @@ export class SyncDataProvider {
15
14
  await this.#synchronizedHeader.set(header.toBuffer());
16
15
  }
17
16
 
18
- async getBlockNumber(): Promise<BlockNumber> {
19
- const headerBuffer = await this.#synchronizedHeader.getAsync();
20
- if (!headerBuffer) {
21
- throw new Error(`Trying to get block number with a not-yet-synchronized PXE - this should never happen`);
22
- }
23
-
24
- return BlockHeader.fromBuffer(headerBuffer).globalVariables.blockNumber;
25
- }
26
-
27
17
  async getBlockHeader(): Promise<BlockHeader> {
28
18
  const headerBuffer = await this.#synchronizedHeader.getAsync();
29
19
  if (!headerBuffer) {
30
- throw new Error(`Header not set`);
20
+ throw new Error(`Trying to get block header with a not-yet-synchronized PXE - this should never happen`);
31
21
  }
32
22
 
33
23
  return BlockHeader.fromBuffer(headerBuffer);
@@ -0,0 +1 @@
1
+ export { AnchorBlockDataProvider } from './anchor_block_data_provider.js';
@@ -8,11 +8,13 @@ import {
8
8
  type FunctionAbi,
9
9
  type FunctionArtifact,
10
10
  type FunctionArtifactWithContractName,
11
+ FunctionCall,
11
12
  type FunctionDebugMetadata,
12
13
  FunctionSelector,
13
14
  FunctionType,
14
15
  contractArtifactFromBuffer,
15
16
  contractArtifactToBuffer,
17
+ encodeArguments,
16
18
  getFunctionDebugMetadata,
17
19
  } from '@aztec/stdlib/abi';
18
20
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -274,4 +276,29 @@ export class ContractDataProvider {
274
276
  }
275
277
  }
276
278
  }
279
+
280
+ public async getFunctionCall(functionName: string, args: any[], to: AztecAddress): Promise<FunctionCall> {
281
+ const contract = await this.getContract(to);
282
+ if (!contract) {
283
+ throw new Error(
284
+ `Unknown contract ${to}: add it to PXE by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/resources/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
285
+ );
286
+ }
287
+
288
+ const functionDao = contract.functions.find(f => f.name === functionName);
289
+ if (!functionDao) {
290
+ throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
291
+ }
292
+
293
+ return {
294
+ name: functionDao.name,
295
+ args: encodeArguments(functionDao, args),
296
+ selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
297
+ type: functionDao.functionType,
298
+ to,
299
+ hideMsgSender: false,
300
+ isStatic: functionDao.isStatic,
301
+ returnTypes: functionDao.returnTypes,
302
+ };
303
+ }
277
304
  }
@@ -2,7 +2,7 @@ export * from './address_data_provider/index.js';
2
2
  export * from './capsule_data_provider/index.js';
3
3
  export * from './contract_data_provider/index.js';
4
4
  export * from './note_data_provider/index.js';
5
- export * from './sync_data_provider/index.js';
5
+ export * from './anchor_block_data_provider/index.js';
6
6
  export * from './tagging_data_provider/index.js';
7
7
  export * from './metadata.js';
8
8
  export * from './private_event_data_provider/private_event_data_provider.js';
@@ -1 +1,2 @@
1
- export { TaggingDataProvider } from './tagging_data_provider.js';
1
+ export { SenderTaggingDataProvider } from './sender_tagging_data_provider.js';
2
+ export { RecipientTaggingDataProvider } from './recipient_tagging_data_provider.js';
@@ -0,0 +1,86 @@
1
+ import { toArray } from '@aztec/foundation/iterable';
2
+ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
3
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
4
+ import type { DirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs';
5
+
6
+ /**
7
+ * Data provider of tagging data used when syncing the logs as a recipient. The sender counterpart of this class is
8
+ * called SenderTaggingDataProvider. We have the providers separate for the sender and recipient because
9
+ * the algorithms are completely disjoint and there is not data reuse between the 2.
10
+ */
11
+ export class RecipientTaggingDataProvider {
12
+ #store: AztecAsyncKVStore;
13
+ #addressBook: AztecAsyncMap<string, true>;
14
+
15
+ // Stores the last used index for each directional app tagging secret.
16
+ #lastUsedIndexes: AztecAsyncMap<string, number>;
17
+
18
+ constructor(store: AztecAsyncKVStore) {
19
+ this.#store = store;
20
+
21
+ this.#addressBook = this.#store.openMap('address_book');
22
+ this.#lastUsedIndexes = this.#store.openMap('last_used_indexes');
23
+ }
24
+
25
+ /**
26
+ * Sets the last used indexes when looking for logs.
27
+ * @param preTags - The pre-tags containing the directional app tagging secrets and the indexes that are to be
28
+ * updated in the db.
29
+ * @throws If any two pre-tags contain the same directional app tagging secret
30
+ */
31
+ setLastUsedIndexes(preTags: PreTag[]) {
32
+ // Non-unique secrets would indicate a bug in the caller function.
33
+ const secretsSet = new Set(preTags.map(preTag => preTag.secret.toString()));
34
+ if (secretsSet.size !== preTags.length) {
35
+ throw new Error(`Duplicate secrets found when setting last used indexes`);
36
+ }
37
+
38
+ return Promise.all(preTags.map(({ secret, index }) => this.#lastUsedIndexes.set(secret.toString(), index)));
39
+ }
40
+
41
+ /**
42
+ * Returns the last used indexes when looking for logs.
43
+ * @param secrets - The directional app tagging secrets to obtain the indexes for.
44
+ * @returns The last used indexes for the given directional app tagging secrets, or undefined if have never yet found
45
+ * a log for a given secret.
46
+ */
47
+ getLastUsedIndexes(secrets: DirectionalAppTaggingSecret[]): Promise<(number | undefined)[]> {
48
+ return Promise.all(secrets.map(secret => this.#lastUsedIndexes.getAsync(secret.toString())));
49
+ }
50
+
51
+ resetNoteSyncData(): Promise<void> {
52
+ return this.#store.transactionAsync(async () => {
53
+ const keys = await toArray(this.#lastUsedIndexes.keysAsync());
54
+ await Promise.all(keys.map(secret => this.#lastUsedIndexes.delete(secret)));
55
+ });
56
+ }
57
+
58
+ // It might seem weird that the following 3 methods are in RecipientTaggingDataProvider and not
59
+ // in SenderTaggingDataProvider but that is because this data is truly only used for the purposes of syncing logs
60
+ // as a recipient. When sending logs or when syncing sender tagging indexes we only receive directional app tagging
61
+ // secret from Aztec.nr via an oracle and we don't need to access sender addresses.
62
+
63
+ async addSenderAddress(address: AztecAddress): Promise<boolean> {
64
+ if (await this.#addressBook.hasAsync(address.toString())) {
65
+ return false;
66
+ }
67
+
68
+ await this.#addressBook.set(address.toString(), true);
69
+
70
+ return true;
71
+ }
72
+
73
+ async getSenderAddresses(): Promise<AztecAddress[]> {
74
+ return (await toArray(this.#addressBook.keysAsync())).map(AztecAddress.fromString);
75
+ }
76
+
77
+ async removeSenderAddress(address: AztecAddress): Promise<boolean> {
78
+ if (!(await this.#addressBook.hasAsync(address.toString()))) {
79
+ return false;
80
+ }
81
+
82
+ await this.#addressBook.delete(address.toString());
83
+
84
+ return true;
85
+ }
86
+ }