@aztec/pxe 0.82.3 → 0.83.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 (37) hide show
  1. package/dest/config/package_info.js +1 -1
  2. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +15 -20
  3. package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
  4. package/dest/pxe_oracle_interface/pxe_oracle_interface.js +56 -103
  5. package/dest/pxe_service/pxe_service.d.ts +3 -2
  6. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  7. package/dest/pxe_service/pxe_service.js +26 -56
  8. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +9 -0
  9. package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -1
  10. package/dest/storage/capsule_data_provider/capsule_data_provider.js +24 -0
  11. package/dest/storage/index.d.ts +1 -0
  12. package/dest/storage/index.d.ts.map +1 -1
  13. package/dest/storage/index.js +1 -0
  14. package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts +37 -0
  15. package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts.map +1 -0
  16. package/dest/storage/private_event_data_provider/private_event_data_provider.js +106 -0
  17. package/dest/storage/sync_data_provider/sync_data_provider.d.ts +1 -1
  18. package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +1 -1
  19. package/dest/storage/sync_data_provider/sync_data_provider.js +1 -1
  20. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +4 -4
  21. package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +1 -1
  22. package/dest/storage/tagging_data_provider/tagging_data_provider.js +29 -12
  23. package/dest/synchronizer/synchronizer.d.ts +4 -6
  24. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  25. package/dest/synchronizer/synchronizer.js +11 -15
  26. package/dest/test/pxe_test_suite.js +1 -1
  27. package/package.json +15 -15
  28. package/src/config/package_info.ts +1 -1
  29. package/src/pxe_oracle_interface/pxe_oracle_interface.ts +113 -143
  30. package/src/pxe_service/pxe_service.ts +35 -76
  31. package/src/storage/capsule_data_provider/capsule_data_provider.ts +26 -0
  32. package/src/storage/index.ts +1 -0
  33. package/src/storage/private_event_data_provider/private_event_data_provider.ts +137 -0
  34. package/src/storage/sync_data_provider/sync_data_provider.ts +2 -2
  35. package/src/storage/tagging_data_provider/tagging_data_provider.ts +44 -13
  36. package/src/synchronizer/synchronizer.ts +11 -14
  37. package/src/test/pxe_test_suite.ts +1 -1
@@ -89,7 +89,7 @@ export const pxeTestSuite = (testName, pxeSetup)=>{
89
89
  });
