@aztec/pxe 0.79.0 → 0.81.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 (26) hide show
  1. package/dest/config/index.d.ts.map +1 -1
  2. package/dest/config/index.js +2 -1
  3. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +7 -6
  4. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
  5. package/dest/pxe_oracle_interface/pxe_oracle_interface.js +44 -80
  6. package/dest/pxe_service/pxe_service.d.ts +1 -0
  7. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  8. package/dest/pxe_service/pxe_service.js +135 -100
  9. package/dest/storage/note_data_provider/note_dao.d.ts +9 -13
  10. package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
  11. package/dest/storage/note_data_provider/note_dao.js +11 -15
  12. package/dest/storage/note_data_provider/note_data_provider.d.ts +2 -2
  13. package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
  14. package/dest/storage/note_data_provider/note_data_provider.js +18 -19
  15. package/dest/synchronizer/synchronizer.js +1 -1
  16. package/package.json +15 -15
  17. package/src/config/index.ts +1 -0
  18. package/src/pxe_oracle_interface/pxe_oracle_interface.ts +55 -117
  19. package/src/pxe_service/pxe_service.ts +180 -134
  20. package/src/storage/note_data_provider/note_dao.ts +9 -18
  21. package/src/storage/note_data_provider/note_data_provider.ts +22 -28
  22. package/src/synchronizer/synchronizer.ts +1 -1
  23. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +0 -11
  24. package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +0 -1
  25. package/dest/note_decryption_utils/add_public_values_to_payload.js +0 -47
  26. package/src/note_decryption_utils/add_public_values_to_payload.ts +0 -64
@@ -13,14 +13,14 @@ export class NoteDataProvider {
13
13
  #nullifiedNotesByContract;
14
14
  #nullifiedNotesByStorageSlot;
15
15
  #nullifiedNotesByTxHash;
16
- #nullifiedNotesByAddressPoint;
16
+ #nullifiedNotesByRecipient;
17
17
  #nullifiedNotesByNullifier;
18
18
  #scopes;
19
19
  #notesToScope;
20
20
  #notesByContractAndScope;
21
21
  #notesByStorageSlotAndScope;
22
22
  #notesByTxHashAndScope;
23
- #notesByAddressPointAndScope;
23
+ #notesByRecipientAndScope;
24
24
  constructor(store){
25
25
  this.#store = store;
26
26
  this.#notes = store.openMap('notes');
@@ -31,14 +31,14 @@ export class NoteDataProvider {
31
31
  this.#nullifiedNotesByContract = store.openMultiMap('nullified_notes_by_contract');
32
32
  this.#nullifiedNotesByStorageSlot = store.openMultiMap('nullified_notes_by_storage_slot');
33
33
  this.#nullifiedNotesByTxHash = store.openMultiMap('nullified_notes_by_tx_hash');
34
- this.#nullifiedNotesByAddressPoint = store.openMultiMap('nullified_notes_by_address_point');
34
+ this.#nullifiedNotesByRecipient = store.openMultiMap('nullified_notes_by_recipient');
35
35
  this.#nullifiedNotesByNullifier = store.openMap('nullified_notes_by_nullifier');
36
36
  this.#scopes = store.openMap('scopes');
37
37
  this.#notesToScope = store.openMultiMap('notes_to_scope');
38
38
  this.#notesByContractAndScope = new Map();
39
39
  this.#notesByStorageSlotAndScope = new Map();
40
40
  this.#notesByTxHashAndScope = new Map();
41
- this.#notesByAddressPointAndScope = new Map();
41
+ this.#notesByRecipientAndScope = new Map();
42
42
  }
43
43
  static async create(store) {
44
44
  const pxeDB = new NoteDataProvider(store);
@@ -46,7 +46,7 @@ export class NoteDataProvider {
46
46
  pxeDB.#notesByContractAndScope.set(scope, store.openMultiMap(`${scope}:notes_by_contract`));
47
47
  pxeDB.#notesByStorageSlotAndScope.set(scope, store.openMultiMap(`${scope}:notes_by_storage_slot`));
48
48
  pxeDB.#notesByTxHashAndScope.set(scope, store.openMultiMap(`${scope}:notes_by_tx_hash`));
49
- pxeDB.#notesByAddressPointAndScope.set(scope, store.openMultiMap(`${scope}:notes_by_address_point`));
49
+ pxeDB.#notesByRecipientAndScope.set(scope, store.openMultiMap(`${scope}:notes_by_recipient`));
50
50
  }
51
51
  return pxeDB;
52
52
  }
@@ -59,7 +59,7 @@ export class NoteDataProvider {
59
59
  this.#notesByContractAndScope.set(scopeString, this.#store.openMultiMap(`${scopeString}:notes_by_contract`));
60
60
  this.#notesByStorageSlotAndScope.set(scopeString, this.#store.openMultiMap(`${scopeString}:notes_by_storage_slot`));
61
61
  this.#notesByTxHashAndScope.set(scopeString, this.#store.openMultiMap(`${scopeString}:notes_by_tx_hash`));
62
- this.#notesByAddressPointAndScope.set(scopeString, this.#store.openMultiMap(`${scopeString}:notes_by_address_point`));
62
+ this.#notesByRecipientAndScope.set(scopeString, this.#store.openMultiMap(`${scopeString}:notes_by_recipient`));
63
63
  return true;
64
64
  }
65
65
  async addNotes(notes, scope = AztecAddress.ZERO) {
@@ -79,7 +79,7 @@ export class NoteDataProvider {
79
79
  await this.#notesByContractAndScope.get(scope.toString()).set(dao.contractAddress.toString(), noteIndex);
80
80
  await this.#notesByStorageSlotAndScope.get(scope.toString()).set(dao.storageSlot.toString(), noteIndex);
81
81
  await this.#notesByTxHashAndScope.get(scope.toString()).set(dao.txHash.toString(), noteIndex);
82
- await this.#notesByAddressPointAndScope.get(scope.toString()).set(dao.addressPoint.toString(), noteIndex);
82
+ await this.#notesByRecipientAndScope.get(scope.toString()).set(dao.recipient.toString(), noteIndex);
83
83
  }
84
84
  });
85
85
  }
