@aztec/pxe 0.82.2 → 0.82.3-nightly.20250330
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 +6 -3
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.js +29 -7
- 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 +21 -51
- 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 +94 -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/synchronizer/synchronizer.d.ts +6 -8
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +6 -10
- package/package.json +15 -15
- package/src/config/package_info.ts +1 -1
- package/src/pxe_oracle_interface/pxe_oracle_interface.ts +58 -6
- package/src/pxe_service/pxe_service.ts +25 -62
- package/src/storage/index.ts +1 -0
- package/src/storage/private_event_data_provider/private_event_data_provider.ts +128 -0
- package/src/storage/sync_data_provider/sync_data_provider.ts +2 -2
- package/src/synchronizer/synchronizer.ts +8 -11
|
@@ -2,7 +2,7 @@ import { type L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
|
|
|
2
2
|
import { Fr, Point } from '@aztec/foundation/fields';
|
|
3
3
|
import type { KeyStore } from '@aztec/key-store';
|
|
4
4
|
import { AcirSimulator, type ExecutionDataProvider, MessageLoadOracleInputs, type SimulationProvider } from '@aztec/simulator/client';
|
|
5
|
-
import { type FunctionArtifactWithContractName, FunctionSelector } from '@aztec/stdlib/abi';
|
|
5
|
+
import { EventSelector, type FunctionArtifactWithContractName, FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
6
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
7
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
8
8
|
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
@@ -17,6 +17,7 @@ import type { AddressDataProvider } from '../storage/address_data_provider/addre
|
|
|
17
17
|
import type { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
|
|
18
18
|
import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
19
19
|
import type { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
|
|
20
|
+
import type { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
|
|
20
21
|
import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
|
|
21
22
|
import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
|
|
22
23
|
/**
|
|
@@ -33,8 +34,9 @@ export declare class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
33
34
|
private syncDataProvider;
|
|
34
35
|
private taggingDataProvider;
|
|
35
36
|
private addressDataProvider;
|
|
37
|
+
private privateEventDataProvider;
|
|
36
38
|
private log;
|
|
37
|
-
constructor(aztecNode: AztecNode, keyStore: KeyStore, simulationProvider: SimulationProvider, contractDataProvider: ContractDataProvider, noteDataProvider: NoteDataProvider, capsuleDataProvider: CapsuleDataProvider, syncDataProvider: SyncDataProvider, taggingDataProvider: TaggingDataProvider, addressDataProvider: AddressDataProvider, log?: import("@aztec/foundation/log").Logger);
|
|
39
|
+
constructor(aztecNode: AztecNode, keyStore: KeyStore, simulationProvider: SimulationProvider, contractDataProvider: ContractDataProvider, noteDataProvider: NoteDataProvider, capsuleDataProvider: CapsuleDataProvider, syncDataProvider: SyncDataProvider, taggingDataProvider: TaggingDataProvider, addressDataProvider: AddressDataProvider, privateEventDataProvider: PrivateEventDataProvider, log?: import("@aztec/foundation/log").Logger);
|
|
38
40
|
getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest>;
|
|
39
41
|
getCompleteAddress(account: AztecAddress): Promise<CompleteAddress>;
|
|
40
42
|
getContractInstance(address: AztecAddress): Promise<ContractInstance>;
|
|
@@ -141,11 +143,12 @@ export declare class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
141
143
|
deliverNote(contractAddress: AztecAddress, storageSlot: Fr, nonce: Fr, content: Fr[], noteHash: Fr, nullifier: Fr, txHash: Fr, recipient: AztecAddress): Promise<void>;
|
|
142
144
|
getLogByTag(tag: Fr): Promise<LogWithTxData | null>;
|
|
143
145
|
removeNullifiedNotes(contractAddress: AztecAddress): Promise<void>;
|
|
144
|
-
callProcessLog(contractAddress: AztecAddress, logCiphertext: Fr[], txHash: TxHash, noteHashes: Fr[], firstNullifier: Fr, recipient: AztecAddress, simulator?: AcirSimulator): Promise<void>;
|
|
146
|
+
callProcessLog(contractAddress: AztecAddress, logCiphertext: Fr[], txHash: TxHash, noteHashes: Fr[], firstNullifier: Fr, logIndexInTx: number, recipient: AztecAddress, simulator?: AcirSimulator): Promise<void>;
|
|
145
147
|
storeCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void>;
|
|
146
148
|
loadCapsule(contractAddress: AztecAddress, slot: Fr): Promise<Fr[] | null>;
|
|
147
149
|
deleteCapsule(contractAddress: AztecAddress, slot: Fr): Promise<void>;
|
|
148
150
|
copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void>;
|
|
149
151
|
getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point>;
|
|
152
|
+
storePrivateEventLog(contractAddress: AztecAddress, recipient: AztecAddress, eventSelector: EventSelector, logContent: Fr[], txHash: TxHash, logIndexInTx: number): Promise<void>;
|
|
150
153
|
}
|
|
151
154
|
//# sourceMappingURL=pxe_oracle_interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pxe_oracle_interface.d.ts","sourceRoot":"","sources":["../../src/pxe_oracle_interface/pxe_oracle_interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAsD,MAAM,kBAAkB,CAAC;AAGrH,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,EAC1B,uBAAuB,EACvB,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"pxe_oracle_interface.d.ts","sourceRoot":"","sources":["../../src/pxe_oracle_interface/pxe_oracle_interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
|
|
2
2
|
import { timesParallel } from '@aztec/foundation/collection';
|
|
3
|
-
import { poseidon2Hash } from '@aztec/foundation/crypto';
|
|
3
|
+
import { poseidon2Hash, randomInt } from '@aztec/foundation/crypto';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { AcirSimulator, MessageLoadOracleInputs } from '@aztec/simulator/client';
|
|
@@ -26,8 +26,9 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
26
26
|
syncDataProvider;
|
|
27
27
|
taggingDataProvider;
|
|
28
28
|
addressDataProvider;
|
|
29
|
+
privateEventDataProvider;
|
|
29
30
|
log;
|
|
30
|
-
constructor(aztecNode, keyStore, simulationProvider, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, log = createLogger('pxe:pxe_oracle_interface')){
|
|
31
|
+
constructor(aztecNode, keyStore, simulationProvider, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, log = createLogger('pxe:pxe_oracle_interface')){
|
|
31
32
|
this.aztecNode = aztecNode;
|
|
32
33
|
this.keyStore = keyStore;
|
|
33
34
|
this.simulationProvider = simulationProvider;
|
|
@@ -37,6 +38,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
37
38
|
this.syncDataProvider = syncDataProvider;
|
|
38
39
|
this.taggingDataProvider = taggingDataProvider;
|
|
39
40
|
this.addressDataProvider = addressDataProvider;
|
|
41
|
+
this.privateEventDataProvider = privateEventDataProvider;
|
|
40
42
|
this.log = log;
|
|
41
43
|
}
|
|
42
44
|
getKeyValidationRequest(pkMHash, contractAddress) {
|
|
@@ -462,8 +464,18 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
462
464
|
if (!txEffect) {
|
|
463
465
|
throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
|
|
464
466
|
}
|
|
467
|
+
// TODO(#13155): Handle multiple found indexes for the same log.
|
|
468
|
+
let logIndexInTx = txEffect.data.privateLogs.findIndex((log)=>log.equals(scopedLog.log));
|
|
469
|
+
// TODO(#13137): The following is a workaround to disable the logIndexInTx check for TXE tests as TXE currently
|
|
470
|
+
// returns nonsensical tx effects and the tx has is incremented from 0 up (so it never crosses a 1000).
|
|
471
|
+
if (scopedLog.txHash.toBigInt() < 1000n) {
|
|
472
|
+
logIndexInTx = randomInt(10);
|
|
473
|
+
}
|
|
474
|
+
if (logIndexInTx === -1) {
|
|
475
|
+
throw new Error(`Could not find log in tx effect for tx hash ${scopedLog.txHash}`);
|
|
476
|
+
}
|
|
465
477
|
// This will trigger calls to the deliverNote oracle
|
|
466
|
-
await this.callProcessLog(contractAddress, scopedLog.log.toFields(), scopedLog.txHash, txEffect.data.noteHashes, txEffect.data.nullifiers[0], recipient, simulator);
|
|
478
|
+
await this.callProcessLog(contractAddress, scopedLog.log.toFields(), scopedLog.txHash, txEffect.data.noteHashes, txEffect.data.nullifiers[0], logIndexInTx, recipient, simulator);
|
|
467
479
|
}
|
|
468
480
|
return;
|
|
469
481
|
}
|
|
@@ -485,9 +497,6 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
485
497
|
// Note that while this technically results in historical queries, we perform it at the latest locally synced block
|
|
486
498
|
// number which *should* be recent enough to be available, even for non-archive nodes.
|
|
487
499
|
const syncedBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
488
|
-
if (syncedBlockNumber === undefined) {
|
|
489
|
-
throw new Error(`Attempted to deliver a note with an unsynchronized PXE - this should never happen`);
|
|
490
|
-
}
|
|
491
500
|
// By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
|
|
492
501
|
// of other contracts, which would constitute a security breach.
|
|
493
502
|
const uniqueNoteHash = await computeUniqueNoteHash(nonce, await siloNoteHash(contractAddress, noteHash));
|
|
@@ -590,7 +599,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
590
599
|
});
|
|
591
600
|
}
|
|
592
601
|
}
|
|
593
|
-
async callProcessLog(contractAddress, logCiphertext, txHash, noteHashes, firstNullifier, recipient, simulator) {
|
|
602
|
+
async callProcessLog(contractAddress, logCiphertext, txHash, noteHashes, firstNullifier, logIndexInTx, recipient, simulator) {
|
|
594
603
|
const artifact = await this.contractDataProvider.getFunctionArtifactByName(contractAddress, 'process_log');
|
|
595
604
|
if (!artifact) {
|
|
596
605
|
throw new Error(`Mandatory implementation of "process_log" missing in noir contract ${contractAddress.toString()}.`);
|
|
@@ -607,6 +616,7 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
607
616
|
txHash.toString(),
|
|
608
617
|
toBoundedVec(noteHashes, MAX_NOTE_HASHES_PER_TX),
|
|
609
618
|
firstNullifier,
|
|
619
|
+
logIndexInTx,
|
|
610
620
|
recipient
|
|
611
621
|
]),
|
|
612
622
|
returnTypes: artifact.returnTypes
|
|
@@ -632,6 +642,18 @@ import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndex
|
|
|
632
642
|
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
633
643
|
return deriveEcdhSharedSecret(addressSecret, ephPk);
|
|
634
644
|
}
|
|
645
|
+
async storePrivateEventLog(contractAddress, recipient, eventSelector, logContent, txHash, logIndexInTx) {
|
|
646
|
+
const txReceipt = await this.aztecNode.getTxReceipt(txHash);
|
|
647
|
+
const blockNumber = txReceipt.blockNumber;
|
|
648
|
+
if (blockNumber === undefined) {
|
|
649
|
+
throw new Error(`Block number is undefined for tx ${txHash} in storePrivateEventLog`);
|
|
650
|
+
}
|
|
651
|
+
const historicalBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
652
|
+
if (blockNumber > historicalBlockNumber) {
|
|
653
|
+
throw new Error(`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}`);
|
|
654
|
+
}
|
|
655
|
+
return this.privateEventDataProvider.storePrivateEventLog(contractAddress, recipient, eventSelector, logContent, txHash, logIndexInTx, blockNumber);
|
|
656
|
+
}
|
|
635
657
|
}
|
|
636
658
|
function toBoundedVec(array, maxLength) {
|
|
637
659
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
|
|
2
|
-
import { Fr
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { type Logger } from '@aztec/foundation/log';
|
|
4
4
|
import type { SiblingPath } from '@aztec/foundation/trees';
|
|
5
5
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
@@ -30,6 +30,7 @@ export declare class PXEService implements PXE {
|
|
|
30
30
|
private syncDataProvider;
|
|
31
31
|
private taggingDataProvider;
|
|
32
32
|
private addressDataProvider;
|
|
33
|
+
private privateEventDataProvider;
|
|
33
34
|
private simulator;
|
|
34
35
|
private packageVersion;
|
|
35
36
|
private proverEnabled;
|
|
@@ -91,7 +92,7 @@ export declare class PXEService implements PXE {
|
|
|
91
92
|
simulateUnconstrained(functionName: string, args: any[], to: AztecAddress, authwits?: AuthWitness[], _from?: AztecAddress, scopes?: AztecAddress[]): Promise<AbiDecoded>;
|
|
92
93
|
getNodeInfo(): Promise<NodeInfo>;
|
|
93
94
|
getPXEInfo(): Promise<PXEInfo>;
|
|
94
|
-
getPrivateEvents<T>(eventMetadataDef: EventMetadataDefinition, from: number,
|
|
95
|
+
getPrivateEvents<T>(contractAddress: AztecAddress, eventMetadataDef: EventMetadataDefinition, from: number, numBlocks: number, recipients: AztecAddress[]): Promise<T[]>;
|
|
95
96
|
getPublicEvents<T>(eventMetadataDef: EventMetadataDefinition, from: number, limit: number): Promise<T[]>;
|
|
96
97
|
resetNoteSyncData(): Promise<void>;
|
|
97
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pxe_service.d.ts","sourceRoot":"","sources":["../../src/pxe_service/pxe_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"pxe_service.d.ts","sourceRoot":"","sources":["../../src/pxe_service/pxe_service.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,15 +3,14 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
3
3
|
import { SerialQueue } from '@aztec/foundation/queue';
|
|
4
4
|
import { Timer } from '@aztec/foundation/timer';
|
|
5
5
|
import { KeyStore } from '@aztec/key-store';
|
|
6
|
-
import {
|
|
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
|
|
12
|
+
import { EventMetadata } from '@aztec/stdlib/event';
|
|
13
13
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
14
|
-
import { computeAddressSecret } from '@aztec/stdlib/keys';
|
|
15
14
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
16
15
|
import { UniqueNote } from '@aztec/stdlib/note';
|
|
17
16
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
@@ -25,6 +24,7 @@ import { AddressDataProvider } from '../storage/address_data_provider/address_da
|
|
|
25
24
|
import { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
|
|
26
25
|
import { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
27
26
|
import { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
|
|
27
|
+
import { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
|
|
28
28
|
import { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
|
|
29
29
|
import { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
|
|
30
30
|
import { Synchronizer } from '../synchronizer/index.js';
|
|
@@ -41,6 +41,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
41
41
|
syncDataProvider;
|
|
42
42
|
taggingDataProvider;
|
|
43
43
|
addressDataProvider;
|
|
44
|
+
privateEventDataProvider;
|
|
44
45
|
simulator;
|
|
45
46
|
packageVersion;
|
|
46
47
|
proverEnabled;
|
|
@@ -48,7 +49,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
48
49
|
protocolContractsProvider;
|
|
49
50
|
log;
|
|
50
51
|
jobQueue;
|
|
51
|
-
constructor(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue){
|
|
52
|
+
constructor(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue){
|
|
52
53
|
this.node = node;
|
|
53
54
|
this.synchronizer = synchronizer;
|
|
54
55
|
this.keyStore = keyStore;
|
|
@@ -58,6 +59,7 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
58
59
|
this.syncDataProvider = syncDataProvider;
|
|
59
60
|
this.taggingDataProvider = taggingDataProvider;
|
|
60
61
|
this.addressDataProvider = addressDataProvider;
|
|
62
|
+
this.privateEventDataProvider = privateEventDataProvider;
|
|
61
63
|
this.simulator = simulator;
|
|
62
64
|
this.packageVersion = packageVersion;
|
|
63
65
|
this.proverEnabled = proverEnabled;
|
|
@@ -77,18 +79,19 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
77
79
|
const packageVersion = getPackageInfo().version;
|
|
78
80
|
const proverEnabled = !!config.proverEnabled;
|
|
79
81
|
const addressDataProvider = new AddressDataProvider(store);
|
|
82
|
+
const privateEventDataProvider = new PrivateEventDataProvider(store);
|
|
80
83
|
const contractDataProvider = new ContractDataProvider(store);
|
|
81
84
|
const noteDataProvider = await NoteDataProvider.create(store);
|
|
82
85
|
const syncDataProvider = new SyncDataProvider(store);
|
|
83
86
|
const taggingDataProvider = new TaggingDataProvider(store);
|
|
84
87
|
const capsuleDataProvider = new CapsuleDataProvider(store);
|
|
85
88
|
const keyStore = new KeyStore(store);
|
|
86
|
-
const tipsStore = new
|
|
89
|
+
const tipsStore = new L2TipsKVStore(store, 'pxe');
|
|
87
90
|
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);
|
|
91
|
+
const pxeOracleInterface = new PXEOracleInterface(node, keyStore, simulationProvider, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, log);
|
|
89
92
|
const simulator = new AcirSimulator(pxeOracleInterface, simulationProvider);
|
|
90
93
|
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);
|
|
94
|
+
const pxeService = new PXEService(node, synchronizer, keyStore, contractDataProvider, noteDataProvider, capsuleDataProvider, syncDataProvider, taggingDataProvider, addressDataProvider, privateEventDataProvider, simulator, packageVersion, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue);
|
|
92
95
|
pxeService.jobQueue.start();
|
|
93
96
|
await pxeService.#registerProtocolContracts();
|
|
94
97
|
const info = await pxeService.getNodeInfo();
|
|
@@ -601,50 +604,17 @@ import { enrichPublicSimulationError, enrichSimulationError } from './error_enri
|
|
|
601
604
|
}
|
|
602
605
|
});
|
|
603
606
|
}
|
|
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');
|
|
607
|
+
async getPrivateEvents(contractAddress, eventMetadataDef, from, numBlocks, recipients) {
|
|
608
|
+
if (recipients.length === 0) {
|
|
609
|
+
throw new Error('Recipients are required to get private events');
|
|
609
610
|
}
|
|
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);
|
|
611
|
+
this.log.verbose(`Getting private events for ${contractAddress.toString()} from ${from} to ${from + numBlocks}`);
|
|
612
|
+
// TODO(#13113): This is a temporary hack to ensure that the notes are synced before getting the events.
|
|
613
|
+
await this.simulateUnconstrained('sync_notes', [], contractAddress);
|
|
614
|
+
const events = await this.privateEventDataProvider.getPrivateEvents(contractAddress, from, numBlocks, recipients, eventMetadataDef.eventSelector);
|
|
615
|
+
const decodedEvents = events.map((event)=>decodeFromAbi([
|
|
616
|
+
eventMetadataDef.abiType
|
|
617
|
+
], event));
|
|
648
618
|
return decodedEvents;
|
|
649
619
|
}
|
|
650
620
|
async getPublicEvents(eventMetadataDef, from, limit) {
|
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;AAOxD;;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;IAyBlB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAG3B"}
|
|
@@ -0,0 +1,94 @@
|
|
|
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
|
+
});
|
|
55
|
+
const existingIndices = await this.#eventLogIndex.getAsync(key) || [];
|
|
56
|
+
await this.#eventLogIndex.set(key, [
|
|
57
|
+
...existingIndices,
|
|
58
|
+
index
|
|
59
|
+
]);
|
|
60
|
+
// Mark this log as seen
|
|
61
|
+
await this.#seenLogs.set(txKey, true);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Returns the private events given search parameters.
|
|
66
|
+
* @param contractAddress - The address of the contract to get events from.
|
|
67
|
+
* @param from - The block number to search from.
|
|
68
|
+
* @param numBlocks - The amount of blocks to search.
|
|
69
|
+
* @param recipients - The addresses that decrypted the logs.
|
|
70
|
+
* @param eventSelector - The event selector to filter by.
|
|
71
|
+
* @returns - The event log contents.
|
|
72
|
+
*/ async getPrivateEvents(contractAddress, from, numBlocks, recipients, eventSelector) {
|
|
73
|
+
const events = [];
|
|
74
|
+
for (const recipient of recipients){
|
|
75
|
+
const key = `${contractAddress.toString()}_${recipient.toString()}_${eventSelector.toString()}`;
|
|
76
|
+
const indices = await this.#eventLogIndex.getAsync(key) || [];
|
|
77
|
+
for (const index of indices){
|
|
78
|
+
const entry = await this.#eventLogs.atAsync(index);
|
|
79
|
+
if (!entry || entry.blockNumber < from || entry.blockNumber >= from + numBlocks) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// Convert buffer back to Fr array
|
|
83
|
+
const reader = BufferReader.asReader(entry.logContent);
|
|
84
|
+
const numFields = entry.logContent.length / Fr.SIZE_IN_BYTES;
|
|
85
|
+
const logContent = reader.readArray(numFields, Fr);
|
|
86
|
+
events.push(logContent);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return events;
|
|
90
|
+
}
|
|
91
|
+
getSize() {
|
|
92
|
+
return this.#eventLogs.lengthAsync();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -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
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Logger } from '@aztec/foundation/log';
|
|
2
|
-
import type {
|
|
2
|
+
import type { L2TipsKVStore } from '@aztec/kv-store/stores';
|
|
3
3
|
import { L2BlockStream, type L2BlockStreamEvent, type L2BlockStreamEventHandler } from '@aztec/stdlib/block';
|
|
4
4
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
5
5
|
import type { PXEConfig } from '../config/index.js';
|
|
@@ -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,16 +17,15 @@ 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;
|
|
25
|
-
constructor(node: AztecNode, syncDataProvider: SyncDataProvider, noteDataProvider: NoteDataProvider, taggingDataProvider: TaggingDataProvider, l2TipsStore:
|
|
23
|
+
constructor(node: AztecNode, syncDataProvider: SyncDataProvider, noteDataProvider: NoteDataProvider, taggingDataProvider: TaggingDataProvider, l2TipsStore: L2TipsKVStore, config?: Partial<Pick<PXEConfig, 'l2StartingBlock'>>, loggerOrSuffix?: string | Logger);
|
|
26
24
|
protected createBlockStream(config: Partial<Pick<PXEConfig, 'l2StartingBlock'>>): L2BlockStream;
|
|
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
|
}
|
|
@@ -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
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.82.
|
|
3
|
+
"version": "0.82.3-nightly.20250330",
|
|
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.
|
|
63
|
-
"@aztec/bb.js": "0.82.
|
|
64
|
-
"@aztec/builder": "0.82.
|
|
65
|
-
"@aztec/constants": "0.82.
|
|
66
|
-
"@aztec/ethereum": "0.82.
|
|
67
|
-
"@aztec/foundation": "0.82.
|
|
68
|
-
"@aztec/key-store": "0.82.
|
|
69
|
-
"@aztec/kv-store": "0.82.
|
|
70
|
-
"@aztec/noir-protocol-circuits-types": "0.82.
|
|
71
|
-
"@aztec/noir-types": "0.82.
|
|
72
|
-
"@aztec/protocol-contracts": "0.82.
|
|
73
|
-
"@aztec/simulator": "0.82.
|
|
74
|
-
"@aztec/stdlib": "0.82.
|
|
62
|
+
"@aztec/bb-prover": "0.82.3-nightly.20250330",
|
|
63
|
+
"@aztec/bb.js": "0.82.3-nightly.20250330",
|
|
64
|
+
"@aztec/builder": "0.82.3-nightly.20250330",
|
|
65
|
+
"@aztec/constants": "0.82.3-nightly.20250330",
|
|
66
|
+
"@aztec/ethereum": "0.82.3-nightly.20250330",
|
|
67
|
+
"@aztec/foundation": "0.82.3-nightly.20250330",
|
|
68
|
+
"@aztec/key-store": "0.82.3-nightly.20250330",
|
|
69
|
+
"@aztec/kv-store": "0.82.3-nightly.20250330",
|
|
70
|
+
"@aztec/noir-protocol-circuits-types": "0.82.3-nightly.20250330",
|
|
71
|
+
"@aztec/noir-types": "0.82.3-nightly.20250330",
|
|
72
|
+
"@aztec/protocol-contracts": "0.82.3-nightly.20250330",
|
|
73
|
+
"@aztec/simulator": "0.82.3-nightly.20250330",
|
|
74
|
+
"@aztec/stdlib": "0.82.3-nightly.20250330",
|
|
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.
|
|
84
|
+
"@aztec/noir-contracts.js": "0.82.3-nightly.20250330",
|
|
85
85
|
"@jest/globals": "^29.5.0",
|
|
86
86
|
"@types/jest": "^29.5.0",
|
|
87
87
|
"@types/lodash.omit": "^4.5.7",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type L1_TO_L2_MSG_TREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
|
|
2
2
|
import { timesParallel } from '@aztec/foundation/collection';
|
|
3
|
-
import { poseidon2Hash } from '@aztec/foundation/crypto';
|
|
3
|
+
import { poseidon2Hash, randomInt } from '@aztec/foundation/crypto';
|
|
4
4
|
import { Fr, Point } from '@aztec/foundation/fields';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import type { KeyStore } from '@aztec/key-store';
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type SimulationProvider,
|
|
12
12
|
} from '@aztec/simulator/client';
|
|
13
13
|
import {
|
|
14
|
+
EventSelector,
|
|
14
15
|
type FunctionArtifact,
|
|
15
16
|
type FunctionArtifactWithContractName,
|
|
16
17
|
FunctionCall,
|
|
@@ -26,7 +27,13 @@ import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdli
|
|
|
26
27
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
27
28
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
28
29
|
import { computeAddressSecret, computeTaggingSecretPoint } from '@aztec/stdlib/keys';
|
|
29
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
IndexedTaggingSecret,
|
|
32
|
+
LogWithTxData,
|
|
33
|
+
PrivateLog,
|
|
34
|
+
TxScopedL2Log,
|
|
35
|
+
deriveEcdhSharedSecret,
|
|
36
|
+
} from '@aztec/stdlib/logs';
|
|
30
37
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
31
38
|
import { Note, type NoteStatus } from '@aztec/stdlib/note';
|
|
32
39
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
@@ -38,6 +45,7 @@ import type { CapsuleDataProvider } from '../storage/capsule_data_provider/capsu
|
|
|
38
45
|
import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
39
46
|
import { NoteDao } from '../storage/note_data_provider/note_dao.js';
|
|
40
47
|
import type { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
|
|
48
|
+
import type { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
|
|
41
49
|
import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
|
|
42
50
|
import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
|
|
43
51
|
import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
|
|
@@ -56,6 +64,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
56
64
|
private syncDataProvider: SyncDataProvider,
|
|
57
65
|
private taggingDataProvider: TaggingDataProvider,
|
|
58
66
|
private addressDataProvider: AddressDataProvider,
|
|
67
|
+
private privateEventDataProvider: PrivateEventDataProvider,
|
|
59
68
|
private log = createLogger('pxe:pxe_oracle_interface'),
|
|
60
69
|
) {}
|
|
61
70
|
|
|
@@ -608,6 +617,19 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
608
617
|
throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
|
|
609
618
|
}
|
|
610
619
|
|
|
620
|
+
// TODO(#13155): Handle multiple found indexes for the same log.
|
|
621
|
+
let logIndexInTx = txEffect.data.privateLogs.findIndex(log => log.equals(scopedLog.log as PrivateLog));
|
|
622
|
+
|
|
623
|
+
// TODO(#13137): The following is a workaround to disable the logIndexInTx check for TXE tests as TXE currently
|
|
624
|
+
// returns nonsensical tx effects and the tx has is incremented from 0 up (so it never crosses a 1000).
|
|
625
|
+
if (scopedLog.txHash.toBigInt() < 1000n) {
|
|
626
|
+
logIndexInTx = randomInt(10);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
if (logIndexInTx === -1) {
|
|
630
|
+
throw new Error(`Could not find log in tx effect for tx hash ${scopedLog.txHash}`);
|
|
631
|
+
}
|
|
632
|
+
|
|
611
633
|
// This will trigger calls to the deliverNote oracle
|
|
612
634
|
await this.callProcessLog(
|
|
613
635
|
contractAddress,
|
|
@@ -615,6 +637,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
615
637
|
scopedLog.txHash,
|
|
616
638
|
txEffect.data.noteHashes,
|
|
617
639
|
txEffect.data.nullifiers[0],
|
|
640
|
+
logIndexInTx,
|
|
618
641
|
recipient,
|
|
619
642
|
simulator,
|
|
620
643
|
);
|
|
@@ -649,10 +672,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
649
672
|
// in time of the locally synced state.
|
|
650
673
|
// Note that while this technically results in historical queries, we perform it at the latest locally synced block
|
|
651
674
|
// number which *should* be recent enough to be available, even for non-archive nodes.
|
|
652
|
-
const syncedBlockNumber =
|
|
653
|
-
if (syncedBlockNumber === undefined) {
|
|
654
|
-
throw new Error(`Attempted to deliver a note with an unsynchronized PXE - this should never happen`);
|
|
655
|
-
}
|
|
675
|
+
const syncedBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
656
676
|
|
|
657
677
|
// By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
|
|
658
678
|
// of other contracts, which would constitute a security breach.
|
|
@@ -784,6 +804,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
784
804
|
txHash: TxHash,
|
|
785
805
|
noteHashes: Fr[],
|
|
786
806
|
firstNullifier: Fr,
|
|
807
|
+
logIndexInTx: number,
|
|
787
808
|
recipient: AztecAddress,
|
|
788
809
|
simulator?: AcirSimulator,
|
|
789
810
|
) {
|
|
@@ -809,6 +830,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
809
830
|
txHash.toString(),
|
|
810
831
|
toBoundedVec(noteHashes, MAX_NOTE_HASHES_PER_TX),
|
|
811
832
|
firstNullifier,
|
|
833
|
+
logIndexInTx,
|
|
812
834
|
recipient,
|
|
813
835
|
]),
|
|
814
836
|
returnTypes: artifact.returnTypes,
|
|
@@ -847,6 +869,36 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
847
869
|
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
848
870
|
return deriveEcdhSharedSecret(addressSecret, ephPk);
|
|
849
871
|
}
|
|
872
|
+
|
|
873
|
+
async storePrivateEventLog(
|
|
874
|
+
contractAddress: AztecAddress,
|
|
875
|
+
recipient: AztecAddress,
|
|
876
|
+
eventSelector: EventSelector,
|
|
877
|
+
logContent: Fr[],
|
|
878
|
+
txHash: TxHash,
|
|
879
|
+
logIndexInTx: number,
|
|
880
|
+
): Promise<void> {
|
|
881
|
+
const txReceipt = await this.aztecNode.getTxReceipt(txHash);
|
|
882
|
+
const blockNumber = txReceipt.blockNumber;
|
|
883
|
+
if (blockNumber === undefined) {
|
|
884
|
+
throw new Error(`Block number is undefined for tx ${txHash} in storePrivateEventLog`);
|
|
885
|
+
}
|
|
886
|
+
const historicalBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
887
|
+
if (blockNumber > historicalBlockNumber) {
|
|
888
|
+
throw new Error(
|
|
889
|
+
`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}`,
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
return this.privateEventDataProvider.storePrivateEventLog(
|
|
893
|
+
contractAddress,
|
|
894
|
+
recipient,
|
|
895
|
+
eventSelector,
|
|
896
|
+
logContent,
|
|
897
|
+
txHash,
|
|
898
|
+
logIndexInTx,
|
|
899
|
+
blockNumber,
|
|
900
|
+
);
|
|
901
|
+
}
|
|
850
902
|
}
|
|
851
903
|
|
|
852
904
|
function toBoundedVec(array: Fr[], maxLength: number) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
|
|
2
|
-
import { Fr
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { SerialQueue } from '@aztec/foundation/queue';
|
|
5
5
|
import { Timer } from '@aztec/foundation/timer';
|
|
6
6
|
import type { SiblingPath } from '@aztec/foundation/trees';
|
|
7
7
|
import { KeyStore } from '@aztec/key-store';
|
|
8
8
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
9
|
-
import {
|
|
9
|
+
import { L2TipsKVStore } from '@aztec/kv-store/stores';
|
|
10
10
|
import {
|
|
11
11
|
ProtocolContractAddress,
|
|
12
12
|
type ProtocolContractsProvider,
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
FunctionCall,
|
|
21
21
|
FunctionSelector,
|
|
22
22
|
FunctionType,
|
|
23
|
+
decodeFromAbi,
|
|
23
24
|
decodeFunctionSignature,
|
|
24
25
|
encodeArguments,
|
|
25
26
|
} from '@aztec/stdlib/abi';
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
getContractClassFromArtifact,
|
|
37
38
|
} from '@aztec/stdlib/contract';
|
|
38
39
|
import { SimulationError } from '@aztec/stdlib/errors';
|
|
39
|
-
import { EventMetadata
|
|
40
|
+
import { EventMetadata } from '@aztec/stdlib/event';
|
|
40
41
|
import type { GasFees } from '@aztec/stdlib/gas';
|
|
41
42
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
42
43
|
import type {
|
|
@@ -49,7 +50,6 @@ import type {
|
|
|
49
50
|
PrivateKernelProver,
|
|
50
51
|
} from '@aztec/stdlib/interfaces/client';
|
|
51
52
|
import type { PrivateKernelExecutionProofOutput, PrivateKernelTailCircuitPublicInputs } from '@aztec/stdlib/kernel';
|
|
52
|
-
import { computeAddressSecret } from '@aztec/stdlib/keys';
|
|
53
53
|
import type { LogFilter } from '@aztec/stdlib/logs';
|
|
54
54
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
55
55
|
import { type NotesFilter, UniqueNote } from '@aztec/stdlib/note';
|
|
@@ -82,6 +82,7 @@ import { AddressDataProvider } from '../storage/address_data_provider/address_da
|
|
|
82
82
|
import { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
|
|
83
83
|
import { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
84
84
|
import { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
|
|
85
|
+
import { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
|
|
85
86
|
import { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
|
|
86
87
|
import { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
|
|
87
88
|
import { Synchronizer } from '../synchronizer/index.js';
|
|
@@ -101,6 +102,7 @@ export class PXEService implements PXE {
|
|
|
101
102
|
private syncDataProvider: SyncDataProvider,
|
|
102
103
|
private taggingDataProvider: TaggingDataProvider,
|
|
103
104
|
private addressDataProvider: AddressDataProvider,
|
|
105
|
+
private privateEventDataProvider: PrivateEventDataProvider,
|
|
104
106
|
private simulator: AcirSimulator,
|
|
105
107
|
private packageVersion: string,
|
|
106
108
|
private proverEnabled: boolean,
|
|
@@ -134,13 +136,14 @@ export class PXEService implements PXE {
|
|
|
134
136
|
const packageVersion = getPackageInfo().version;
|
|
135
137
|
const proverEnabled = !!config.proverEnabled;
|
|
136
138
|
const addressDataProvider = new AddressDataProvider(store);
|
|
139
|
+
const privateEventDataProvider = new PrivateEventDataProvider(store);
|
|
137
140
|
const contractDataProvider = new ContractDataProvider(store);
|
|
138
141
|
const noteDataProvider = await NoteDataProvider.create(store);
|
|
139
142
|
const syncDataProvider = new SyncDataProvider(store);
|
|
140
143
|
const taggingDataProvider = new TaggingDataProvider(store);
|
|
141
144
|
const capsuleDataProvider = new CapsuleDataProvider(store);
|
|
142
145
|
const keyStore = new KeyStore(store);
|
|
143
|
-
const tipsStore = new
|
|
146
|
+
const tipsStore = new L2TipsKVStore(store, 'pxe');
|
|
144
147
|
const synchronizer = new Synchronizer(
|
|
145
148
|
node,
|
|
146
149
|
syncDataProvider,
|
|
@@ -160,6 +163,7 @@ export class PXEService implements PXE {
|
|
|
160
163
|
syncDataProvider,
|
|
161
164
|
taggingDataProvider,
|
|
162
165
|
addressDataProvider,
|
|
166
|
+
privateEventDataProvider,
|
|
163
167
|
log,
|
|
164
168
|
);
|
|
165
169
|
const simulator = new AcirSimulator(pxeOracleInterface, simulationProvider);
|
|
@@ -175,6 +179,7 @@ export class PXEService implements PXE {
|
|
|
175
179
|
syncDataProvider,
|
|
176
180
|
taggingDataProvider,
|
|
177
181
|
addressDataProvider,
|
|
182
|
+
privateEventDataProvider,
|
|
178
183
|
simulator,
|
|
179
184
|
packageVersion,
|
|
180
185
|
proverEnabled,
|
|
@@ -881,72 +886,30 @@ export class PXEService implements PXE {
|
|
|
881
886
|
}
|
|
882
887
|
|
|
883
888
|
public async getPrivateEvents<T>(
|
|
889
|
+
contractAddress: AztecAddress,
|
|
884
890
|
eventMetadataDef: EventMetadataDefinition,
|
|
885
891
|
from: number,
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
vpks: Point[],
|
|
892
|
+
numBlocks: number,
|
|
893
|
+
recipients: AztecAddress[],
|
|
889
894
|
): Promise<T[]> {
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
throw new Error('Tried to get encrypted events without supplying any viewing public keys');
|
|
895
|
+
if (recipients.length === 0) {
|
|
896
|
+
throw new Error('Recipients are required to get private events');
|
|
893
897
|
}
|
|
894
898
|
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
const txEffects = blocks.flatMap(block => block.body.txEffects);
|
|
898
|
-
const privateLogs = txEffects.flatMap(txEffect => txEffect.privateLogs);
|
|
899
|
+
this.log.verbose(`Getting private events for ${contractAddress.toString()} from ${from} to ${from + numBlocks}`);
|
|
899
900
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
const [keyPrefix, account] = await this.keyStore.getKeyPrefixAndAccount(vpk);
|
|
903
|
-
let secretKey = await this.keyStore.getMasterSecretKey(vpk);
|
|
904
|
-
if (keyPrefix === 'iv') {
|
|
905
|
-
const registeredAccount = (await this.getRegisteredAccounts()).find(completeAddress =>
|
|
906
|
-
completeAddress.address.equals(account),
|
|
907
|
-
);
|
|
908
|
-
if (!registeredAccount) {
|
|
909
|
-
throw new Error('No registered account');
|
|
910
|
-
}
|
|
901
|
+
// TODO(#13113): This is a temporary hack to ensure that the notes are synced before getting the events.
|
|
902
|
+
await this.simulateUnconstrained('sync_notes', [], contractAddress);
|
|
911
903
|
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
}),
|
|
904
|
+
const events = await this.privateEventDataProvider.getPrivateEvents(
|
|
905
|
+
contractAddress,
|
|
906
|
+
from,
|
|
907
|
+
numBlocks,
|
|
908
|
+
recipients,
|
|
909
|
+
eventMetadataDef.eventSelector,
|
|
919
910
|
);
|
|
920
911
|
|
|
921
|
-
const
|
|
922
|
-
await Promise.all(
|
|
923
|
-
privateLogs.map(async log => {
|
|
924
|
-
for (const sk of vsks) {
|
|
925
|
-
// TODO: Verify that the first field of the log is the tag siloed with contract address.
|
|
926
|
-
// Or use tags to query logs, like we do with notes.
|
|
927
|
-
const decryptedEvent = await L1EventPayload.decryptAsIncoming(log, sk);
|
|
928
|
-
if (decryptedEvent !== undefined) {
|
|
929
|
-
return [decryptedEvent];
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
return [];
|
|
934
|
-
}),
|
|
935
|
-
)
|
|
936
|
-
).flat();
|
|
937
|
-
|
|
938
|
-
const decodedEvents = visibleEvents
|
|
939
|
-
.map(visibleEvent => {
|
|
940
|
-
if (visibleEvent === undefined) {
|
|
941
|
-
return undefined;
|
|
942
|
-
}
|
|
943
|
-
if (!visibleEvent.eventTypeId.equals(eventMetadata.eventSelector)) {
|
|
944
|
-
return undefined;
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
return eventMetadata.decode(visibleEvent);
|
|
948
|
-
})
|
|
949
|
-
.filter(visibleEvent => visibleEvent !== undefined) as T[];
|
|
912
|
+
const decodedEvents = events.map((event: Fr[]): T => decodeFromAbi([eventMetadataDef.abiType], event) as T);
|
|
950
913
|
|
|
951
914
|
return decodedEvents;
|
|
952
915
|
}
|
package/src/storage/index.ts
CHANGED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
4
|
+
import type { AztecAsyncArray, AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
5
|
+
import type { EventSelector } from '@aztec/stdlib/abi';
|
|
6
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
+
import type { TxHash } from '@aztec/stdlib/tx';
|
|
8
|
+
|
|
9
|
+
import type { DataProvider } from '../data_provider.js';
|
|
10
|
+
|
|
11
|
+
interface PrivateEventEntry {
|
|
12
|
+
logContent: Buffer;
|
|
13
|
+
blockNumber: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Stores decrypted private event logs.
|
|
18
|
+
*/
|
|
19
|
+
export class PrivateEventDataProvider implements DataProvider {
|
|
20
|
+
#store: AztecAsyncKVStore;
|
|
21
|
+
/** Array storing the actual private event log entries containing the log content and block number */
|
|
22
|
+
#eventLogs: AztecAsyncArray<PrivateEventEntry>;
|
|
23
|
+
/** Map from contract_address_recipient_eventSelector to array of indices into #eventLogs for efficient lookup */
|
|
24
|
+
#eventLogIndex: AztecAsyncMap<string, number[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Map from txHash_logIndexInTx to boolean indicating if log has been seen.
|
|
27
|
+
* @dev A single transaction can have multiple logs.
|
|
28
|
+
*/
|
|
29
|
+
#seenLogs: AztecAsyncMap<string, boolean>;
|
|
30
|
+
|
|
31
|
+
logger = createLogger('private_event_data_provider');
|
|
32
|
+
|
|
33
|
+
constructor(store: AztecAsyncKVStore) {
|
|
34
|
+
this.#store = store;
|
|
35
|
+
this.#eventLogs = this.#store.openArray('private_event_logs');
|
|
36
|
+
this.#eventLogIndex = this.#store.openMap('private_event_log_index');
|
|
37
|
+
this.#seenLogs = this.#store.openMap('seen_logs');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Store a private event log.
|
|
42
|
+
* @param contractAddress - The address of the contract that emitted the event.
|
|
43
|
+
* @param recipient - The recipient of the event.
|
|
44
|
+
* @param eventSelector - The event selector of the event.
|
|
45
|
+
* @param logContent - The content of the event.
|
|
46
|
+
* @param txHash - The transaction hash of the event log.
|
|
47
|
+
* @param logIndexInTx - The index of the log within the transaction.
|
|
48
|
+
* @param blockNumber - The block number in which the event was emitted.
|
|
49
|
+
*/
|
|
50
|
+
storePrivateEventLog(
|
|
51
|
+
contractAddress: AztecAddress,
|
|
52
|
+
recipient: AztecAddress,
|
|
53
|
+
eventSelector: EventSelector,
|
|
54
|
+
logContent: Fr[],
|
|
55
|
+
txHash: TxHash,
|
|
56
|
+
logIndexInTx: number,
|
|
57
|
+
blockNumber: number,
|
|
58
|
+
): Promise<void> {
|
|
59
|
+
return this.#store.transactionAsync(async () => {
|
|
60
|
+
const key = `${contractAddress.toString()}_${recipient.toString()}_${eventSelector.toString()}`;
|
|
61
|
+
|
|
62
|
+
// We identify a unique log by its transaction hash and index within that transaction
|
|
63
|
+
const txKey = `${txHash.toString()}_${logIndexInTx}`;
|
|
64
|
+
|
|
65
|
+
// Check if this exact log has already been stored
|
|
66
|
+
const hasBeenSeen = await this.#seenLogs.getAsync(txKey);
|
|
67
|
+
if (hasBeenSeen) {
|
|
68
|
+
this.logger.verbose('Ignoring duplicate event log', { txHash: txHash.toString(), logIndexInTx });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.logger.verbose('storing private event log', { contractAddress, recipient, logContent, blockNumber });
|
|
73
|
+
|
|
74
|
+
const index = await this.#eventLogs.lengthAsync();
|
|
75
|
+
await this.#eventLogs.push({ logContent: serializeToBuffer(logContent), blockNumber });
|
|
76
|
+
|
|
77
|
+
const existingIndices = (await this.#eventLogIndex.getAsync(key)) || [];
|
|
78
|
+
await this.#eventLogIndex.set(key, [...existingIndices, index]);
|
|
79
|
+
|
|
80
|
+
// Mark this log as seen
|
|
81
|
+
await this.#seenLogs.set(txKey, true);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns the private events given search parameters.
|
|
87
|
+
* @param contractAddress - The address of the contract to get events from.
|
|
88
|
+
* @param from - The block number to search from.
|
|
89
|
+
* @param numBlocks - The amount of blocks to search.
|
|
90
|
+
* @param recipients - The addresses that decrypted the logs.
|
|
91
|
+
* @param eventSelector - The event selector to filter by.
|
|
92
|
+
* @returns - The event log contents.
|
|
93
|
+
*/
|
|
94
|
+
public async getPrivateEvents(
|
|
95
|
+
contractAddress: AztecAddress,
|
|
96
|
+
from: number,
|
|
97
|
+
numBlocks: number,
|
|
98
|
+
recipients: AztecAddress[],
|
|
99
|
+
eventSelector: EventSelector,
|
|
100
|
+
): Promise<Fr[][]> {
|
|
101
|
+
const events: Fr[][] = [];
|
|
102
|
+
|
|
103
|
+
for (const recipient of recipients) {
|
|
104
|
+
const key = `${contractAddress.toString()}_${recipient.toString()}_${eventSelector.toString()}`;
|
|
105
|
+
const indices = (await this.#eventLogIndex.getAsync(key)) || [];
|
|
106
|
+
|
|
107
|
+
for (const index of indices) {
|
|
108
|
+
const entry = await this.#eventLogs.atAsync(index);
|
|
109
|
+
if (!entry || entry.blockNumber < from || entry.blockNumber >= from + numBlocks) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Convert buffer back to Fr array
|
|
114
|
+
const reader = BufferReader.asReader(entry.logContent);
|
|
115
|
+
const numFields = entry.logContent.length / Fr.SIZE_IN_BYTES;
|
|
116
|
+
const logContent = reader.readArray(numFields, Fr);
|
|
117
|
+
|
|
118
|
+
events.push(logContent);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return events;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getSize(): Promise<number> {
|
|
126
|
+
return this.#eventLogs.lengthAsync();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -16,10 +16,10 @@ export class SyncDataProvider implements DataProvider {
|
|
|
16
16
|
await this.#synchronizedHeader.set(header.toBuffer());
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
async getBlockNumber(): Promise<number
|
|
19
|
+
async getBlockNumber(): Promise<number> {
|
|
20
20
|
const headerBuffer = await this.#synchronizedHeader.getAsync();
|
|
21
21
|
if (!headerBuffer) {
|
|
22
|
-
|
|
22
|
+
throw new Error(`Trying to get block number with a not-yet-synchronized PXE - this should never happen`);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
return Number(BlockHeader.fromBuffer(headerBuffer).globalVariables.blockNumber.toBigInt());
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
1
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import type {
|
|
2
|
+
import type { L2TipsKVStore } from '@aztec/kv-store/stores';
|
|
4
3
|
import { L2BlockStream, type L2BlockStreamEvent, type L2BlockStreamEventHandler } from '@aztec/stdlib/block';
|
|
5
4
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
6
5
|
|
|
@@ -10,13 +9,11 @@ import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_p
|
|
|
10
9
|
import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
|
-
* The Synchronizer class
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* details, and fetch transactions by hash.
|
|
12
|
+
* The Synchronizer class orchestrates synchronization between the PXE and Aztec node, maintaining an up-to-date
|
|
13
|
+
* view of the L2 chain state. It handles block header retrieval, chain reorganizations, and provides an interface
|
|
14
|
+
* for querying sync status.
|
|
17
15
|
*/
|
|
18
16
|
export class Synchronizer implements L2BlockStreamEventHandler {
|
|
19
|
-
private initialSyncBlockNumber = INITIAL_L2_BLOCK_NUM - 1;
|
|
20
17
|
private log: Logger;
|
|
21
18
|
private isSyncing: Promise<void> | undefined;
|
|
22
19
|
protected readonly blockStream: L2BlockStream;
|
|
@@ -26,7 +23,7 @@ export class Synchronizer implements L2BlockStreamEventHandler {
|
|
|
26
23
|
private syncDataProvider: SyncDataProvider,
|
|
27
24
|
private noteDataProvider: NoteDataProvider,
|
|
28
25
|
private taggingDataProvider: TaggingDataProvider,
|
|
29
|
-
private l2TipsStore:
|
|
26
|
+
private l2TipsStore: L2TipsKVStore,
|
|
30
27
|
config: Partial<Pick<PXEConfig, 'l2StartingBlock'>> = {},
|
|
31
28
|
loggerOrSuffix?: string | Logger,
|
|
32
29
|
) {
|
|
@@ -80,7 +77,7 @@ export class Synchronizer implements L2BlockStreamEventHandler {
|
|
|
80
77
|
}
|
|
81
78
|
|
|
82
79
|
/**
|
|
83
|
-
* Syncs PXE and the node by
|
|
80
|
+
* Syncs PXE and the node by downloading the metadata of the latest blocks, allowing simulations to use
|
|
84
81
|
* recent data (e.g. notes), and handling any reorgs that might have occurred.
|
|
85
82
|
*/
|
|
86
83
|
public async sync() {
|
|
@@ -115,7 +112,7 @@ export class Synchronizer implements L2BlockStreamEventHandler {
|
|
|
115
112
|
await this.blockStream.sync();
|
|
116
113
|
}
|
|
117
114
|
|
|
118
|
-
public
|
|
119
|
-
return
|
|
115
|
+
public getSynchedBlockNumber() {
|
|
116
|
+
return this.syncDataProvider.getBlockNumber();
|
|
120
117
|
}
|
|
121
118
|
}
|