90
90
  it('successfully gets node info', async ()=>{
91
91
  const nodeInfo = await pxe.getNodeInfo();
92
- expect(typeof nodeInfo.protocolVersion).toEqual('number');
92
+ expect(typeof nodeInfo.rollupVersion).toEqual('number');
93
93
  expect(typeof nodeInfo.l1ChainId).toEqual('number');
94
94
  expect(nodeInfo.l1ContractAddresses.rollupAddress.toString()).toMatch(/0x[a-fA-F0-9]+/);
95
95
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/pxe",
3
- "version": "0.82.3",
3
+ "version": "0.83.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.82.3",
63
- "@aztec/bb.js": "0.82.3",
64
- "@aztec/builder": "0.82.3",
65
- "@aztec/constants": "0.82.3",
66
- "@aztec/ethereum": "0.82.3",
67
- "@aztec/foundation": "0.82.3",
68
- "@aztec/key-store": "0.82.3",
69
- "@aztec/kv-store": "0.82.3",
70
- "@aztec/noir-protocol-circuits-types": "0.82.3",
71
- "@aztec/noir-types": "0.82.3",
72
- "@aztec/protocol-contracts": "0.82.3",
73
- "@aztec/simulator": "0.82.3",
74
- "@aztec/stdlib": "0.82.3",
62
+ "@aztec/bb-prover": "0.83.0",
63
+ "@aztec/bb.js": "0.83.0",
64
+ "@aztec/builder": "0.83.0",
65
+ "@aztec/constants": "0.83.0",
66
+ "@aztec/ethereum": "0.83.0",
67
+ "@aztec/foundation": "0.83.0",
68
+ "@aztec/key-store": "0.83.0",
69
+ "@aztec/kv-store": "0.83.0",
70
+ "@aztec/noir-protocol-circuits-types": "0.83.0",
71
+ "@aztec/noir-types": "0.83.0",
72
+ "@aztec/protocol-contracts": "0.83.0",
73
+ "@aztec/simulator": "0.83.0",
74
+ "@aztec/stdlib": "0.83.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.82.3",
84
+ "@aztec/noir-contracts.js": "0.83.0",
85
85
  "@jest/globals": "^29.5.0",
86
86
  "@types/jest": "^29.5.0",
87
87
  "@types/lodash.omit": "^4.5.7",
@@ -1,3 +1,3 @@
1
1
  export function getPackageInfo() {
2
- return { version: '0.82.2', name: '@aztec/pxe' };
2
+ return { version: '0.83.0', name: '@aztec/pxe' };
3
3
  }
@@ -1,22 +1,13 @@
1
- import { type L1_TO_L2_MSG_TREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
1
+ import type { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
2
2
  import { timesParallel } from '@aztec/foundation/collection';
3
- import { poseidon2Hash } from '@aztec/foundation/crypto';
4
3
  import { Fr, Point } from '@aztec/foundation/fields';
5
4
  import { createLogger } from '@aztec/foundation/log';
6
5
  import type { KeyStore } from '@aztec/key-store';
6
+ import { type ExecutionDataProvider, MessageLoadOracleInputs } from '@aztec/simulator/client';
7
7
  import {
8
- AcirSimulator,
9
- type ExecutionDataProvider,
10
- MessageLoadOracleInputs,
11
- type SimulationProvider,
12
- } from '@aztec/simulator/client';
13
- import {
14
- type FunctionArtifact,
8
+ EventSelector,
15
9
  type FunctionArtifactWithContractName,
16
- FunctionCall,
17
10
  FunctionSelector,
18
- FunctionType,
19
- encodeArguments,
20
11
  getFunctionArtifact,
21
12
  } from '@aztec/stdlib/abi';
22
13
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -25,8 +16,14 @@ import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
25
16
  import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
26
17
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
27
18
  import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
28
- import { computeAddressSecret, computeTaggingSecretPoint } from '@aztec/stdlib/keys';
29
- import { IndexedTaggingSecret, LogWithTxData, TxScopedL2Log, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
19
+ import { computeAddressSecret, computeAppTaggingSecret } from '@aztec/stdlib/keys';
20
+ import {
21
+ IndexedTaggingSecret,
22
+ LogWithTxData,
23
+ PendingTaggedLog,
24
+ TxScopedL2Log,
25
+ deriveEcdhSharedSecret,
26
+ } from '@aztec/stdlib/logs';
30
27
  import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
31
28
  import { Note, type NoteStatus } from '@aztec/stdlib/note';
32
29
  import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
@@ -38,6 +35,7 @@ import type { CapsuleDataProvider } from '../storage/capsule_data_provider/capsu
38
35
  import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
39
36
  import { NoteDao } from '../storage/note_data_provider/note_dao.js';
40
37
  import type { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
38
+ import type { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
41
39
  import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
42
40
  import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
43
41
  import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
@@ -49,13 +47,13 @@ export class PXEOracleInterface implements ExecutionDataProvider {
49
47
  constructor(
50
48
  private aztecNode: AztecNode,
51
49
  private keyStore: KeyStore,
52
- private simulationProvider: SimulationProvider,
53
50
  private contractDataProvider: ContractDataProvider,
54
51
  private noteDataProvider: NoteDataProvider,
55
52
  private capsuleDataProvider: CapsuleDataProvider,
56
53
  private syncDataProvider: SyncDataProvider,
57
54
  private taggingDataProvider: TaggingDataProvider,
58
55
  private addressDataProvider: AddressDataProvider,
56
+ private privateEventDataProvider: PrivateEventDataProvider,
59
57
  private log = createLogger('pxe:pxe_oracle_interface'),
60
58
  ) {}
61
59
 
@@ -291,7 +289,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
291
289
  await this.syncTaggedLogsAsSender(contractAddress, sender, recipient);
292
290
 
293
291
  const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
294
- const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
292
+ const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret], sender);
295
293
 
296
294
  return new IndexedTaggingSecret(appTaggingSecret, index);
297
295
  }
@@ -317,17 +315,17 @@ export class PXEOracleInterface implements ExecutionDataProvider {
317
315
  contractAddress,
318
316
  });
319
317
 
320
- const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([secret]);
321
- await this.taggingDataProvider.setTaggingSecretsIndexesAsSender([new IndexedTaggingSecret(secret, index + 1)]);
318
+ const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([secret], sender);
319
+ await this.taggingDataProvider.setTaggingSecretsIndexesAsSender(
320
+ [new IndexedTaggingSecret(secret, index + 1)],
321
+ sender,
322
+ );
322
323
  }
323
324
 
324
325
  async #calculateAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
325
326
  const senderCompleteAddress = await this.getCompleteAddress(sender);
326
327
  const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
327
- const secretPoint = await computeTaggingSecretPoint(senderCompleteAddress, senderIvsk, recipient);
328
- // Silo the secret so it can't be used to track other app's notes
329
- const appSecret = poseidon2Hash([secretPoint.x, secretPoint.y, contractAddress]);
330
- return appSecret;
328
+ return computeAppTaggingSecret(senderCompleteAddress, senderIvsk, recipient, contractAddress);
331
329
  }
332
330
 
333
331
  /**
@@ -353,12 +351,11 @@ export class PXEOracleInterface implements ExecutionDataProvider {
353
351
  ...(await this.keyStore.getAccounts()),
354
352
  ].filter((address, index, self) => index === self.findIndex(otherAddress => otherAddress.equals(address)));
355
353
  const appTaggingSecrets = await Promise.all(
356
- senders.map(async contact => {
357
- const sharedSecret = await computeTaggingSecretPoint(recipientCompleteAddress, recipientIvsk, contact);
358
- return poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]);
359
- }),
354
+ senders.map(contact =>
355
+ computeAppTaggingSecret(recipientCompleteAddress, recipientIvsk, contact, contractAddress),
356
+ ),
360
357
  );
361
- const indexes = await this.taggingDataProvider.getTaggingSecretsIndexesAsRecipient(appTaggingSecrets);
358
+ const indexes = await this.taggingDataProvider.getTaggingSecretsIndexesAsRecipient(appTaggingSecrets, recipient);
362
359
  return appTaggingSecrets.map((secret, i) => new IndexedTaggingSecret(secret, indexes[i]));
363
360
  }
364
361
 
@@ -375,7 +372,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
375
372
  recipient: AztecAddress,
376
373
  ): Promise<void> {
377
374
  const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
378
- const [oldIndex] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
375
+ const [oldIndex] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret], sender);
379
376
 
380
377
  // This algorithm works such that:
381
378
  // 1. If we find minimum consecutive empty logs in a window of logs we set the index to the index of the last log
@@ -413,9 +410,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
413
410
 
414
411
  const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
415
412
  if (currentIndex !== oldIndex) {
416
- await this.taggingDataProvider.setTaggingSecretsIndexesAsSender([
417
- new IndexedTaggingSecret(appTaggingSecret, currentIndex),
418
- ]);
413
+ await this.taggingDataProvider.setTaggingSecretsIndexesAsSender(
414
+ [new IndexedTaggingSecret(appTaggingSecret, currentIndex)],
415
+ sender,
416
+ );
419
417
 
420
418
  this.log.debug(`Syncing logs for sender ${sender} at contract ${contractName}(${contractAddress})`, {
421
419
  sender,
@@ -430,20 +428,23 @@ export class PXEOracleInterface implements ExecutionDataProvider {
430
428
  }
431
429
 
432
430
  /**
433
- * Synchronizes the logs tagged with scoped addresses and all the senders in the address book.
434
- * Returns the unsynched logs and updates the indexes of the secrets used to tag them until there are no more logs
435
- * to sync.
436
- * @param contractAddress - The address of the contract that the logs are tagged for
437
- * @param recipient - The address of the recipient
438
- * @returns A list of encrypted logs tagged with the recipient's address
431
+ * Synchronizes the logs tagged with scoped addresses and all the senders in the address book. Stores the found logs
432
+ * in CapsuleArray ready for a later retrieval in Aztec.nr.
433
+ * @param contractAddress - The address of the contract that the logs are tagged for.
434
+ * @param pendingTaggedLogArrayBaseSlot - The base slot of the pending tagged logs capsule array in which
435
+ * found logs will be stored.
436
+ * @param scopes - The scoped addresses to sync logs for. If not provided, all accounts in the address book will be
437
+ * synced.
439
438
  */
440
439
  public async syncTaggedLogs(
441
440
  contractAddress: AztecAddress,
442
- maxBlockNumber: number,
441
+ pendingTaggedLogArrayBaseSlot: Fr,
443
442
  scopes?: AztecAddress[],
444
- ): Promise<Map<string, TxScopedL2Log[]>> {
443
+ ) {
445
444
  this.log.verbose('Searching for tagged logs', { contract: contractAddress });
446
445
 
446
+ const maxBlockNumber = await this.syncDataProvider.getBlockNumber();
447
+
447
448
  // Ideally this algorithm would be implemented in noir, exposing its building blocks as oracles.
448
449
  // However it is impossible at the moment due to the language not supporting nested slices.
449
450
  // This nesting is necessary because for a given set of tags we don't
@@ -451,14 +452,8 @@ export class PXEOracleInterface implements ExecutionDataProvider {
451
452
  // length, since we don't really know the note they correspond to until we decrypt them.
452
453
 
453
454
  const recipients = scopes ? scopes : await this.keyStore.getAccounts();
454
- // A map of logs going from recipient address to logs. Note that the logs might have been processed before
455
- // due to us having a sliding window that "looks back" for logs as well. (We look back as there is no guarantee
456
- // that a logs will be received ordered by a given tag index and that the tags won't be reused).
457
- const logsMap = new Map<string, TxScopedL2Log[]>();
458
455
  const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
459
456
  for (const recipient of recipients) {
460
- const logsForRecipient: TxScopedL2Log[] = [];
461
-
462
457
  // Get all the secrets for the recipient and sender pairs (#9365)
463
458
  const secrets = await this.#getIndexedTaggingSecretsForSenders(contractAddress, recipient);
464
459
 
@@ -497,7 +492,8 @@ export class PXEOracleInterface implements ExecutionDataProvider {
497
492
  // Fetch the logs for the tags and iterate over them
498
493
  const logsByTags = await this.aztecNode.getLogsByTags(tagsForTheWholeWindow);
499
494
 
500
- logsByTags.forEach((logsByTag, logIndex) => {
495
+ for (let logIndex = 0; logIndex < logsByTags.length; logIndex++) {
496
+ const logsByTag = logsByTags[logIndex];
501
497
  if (logsByTag.length > 0) {
502
498
  // Discard public logs
503
499
  const filteredLogsByTag = logsByTag.filter(l => !l.isFromPublic);
@@ -505,8 +501,16 @@ export class PXEOracleInterface implements ExecutionDataProvider {
505
501
  this.log.warn(`Discarded ${logsByTag.filter(l => l.isFromPublic).length} public logs with matching tags`);
506
502
  }
507
503
 
508
- // The logs for the given tag exist so we store them for later processing
509
- logsForRecipient.push(...filteredLogsByTag);
504
+ // We filter out the logs that are newer than the historical block number of the tx currently being constructed
505
+ const filteredLogsByBlockNumber = filteredLogsByTag.filter(l => l.blockNumber <= maxBlockNumber);
506
+
507
+ // We store the logs in capsules (to later be obtained in Noir)
508
+ await this.#storePendingTaggedLogs(
509
+ contractAddress,
510
+ pendingTaggedLogArrayBaseSlot,
511
+ recipient,
512
+ filteredLogsByBlockNumber,
513
+ );
510
514
 
511
515
  // We retrieve the indexed tagging secret corresponding to the log as I need that to evaluate whether
512
516
  // a new largest index have been found.
@@ -538,7 +542,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
538
542
  );
539
543
  }
540
544
  }
541
- });
545
+ }
542
546
 
543
547
  // Now based on the new largest indexes we found, we will construct a new secrets and windows set to fetch logs
544
548
  // for. Note that it's very unlikely that a new log from the current window would appear between the iterations
@@ -567,59 +571,45 @@ export class PXEOracleInterface implements ExecutionDataProvider {
567
571
  secretsAndWindows = newSecretsAndWindows;
568
572
  }
569
573
 
570
- // We filter the logs by block number and store them in the map.
571
- logsMap.set(
572
- recipient.toString(),
573
- logsForRecipient.filter(log => log.blockNumber <= maxBlockNumber),
574
- );
575
-
576
574
  // At this point we have processed all the logs for the recipient so we store the new largest indexes in the db.
577
575
  await this.taggingDataProvider.setTaggingSecretsIndexesAsRecipient(
578
576
  Object.entries(newLargestIndexMapToStore).map(
579
577
  ([appTaggingSecret, index]) => new IndexedTaggingSecret(Fr.fromHexString(appTaggingSecret), index),
580
578
  ),
579
+ recipient,
581
580
  );
582
581
  }
583
- return logsMap;
584
582
  }
585
583
 
586
- /**
587
- * Processes the tagged logs returned by syncTaggedLogs by decrypting them and storing them in the database.
588
- * @param contractAddress - The address of the contract that the logs are tagged for.
589
- * @param logs - The logs to process.
590
- * @param recipient - The recipient of the logs.
591
- */
592
- public async processTaggedLogs(
584
+ async #storePendingTaggedLogs(
593
585
  contractAddress: AztecAddress,
594
- logs: TxScopedL2Log[],
586
+ capsuleArrayBaseSlot: Fr,
595
587
  recipient: AztecAddress,
596
- simulator?: AcirSimulator,
597
- ): Promise<void> {
598
- for (const scopedLog of logs) {
599
- if (scopedLog.isFromPublic) {
600
- throw new Error('Attempted to decrypt public log');
601
- }
588
+ logs: TxScopedL2Log[],
589
+ ) {
590
+ // Build all pending tagged logs upfront with their tx effects
591
+ const pendingTaggedLogs = await Promise.all(
592
+ logs.map(async scopedLog => {
593
+ // TODO(#9789): get these effects along with the log
594
+ const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
595
+ if (!txEffect) {
596
+ throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
597
+ }
602
598
 
603
- // Log processing requires the note hashes in the tx in which the note was created. We are now assuming that the
604
- // note was included in the same block in which the log was delivered - note that partial notes will not work this
605
- // way.
606
- const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
607
- if (!txEffect) {
608
- throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
609
- }
599
+ const pendingTaggedLog = new PendingTaggedLog(
600
+ scopedLog.log.toFields(),
601
+ scopedLog.txHash.hash,
602
+ txEffect.data.noteHashes,
603
+ txEffect.data.nullifiers[0],
604
+ recipient,
605
+ scopedLog.logIndexInTx,
606
+ );
610
607
 
611
- // This will trigger calls to the deliverNote oracle
612
- await this.callProcessLog(
613
- contractAddress,
614
- scopedLog.log.toFields(),
615
- scopedLog.txHash,
616
- txEffect.data.noteHashes,
617
- txEffect.data.nullifiers[0],
618
- recipient,
619
- simulator,
620
- );
621
- }
622
- return;
608
+ return pendingTaggedLog.toFields();
609
+ }),
610
+ );
611
+
612
+ return this.capsuleDataProvider.appendToCapsuleArray(contractAddress, capsuleArrayBaseSlot, pendingTaggedLogs);
623
613
  }
624
614
 
625
615
  public async deliverNote(
@@ -649,10 +639,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
649
639
  // in time of the locally synced state.
650
640
  // Note that while this technically results in historical queries, we perform it at the latest locally synced block
651
641
  // number which *should* be recent enough to be available, even for non-archive nodes.
652
- const syncedBlockNumber = (await this.syncDataProvider.getBlockNumber())!;
653
- if (syncedBlockNumber === undefined) {
654
- throw new Error(`Attempted to deliver a note with an unsynchronized PXE - this should never happen`);
655
- }
642
+ const syncedBlockNumber = await this.syncDataProvider.getBlockNumber();
656
643
 
657
644
  // By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
658
645
  // of other contracts, which would constitute a security breach.
@@ -688,9 +675,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
688
675
 
689
676
  await this.noteDataProvider.addNotes([noteDao], recipient);
690
677
  this.log.verbose('Added note', {
691
- contract: noteDao.contractAddress,
692
- slot: noteDao.storageSlot,
693
- noteHash: noteDao.noteHash,
678
+ index: noteDao.index,
679
+ contract: noteDao.contractAddress.toString(),
680
+ slot: noteDao.storageSlot.toString(),
681
+ noteHash: noteDao.noteHash.toString(),
694
682
  nullifier: noteDao.siloedNullifier.toString(),
695
683
  });
696
684
 
@@ -778,50 +766,6 @@ export class PXEOracleInterface implements ExecutionDataProvider {
778
766
  }
779
767
  }
780
768
 
781
- async callProcessLog(
782
- contractAddress: AztecAddress,
783
- logCiphertext: Fr[],
784
- txHash: TxHash,
785
- noteHashes: Fr[],
786
- firstNullifier: Fr,
787
- recipient: AztecAddress,
788
- simulator?: AcirSimulator,
789
- ) {
790
- const artifact: FunctionArtifact | undefined = await this.contractDataProvider.getFunctionArtifactByName(
791
- contractAddress,
792
- 'process_log',
793
- );
794
- if (!artifact) {
795
- throw new Error(
796
- `Mandatory implementation of "process_log" missing in noir contract ${contractAddress.toString()}.`,
797
- );
798
- }
799
-
800
- const selector = await FunctionSelector.fromNameAndParameters(artifact);
801
- const execRequest: FunctionCall = {
802
- name: artifact.name,
803
- to: contractAddress,
804
- selector,
805
- type: FunctionType.UNCONSTRAINED,
806
- isStatic: artifact.isStatic,
807
- args: encodeArguments(artifact, [
808
- toBoundedVec(logCiphertext, PRIVATE_LOG_SIZE_IN_FIELDS),
809
- txHash.toString(),
810
- toBoundedVec(noteHashes, MAX_NOTE_HASHES_PER_TX),
811
- firstNullifier,
812
- recipient,
813
- ]),
814
- returnTypes: artifact.returnTypes,
815
- };
816
-
817
- await (simulator ?? new AcirSimulator(this, this.simulationProvider)).runUnconstrained(
818
- execRequest,
819
- contractAddress,
820
- selector,
821
- [], // empty scope as this call should not require access to private information
822
- );
823
- }
824
-
825
769
  storeCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void> {
826
770
  return this.capsuleDataProvider.storeCapsule(contractAddress, slot, capsule);
827
771
  }
@@ -847,8 +791,34 @@ export class PXEOracleInterface implements ExecutionDataProvider {
847
791
  const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
848
792
  return deriveEcdhSharedSecret(addressSecret, ephPk);
849
793
  }
850
- }
851
794
 
