@aztec/pxe 0.80.0 → 0.82.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 (86) hide show
  1. package/dest/config/package_info.js +1 -1
  2. package/dest/entrypoints/server/utils.d.ts +15 -7
  3. package/dest/entrypoints/server/utils.d.ts.map +1 -1
  4. package/dest/entrypoints/server/utils.js +17 -9
  5. package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.d.ts +2 -2
  6. package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -0
  7. package/dest/private_kernel/hints/index.d.ts.map +1 -0
  8. package/dest/private_kernel/index.d.ts +3 -0
  9. package/dest/private_kernel/index.d.ts.map +1 -0
  10. package/dest/private_kernel/index.js +2 -0
  11. package/dest/{kernel_prover/kernel_prover.d.ts → private_kernel/private_kernel_execution_prover.d.ts} +13 -14
  12. package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -0
  13. package/dest/{kernel_prover/kernel_prover.js → private_kernel/private_kernel_execution_prover.js} +64 -64
  14. package/dest/{kernel_prover/proving_data_oracle.d.ts → private_kernel/private_kernel_oracle.d.ts} +17 -28
  15. package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -0
  16. package/dest/private_kernel/private_kernel_oracle.js +4 -0
  17. package/dest/{kernel_oracle/index.d.ts → private_kernel/private_kernel_oracle_impl.d.ts} +5 -5
  18. package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -0
  19. package/dest/{kernel_oracle/index.js → private_kernel/private_kernel_oracle_impl.js} +2 -2
  20. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +14 -22
  21. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
  22. package/dest/pxe_oracle_interface/pxe_oracle_interface.js +51 -107
  23. package/dest/pxe_service/pxe_service.d.ts +13 -27
  24. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  25. package/dest/pxe_service/pxe_service.js +213 -241
  26. package/dest/storage/contract_data_provider/contract_data_provider.d.ts +2 -2
  27. package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
  28. package/dest/storage/contract_data_provider/contract_data_provider.js +6 -1
  29. package/dest/storage/contract_data_provider/private_functions_tree.d.ts +2 -2
  30. package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
  31. package/dest/storage/index.d.ts +1 -2
  32. package/dest/storage/index.d.ts.map +1 -1
  33. package/dest/storage/index.js +1 -2
  34. package/dest/storage/metadata.d.ts +2 -0
  35. package/dest/storage/metadata.d.ts.map +1 -0
  36. package/dest/storage/metadata.js +1 -0
  37. package/dest/storage/note_data_provider/note_dao.d.ts +9 -13
  38. package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
  39. package/dest/storage/note_data_provider/note_dao.js +11 -15
  40. package/dest/storage/note_data_provider/note_data_provider.d.ts +2 -2
  41. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
  42. package/dest/storage/note_data_provider/note_data_provider.js +18 -19
  43. package/dest/synchronizer/synchronizer.js +1 -1
  44. package/package.json +15 -15
  45. package/src/config/package_info.ts +1 -1
  46. package/src/entrypoints/server/utils.ts +25 -11
  47. package/src/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.ts +4 -4
  48. package/src/private_kernel/index.ts +2 -0
  49. package/src/{kernel_prover/kernel_prover.ts → private_kernel/private_kernel_execution_prover.ts} +76 -71
  50. package/src/{kernel_prover/proving_data_oracle.ts → private_kernel/private_kernel_oracle.ts} +17 -29
  51. package/src/{kernel_oracle/index.ts → private_kernel/private_kernel_oracle_impl.ts} +6 -5
  52. package/src/pxe_oracle_interface/pxe_oracle_interface.ts +77 -153
  53. package/src/pxe_service/pxe_service.ts +289 -310
  54. package/src/storage/contract_data_provider/contract_data_provider.ts +11 -2
  55. package/src/storage/contract_data_provider/private_functions_tree.ts +2 -2
  56. package/src/storage/index.ts +1 -3
  57. package/src/storage/metadata.ts +1 -0
  58. package/src/storage/note_data_provider/note_dao.ts +9 -18
  59. package/src/storage/note_data_provider/note_data_provider.ts +22 -28
  60. package/src/synchronizer/synchronizer.ts +1 -1
  61. package/dest/kernel_oracle/index.d.ts.map +0 -1
  62. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
  63. package/dest/kernel_prover/hints/index.d.ts.map +0 -1
  64. package/dest/kernel_prover/index.d.ts +0 -3
  65. package/dest/kernel_prover/index.d.ts.map +0 -1
  66. package/dest/kernel_prover/index.js +0 -2
  67. package/dest/kernel_prover/kernel_prover.d.ts.map +0 -1
  68. package/dest/kernel_prover/proving_data_oracle.d.ts.map +0 -1
  69. package/dest/kernel_prover/proving_data_oracle.js +0 -4
  70. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +0 -11
  71. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +0 -1
  72. package/dest/note_decryption_utils/add_public_values_to_payload.js +0 -47
  73. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts +0 -11
  74. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts.map +0 -1
  75. package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.js +0 -20
  76. package/dest/storage/auth_witness_data_provider/index.d.ts +0 -2
  77. package/dest/storage/auth_witness_data_provider/index.d.ts.map +0 -1
  78. package/dest/storage/auth_witness_data_provider/index.js +0 -1
  79. package/src/kernel_prover/index.ts +0 -2
  80. package/src/note_decryption_utils/add_public_values_to_payload.ts +0 -64
  81. package/src/storage/auth_witness_data_provider/auth_witness_data_provider.ts +0 -34
  82. package/src/storage/auth_witness_data_provider/index.ts +0 -1
  83. /package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.js +0 -0
  84. /package/dest/{kernel_prover → private_kernel}/hints/index.d.ts +0 -0
  85. /package/dest/{kernel_prover → private_kernel}/hints/index.js +0 -0
  86. /package/src/{kernel_prover → private_kernel}/hints/index.ts +0 -0