@@ -95,7 +95,7 @@ export class NoteDataProvider {
95
95
  await this.#nullifierToNoteId.delete(noteDao.siloedNullifier.toString());
96
96
  const scopes = await toArray(this.#scopes.keysAsync());
97
97
  for (const scope of scopes){
98
- await this.#notesByAddressPointAndScope.get(scope).deleteValue(noteDao.addressPoint.toString(), noteIndex);
98
+ await this.#notesByRecipientAndScope.get(scope).deleteValue(noteDao.recipient.toString(), noteIndex);
99
99
  await this.#notesByTxHashAndScope.get(scope).deleteValue(noteDao.txHash.toString(), noteIndex);
100
100
  await this.#notesByContractAndScope.get(scope).deleteValue(noteDao.contractAddress.toString(), noteIndex);
101
101
  await this.#notesByStorageSlotAndScope.get(scope).deleteValue(noteDao.storageSlot.toString(), noteIndex);
@@ -123,14 +123,14 @@ export class NoteDataProvider {
123
123
  let scopes = await toArray(this.#nullifiedNotesToScope.getValuesAsync(noteIndex)) ?? [];
124
124
  if (scopes.length === 0) {
125
125
  scopes = [
126
- new AztecAddress(dao.addressPoint.x).toString()
126
+ dao.recipient.toString()
127
127
  ];
128
128
  }
129
129
  for (const scope of scopes){
130
130
  await this.#notesByContractAndScope.get(scope.toString()).set(dao.contractAddress.toString(), noteIndex);
131
131
  await this.#notesByStorageSlotAndScope.get(scope.toString()).set(dao.storageSlot.toString(), noteIndex);
132
132
  await this.#notesByTxHashAndScope.get(scope.toString()).set(dao.txHash.toString(), noteIndex);
133
- await this.#notesByAddressPointAndScope.get(scope.toString()).set(dao.addressPoint.toString(), noteIndex);
133
+ await this.#notesByRecipientAndScope.get(scope.toString()).set(dao.recipient.toString(), noteIndex);
134
134
  await this.#notesToScope.set(noteIndex, scope);
135
135
  }
136
136
  await this.#nullifiedNotes.delete(noteIndex);
@@ -139,13 +139,12 @@ export class NoteDataProvider {
139
139
  await this.#nullifiedNotesByContract.deleteValue(dao.contractAddress.toString(), noteIndex);
140
140
  await this.#nullifiedNotesByStorageSlot.deleteValue(dao.storageSlot.toString(), noteIndex);
141
141
  await this.#nullifiedNotesByTxHash.deleteValue(dao.txHash.toString(), noteIndex);
142
- await this.#nullifiedNotesByAddressPoint.deleteValue(dao.addressPoint.toString(), noteIndex);
142
+ await this.#nullifiedNotesByRecipient.deleteValue(dao.recipient.toString(), noteIndex);
143
143
  await this.#nullifiedNotesByNullifier.delete(dao.siloedNullifier.toString());
144
144
  }
145
145
  });
146
146
  }
147
147
  async getNotes(filter) {
148
- const publicKey = filter.owner ? await filter.owner.toAddressPoint() : undefined;
149
148
  filter.status = filter.status ?? NoteStatus.ACTIVE;
150
149
  const candidateNoteSources = [];
151
150
  filter.scopes ??= (await toArray(this.#scopes.keysAsync())).map((addressString)=>AztecAddress.fromString(addressString));
@@ -155,7 +154,7 @@ export class NoteDataProvider {
155
154
  if (!await this.#scopes.hasAsync(formattedScopeString)) {
156
155
  throw new Error('Trying to get incoming notes of an scope that is not in the PXE database');
157
156
  }
158
- activeNoteIdsPerScope.push(publicKey ? await toArray(this.#notesByAddressPointAndScope.get(formattedScopeString).getValuesAsync(publicKey.toString())) : filter.txHash ? await toArray(this.#notesByTxHashAndScope.get(formattedScopeString).getValuesAsync(filter.txHash.toString())) : filter.contractAddress ? await toArray(this.#notesByContractAndScope.get(formattedScopeString).getValuesAsync(filter.contractAddress.toString())) : filter.storageSlot ? await toArray(this.#notesByStorageSlotAndScope.get(formattedScopeString).getValuesAsync(filter.storageSlot.toString())) : await toArray(this.#notesByAddressPointAndScope.get(formattedScopeString).valuesAsync()));
157
+ activeNoteIdsPerScope.push(filter.recipient ? await toArray(this.#notesByRecipientAndScope.get(formattedScopeString).getValuesAsync(filter.recipient.toString())) : filter.txHash ? await toArray(this.#notesByTxHashAndScope.get(formattedScopeString).getValuesAsync(filter.txHash.toString())) : filter.contractAddress ? await toArray(this.#notesByContractAndScope.get(formattedScopeString).getValuesAsync(filter.contractAddress.toString())) : filter.storageSlot ? await toArray(this.#notesByStorageSlotAndScope.get(formattedScopeString).getValuesAsync(filter.storageSlot.toString())) : await toArray(this.#notesByRecipientAndScope.get(formattedScopeString).valuesAsync()));
159
158
  }
160
159
  candidateNoteSources.push({
161
160
  ids: new Set(activeNoteIdsPerScope.flat()),
@@ -163,7 +162,7 @@ export class NoteDataProvider {
163
162
  });
164
163
  if (filter.status == NoteStatus.ACTIVE_OR_NULLIFIED) {
165
164
  candidateNoteSources.push({
166
- ids: publicKey ? await toArray(this.#nullifiedNotesByAddressPoint.getValuesAsync(publicKey.toString())) : filter.txHash ? await toArray(this.#nullifiedNotesByTxHash.getValuesAsync(filter.txHash.toString())) : filter.contractAddress ? await toArray(this.#nullifiedNotesByContract.getValuesAsync(filter.contractAddress.toString())) : filter.storageSlot ? await toArray(this.#nullifiedNotesByStorageSlot.getValuesAsync(filter.storageSlot.toString())) : await toArray(this.#nullifiedNotes.keysAsync()),
165
+ ids: filter.recipient ? await toArray(this.#nullifiedNotesByRecipient.getValuesAsync(filter.recipient.toString())) : filter.txHash ? await toArray(this.#nullifiedNotesByTxHash.getValuesAsync(filter.txHash.toString())) : filter.contractAddress ? await toArray(this.#nullifiedNotesByContract.getValuesAsync(filter.contractAddress.toString())) : filter.storageSlot ? await toArray(this.#nullifiedNotesByStorageSlot.getValuesAsync(filter.storageSlot.toString())) : await toArray(this.#nullifiedNotes.keysAsync()),
167
166
  notes: this.#nullifiedNotes
168
167
  });
169
168
  }
@@ -184,7 +183,7 @@ export class NoteDataProvider {
184
183
  if (filter.storageSlot && !note.storageSlot.equals(filter.storageSlot)) {
185
184
  continue;
186
185
  }
187
- if (publicKey && !note.addressPoint.equals(publicKey)) {
186
+ if (filter.recipient && !note.recipient.equals(filter.recipient)) {
188
187
  continue;
189
188
  }
190
189
  if (filter.siloedNullifier && !note.siloedNullifier.equals(filter.siloedNullifier)) {
@@ -195,7 +194,7 @@ export class NoteDataProvider {
195
194
  }
196
195
  return result;
197
196
  }
198
- removeNullifiedNotes(nullifiers, accountAddressPoint) {
197
+ removeNullifiedNotes(nullifiers, recipient) {
199
198
  if (nullifiers.length === 0) {
200
199
  return Promise.resolve([]);
201
200
  }
@@ -213,7 +212,7 @@ export class NoteDataProvider {
213
212
  }
214
213
  const noteScopes = await toArray(this.#notesToScope.getValuesAsync(noteIndex)) ?? [];
215
214
  const note = NoteDao.fromBuffer(noteBuffer);
216
- if (!note.addressPoint.equals(accountAddressPoint)) {
215
+ if (!note.recipient.equals(recipient)) {
217
216
  continue;
218
217
  }
219
218
  nullifiedNotes.push(note);
@@ -221,7 +220,7 @@ export class NoteDataProvider {
221
220
  await this.#notesToScope.delete(noteIndex);
222
221
  const scopes = await toArray(this.#scopes.keysAsync());
223
222
  for (const scope of scopes){
224
- await this.#notesByAddressPointAndScope.get(scope).deleteValue(accountAddressPoint.toString(), noteIndex);
223
+ await this.#notesByRecipientAndScope.get(scope).deleteValue(note.recipient.toString(), noteIndex);
225
224
  await this.#notesByTxHashAndScope.get(scope).deleteValue(note.txHash.toString(), noteIndex);
226
225
  await this.#notesByContractAndScope.get(scope).deleteValue(note.contractAddress.toString(), noteIndex);
227
226
  await this.#notesByStorageSlotAndScope.get(scope).deleteValue(note.storageSlot.toString(), noteIndex);
@@ -236,7 +235,7 @@ export class NoteDataProvider {
236
235
  await this.#nullifiedNotesByContract.set(note.contractAddress.toString(), noteIndex);
237
236
  await this.#nullifiedNotesByStorageSlot.set(note.storageSlot.toString(), noteIndex);
238
237
  await this.#nullifiedNotesByTxHash.set(note.txHash.toString(), noteIndex);
239
- await this.#nullifiedNotesByAddressPoint.set(note.addressPoint.toString(), noteIndex);
238
+ await this.#nullifiedNotesByRecipient.set(note.recipient.toString(), noteIndex);
240
239
  await this.#nullifiedNotesByNullifier.set(nullifier.toString(), noteIndex);
241
240
  await this.#nullifierToNoteId.delete(nullifier.toString());
242
241
  }
@@ -36,7 +36,7 @@ import { L2BlockStream } from '@aztec/stdlib/block';
36
36
  switch(event.type){
37
37
  case 'blocks-added':
38
38
  {
39
- const lastBlock = event.blocks.at(-1);
39
+ const lastBlock = event.blocks.at(-1).block;
40
40
  this.log.verbose(`Updated pxe last block to ${lastBlock.number}`, {
41
41
  blockHash: lastBlock.hash(),
42
42
  archive: lastBlock.archive.root.toString(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/pxe",
3
- "version": "0.79.0",
3
+ "version": "0.81.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": "./dest/entrypoints/server/index.js",
@@ -59,19 +59,19 @@
59
59
  ]
60
60
  },
61
61
  "dependencies": {
62
- "@aztec/bb-prover": "0.79.0",
63
- "@aztec/bb.js": "0.79.0",
64
- "@aztec/builder": "0.79.0",
65
- "@aztec/constants": "0.79.0",
66
- "@aztec/ethereum": "0.79.0",
67
- "@aztec/foundation": "0.79.0",
68
- "@aztec/key-store": "0.79.0",
69
- "@aztec/kv-store": "0.79.0",
70
- "@aztec/noir-protocol-circuits-types": "0.79.0",
71
- "@aztec/noir-types": "0.79.0",
72
- "@aztec/protocol-contracts": "0.79.0",
73
- "@aztec/simulator": "0.79.0",
74
- "@aztec/stdlib": "0.79.0",
62
+ "@aztec/bb-prover": "0.81.0",
63
+ "@aztec/bb.js": "0.81.0",
64
+ "@aztec/builder": "0.81.0",
65
+ "@aztec/constants": "0.81.0",
66
+ "@aztec/ethereum": "0.81.0",
67
+ "@aztec/foundation": "0.81.0",
68
+ "@aztec/key-store": "0.81.0",
69
+ "@aztec/kv-store": "0.81.0",
70
+ "@aztec/noir-protocol-circuits-types": "0.81.0",
71
+ "@aztec/noir-types": "0.81.0",
72
+ "@aztec/protocol-contracts": "0.81.0",
73
+ "@aztec/simulator": "0.81.0",
74
+ "@aztec/stdlib": "0.81.0",
75
75
  "@msgpack/msgpack": "^3.0.0-beta2",
76
76
  "koa": "^2.14.2",
77
77
  "koa-router": "^12.0.0",
@@ -81,7 +81,7 @@
81
81
  "viem": "2.23.7"
82
82
  },
83
83
  "devDependencies": {
84
- "@aztec/noir-contracts.js": "0.79.0",
84
+ "@aztec/noir-contracts.js": "0.81.0",
85
85
  "@jest/globals": "^29.5.0",
86
86
  "@types/jest": "^29.5.0",
87
87
  "@types/lodash.omit": "^4.5.7",
@@ -107,6 +107,7 @@ export const allPxeConfigMappings: ConfigMappingsType<CliPXEOptions & PXEService
107
107
  parseEnv: (val: string) => parseBooleanEnv(val) || !!process.env.NETWORK,
108
108
  description: 'Enable real proofs',
109
109
  isBoolean: true,
110
+ defaultValue: true,
110
111
  },
111
112
  };
112
113
 
@@ -1,48 +1,37 @@
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,
17
15
  FunctionCall,
18
16
  FunctionSelector,
19
17
  FunctionType,
20
- NoteSelector,
21
18
  encodeArguments,
22
19
  getFunctionArtifact,
23
20
  } from '@aztec/stdlib/abi';
24
- import type { AztecAddress } from '@aztec/stdlib/aztec-address';
21
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
25
22
  import type { InBlock, L2Block, L2BlockNumber } from '@aztec/stdlib/block';
26
23
  import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
27
24
  import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
28
25
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
29
26
  import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
30
27
  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';
28
+ import { IndexedTaggingSecret, LogWithTxData, TxScopedL2Log, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
39
29
  import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
40
30
  import { Note, type NoteStatus } from '@aztec/stdlib/note';
41
31
  import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
42
32
  import type { BlockHeader } from '@aztec/stdlib/tx';
43
33
  import { TxHash } from '@aztec/stdlib/tx';
44
34
 
45
- import { getOrderedNoteItems } from '../note_decryption_utils/add_public_values_to_payload.js';
46
35
  import type { AddressDataProvider } from '../storage/address_data_provider/address_data_provider.js';
47
36
  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';
@@ -470,7 +459,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
470
459
  const recipients = scopes ? scopes : await this.keyStore.getAccounts();
471
460
  // A map of logs going from recipient address to logs. Note that the logs might have been processed before
472
461
  // 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).
462
+ // that a logs will be received ordered by a given tag index and that the tags won't be reused).
474
463
  const logsMap = new Map<string, TxScopedL2Log[]>();
475
464
  const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
476
465
  for (const recipient of recipients) {
@@ -516,31 +505,21 @@ export class PXEOracleInterface implements ExecutionDataProvider {
516
505
 
517
506
  logsByTags.forEach((logsByTag, logIndex) => {
518
507
  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
- );
508
+ // Discard public logs
509
+ const filteredLogsByTag = logsByTag.filter(l => !l.isFromPublic);
510
+ if (filteredLogsByTag.length < logsByTag.length) {
511
+ this.log.warn(`Discarded ${logsByTag.filter(l => l.isFromPublic).length} public logs with matching tags`);
533
512
  }
534
513
 
535
514
  // The logs for the given tag exist so we store them for later processing
536
- logsForRecipient.push(...checkedLogsbyTag);
515
+ logsForRecipient.push(...filteredLogsByTag);
537
516
 
538
517
  // We retrieve the indexed tagging secret corresponding to the log as I need that to evaluate whether
539
518
  // a new largest index have been found.
540
519
  const secretCorrespondingToLog = secretsForTheWholeWindow[logIndex];
541
520
  const initialIndex = initialIndexesMap[secretCorrespondingToLog.appTaggingSecret.toString()];
542
521
 
543
- this.log.debug(`Found ${checkedLogsbyTag.length} logs as recipient ${recipient}`, {
522
+ this.log.debug(`Found ${filteredLogsByTag.length} logs as recipient ${recipient}`, {
544
523
  recipient,
545
524
  secret: secretCorrespondingToLog.appTaggingSecret,
546
525
  contractName,
@@ -610,77 +589,36 @@ export class PXEOracleInterface implements ExecutionDataProvider {
610
589
  return logsMap;
611
590
  }
612
591
 
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
592
  /**
655
593
  * Processes the tagged logs returned by syncTaggedLogs by decrypting them and storing them in the database.
594
+ * @param contractAddress - The address of the contract that the logs are tagged for.
656
595
  * @param logs - The logs to process.
657
596
  * @param recipient - The recipient of the logs.
658
597
  */
659
598
  public async processTaggedLogs(
599
+ contractAddress: AztecAddress,
660
600
  logs: TxScopedL2Log[],
661
601
  recipient: AztecAddress,
662
602
  simulator?: AcirSimulator,
663
603
  ): Promise<void> {
664
- const decryptedLogs = await this.#decryptTaggedLogs(logs, recipient);
604
+ for (const scopedLog of logs) {
605
+ if (scopedLog.isFromPublic) {
606
+ throw new Error('Attempted to decrypt public log');
607
+ }
665
608
 
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
609
  // Log processing requires the note hashes in the tx in which the note was created. We are now assuming that the
672
610
  // note was included in the same block in which the log was delivered - note that partial notes will not work this
673
611
  // way.
674
- const txEffect = await this.aztecNode.getTxEffect(decryptedLog.txHash);
612
+ const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
675
613
  if (!txEffect) {
676
- throw new Error(`Could not find tx effect for tx hash ${decryptedLog.txHash}`);
614
+ throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
677
615
  }
678
616
 
679
617
  // This will trigger calls to the deliverNote oracle
680
618
  await this.callProcessLog(
681
- decryptedLog.contractAddress,
682
- decryptedLog.plaintext,
683
- decryptedLog.txHash,
619
+ contractAddress,
620
+ scopedLog.log.toFields(),
621
+ scopedLog.txHash,
684
622
  txEffect.data.noteHashes,
685
623
  txEffect.data.nullifiers[0],
686
624
  recipient,
@@ -718,10 +656,9 @@ export class PXEOracleInterface implements ExecutionDataProvider {
718
656
  // Note that while this technically results in historical queries, we perform it at the latest locally synced block
719
657
  // number which *should* be recent enough to be available, even for non-archive nodes.
720
658
  const syncedBlockNumber = (await this.syncDataProvider.getBlockNumber())!;
721
- // TODO (#12559): handle undefined syncedBlockNumber
722
- // if (syncedBlockNumber === undefined) {
723
- // throw new Error(`Attempted to deliver a note with an unsynchronized PXE - this should never happen`);
724
- //}
659
+ if (syncedBlockNumber === undefined) {
660
+ throw new Error(`Attempted to deliver a note with an unsynchronized PXE - this should never happen`);
661
+ }
725
662
 
726
663
  // By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
727
664
  // of other contracts, which would constitute a security breach.
@@ -750,8 +687,6 @@ export class PXEOracleInterface implements ExecutionDataProvider {
750
687
  throw new Error(`Failed to fetch tx receipt for tx hash ${txHash} when searching for note hashes`);
751
688
  }
752
689
 
753
- // TODO(#12549): does it make sense to store the recipient's address point instead of just its address?
754
- const recipientAddressPoint = await recipient.toAddressPoint();
755
690
  const noteDao = new NoteDao(
756
691
  new Note(content),
757
692
  contractAddress,
@@ -763,8 +698,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
763
698
  txReceipt.blockNumber!,
764
699
  txReceipt.blockHash!.toString(),
765
700
  uniqueNoteHashTreeIndex,
766
- recipientAddressPoint,
767
- NoteSelector.empty(), // TODO(#12013): remove
701
+ recipient,
768
702
  );
769
703
 
770
704
  await this.noteDataProvider.addNotes([noteDao], recipient);
@@ -778,10 +712,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
778
712
  const [nullifierIndex] = await this.aztecNode.findNullifiersIndexesWithBlock(syncedBlockNumber, [siloedNullifier]);
779
713
  if (nullifierIndex !== undefined) {
780
714
  const { data: _, ...blockHashAndNum } = nullifierIndex;
781
- await this.noteDataProvider.removeNullifiedNotes(
782
- [{ data: siloedNullifier, ...blockHashAndNum }],
783
- recipientAddressPoint,
784
- );
715
+ await this.noteDataProvider.removeNullifiedNotes([{ data: siloedNullifier, ...blockHashAndNum }], recipient);
785
716
 
786
717
  this.log.verbose(`Removed just-added note`, {
787
718
  contract: contractAddress,
@@ -807,33 +738,33 @@ export class PXEOracleInterface implements ExecutionDataProvider {
807
738
  );
808
739
  }
809
740
 
810
- const log = logsForTag[0];
741
+ const scopedLog = logsForTag[0];
811
742
 
812
743
  // getLogsByTag doesn't have all of the information that we need (notably note hashes and the first nullifier), so
813
744
  // we need to make a second call to the node for `getTxEffect`.
814
745
  // TODO(#9789): bundle this information in the `getLogsByTag` call.
815
- const txEffect = await this.aztecNode.getTxEffect(log.txHash);
746
+ const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
816
747
  if (txEffect == undefined) {
817
- throw new Error(`Unexpected: failed to retrieve tx effects for tx ${log.txHash} which is known to exist`);
748
+ throw new Error(`Unexpected: failed to retrieve tx effects for tx ${scopedLog.txHash} which is known to exist`);
818
749
  }
819
750
 
820
- const reader = BufferReader.asReader(log.logData);
821
- const logArray = reader.readArray(PUBLIC_LOG_DATA_SIZE_IN_FIELDS, Fr);
822
-
823
751
  // Public logs always take up all available fields by padding with zeroes, and the length of the originally emitted
824
752
  // log is lost. Until this is improved, we simply remove all of the zero elements (which are expected to be at the
825
753
  // end).
826
754
  // TODO(#11636): use the actual log length.
827
- const trimmedLog = logArray.filter(x => !x.isZero());
755
+ const trimmedLog = scopedLog.log.toFields().filter(x => !x.isZero());
828
756
 
829
- return new LogWithTxData(trimmedLog, log.txHash.hash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
757
+ return new LogWithTxData(trimmedLog, scopedLog.txHash.hash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
830
758
  }
831
759
 
760
+ // TODO(#12553): nuke this as part of tackling that issue. This function is no longer unit tested as I had to remove
761
+ // it from pxe_oracle_interface.test.ts when moving decryption to Noir (at that point we could not get a hold of
762
+ // the decrypted note in the test as TS decryption no longer existed).
832
763
  public async removeNullifiedNotes(contractAddress: AztecAddress) {
833
764
  this.log.verbose('Searching for nullifiers of known notes', { contract: contractAddress });
834
765
 
835
766
  for (const recipient of await this.keyStore.getAccounts()) {
836
- const currentNotesForRecipient = await this.noteDataProvider.getNotes({ contractAddress, owner: recipient });
767
+ const currentNotesForRecipient = await this.noteDataProvider.getNotes({ contractAddress, recipient });
837
768
  const nullifiersToCheck = currentNotesForRecipient.map(note => note.siloedNullifier);
838
769
  const nullifierIndexes = await this.aztecNode.findNullifiersIndexesWithBlock('latest', nullifiersToCheck);
839
770
 
@@ -845,10 +776,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
845
776
  })
846
777
  .filter(nullifier => nullifier !== undefined) as InBlock<Fr>[];
847
778
 
848
- const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(
849
- foundNullifiers,
850
- await recipient.toAddressPoint(),
851
- );
779
+ const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(foundNullifiers, recipient);
852
780
  nullifiedNotes.forEach(noteDao => {
853
781
  this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
854
782
  contract: noteDao.contractAddress,
@@ -861,7 +789,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
861
789
 
862
790
  async callProcessLog(
863
791
  contractAddress: AztecAddress,
864
- logPlaintext: Fr[],
792
+ logCiphertext: Fr[],
865
793
  txHash: TxHash,
866
794
  noteHashes: Fr[],
867
795
  firstNullifier: Fr,
@@ -886,7 +814,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
886
814
  type: FunctionType.UNCONSTRAINED,
887
815
  isStatic: artifact.isStatic,
888
816
  args: encodeArguments(artifact, [
889
- toBoundedVec(logPlaintext, PRIVATE_LOG_SIZE_IN_FIELDS),
817
+ toBoundedVec(logCiphertext, PRIVATE_LOG_SIZE_IN_FIELDS),
890
818
  txHash.toString(),
891
819
  toBoundedVec(noteHashes, MAX_NOTE_HASHES_PER_TX),
892
820
  firstNullifier,
@@ -918,6 +846,16 @@ export class PXEOracleInterface implements ExecutionDataProvider {
918
846
  copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void> {
919
847
  return this.capsuleDataProvider.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
920
848
  }
849
+
850
+ async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
851
+ // TODO(#12656): return an app-siloed secret
852
+ const recipientCompleteAddress = await this.getCompleteAddress(address);
853
+ const ivskM = await this.keyStore.getMasterSecretKey(
854
+ recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
855
+ );
856
+ const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
857
+ return deriveEcdhSharedSecret(addressSecret, ephPk);
858
+ }
921
859
  }
922
860
 
923
861
  function toBoundedVec(array: Fr[], maxLength: number) {