852
- function toBoundedVec(array: Fr[], maxLength: number) {
853
- return { storage: array.concat(Array(maxLength - array.length).fill(new Fr(0))), len: array.length };
795
+ async storePrivateEventLog(
796
+ contractAddress: AztecAddress,
797
+ recipient: AztecAddress,
798
+ eventSelector: EventSelector,
799
+ logContent: Fr[],
800
+ txHash: TxHash,
801
+ logIndexInTx: number,
802
+ ): Promise<void> {
803
+ const txReceipt = await this.aztecNode.getTxReceipt(txHash);
804
+ const blockNumber = txReceipt.blockNumber;
805
+ if (blockNumber === undefined) {
806
+ throw new Error(`Block number is undefined for tx ${txHash} in storePrivateEventLog`);
807
+ }
808
+ const historicalBlockNumber = await this.syncDataProvider.getBlockNumber();
809
+ if (blockNumber > historicalBlockNumber) {
810
+ throw new Error(
811
+ `Attempting to store private event log from a block newer than the historical block of the simulation. Log block number: ${blockNumber}, historical block number: ${historicalBlockNumber}`,
812
+ );
813
+ }
814
+ return this.privateEventDataProvider.storePrivateEventLog(
815
+ contractAddress,
816
+ recipient,
817
+ eventSelector,
818
+ logContent,
819
+ txHash,
820
+ logIndexInTx,
821
+ blockNumber,
822
+ );
823
+ }
854
824
  }