@@ -1,50 +1,39 @@
1
- import {
2
- type L1_TO_L2_MSG_TREE_HEIGHT,
3
- MAX_NOTE_HASHES_PER_TX,
4
- PRIVATE_LOG_SIZE_IN_FIELDS,
5
- PUBLIC_LOG_DATA_SIZE_IN_FIELDS,
6
- } from '@aztec/constants';
1
+ import { type L1_TO_L2_MSG_TREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
7
2
  import { timesParallel } from '@aztec/foundation/collection';
8
3
  import { poseidon2Hash } from '@aztec/foundation/crypto';
9
- import { Fr } from '@aztec/foundation/fields';
4
+ import { Fr, Point } from '@aztec/foundation/fields';
10
5
  import { createLogger } from '@aztec/foundation/log';
11
- import { BufferReader } from '@aztec/foundation/serialize';
12
6
  import type { KeyStore } from '@aztec/key-store';
13
- import { AcirSimulator, type ExecutionDataProvider, type SimulationProvider } from '@aztec/simulator/client';
14
- import { MessageLoadOracleInputs } from '@aztec/simulator/client';
7
+ import {
8
+ AcirSimulator,
9
+ type ExecutionDataProvider,
10
+ MessageLoadOracleInputs,
11
+ type SimulationProvider,
12
+ } from '@aztec/simulator/client';
15
13
  import {
16
14
  type FunctionArtifact,
15
+ type FunctionArtifactWithContractName,
17
16
  FunctionCall,
18
17
  FunctionSelector,
19
18
  FunctionType,
20
- NoteSelector,
21
19
  encodeArguments,
22
20
  getFunctionArtifact,
23
21
  } from '@aztec/stdlib/abi';
24
- import type { AztecAddress } from '@aztec/stdlib/aztec-address';
22
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
25
23
  import type { InBlock, L2Block, L2BlockNumber } from '@aztec/stdlib/block';
26
24
  import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
27
25
  import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
28
26
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
29
27
  import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
30
28
  import { computeAddressSecret, computeTaggingSecretPoint } from '@aztec/stdlib/keys';
31
- import {
32
- IndexedTaggingSecret,
33
- L1NotePayload,
34
- LogWithTxData,
35
- PrivateLog,
36
- PublicLog,
37
- TxScopedL2Log,
38
- } from '@aztec/stdlib/logs';
29
+ import { IndexedTaggingSecret, LogWithTxData, TxScopedL2Log, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
39
30
  import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
40
31
  import { Note, type NoteStatus } from '@aztec/stdlib/note';
41
32
  import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
42
33
  import type { BlockHeader } from '@aztec/stdlib/tx';
43
34
  import { TxHash } from '@aztec/stdlib/tx';
44
35
 
45
- import { getOrderedNoteItems } from '../note_decryption_utils/add_public_values_to_payload.js';
46
36
  import type { AddressDataProvider } from '../storage/address_data_provider/address_data_provider.js';
47
- import type { AuthWitnessDataProvider } from '../storage/auth_witness_data_provider/auth_witness_data_provider.js';
48
37
  import type { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
49
38
  import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
50
39
  import { NoteDao } from '../storage/note_data_provider/note_dao.js';
@@ -67,8 +56,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
67
56
  private syncDataProvider: SyncDataProvider,
68
57
  private taggingDataProvider: TaggingDataProvider,
69
58
  private addressDataProvider: AddressDataProvider,
70
- private authWitnessDataProvider: AuthWitnessDataProvider,
71
- private log = createLogger('pxe:pxe_data_manager'),
59
+ private log = createLogger('pxe:pxe_oracle_interface'),
72
60
  ) {}
73
61
 
74
62
  getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest> {
@@ -94,11 +82,6 @@ export class PXEOracleInterface implements ExecutionDataProvider {
94
82
  return instance;
95
83
  }
96
84
 
97
- async getAuthWitness(messageHash: Fr): Promise<Fr[] | undefined> {
98
- const witness = await this.authWitnessDataProvider.getAuthWitness(messageHash);
99
- return witness;
100
- }
101
-
102
85
  async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus, scopes?: AztecAddress[]) {
103
86
  const noteDaos = await this.noteDataProvider.getNotes({
104
87
  contractAddress,
@@ -118,7 +101,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
118
101
  }));
119
102
  }
120
103
 
121
- async getFunctionArtifact(contractAddress: AztecAddress, selector: FunctionSelector): Promise<FunctionArtifact> {
104
+ async getFunctionArtifact(
105
+ contractAddress: AztecAddress,
106
+ selector: FunctionSelector,
107
+ ): Promise<FunctionArtifactWithContractName> {
122
108
  const artifact = await this.contractDataProvider.getFunctionArtifact(contractAddress, selector);
123
109
  const debug = await this.contractDataProvider.getFunctionDebugMetadata(contractAddress, selector);
124
110
  return {
@@ -130,7 +116,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
130
116
  async getFunctionArtifactByName(
131
117
  contractAddress: AztecAddress,
132
118
  functionName: string,
133
- ): Promise<FunctionArtifact | undefined> {
119
+ ): Promise<FunctionArtifactWithContractName | undefined> {
134
120
  const instance = await this.contractDataProvider.getContractInstance(contractAddress);
135
121
  const artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
136
122
  return artifact && getFunctionArtifact(artifact, functionName);
@@ -161,21 +147,12 @@ export class PXEOracleInterface implements ExecutionDataProvider {
161
147
  }
162
148
 
163
149
  // Only used in public.
164
- public getL1ToL2LeafValue(_leafIndex: bigint): Promise<Fr | undefined> {
150
+ public getL1ToL2MessageHash(_leafIndex: bigint): Promise<Fr | undefined> {
165
151
  throw new Error('Unimplemented in private!');
166
152
  }
167
153
 
168
- /**
169
- * Gets the index of a commitment in the note hash tree.
170
- * @param commitment - The commitment.
171
- * @returns - The index of the commitment. Undefined if it does not exist in the tree.
172
- */
173
- async getCommitmentIndex(commitment: Fr) {
174
- return await this.#findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, commitment);
175
- }
176
-
177
154
  // We need this in public as part of the EXISTS calls - but isn't used in private
178
- public getCommitmentValue(_leafIndex: bigint): Promise<Fr | undefined> {
155
+ public getNoteHash(_leafIndex: bigint): Promise<Fr | undefined> {
179
156
  throw new Error('Unimplemented in private!');
180
157
  }
181
158
 
@@ -185,7 +162,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
185
162
 
186
163
  async #findLeafIndex(blockNumber: L2BlockNumber, treeId: MerkleTreeId, leafValue: Fr): Promise<bigint | undefined> {
187
164
  const [leafIndex] = await this.aztecNode.findLeavesIndexes(blockNumber, treeId, [leafValue]);
188
- return leafIndex;
165
+ return leafIndex?.data;
189
166
  }
190
167
 
191
168
  public async getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[]> {
@@ -236,8 +213,8 @@ export class PXEOracleInterface implements ExecutionDataProvider {
236
213
  return await this.aztecNode.getBlock(blockNumber);
237
214
  }
238
215
 
239
- public async getPublicDataTreeWitness(blockNumber: number, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
240
- return await this.aztecNode.getPublicDataTreeWitness(blockNumber, leafSlot);
216
+ public async getPublicDataWitness(blockNumber: number, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
217
+ return await this.aztecNode.getPublicDataWitness(blockNumber, leafSlot);
241
218
  }
242
219
 
243
220
  public async getPublicStorageAt(blockNumber: number, contract: AztecAddress, slot: Fr): Promise<Fr> {
@@ -470,7 +447,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
470
447
  const recipients = scopes ? scopes : await this.keyStore.getAccounts();
471
448
  // A map of logs going from recipient address to logs. Note that the logs might have been processed before
472
449
  // due to us having a sliding window that "looks back" for logs as well. (We look back as there is no guarantee
473
- // that a logs will be received ordered by a given tax index and that the tags won't be reused).
450
+ // that a logs will be received ordered by a given tag index and that the tags won't be reused).
474
451
  const logsMap = new Map<string, TxScopedL2Log[]>();
475
452
  const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
476
453
  for (const recipient of recipients) {
@@ -516,31 +493,21 @@ export class PXEOracleInterface implements ExecutionDataProvider {
516
493
 
517
494
  logsByTags.forEach((logsByTag, logIndex) => {
518
495
  if (logsByTag.length > 0) {
519
- // Check that public logs have the correct contract address
520
- const checkedLogsbyTag = logsByTag.filter(
521
- l => !l.isFromPublic || PublicLog.fromBuffer(l.logData).contractAddress.equals(contractAddress),
522
- );
523
- if (checkedLogsbyTag.length < logsByTag.length) {
524
- const discarded = logsByTag.filter(
525
- log => checkedLogsbyTag.find(filteredLog => filteredLog.equals(log)) === undefined,
526
- );
527
- this.log.warn(
528
- `Discarded ${
529
- logsByTag.length - checkedLogsbyTag.length
530
- } public logs with mismatched contract address ${contractAddress}:`,
531
- discarded.map(l => PublicLog.fromBuffer(l.logData)),
532
- );
496
+ // Discard public logs
497
+ const filteredLogsByTag = logsByTag.filter(l => !l.isFromPublic);
498
+ if (filteredLogsByTag.length < logsByTag.length) {
499
+ this.log.warn(`Discarded ${logsByTag.filter(l => l.isFromPublic).length} public logs with matching tags`);
533
500
  }
534
501
 
535
502
  // The logs for the given tag exist so we store them for later processing
536
- logsForRecipient.push(...checkedLogsbyTag);
503
+ logsForRecipient.push(...filteredLogsByTag);
537
504
 
538
505
  // We retrieve the indexed tagging secret corresponding to the log as I need that to evaluate whether
539
506
  // a new largest index have been found.
540
507
  const secretCorrespondingToLog = secretsForTheWholeWindow[logIndex];
541
508
  const initialIndex = initialIndexesMap[secretCorrespondingToLog.appTaggingSecret.toString()];
542
509
 
543
- this.log.debug(`Found ${checkedLogsbyTag.length} logs as recipient ${recipient}`, {
510
+ this.log.debug(`Found ${filteredLogsByTag.length} logs as recipient ${recipient}`, {
544
511
  recipient,
545
512
  secret: secretCorrespondingToLog.appTaggingSecret,
546
513
  contractName,
@@ -610,77 +577,36 @@ export class PXEOracleInterface implements ExecutionDataProvider {
610
577
  return logsMap;
611
578
  }
612
579
 
613
- /**
614
- * Decrypts logs tagged for a recipient and returns them.
615
- * @param scopedLogs - The logs to decrypt.
616
- * @param recipient - The recipient of the logs.
617
- * @returns The decrypted notes.
618
- */
619
- async #decryptTaggedLogs(scopedLogs: TxScopedL2Log[], recipient: AztecAddress) {
620
- const recipientCompleteAddress = await this.getCompleteAddress(recipient);
621
- const ivskM = await this.keyStore.getMasterSecretKey(
622
- recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
623
- );
624
- const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
625
-
626
- // Since we could have notes with the same index for different txs, we need
627
- // to keep track of them scoping by txHash
628
- const excludedIndices: Map<string, Set<number>> = new Map();
629
- const decrypted = [];
630
-
631
- for (const scopedLog of scopedLogs) {
632
- const payload = scopedLog.isFromPublic
633
- ? await L1NotePayload.decryptAsIncomingFromPublic(PublicLog.fromBuffer(scopedLog.logData), addressSecret)
634
- : await L1NotePayload.decryptAsIncoming(PrivateLog.fromBuffer(scopedLog.logData), addressSecret);
635
-
636
- if (!payload) {
637
- this.log.verbose('Unable to decrypt log');
638
- continue;
639
- }
640
-
641
- if (!excludedIndices.has(scopedLog.txHash.toString())) {
642
- excludedIndices.set(scopedLog.txHash.toString(), new Set());
643
- }
644
-
645
- const note = await getOrderedNoteItems(this.contractDataProvider, payload);
646
- const plaintext = [payload.storageSlot, payload.noteTypeId.toField(), ...note.items];
647
-
648
- decrypted.push({ plaintext, txHash: scopedLog.txHash, contractAddress: payload.contractAddress });
649
- }
650
-
651
- return decrypted;
652
- }
653
-
654
580
  /**
655
581
  * Processes the tagged logs returned by syncTaggedLogs by decrypting them and storing them in the database.
582
+ * @param contractAddress - The address of the contract that the logs are tagged for.
656
583
  * @param logs - The logs to process.
657
584
  * @param recipient - The recipient of the logs.
658
585
  */
659
586
  public async processTaggedLogs(
587
+ contractAddress: AztecAddress,
660
588
  logs: TxScopedL2Log[],
661
589
  recipient: AztecAddress,
662
590
  simulator?: AcirSimulator,
663
591
  ): Promise<void> {
664
- const decryptedLogs = await this.#decryptTaggedLogs(logs, recipient);
592
+ for (const scopedLog of logs) {
593
+ if (scopedLog.isFromPublic) {
594
+ throw new Error('Attempted to decrypt public log');
595
+ }
665
596
 
666
- // We've produced the full NoteDao, which we'd be able to simply insert into the database. However, this is
667
- // only a temporary measure as we migrate from the PXE-driven discovery into the new contract-driven approach. We
668
- // discard most of the work done up to this point and reconstruct the note plaintext to then hand over to the
669
- // contract for further processing.
670
- for (const decryptedLog of decryptedLogs) {
671
597
  // Log processing requires the note hashes in the tx in which the note was created. We are now assuming that the
672
598
  // note was included in the same block in which the log was delivered - note that partial notes will not work this
673
599
  // way.
674
- const txEffect = await this.aztecNode.getTxEffect(decryptedLog.txHash);
600
+ const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
675
601
  if (!txEffect) {
676
- throw new Error(`Could not find tx effect for tx hash ${decryptedLog.txHash}`);
602
+ throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
677
603
  }
678
604
 
679
605
  // This will trigger calls to the deliverNote oracle
680
606
  await this.callProcessLog(
681
- decryptedLog.contractAddress,
682
- decryptedLog.plaintext,
683
- decryptedLog.txHash,
607
+ contractAddress,
608
+ scopedLog.log.toFields(),
609
+ scopedLog.txHash,
684
610
  txEffect.data.noteHashes,
685
611
  txEffect.data.nullifiers[0],
686
612
  recipient,
@@ -729,28 +655,17 @@ export class PXEOracleInterface implements ExecutionDataProvider {
729
655
 
730
656
  // We store notes by their index in the global note hash tree, which has the convenient side effect of validating
731
657
  // note existence in said tree.
732
- const [uniqueNoteHashTreeIndex] = await this.aztecNode.findLeavesIndexes(
658
+ const [uniqueNoteHashTreeIndexInBlock] = await this.aztecNode.findLeavesIndexes(
733
659
  syncedBlockNumber,
734
660
  MerkleTreeId.NOTE_HASH_TREE,
735
661
  [uniqueNoteHash],
736
662
  );
737
- if (uniqueNoteHashTreeIndex === undefined) {
663
+ if (uniqueNoteHashTreeIndexInBlock === undefined) {
738
664
  throw new Error(
739
665
  `Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present on the tree at block ${syncedBlockNumber} (from tx ${txHash})`,
740
666
  );
741
667
  }
742
668
 
743
- // TODO (#12550): findLeavesIndexes should probably return an InBlock, same as findNullifiersIndexesWithBlock. This
744
- // would save us from having to then query the tx receipt in order to get the block hash and number. Note regardless
745
- // that we're not validating that the note was indeed created in this tx (which would require inspecting the tx
746
- // effects), so maybe what we really want is an InTx.
747
- const txReceipt = await this.aztecNode.getTxReceipt(new TxHash(txHash));
748
- if (txReceipt === undefined) {
749
- throw new Error(`Failed to fetch tx receipt for tx hash ${txHash} when searching for note hashes`);
750
- }
751
-
752
- // TODO(#12549): does it make sense to store the recipient's address point instead of just its address?
753
- const recipientAddressPoint = await recipient.toAddressPoint();
754
669
  const noteDao = new NoteDao(
755
670
  new Note(content),
756
671
  contractAddress,
@@ -759,11 +674,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
759
674
  noteHash,
760
675
  siloedNullifier,
761
676
  new TxHash(txHash),
762
- txReceipt.blockNumber!,
763
- txReceipt.blockHash!.toString(),
764
- uniqueNoteHashTreeIndex,
765
- recipientAddressPoint,
766
- NoteSelector.empty(), // TODO(#12013): remove
677
+ uniqueNoteHashTreeIndexInBlock?.l2BlockNumber,
678
+ uniqueNoteHashTreeIndexInBlock?.l2BlockHash,
679
+ uniqueNoteHashTreeIndexInBlock?.data,
680
+ recipient,
767
681
  );
768
682
 
769
683
  await this.noteDataProvider.addNotes([noteDao], recipient);
@@ -774,13 +688,12 @@ export class PXEOracleInterface implements ExecutionDataProvider {
774
688
  nullifier: noteDao.siloedNullifier.toString(),
775
689
  });
776
690
 
777
- const [nullifierIndex] = await this.aztecNode.findNullifiersIndexesWithBlock(syncedBlockNumber, [siloedNullifier]);
691
+ const [nullifierIndex] = await this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, [
692
+ siloedNullifier,
693
+ ]);
778
694
  if (nullifierIndex !== undefined) {
779
695
  const { data: _, ...blockHashAndNum } = nullifierIndex;
780
- await this.noteDataProvider.removeNullifiedNotes(
781
- [{ data: siloedNullifier, ...blockHashAndNum }],
782
- recipientAddressPoint,
783
- );
696
+ await this.noteDataProvider.removeNullifiedNotes([{ data: siloedNullifier, ...blockHashAndNum }], recipient);
784
697
 
785
698
  this.log.verbose(`Removed just-added note`, {
786
699
  contract: contractAddress,
@@ -806,35 +719,39 @@ export class PXEOracleInterface implements ExecutionDataProvider {
806
719
  );
807
720
  }
808
721
 
809
- const log = logsForTag[0];
722
+ const scopedLog = logsForTag[0];
810
723
 
811
724
  // getLogsByTag doesn't have all of the information that we need (notably note hashes and the first nullifier), so
812
725
  // we need to make a second call to the node for `getTxEffect`.
813
726
  // TODO(#9789): bundle this information in the `getLogsByTag` call.
814
- const txEffect = await this.aztecNode.getTxEffect(log.txHash);
727
+ const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
815
728
  if (txEffect == undefined) {
816
- throw new Error(`Unexpected: failed to retrieve tx effects for tx ${log.txHash} which is known to exist`);
729
+ throw new Error(`Unexpected: failed to retrieve tx effects for tx ${scopedLog.txHash} which is known to exist`);
817
730
  }
818
731
 
819
- const reader = BufferReader.asReader(log.logData);
820
- const logArray = reader.readArray(PUBLIC_LOG_DATA_SIZE_IN_FIELDS, Fr);
821
-
822
732
  // Public logs always take up all available fields by padding with zeroes, and the length of the originally emitted
823
733
  // log is lost. Until this is improved, we simply remove all of the zero elements (which are expected to be at the
824
734
  // end).
825
735
  // TODO(#11636): use the actual log length.
826
- const trimmedLog = logArray.filter(x => !x.isZero());
736
+ const trimmedLog = scopedLog.log.toFields().filter(x => !x.isZero());
827
737
 
828
- return new LogWithTxData(trimmedLog, log.txHash.hash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
738
+ return new LogWithTxData(trimmedLog, scopedLog.txHash.hash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
829
739
  }
830
740
 
741
+ // TODO(#12553): nuke this as part of tackling that issue. This function is no longer unit tested as I had to remove
742
+ // it from pxe_oracle_interface.test.ts when moving decryption to Noir (at that point we could not get a hold of
743
+ // the decrypted note in the test as TS decryption no longer existed).
831
744
  public async removeNullifiedNotes(contractAddress: AztecAddress) {
832
745
  this.log.verbose('Searching for nullifiers of known notes', { contract: contractAddress });
833
746
 
834
747
  for (const recipient of await this.keyStore.getAccounts()) {
835
- const currentNotesForRecipient = await this.noteDataProvider.getNotes({ contractAddress, owner: recipient });
748
+ const currentNotesForRecipient = await this.noteDataProvider.getNotes({ contractAddress, recipient });
836
749
  const nullifiersToCheck = currentNotesForRecipient.map(note => note.siloedNullifier);
837
- const nullifierIndexes = await this.aztecNode.findNullifiersIndexesWithBlock('latest', nullifiersToCheck);
750
+ const nullifierIndexes = await this.aztecNode.findLeavesIndexes(
751
+ 'latest',
752
+ MerkleTreeId.NULLIFIER_TREE,
753
+ nullifiersToCheck,
754
+ );
838
755
 
839
756
  const foundNullifiers = nullifiersToCheck
840
757
  .map((nullifier, i) => {
@@ -844,10 +761,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
844
761
  })
845
762
  .filter(nullifier => nullifier !== undefined) as InBlock<Fr>[];
846
763
 
847
- const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(
848
- foundNullifiers,
849
- await recipient.toAddressPoint(),
850
- );
764
+ const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(foundNullifiers, recipient);
851
765
  nullifiedNotes.forEach(noteDao => {
852
766
  this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
853
767
  contract: noteDao.contractAddress,
@@ -860,7 +774,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
860
774
 
861
775
  async callProcessLog(
862
776
  contractAddress: AztecAddress,
863
- logPlaintext: Fr[],
777
+ logCiphertext: Fr[],
864
778
  txHash: TxHash,
865
779
  noteHashes: Fr[],
866
780
  firstNullifier: Fr,
@@ -885,7 +799,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
885
799
  type: FunctionType.UNCONSTRAINED,
886
800
  isStatic: artifact.isStatic,
887
801
  args: encodeArguments(artifact, [
888
- toBoundedVec(logPlaintext, PRIVATE_LOG_SIZE_IN_FIELDS),
802
+ toBoundedVec(logCiphertext, PRIVATE_LOG_SIZE_IN_FIELDS),
889
803
  txHash.toString(),
890
804
  toBoundedVec(noteHashes, MAX_NOTE_HASHES_PER_TX),
891
805
  firstNullifier,
@@ -917,6 +831,16 @@ export class PXEOracleInterface implements ExecutionDataProvider {
917
831
  copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void> {
918
832
  return this.capsuleDataProvider.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
919
833
  }
834
+
835
+ async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
836
+ // TODO(#12656): return an app-siloed secret
837
+ const recipientCompleteAddress = await this.getCompleteAddress(address);
838
+ const ivskM = await this.keyStore.getMasterSecretKey(
839
+ recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
840
+ );
841
+ const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
842
+ return deriveEcdhSharedSecret(addressSecret, ephPk);
843
+ }
920
844
  }
921
845
 
922
846
  function toBoundedVec(array: Fr[], maxLength: number) {