@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.
- package/dest/config/package_info.js +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +15 -20
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.js +56 -103
- package/dest/pxe_service/pxe_service.d.ts +3 -2
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +26 -56
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +9 -0
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -1
- package/dest/storage/capsule_data_provider/capsule_data_provider.js +24 -0
- package/dest/storage/index.d.ts +1 -0
- package/dest/storage/index.d.ts.map +1 -1
- package/dest/storage/index.js +1 -0
- package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts +37 -0
- package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts.map +1 -0
- package/dest/storage/private_event_data_provider/private_event_data_provider.js +106 -0
- package/dest/storage/sync_data_provider/sync_data_provider.d.ts +1 -1
- package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +1 -1
- package/dest/storage/sync_data_provider/sync_data_provider.js +1 -1
- package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +4 -4
- package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +1 -1
- package/dest/storage/tagging_data_provider/tagging_data_provider.js +29 -12
- package/dest/synchronizer/synchronizer.d.ts +4 -6
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +11 -15
- package/dest/test/pxe_test_suite.js +1 -1
- package/package.json +15 -15
- package/src/config/package_info.ts +1 -1
- package/src/pxe_oracle_interface/pxe_oracle_interface.ts +113 -143
- package/src/pxe_service/pxe_service.ts +35 -76
- package/src/storage/capsule_data_provider/capsule_data_provider.ts +26 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/private_event_data_provider/private_event_data_provider.ts +137 -0
- package/src/storage/sync_data_provider/sync_data_provider.ts +2 -2
- package/src/storage/tagging_data_provider/tagging_data_provider.ts +44 -13
- package/src/synchronizer/synchronizer.ts +11 -14
- 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,
|
|
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.
|
|
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,
|
|
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
|
-
|
|
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,
|
|
605
|
-
|
|
606
|
-
|
|
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
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
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 =
|
|
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(
|
|
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
|
|
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;
|
|
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
|
}
|
package/dest/storage/index.d.ts
CHANGED
|
@@ -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"}
|
package/dest/storage/index.js
CHANGED
|
@@ -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
|
|
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,
|
|
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
|
-
|
|
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;
|
|
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
|
-
|
|
18
|
-
|
|
17
|
+
setTaggingSecretsIndexesAsSender(indexedSecrets, sender) {
|
|
18
|
+
return this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForSenders, sender);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
setTaggingSecretsIndexesAsRecipient(indexedSecrets, recipient) {
|
|
21
|
+
return this.#setTaggingSecretsIndexes(indexedSecrets, this.#taggingSecretIndexesForRecipients, recipient);
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
return
|
|
34
|
+
getTaggingSecretsIndexesAsRecipient(appTaggingSecrets, recipient) {
|
|
35
|
+
return this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForRecipients, recipient);
|
|
28
36
|
}
|
|
29
|
-
|
|
30
|
-
return
|
|
37
|
+
getTaggingSecretsIndexesAsSender(appTaggingSecrets, sender) {
|
|
38
|
+
return this.#getTaggingSecretsIndexes(appTaggingSecrets, this.#taggingSecretIndexesForSenders, sender);
|
|
31
39
|
}
|
|
32
|
-
|
|
33
|
-
|
|
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
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
|
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":"
|
|
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
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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.
|
|
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.
|
|
54
|
-
await this.noteDataProvider.removeNotesAfter(event.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
101
|
-
return
|
|
96
|
+
getSynchedBlockNumber() {
|
|
97
|
+
return this.syncDataProvider.getBlockNumber();
|
|
102
98
|
}
|
|
103
99
|
}
|