@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
@@ -6,12 +6,10 @@ import { KeyStore } from '@aztec/key-store';
6
6
  import { L2TipsKVStore } from '@aztec/kv-store/stores';
7
7
  import { ProtocolContractAddress, protocolContractNames } from '@aztec/protocol-contracts';
8
8
  import { AcirSimulator, readCurrentClassId } from '@aztec/simulator/client';
9
- import { EventSelector, FunctionSelector, FunctionType, decodeFunctionSignature, encodeArguments } from '@aztec/stdlib/abi';
9
+ import { EventSelector, FunctionSelector, FunctionType, decodeFromAbi, decodeFunctionSignature, encodeArguments } from '@aztec/stdlib/abi';
10
10
  import { computeContractAddressFromInstance, getContractClassFromArtifact } from '@aztec/stdlib/contract';
11
11
  import { SimulationError } from '@aztec/stdlib/errors';
12
- import { EventMetadata, L1EventPayload } from '@aztec/stdlib/event';
13
12
  import { siloNullifier } from '@aztec/stdlib/hash';
14
- import { computeAddressSecret } from '@aztec/stdlib/keys';
15
13
  import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
16
14
  import { UniqueNote } from '@aztec/stdlib/note';
17
15
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -25,6 +23,7 @@ import { AddressDataProvider } from '../storage/address_data_provider/address_da
25
23
  import { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
26
24
  import { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
27
25
  import { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
26
+ import { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
28
27
  import { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
29
28
  import { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
30
29
  import { Synchronizer } from '../synchronizer/index.js';
@@ -41,6 +40,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
41
40
  syncDataProvider;
42
41
  taggingDataProvider;
43
42
  addressDataProvider;
43
+ privateEventDataProvider;
44
44
  simulator;
45
45
  packageVersion;
46
46
  proverEnabled;
@@ -48,7 +48,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
48
48
  protocolContractsProvider;
49
49
  log;
50
50
  jobQueue;
51
- constructor(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue){
51
+ constructor(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue){
52
52
  this.node = node;
53
53
  this.synchronizer = synchronizer;
54
54
  this.keyStore = keyStore;
@@ -58,6 +58,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
58
58
  this.syncDataProvider = syncDataProvider;
59
59
  this.taggingDataProvider = taggingDataProvider;
60
60
  this.addressDataProvider = addressDataProvider;
61
+ this.privateEventDataProvider = privateEventDataProvider;
61
62
  this.simulator = simulator;
62
63
  this.packageVersion = packageVersion;
63
64
  this.proverEnabled = proverEnabled;
@@ -77,6 +78,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
77
78
  const packageVersion = getPackageInfo().version;
78
79
  const proverEnabled = !!config.proverEnabled;
79
80
  const addressDataProvider = new AddressDataProvider(store);
81
+ const privateEventDataProvider = new PrivateEventDataProvider(store);
80
82
  const contractDataProvider = new ContractDataProvider(store);
81
83
  const noteDataProvider = await NoteDataProvider.create(store);
82
84
  const syncDataProvider = new SyncDataProvider(store);
@@ -85,14 +87,14 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
85
87
  const keyStore = new KeyStore(store);
86
88
  const tipsStore = new L2TipsKVStore(store, 'pxe');
87
89
  const synchronizer = new Synchronizer(node, syncDataProvider, noteDataProvider, taggingDataProvider, tipsStore, config, loggerOrSuffix);
88
- const pxeOracleInterface = new PXEOracleInterface(node, keyStore, simulationProvider, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, log);
90
+ const pxeOracleInterface = new PXEOracleInterface(node, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, log);
89
91
  const simulator = new AcirSimulator(pxeOracleInterface, simulationProvider);
90
92
  const jobQueue = new SerialQueue();
91
- const pxeService = new PXEService(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue);
93
+ const pxeService = new PXEService(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue);
92
94
  pxeService.jobQueue.start();
93
95
  await pxeService.#registerProtocolContracts();
94
96
  const info = await pxeService.getNodeInfo();
95
- log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.protocolVersion}`);
97
+ log.info(`Started PXE connected to chain ${info.l1ChainId} version ${info.rollupVersion}`);
96
98
  return pxeService;
97
99
  }
98
100
  // Aztec node proxy methods
@@ -572,7 +574,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
572
574
  });
573
575
  }
574
576
  async getNodeInfo() {
575
- const [nodeVersion, protocolVersion, chainId, enr, contractAddresses, protocolContractAddresses] = await Promise.all([
577
+ const [nodeVersion, rollupVersion, chainId, enr, contractAddresses, protocolContractAddresses] = await Promise.all([
576
578
  this.node.getNodeVersion(),
577
579
  this.node.getVersion(),
578
580
  this.node.getChainId(),
@@ -583,7 +585,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
583
585
  const nodeInfo = {
584
586
  nodeVersion,
585
587
  l1ChainId: chainId,
586
- protocolVersion,
588
+ rollupVersion,
587
589
  enr,
588
590
  l1ContractAddresses: contractAddresses,
589
591
  protocolContractAddresses: protocolContractAddresses
@@ -601,71 +603,39 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
601
603
  }
602
604
  });
603
605
  }
604
- async getPrivateEvents(eventMetadataDef, from, limit, // TODO (#9272): Make this better, we should be able to only pass an address now
605
- vpks) {
606
- const eventMetadata = new EventMetadata(eventMetadataDef);
607
- if (vpks.length === 0) {
608
- throw new Error('Tried to get encrypted events without supplying any viewing public keys');
606
+ async getPrivateEvents(contractAddress, eventMetadataDef, from, numBlocks, recipients) {
607
+ if (recipients.length === 0) {
608
+ throw new Error('Recipients are required to get private events');
609
609
  }
610
- const blocks = await this.node.getBlocks(from, limit);
611
- const txEffects = blocks.flatMap((block)=>block.body.txEffects);
612
- const privateLogs = txEffects.flatMap((txEffect)=>txEffect.privateLogs);
613
- const vsks = await Promise.all(vpks.map(async (vpk)=>{
614
- const [keyPrefix, account] = await this.keyStore.getKeyPrefixAndAccount(vpk);
615
- let secretKey = await this.keyStore.getMasterSecretKey(vpk);
616
- if (keyPrefix === 'iv') {
617
- const registeredAccount = (await this.getRegisteredAccounts()).find((completeAddress)=>completeAddress.address.equals(account));
618
- if (!registeredAccount) {
619
- throw new Error('No registered account');
620
- }
621
- const preaddress = await registeredAccount.getPreaddress();
622
- secretKey = await computeAddressSecret(preaddress, secretKey);
623
- }
624
- return secretKey;
625
- }));
626
- const visibleEvents = (await Promise.all(privateLogs.map(async (log)=>{
627
- for (const sk of vsks){
628
- // TODO: Verify that the first field of the log is the tag siloed with contract address.
629
- // Or use tags to query logs, like we do with notes.
630
- const decryptedEvent = await L1EventPayload.decryptAsIncoming(log, sk);
631
- if (decryptedEvent !== undefined) {
632
- return [
633
- decryptedEvent
634
- ];
635
- }
636
- }
637
- return [];
638
- }))).flat();
639
- const decodedEvents = visibleEvents.map((visibleEvent)=>{
640
- if (visibleEvent === undefined) {
641
- return undefined;
642
- }
643
- if (!visibleEvent.eventTypeId.equals(eventMetadata.eventSelector)) {
644
- return undefined;
645
- }
646
- return eventMetadata.decode(visibleEvent);
647
- }).filter((visibleEvent)=>visibleEvent !== undefined);
610
+ this.log.verbose(`Getting private events for ${contractAddress.toString()} from ${from} to ${from + numBlocks}`);
611
+ // TODO(#13113): This is a temporary hack to ensure that the notes are synced before getting the events.
612
+ await this.simulateUnconstrained('sync_notes', [], contractAddress);
613
+ const events = await this.privateEventDataProvider.getPrivateEvents(contractAddress, from, numBlocks, recipients, eventMetadataDef.eventSelector);
614
+ const decodedEvents = events.map((event)=>decodeFromAbi([
615
+ eventMetadataDef.abiType
616
+ ], event));
648
617
  return decodedEvents;
649
618
  }
650
619
  async getPublicEvents(eventMetadataDef, from, limit) {
651
- const eventMetadata = new EventMetadata(eventMetadataDef);
652
620
  const { logs } = await this.node.getPublicLogs({
653
621
  fromBlock: from,
654
622
  toBlock: from + limit
655
623
  });
656
624
  const decodedEvents = logs.map((log)=>{
657
625
  // +1 for the event selector
658
- const expectedLength = eventMetadata.fieldNames.length + 1;
626
+ const expectedLength = eventMetadataDef.fieldNames.length + 1;
659
627
  const logFields = log.log.log.slice(0, expectedLength);
660
628
  // We are assuming here that event logs are the last 4 bytes of the event. This is not enshrined but is a function of aztec.nr raw log emission.
661
- if (!EventSelector.fromField(logFields[logFields.length - 1]).equals(eventMetadata.eventSelector)) {
629
+ if (!EventSelector.fromField(logFields[logFields.length - 1]).equals(eventMetadataDef.eventSelector)) {
662
630
  return undefined;
663
631
  }
664
632
  // If any of the remaining fields, are non-zero, the payload does match expected:
665
633
  if (log.log.log.slice(expectedLength + 1).find((f)=>!f.isZero())) {
666
634
  throw new Error('Something is weird here, we have matching EventSelectors, but the actual payload has mismatched length');
667
635
  }
668
- return eventMetadata.decode(log.log);
636
+ return decodeFromAbi([
637
+ eventMetadataDef.abiType
638
+ ], log.log.log);
669
639
  }).filter((log)=>log !== undefined);
670
640
  return decodedEvents;
671
641
  }
@@ -11,6 +11,15 @@ export declare class CapsuleDataProvider implements DataProvider {
11
11
  loadCapsule(contractAddress: AztecAddress, slot: Fr): Promise<Fr[] | null>;
12
12
  deleteCapsule(contractAddress: AztecAddress, slot: Fr): Promise<void>;
13
13
  copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void>;
14
+ /**
15
+ * Appends multiple capsules to a capsule array stored at the base slot.
16
+ * The array length is stored at the base slot, and elements are stored in consecutive slots after it.
17
+ * All operations are performed in a single transaction.
18
+ * @param contractAddress - The contract address that owns the capsule array
19
+ * @param baseSlot - The slot where the array length is stored
20
+ * @param capsules - Array of capsule data to append
21
+ */
22
+ appendToCapsuleArray(contractAddress: AztecAddress, baseSlot: Fr, capsules: Fr[][]): Promise<void>;
14
23
  getSize(): Promise<number>;
15
24
  }
16
25
  //# sourceMappingURL=capsule_data_provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capsule_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/capsule_data_provider/capsule_data_provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EAAE,KAAK,KAAK,EAAyB,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,qBAAa,mBAAoB,YAAW,YAAY;;IAMtD,KAAK,EAAE,KAAK,CAAC;gBAED,KAAK,EAAE,iBAAiB;IAQ9B,YAAY,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAInF,WAAW,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;IAa1E,aAAa,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE,WAAW,CAAC,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBhG,OAAO;CAMrB"}
1
+ {"version":3,"file":"capsule_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/capsule_data_provider/capsule_data_provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EAAE,KAAK,KAAK,EAAyB,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,qBAAa,mBAAoB,YAAW,YAAY;;IAMtD,KAAK,EAAE,KAAK,CAAC;gBAED,KAAK,EAAE,iBAAiB;IAQ9B,YAAY,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAInF,WAAW,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;IAa1E,aAAa,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE,WAAW,CAAC,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB7G;;;;;;;OAOG;IACH,oBAAoB,CAAC,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBrF,OAAO;CAMrB"}
@@ -48,6 +48,30 @@ export class CapsuleDataProvider {
48
48
  await this.#capsules.set(currentDstSlot, toCopy);
49
49
  }
50
50
  }
51
+ /**
52
+ * Appends multiple capsules to a capsule array stored at the base slot.
53
+ * The array length is stored at the base slot, and elements are stored in consecutive slots after it.
54
+ * All operations are performed in a single transaction.
55
+ * @param contractAddress - The contract address that owns the capsule array
56
+ * @param baseSlot - The slot where the array length is stored
57
+ * @param capsules - Array of capsule data to append
58
+ */ appendToCapsuleArray(contractAddress, baseSlot, capsules) {
59
+ return this.#store.transactionAsync(async ()=>{
60
+ // Load current length, defaulting to 0 if not found
61
+ const lengthData = await this.loadCapsule(contractAddress, baseSlot);
62
+ const currentLength = lengthData ? lengthData[0].toBigInt() : 0n;
63
+ // Store each capsule at consecutive slots after baseSlot + 1 + currentLength
64
+ for(let i = 0; i < capsules.length; i++){
65
+ const nextSlot = baseSlot.add(new Fr(1)).add(new Fr(currentLength + BigInt(i)));
66
+ await this.storeCapsule(contractAddress, nextSlot, capsules[i]);
67
+ }
68
+ // Update length to include all new capsules
69
+ const newLength = currentLength + BigInt(capsules.length);
70
+ await this.storeCapsule(contractAddress, baseSlot, [
71
+ new Fr(newLength)
72
+ ]);
73
+ });
74
+ }
51
75
  async getSize() {
52
76
  return (await toArray(this.#capsules.valuesAsync())).reduce((sum, value)=>sum + value.length * Fr.SIZE_IN_BYTES, 0);
53
77
  }
@@ -6,4 +6,5 @@ export * from './sync_data_provider/index.js';
6
6
  export * from './tagging_data_provider/index.js';
7
7
  export * from './data_provider.js';
8
8
  export * from './metadata.js';
9
+ export * from './private_event_data_provider/private_event_data_provider.js';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,8DAA8D,CAAC"}
@@ -6,3 +6,4 @@ export * from './sync_data_provider/index.js';
6
6
  export * from './tagging_data_provider/index.js';
7
7
  export * from './data_provider.js';
8
8
  export * from './metadata.js';
9
+ export * from './private_event_data_provider/private_event_data_provider.js';
@@ -0,0 +1,37 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import type { AztecAsyncKVStore } from '@aztec/kv-store';
3
+ import type { EventSelector } from '@aztec/stdlib/abi';
4
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
5
+ import type { TxHash } from '@aztec/stdlib/tx';
6
+ import type { DataProvider } from '../data_provider.js';
7
+ /**
8
+ * Stores decrypted private event logs.
9
+ */
10
+ export declare class PrivateEventDataProvider implements DataProvider {
11
+ #private;
12
+ logger: import("@aztec/foundation/log").Logger;
13
+ constructor(store: AztecAsyncKVStore);
14
+ /**
15
+ * Store a private event log.
16
+ * @param contractAddress - The address of the contract that emitted the event.
17
+ * @param recipient - The recipient of the event.
18
+ * @param eventSelector - The event selector of the event.
19
+ * @param logContent - The content of the event.
20
+ * @param txHash - The transaction hash of the event log.
21
+ * @param logIndexInTx - The index of the log within the transaction.
22
+ * @param blockNumber - The block number in which the event was emitted.
23
+ */
24
+ storePrivateEventLog(contractAddress: AztecAddress, recipient: AztecAddress, eventSelector: EventSelector, logContent: Fr[], txHash: TxHash, logIndexInTx: number, blockNumber: number): Promise<void>;
25
+ /**
26
+ * Returns the private events given search parameters.
27
+ * @param contractAddress - The address of the contract to get events from.
28
+ * @param from - The block number to search from.
29
+ * @param numBlocks - The amount of blocks to search.
30
+ * @param recipients - The addresses that decrypted the logs.
31
+ * @param eventSelector - The event selector to filter by.
32
+ * @returns - The event log contents.
33
+ */
34
+ getPrivateEvents(contractAddress: AztecAddress, from: number, numBlocks: number, recipients: AztecAddress[], eventSelector: EventSelector): Promise<Fr[][]>;
35
+ getSize(): Promise<number>;
36
+ }
37
+ //# sourceMappingURL=private_event_data_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private_event_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/private_event_data_provider/private_event_data_provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,KAAK,EAAmB,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAQxD;;GAEG;AACH,qBAAa,wBAAyB,YAAW,YAAY;;IAY3D,MAAM,yCAA+C;gBAEzC,KAAK,EAAE,iBAAiB;IAOpC;;;;;;;;;OASG;IACH,oBAAoB,CAClB,eAAe,EAAE,YAAY,EAC7B,SAAS,EAAE,YAAY,EACvB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,EAAE,EAAE,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IA2BhB;;;;;;;;OAQG;IACU,gBAAgB,CAC3B,eAAe,EAAE,YAAY,EAC7B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,YAAY,EAAE,EAC1B,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC;IAiClB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAG3B"}
@@ -0,0 +1,106 @@
1
+ import { Fr } from '@aztec/foundation/fields';
2
+ import { createLogger } from '@aztec/foundation/log';
3
+ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
4
+ /**
5
+ * Stores decrypted private event logs.
6
+ */ export class PrivateEventDataProvider {
7
+ #store;
8
+ /** Array storing the actual private event log entries containing the log content and block number */ #eventLogs;
9
+ /** Map from contract_address_recipient_eventSelector to array of indices into #eventLogs for efficient lookup */ #eventLogIndex;
10
+ /**
11
+ * Map from txHash_logIndexInTx to boolean indicating if log has been seen.
12
+ * @dev A single transaction can have multiple logs.
13
+ */ #seenLogs;
14
+ logger = createLogger('private_event_data_provider');
15
+ constructor(store){
16
+ this.#store = store;
17
+ this.#eventLogs = this.#store.openArray('private_event_logs');
18
+ this.#eventLogIndex = this.#store.openMap('private_event_log_index');
19
+ this.#seenLogs = this.#store.openMap('seen_logs');
20
+ }
21
+ /**
22
+ * Store a private event log.
23
+ * @param contractAddress - The address of the contract that emitted the event.
24
+ * @param recipient - The recipient of the event.
25
+ * @param eventSelector - The event selector of the event.
26
+ * @param logContent - The content of the event.
27
+ * @param txHash - The transaction hash of the event log.
28
+ * @param logIndexInTx - The index of the log within the transaction.
29
+ * @param blockNumber - The block number in which the event was emitted.
30
+ */ storePrivateEventLog(contractAddress, recipient, eventSelector, logContent, txHash, logIndexInTx, blockNumber) {
31
+ return this.#store.transactionAsync(async ()=>{
32
+ const key = `${contractAddress.toString()}_${recipient.toString()}_${eventSelector.toString()}`;
33
+ // We identify a unique log by its transaction hash and index within that transaction
34
+ const txKey = `${txHash.toString()}_${logIndexInTx}`;
35
+ // Check if this exact log has already been stored
36
+ const hasBeenSeen = await this.#seenLogs.getAsync(txKey);
37
+ if (hasBeenSeen) {
38
+ this.logger.verbose('Ignoring duplicate event log', {
39
+ txHash: txHash.toString(),
40
+ logIndexInTx
41
+ });
42
+ return;
43
+ }
44
+ this.logger.verbose('storing private event log', {
45
+ contractAddress,
46
+ recipient,
47
+ logContent,
48
+ blockNumber
49
+ });
50
+ const index = await this.#eventLogs.lengthAsync();
51
+ await this.#eventLogs.push({
52
+ logContent: serializeToBuffer(logContent),
53
+ blockNumber,
54
+ logIndexInTx
55
+ });
56
+ const existingIndices = await this.#eventLogIndex.getAsync(key) || [];
57
+ await this.#eventLogIndex.set(key, [
58
+ ...existingIndices,
59
+ index
60
+ ]);
61
+ // Mark this log as seen
62
+ await this.#seenLogs.set(txKey, true);
63
+ });
64
+ }
65
+ /**
66
+ * Returns the private events given search parameters.
67
+ * @param contractAddress - The address of the contract to get events from.
68
+ * @param from - The block number to search from.
69
+ * @param numBlocks - The amount of blocks to search.
70
+ * @param recipients - The addresses that decrypted the logs.
71
+ * @param eventSelector - The event selector to filter by.
72
+ * @returns - The event log contents.
73
+ */ async getPrivateEvents(contractAddress, from, numBlocks, recipients, eventSelector) {
74
+ const events = [];
75
+ for (const recipient of recipients){
76
+ const key = `${contractAddress.toString()}_${recipient.toString()}_${eventSelector.toString()}`;
77
+ const indices = await this.#eventLogIndex.getAsync(key) || [];
78
+ for (const index of indices){
79
+ const entry = await this.#eventLogs.atAsync(index);
80
+ if (!entry || entry.blockNumber < from || entry.blockNumber >= from + numBlocks) {
81
+ continue;
82
+ }
83
+ // Convert buffer back to Fr array
84
+ const reader = BufferReader.asReader(entry.logContent);
85
+ const numFields = entry.logContent.length / Fr.SIZE_IN_BYTES;
86
+ const logContent = reader.readArray(numFields, Fr);
87
+ events.push({
88
+ logContent,
89
+ blockNumber: entry.blockNumber,
90
+ logIndexInTx: entry.logIndexInTx
91
+ });
92
+ }
93
+ }
94
+ // Sort by block number first, then by logIndexInTx (note that we currently don't order by txs within a block)
95
+ events.sort((a, b)=>{
96
+ if (a.blockNumber !== b.blockNumber) {
97
+ return a.blockNumber - b.blockNumber;
98
+ }
99
+ return a.logIndexInTx - b.logIndexInTx;
100
+ });
101
+ return events.map((e)=>e.logContent);
102
+ }
103
+ getSize() {
104
+ return this.#eventLogs.lengthAsync();
105
+ }
106
+ }
@@ -5,7 +5,7 @@ export declare class SyncDataProvider implements DataProvider {
5
5
  #private;
6
6
  constructor(store: AztecAsyncKVStore);
7
7
  setHeader(header: BlockHeader): Promise<void>;
8
- getBlockNumber(): Promise<number | undefined>;
8
+ getBlockNumber(): Promise<number>;
9
9
  getBlockHeader(): Promise<BlockHeader>;
10
10
  getSize(): Promise<number>;
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sync_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/sync_data_provider/sync_data_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAuB,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,qBAAa,gBAAiB,YAAW,YAAY;;gBAIvC,KAAK,EAAE,iBAAiB;IAK9B,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAS7C,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAStC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAGjC"}
1
+ {"version":3,"file":"sync_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/sync_data_provider/sync_data_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAuB,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,qBAAa,gBAAiB,YAAW,YAAY;;gBAIvC,KAAK,EAAE,iBAAiB;IAK9B,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IASjC,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAStC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAGjC"}
@@ -12,7 +12,7 @@ export class SyncDataProvider {
12
12
  async getBlockNumber() {
13
13
  const headerBuffer = await this.#synchronizedHeader.getAsync();
14
14
  if (!headerBuffer) {
15
- return undefined;
15
+ throw new Error(`Trying to get block number with a not-yet-synchronized PXE - this should never happen`);
16
16
  }
17
17
  return Number(BlockHeader.fromBuffer(headerBuffer).globalVariables.blockNumber.toBigInt());
18
18
  }
@@ -5,10 +5,10 @@ import type { IndexedTaggingSecret } from '@aztec/stdlib/logs';
5
5
  export declare class TaggingDataProvider {
6
6
  #private;
7
7
  constructor(store: AztecAsyncKVStore);
8
- setTaggingSecretsIndexesAsSender(indexedSecrets: IndexedTaggingSecret[]): Promise<void>;
9
- setTaggingSecretsIndexesAsRecipient(indexedSecrets: IndexedTaggingSecret[]): Promise<void>;
10
- getTaggingSecretsIndexesAsRecipient(appTaggingSecrets: Fr[]): Promise<number[]>;
11
- getTaggingSecretsIndexesAsSender(appTaggingSecrets: Fr[]): Promise<number[]>;
8
+ setTaggingSecretsIndexesAsSender(indexedSecrets: IndexedTaggingSecret[], sender: AztecAddress): Promise<void[]>;
9
+ setTaggingSecretsIndexesAsRecipient(indexedSecrets: IndexedTaggingSecret[], recipient: AztecAddress): Promise<void[]>;
10
+ getTaggingSecretsIndexesAsRecipient(appTaggingSecrets: Fr[], recipient: AztecAddress): Promise<number[]>;
11
+ getTaggingSecretsIndexesAsSender(appTaggingSecrets: Fr[], sender: AztecAddress): Promise<number[]>;
12
12
  resetNoteSyncData(): Promise<void>;
13
13
  addSenderAddress(address: AztecAddress): Promise<boolean>;
14
14
  getSenderAddresses(): Promise<AztecAddress[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"tagging_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/tagging_data_provider/tagging_data_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,qBAAa,mBAAmB;;gBAUlB,KAAK,EAAE,iBAAiB;IAS9B,gCAAgC,CAAC,cAAc,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvF,mCAAmC,CAAC,cAAc,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1F,mCAAmC,CAAC,iBAAiB,EAAE,EAAE,EAAE;IAI3D,gCAAgC,CAAC,iBAAiB,EAAE,EAAE,EAAE;IAQ9D,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzD,kBAAkB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI7C,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5D,OAAO;CAKd"}
1
+ {"version":3,"file":"tagging_data_provider.d.ts","sourceRoot":"","sources":["../../../src/storage/tagging_data_provider/tagging_data_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,qBAAa,mBAAmB;;gBAUlB,KAAK,EAAE,iBAAiB;IASpC,gCAAgC,CAAC,cAAc,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,YAAY;IAI7F,mCAAmC,CAAC,cAAc,EAAE,oBAAoB,EAAE,EAAE,SAAS,EAAE,YAAY;IAyBnG,mCAAmC,CAAC,iBAAiB,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY;IAIpF,gCAAgC,CAAC,iBAAiB,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY;IA0B9E,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzD,kBAAkB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI7C,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5D,OAAO;CAKd"}
@@ -14,23 +14,40 @@ export class TaggingDataProvider {
14
14
  this.#taggingSecretIndexesForSenders = this.#store.openMap('tagging_secret_indexes_for_senders');
15
15
  this.#taggingSecretIndexesForRecipients = this.#store.openMap('tagging_secret_indexes_for_recipients');
16
16
  }
17
- async setTaggingSecretsIndexesAsSender(indexedSecrets) {
18
- await this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForSenders);
17
+ setTaggingSecretsIndexesAsSender(indexedSecrets, sender) {
18
+ return this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForSenders, sender);
19
19
  }
20
- async setTaggingSecretsIndexesAsRecipient(indexedSecrets) {
21
- await this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForRecipients);
20
+ setTaggingSecretsIndexesAsRecipient(indexedSecrets, recipient) {
21
+ return this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForRecipients, recipient);
22
22
  }
23
- async #setTaggingSecretsIndexes(indexedSecrets, storageMap) {
24
- await Promise.all(indexedSecrets.map((indexedSecret)=>storageMap.set(indexedSecret.appTaggingSecret.toString(), indexedSecret.index)));
23
+ /**
24
+ * Sets the indexes of the tagging secrets for the given app tagging secrets in the direction of the given address.
25
+ * @dev We need to specify the direction because app tagging secrets are direction-less due to the way they are generated
26
+ * but we need to guarantee that the index is stored under a uni-directional key because the tags are themselves
27
+ * uni-directional.
28
+ * @param indexedSecrets - The app tagging secrets and indexes to set.
29
+ * @param storageMap - The storage map to set the indexes in.
30
+ * @param inDirectionOf - The address that the secrets are in the direction of.
31
+ */ #setTaggingSecretsIndexes(indexedSecrets, storageMap, inDirectionOf) {
32
+ return Promise.all(indexedSecrets.map((indexedSecret)=>storageMap.set(`${indexedSecret.appTaggingSecret.toString()}_${inDirectionOf.toString()}`, indexedSecret.index)));
25
33
  }
26
- async getTaggingSecretsIndexesAsRecipient(appTaggingSecrets) {
27
- return await this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForRecipients);
34
+ getTaggingSecretsIndexesAsRecipient(appTaggingSecrets, recipient) {
35
+ return this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForRecipients, recipient);
28
36
  }
29
- async getTaggingSecretsIndexesAsSender(appTaggingSecrets) {
30
- return await this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForSenders);
37
+ getTaggingSecretsIndexesAsSender(appTaggingSecrets, sender) {
38
+ return this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForSenders, sender);
31
39
  }
32
- #getTaggingSecretsIndexes(appTaggingSecrets, storageMap) {
33
- return Promise.all(appTaggingSecrets.map(async (secret)=>await storageMap.getAsync(`${secret.toString()}`) ?? 0));
40
+ /**
41
+ * Returns the indexes of the tagging secrets for the given app tagging secrets in the direction of the given address.
42
+ * @dev We need to specify the direction because app tagging secrets are direction-less due to the way they are generated
43
+ * but we need to guarantee that the index is stored under a uni-directional key because the tags are themselves
44
+ * uni-directional.
45
+ * @param appTaggingSecrets - The app tagging secrets to get the indexes for.
46
+ * @param storageMap - The storage map to get the indexes from.
47
+ * @param inDirectionOf - The address that the secrets are in the direction of.
48
+ * @returns The indexes of the tagging secrets.
49
+ */ #getTaggingSecretsIndexes(appTaggingSecrets, storageMap, inDirectionOf) {
50
+ return Promise.all(appTaggingSecrets.map(async (secret)=>await storageMap.getAsync(`${secret.toString()}_${inDirectionOf.toString()}`) ?? 0));
34
51
  }
35
52
  resetNoteSyncData() {
36
53
  return this.#store.transactionAsync(async ()=>{
@@ -7,10 +7,9 @@ import type { NoteDataProvider } from '../storage/note_data_provider/note_data_p
7
7
  import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
8
8
  import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
9
9
  /**
10
- * The Synchronizer class manages the synchronization with the aztec node, allowing PXE to retrieve the
11
- * latest block header and handle reorgs.
12
- * It provides methods to trigger a sync and get the block number we are syncec to
13
- * details, and fetch transactions by hash.
10
+ * The Synchronizer class orchestrates synchronization between the PXE and Aztec node, maintaining an up-to-date
11
+ * view of the L2 chain state. It handles block header retrieval, chain reorganizations, and provides an interface
12
+ * for querying sync status.
14
13
  */
15
14
  export declare class Synchronizer implements L2BlockStreamEventHandler {
16
15
  private node;
@@ -18,7 +17,6 @@ export declare class Synchronizer implements L2BlockStreamEventHandler {
18
17
  private noteDataProvider;
19
18
  private taggingDataProvider;
20
19
  private l2TipsStore;
21
- private initialSyncBlockNumber;
22
20
  private log;
23
21
  private isSyncing;
24
22
  protected readonly blockStream: L2BlockStream;
@@ -27,7 +25,7 @@ export declare class Synchronizer implements L2BlockStreamEventHandler {
27
25
  /** Handle events emitted by the block stream. */
28
26
  handleBlockStreamEvent(event: L2BlockStreamEvent): Promise<void>;
29
27
  /**
30
- * Syncs PXE and the node by dowloading the metadata of the latest blocks, allowing simulations to use
28
+ * Syncs PXE and the node by downloading the metadata of the latest blocks, allowing simulations to use
31
29
  * recent data (e.g. notes), and handling any reorgs that might have occurred.
32
30
  */
33
31
  sync(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"synchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/synchronizer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC7G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qDAAqD,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qDAAqD,CAAC;AAC5F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2DAA2D,CAAC;AAErG;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,yBAAyB;IAO1D,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,WAAW;IAVrB,OAAO,CAAC,sBAAsB,CAA4B;IAC1D,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,SAAS,CAA4B;IAC7C,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC;gBAGpC,IAAI,EAAE,SAAS,EACf,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,gBAAgB,EAClC,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,aAAa,EAClC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAM,EACxD,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;IASlC,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAM/E,iDAAiD;IACpC,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC7E;;;OAGG;IACU,IAAI;YAiBH,MAAM;IAeP,qBAAqB;CAGnC"}
1
+ {"version":3,"file":"synchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/synchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC7G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qDAAqD,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qDAAqD,CAAC;AAC5F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2DAA2D,CAAC;AAErG;;;;GAIG;AACH,qBAAa,YAAa,YAAW,yBAAyB;IAM1D,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,WAAW;IATrB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,SAAS,CAA4B;IAC7C,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC;gBAGpC,IAAI,EAAE,SAAS,EACf,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,gBAAgB,EAClC,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,aAAa,EAClC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAM,EACxD,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;IASlC,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAM/E,iDAAiD;IACpC,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC7E;;;OAGG;IACU,IAAI;YAiBH,MAAM;IAeb,qBAAqB;CAG7B"}
@@ -1,18 +1,15 @@
1
- import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
1
  import { createLogger } from '@aztec/foundation/log';
3
2
  import { L2BlockStream } from '@aztec/stdlib/block';
4
3
  /**
5
- * The Synchronizer class manages the synchronization with the aztec node, allowing PXE to retrieve the
6
- * latest block header and handle reorgs.
7
- * It provides methods to trigger a sync and get the block number we are syncec to
8
- * details, and fetch transactions by hash.
4
+ * The Synchronizer class orchestrates synchronization between the PXE and Aztec node, maintaining an up-to-date
5
+ * view of the L2 chain state. It handles block header retrieval, chain reorganizations, and provides an interface
6
+ * for querying sync status.
9
7
  */ export class Synchronizer {
10
8
  node;
11
9
  syncDataProvider;
12
10
  noteDataProvider;
13
11
  taggingDataProvider;
14
12
  l2TipsStore;
15
- initialSyncBlockNumber;
16
13
  log;
17
14
  isSyncing;
18
15
  blockStream;
@@ -22,7 +19,6 @@ import { L2BlockStream } from '@aztec/stdlib/block';
22
19
  this.noteDataProvider = noteDataProvider;
23
20
  this.taggingDataProvider = taggingDataProvider;
24
21
  this.l2TipsStore = l2TipsStore;
25
- this.initialSyncBlockNumber = INITIAL_L2_BLOCK_NUM - 1;
26
22
  this.log = !loggerOrSuffix || typeof loggerOrSuffix === 'string' ? createLogger(loggerOrSuffix ? `pxe:synchronizer:${loggerOrSuffix}` : `pxe:synchronizer`) : loggerOrSuffix;
27
23
  this.blockStream = this.createBlockStream(config);
28
24
  }
@@ -47,18 +43,18 @@ import { L2BlockStream } from '@aztec/stdlib/block';
47
43
  }
48
44
  case 'chain-pruned':
49
45
  {
50
- this.log.warn(`Pruning data after block ${event.blockNumber} due to reorg`);
46
+ this.log.warn(`Pruning data after block ${event.block.number} due to reorg`);
51
47
  // We first unnullify and then remove so that unnullified notes that were created after the block number end up deleted.
52
48
  const lastSynchedBlockNumber = await this.syncDataProvider.getBlockNumber();
53
- await this.noteDataProvider.unnullifyNotesAfter(event.blockNumber, lastSynchedBlockNumber);
54
- await this.noteDataProvider.removeNotesAfter(event.blockNumber);
49
+ await this.noteDataProvider.unnullifyNotesAfter(event.block.number, lastSynchedBlockNumber);
50
+ await this.noteDataProvider.removeNotesAfter(event.block.number);
55
51
  // Remove all note tagging indexes to force a full resync. This is suboptimal, but unless we track the
56
52
  // block number in which each index is used it's all we can do.
57
53
  await this.taggingDataProvider.resetNoteSyncData();
58
54
  // Update the header to the last block.
59
- const newHeader = await this.node.getBlockHeader(event.blockNumber);
55
+ const newHeader = await this.node.getBlockHeader(event.block.number);
60
56
  if (!newHeader) {
61
- this.log.error(`Block header not found for block number ${event.blockNumber} during chain prune`);
57
+ this.log.error(`Block header not found for block number ${event.block.number} during chain prune`);
62
58
  } else {
63
59
  await this.syncDataProvider.setHeader(newHeader);
64
60
  }
@@ -67,7 +63,7 @@ import { L2BlockStream } from '@aztec/stdlib/block';
67
63
  }
68
64
  }
69
65
  /**
70
- * Syncs PXE and the node by dowloading the metadata of the latest blocks, allowing simulations to use
66
+ * Syncs PXE and the node by downloading the metadata of the latest blocks, allowing simulations to use
71
67
  * recent data (e.g. notes), and handling any reorgs that might have occurred.
72
68
  */ async sync() {
73
69
  if (this.isSyncing !== undefined) {
@@ -97,7 +93,7 @@ import { L2BlockStream } from '@aztec/stdlib/block';
97
93
  }
98
94
  await this.blockStream.sync();
99
95
  }
100
- async getSynchedBlockNumber() {
101
- return await this.syncDataProvider.getBlockNumber() ?? this.initialSyncBlockNumber;
96
+ getSynchedBlockNumber() {
97
+ return this.syncDataProvider.getBlockNumber();
102
98
  }
103
99
  }