@aztec/pxe 0.0.1-commit.e310a4c8 → 0.0.1-commit.e558bd1c
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/block_synchronizer/block_synchronizer.d.ts +4 -2
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +7 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +4 -2
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +4 -2
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +2 -2
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.d.ts +2 -2
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +20 -8
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +4 -2
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +6 -6
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +5 -5
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +20 -18
- package/dest/contract_sync/contract_sync_service.d.ts +41 -0
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -0
- package/dest/contract_sync/contract_sync_service.js +82 -0
- package/dest/contract_sync/helpers.d.ts +28 -0
- package/dest/contract_sync/helpers.d.ts.map +1 -0
- package/dest/contract_sync/{index.js → helpers.js} +13 -12
- package/dest/debug/pxe_debug_utils.d.ts +12 -7
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +16 -12
- package/dest/entrypoints/server/index.d.ts +2 -2
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +1 -1
- package/dest/logs/log_service.d.ts +2 -2
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +2 -4
- package/dest/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +2 -2
- package/dest/pxe.d.ts +2 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +23 -12
- package/dest/storage/note_store/note_store.d.ts +1 -1
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +3 -0
- package/package.json +25 -16
- package/src/block_synchronizer/block_synchronizer.ts +6 -0
- package/src/contract_function_simulator/contract_function_simulator.ts +3 -0
- package/src/contract_function_simulator/oracle/interfaces.ts +1 -1
- package/src/contract_function_simulator/oracle/oracle.ts +11 -4
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +6 -5
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +22 -19
- package/src/contract_sync/contract_sync_service.ts +129 -0
- package/src/contract_sync/{index.ts → helpers.ts} +15 -20
- package/src/debug/pxe_debug_utils.ts +46 -13
- package/src/entrypoints/server/index.ts +1 -1
- package/src/logs/log_service.ts +2 -2
- package/src/oracle_version.ts +2 -2
- package/src/pxe.ts +33 -13
- package/src/storage/note_store/note_store.ts +4 -0
- package/dest/contract_sync/index.d.ts +0 -23
- package/dest/contract_sync/index.d.ts.map +0 -1
package/dest/pxe.js
CHANGED
|
@@ -13,7 +13,8 @@ import { BlockSynchronizer } from './block_synchronizer/index.js';
|
|
|
13
13
|
import { BenchmarkedNodeFactory } from './contract_function_simulator/benchmarked_node.js';
|
|
14
14
|
import { ContractFunctionSimulator, generateSimulatedProvingResult } from './contract_function_simulator/contract_function_simulator.js';
|
|
15
15
|
import { ProxiedContractStoreFactory } from './contract_function_simulator/proxied_contract_data_source.js';
|
|
16
|
-
import {
|
|
16
|
+
import { ContractSyncService } from './contract_sync/contract_sync_service.js';
|
|
17
|
+
import { readCurrentClassId } from './contract_sync/helpers.js';
|
|
17
18
|
import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
|
|
18
19
|
import { enrichPublicSimulationError, enrichSimulationError } from './error_enriching.js';
|
|
19
20
|
import { PrivateEventFilterValidator } from './events/private_event_filter_validator.js';
|
|
@@ -45,6 +46,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
45
46
|
recipientTaggingStore;
|
|
46
47
|
addressStore;
|
|
47
48
|
privateEventStore;
|
|
49
|
+
contractSyncService;
|
|
48
50
|
simulator;
|
|
49
51
|
proverEnabled;
|
|
50
52
|
proofCreator;
|
|
@@ -53,7 +55,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
53
55
|
jobQueue;
|
|
54
56
|
jobCoordinator;
|
|
55
57
|
debug;
|
|
56
|
-
constructor(node, blockStateSynchronizer, keyStore, contractStore, noteStore, capsuleStore, anchorBlockStore, senderTaggingStore, senderAddressBookStore, recipientTaggingStore, addressStore, privateEventStore, simulator, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue, jobCoordinator, debug){
|
|
58
|
+
constructor(node, blockStateSynchronizer, keyStore, contractStore, noteStore, capsuleStore, anchorBlockStore, senderTaggingStore, senderAddressBookStore, recipientTaggingStore, addressStore, privateEventStore, contractSyncService, simulator, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue, jobCoordinator, debug){
|
|
57
59
|
this.node = node;
|
|
58
60
|
this.blockStateSynchronizer = blockStateSynchronizer;
|
|
59
61
|
this.keyStore = keyStore;
|
|
@@ -66,6 +68,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
66
68
|
this.recipientTaggingStore = recipientTaggingStore;
|
|
67
69
|
this.addressStore = addressStore;
|
|
68
70
|
this.privateEventStore = privateEventStore;
|
|
71
|
+
this.contractSyncService = contractSyncService;
|
|
69
72
|
this.simulator = simulator;
|
|
70
73
|
this.proverEnabled = proverEnabled;
|
|
71
74
|
this.proofCreator = proofCreator;
|
|
@@ -97,19 +100,21 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
97
100
|
const capsuleStore = new CapsuleStore(store);
|
|
98
101
|
const keyStore = new KeyStore(store);
|
|
99
102
|
const tipsStore = new L2TipsKVStore(store, 'pxe');
|
|
100
|
-
const
|
|
103
|
+
const contractSyncService = new ContractSyncService(node, contractStore, noteStore, createLogger('pxe:contract_sync', bindings));
|
|
104
|
+
const synchronizer = new BlockSynchronizer(node, store, anchorBlockStore, noteStore, privateEventStore, tipsStore, contractSyncService, config, bindings);
|
|
101
105
|
const jobCoordinator = new JobCoordinator(store, bindings);
|
|
102
106
|
jobCoordinator.registerStores([
|
|
103
107
|
capsuleStore,
|
|
104
108
|
senderTaggingStore,
|
|
105
109
|
recipientTaggingStore,
|
|
106
110
|
privateEventStore,
|
|
107
|
-
noteStore
|
|
111
|
+
noteStore,
|
|
112
|
+
contractSyncService
|
|
108
113
|
]);
|
|
109
|
-
const debugUtils = new PXEDebugUtils(
|
|
114
|
+
const debugUtils = new PXEDebugUtils(contractSyncService, noteStore, synchronizer, anchorBlockStore);
|
|
110
115
|
const jobQueue = new SerialQueue();
|
|
111
|
-
const pxe = new PXE(node, synchronizer, keyStore, contractStore, noteStore, capsuleStore, anchorBlockStore, senderTaggingStore, senderAddressBookStore, recipientTaggingStore, addressStore, privateEventStore, simulator, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue, jobCoordinator, debugUtils);
|
|
112
|
-
debugUtils.
|
|
116
|
+
const pxe = new PXE(node, synchronizer, keyStore, contractStore, noteStore, capsuleStore, anchorBlockStore, senderTaggingStore, senderAddressBookStore, recipientTaggingStore, addressStore, privateEventStore, contractSyncService, simulator, proverEnabled, proofCreator, protocolContractsProvider, log, jobQueue, jobCoordinator, debugUtils);
|
|
117
|
+
debugUtils.setPXEHelpers(pxe.#putInJobQueue.bind(pxe), pxe.#getSimulatorForTx.bind(pxe), pxe.#simulateUtility.bind(pxe));
|
|
113
118
|
pxe.jobQueue.start();
|
|
114
119
|
await pxe.#registerProtocolContracts();
|
|
115
120
|
const info = await node.getNodeInfo();
|
|
@@ -119,7 +124,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
119
124
|
// Internal methods
|
|
120
125
|
#getSimulatorForTx(overrides) {
|
|
121
126
|
const proxyContractStore = ProxiedContractStoreFactory.create(this.contractStore, overrides?.contracts);
|
|
122
|
-
return new ContractFunctionSimulator(proxyContractStore, this.noteStore, this.keyStore, this.addressStore, BenchmarkedNodeFactory.create(this.node), this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.simulator);
|
|
127
|
+
return new ContractFunctionSimulator(proxyContractStore, this.noteStore, this.keyStore, this.addressStore, BenchmarkedNodeFactory.create(this.node), this.senderTaggingStore, this.recipientTaggingStore, this.senderAddressBookStore, this.capsuleStore, this.privateEventStore, this.simulator, this.contractSyncService);
|
|
123
128
|
}
|
|
124
129
|
#contextualizeError(err, ...context) {
|
|
125
130
|
let contextStr = '';
|
|
@@ -175,7 +180,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
175
180
|
const { origin: contractAddress, functionSelector } = txRequest;
|
|
176
181
|
try {
|
|
177
182
|
const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
|
|
178
|
-
await ensureContractSynced(contractAddress, functionSelector, (privateSyncCall)=>this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
|
|
183
|
+
await this.contractSyncService.ensureContractSynced(contractAddress, functionSelector, (privateSyncCall)=>this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId), anchorBlockHeader, jobId);
|
|
179
184
|
const result = await contractFunctionSimulator.run(txRequest, contractAddress, functionSelector, undefined, anchorBlockHeader, // The sender for tags is set by contracts, typically by an account
|
|
180
185
|
// contract entrypoint
|
|
181
186
|
undefined, scopes, jobId);
|
|
@@ -586,7 +591,13 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
586
591
|
// Temporary: in case there are overrides, we have to skip the kernels or validations
|
|
587
592
|
// will fail. Consider handing control to the user/wallet on whether they want to run them
|
|
588
593
|
// or not.
|
|
589
|
-
const
|
|
594
|
+
const overriddenContracts = overrides?.contracts ? new Set(Object.keys(overrides.contracts)) : undefined;
|
|
595
|
+
const hasOverriddenContracts = overriddenContracts !== undefined && overriddenContracts.size > 0;
|
|
596
|
+
const skipKernels = hasOverriddenContracts;
|
|
597
|
+
// Set overridden contracts on the sync service so it knows to skip syncing them
|
|
598
|
+
if (hasOverriddenContracts) {
|
|
599
|
+
this.contractSyncService.setOverriddenContracts(jobId, overriddenContracts);
|
|
600
|
+
}
|
|
590
601
|
// Execution of private functions only; no proving, and no kernel logic.
|
|
591
602
|
const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, scopes, jobId);
|
|
592
603
|
let publicInputs;
|
|
@@ -677,7 +688,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
677
688
|
const functionTimer = new Timer();
|
|
678
689
|
const contractFunctionSimulator = this.#getSimulatorForTx();
|
|
679
690
|
const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
|
|
680
|
-
await ensureContractSynced(call.to, call.selector, (privateSyncCall)=>this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
|
|
691
|
+
await this.contractSyncService.ensureContractSynced(call.to, call.selector, (privateSyncCall)=>this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId), anchorBlockHeader, jobId);
|
|
681
692
|
const executionResult = await this.#simulateUtility(contractFunctionSimulator, call, authwits ?? [], scopes, jobId);
|
|
682
693
|
const functionTime = functionTimer.ms();
|
|
683
694
|
const totalTime = totalTimer.ms();
|
|
@@ -727,7 +738,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
727
738
|
const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
|
|
728
739
|
anchorBlockNumber = anchorBlockHeader.getBlockNumber();
|
|
729
740
|
const contractFunctionSimulator = this.#getSimulatorForTx();
|
|
730
|
-
await ensureContractSynced(filter.contractAddress, null, async (privateSyncCall)=>await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
|
|
741
|
+
await this.contractSyncService.ensureContractSynced(filter.contractAddress, null, async (privateSyncCall)=>await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId), anchorBlockHeader, jobId);
|
|
731
742
|
});
|
|
732
743
|
// anchorBlockNumber is set during the job and fixed to whatever it is after a block sync
|
|
733
744
|
const sanitizedFilter = new PrivateEventFilterValidator(anchorBlockNumber).validate(filter);
|
|
@@ -80,4 +80,4 @@ export declare class NoteStore implements StagedStore {
|
|
|
80
80
|
commit(jobId: string): Promise<void>;
|
|
81
81
|
discardStaged(jobId: string): Promise<void>;
|
|
82
82
|
}
|
|
83
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90ZV9zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3N0b3JhZ2Uvbm90ZV9zdG9yZS9ub3RlX3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3BELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFxQyxNQUFNLGlCQUFpQixDQUFDO0FBQzVGLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxPQUFPLEVBQWMsS0FBSyxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUUzRSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUc1RTs7Ozs7SUFLSTtBQUNKLHFCQUFhLFNBQVUsWUFBVyxXQUFXOztJQUMzQyxRQUFRLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBVTtJQStCcEMsWUFBWSxLQUFLLEVBQUUsaUJBQWlCLEVBUW5DO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksUUFBUSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBYXJGO0lBY0Q7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxRQUFRLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQTZGL0Q7SUFFRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNILGVBQWUsQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0F5Q2hGO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDVSxRQUFRLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU1wRjtJQTZFRDs7Ozs7Ozs7O09BU0c7SUFDRyxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBVXpDO0lBRUQsYUFBYSxDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUcxQztDQWtDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note_store.d.ts","sourceRoot":"","sources":["../../../src/storage/note_store/note_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAG5E;;;;;IAKI;AACJ,qBAAa,SAAU,YAAW,WAAW;;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAU;IA+BpC,YAAY,KAAK,EAAE,iBAAiB,EAQnC;IAED;;;;;;;;;OASG;IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAarF;IAcD;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA6F/D;IAED;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"note_store.d.ts","sourceRoot":"","sources":["../../../src/storage/note_store/note_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAG5E;;;;;IAKI;AACJ,qBAAa,SAAU,YAAW,WAAW;;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAU;IA+BpC,YAAY,KAAK,EAAE,iBAAiB,EAQnC;IAED;;;;;;;;;OASG;IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAarF;IAcD;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA6F/D;IAED;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAyChF;IAED;;;;;;;;;;;OAWG;IACU,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpF;IA6ED;;;;;;;;;OASG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzC;IAED,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1C;CAkCF"}
|
|
@@ -173,6 +173,9 @@ import { StoredNote } from './stored_note.js';
|
|
|
173
173
|
if (nullifiers.length === 0) {
|
|
174
174
|
return Promise.resolve([]);
|
|
175
175
|
}
|
|
176
|
+
if (nullifiers.some((n)=>n.l2BlockNumber === 0)) {
|
|
177
|
+
return Promise.reject(new Error('applyNullifiers: nullifiers cannot have been emitted at block 0'));
|
|
178
|
+
}
|
|
176
179
|
return this.#withJobLock(jobId, ()=>this.#store.transactionAsync(async ()=>{
|
|
177
180
|
const notesToNullify = await Promise.all(nullifiers.map(async (nullifierInBlock)=>{
|
|
178
181
|
const nullifier = nullifierInBlock.data.toString();
|
package/package.json
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.e558bd1c",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"typedocOptions": {
|
|
6
|
+
"entryPoints": [
|
|
7
|
+
"./src/entrypoints/server/index.ts",
|
|
8
|
+
"./src/entrypoints/client/lazy/index.ts",
|
|
9
|
+
"./src/config/index.ts"
|
|
10
|
+
],
|
|
11
|
+
"name": "PXE",
|
|
12
|
+
"tsconfig": "./tsconfig.json"
|
|
13
|
+
},
|
|
5
14
|
"exports": {
|
|
6
15
|
"./server": "./dest/entrypoints/server/index.js",
|
|
7
16
|
"./client/lazy": "./dest/entrypoints/client/lazy/index.js",
|
|
@@ -61,19 +70,19 @@
|
|
|
61
70
|
]
|
|
62
71
|
},
|
|
63
72
|
"dependencies": {
|
|
64
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
65
|
-
"@aztec/bb.js": "0.0.1-commit.
|
|
66
|
-
"@aztec/builder": "0.0.1-commit.
|
|
67
|
-
"@aztec/constants": "0.0.1-commit.
|
|
68
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
69
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
70
|
-
"@aztec/key-store": "0.0.1-commit.
|
|
71
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
72
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
73
|
-
"@aztec/noir-types": "0.0.1-commit.
|
|
74
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
75
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
76
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
73
|
+
"@aztec/bb-prover": "0.0.1-commit.e558bd1c",
|
|
74
|
+
"@aztec/bb.js": "0.0.1-commit.e558bd1c",
|
|
75
|
+
"@aztec/builder": "0.0.1-commit.e558bd1c",
|
|
76
|
+
"@aztec/constants": "0.0.1-commit.e558bd1c",
|
|
77
|
+
"@aztec/ethereum": "0.0.1-commit.e558bd1c",
|
|
78
|
+
"@aztec/foundation": "0.0.1-commit.e558bd1c",
|
|
79
|
+
"@aztec/key-store": "0.0.1-commit.e558bd1c",
|
|
80
|
+
"@aztec/kv-store": "0.0.1-commit.e558bd1c",
|
|
81
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.e558bd1c",
|
|
82
|
+
"@aztec/noir-types": "0.0.1-commit.e558bd1c",
|
|
83
|
+
"@aztec/protocol-contracts": "0.0.1-commit.e558bd1c",
|
|
84
|
+
"@aztec/simulator": "0.0.1-commit.e558bd1c",
|
|
85
|
+
"@aztec/stdlib": "0.0.1-commit.e558bd1c",
|
|
77
86
|
"koa": "^2.16.1",
|
|
78
87
|
"koa-router": "^13.1.1",
|
|
79
88
|
"lodash.omit": "^4.5.0",
|
|
@@ -82,8 +91,8 @@
|
|
|
82
91
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
83
92
|
},
|
|
84
93
|
"devDependencies": {
|
|
85
|
-
"@aztec/merkle-tree": "0.0.1-commit.
|
|
86
|
-
"@aztec/noir-test-contracts.js": "0.0.1-commit.
|
|
94
|
+
"@aztec/merkle-tree": "0.0.1-commit.e558bd1c",
|
|
95
|
+
"@aztec/noir-test-contracts.js": "0.0.1-commit.e558bd1c",
|
|
87
96
|
"@jest/globals": "^30.0.0",
|
|
88
97
|
"@types/jest": "^30.0.0",
|
|
89
98
|
"@types/lodash.omit": "^4.5.7",
|
|
@@ -7,6 +7,7 @@ import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
|
7
7
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
8
8
|
|
|
9
9
|
import type { BlockSynchronizerConfig } from '../config/index.js';
|
|
10
|
+
import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
|
|
10
11
|
import type { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_store.js';
|
|
11
12
|
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
12
13
|
import type { PrivateEventStore } from '../storage/private_event_store/private_event_store.js';
|
|
@@ -28,6 +29,7 @@ export class BlockSynchronizer implements L2BlockStreamEventHandler {
|
|
|
28
29
|
private noteStore: NoteStore,
|
|
29
30
|
private privateEventStore: PrivateEventStore,
|
|
30
31
|
private l2TipsStore: L2TipsKVStore,
|
|
32
|
+
private contractSyncService: ContractSyncService,
|
|
31
33
|
private config: Partial<BlockSynchronizerConfig> = {},
|
|
32
34
|
bindings?: LoggerBindings,
|
|
33
35
|
) {
|
|
@@ -125,6 +127,10 @@ export class BlockSynchronizer implements L2BlockStreamEventHandler {
|
|
|
125
127
|
|
|
126
128
|
/** Updates the anchor block header to the target block */
|
|
127
129
|
private async updateAnchorBlockHeader(blockHeader: BlockHeader) {
|
|
130
|
+
// Whenever the anchor block header is updated, we need to synchronize the private state of contracts again.
|
|
131
|
+
// Therefore, we clear the contract synchronization cache here such that the sync is re-triggered upon new
|
|
132
|
+
// execution.
|
|
133
|
+
this.contractSyncService.wipe();
|
|
128
134
|
this.log.verbose(`Updated pxe last block to ${blockHeader.getBlockNumber()}`, blockHeader.toInspect());
|
|
129
135
|
await this.anchorBlockStore.setHeader(blockHeader);
|
|
130
136
|
}
|
|
@@ -72,6 +72,7 @@ import {
|
|
|
72
72
|
getFinalMinRevertibleSideEffectCounter,
|
|
73
73
|
} from '@aztec/stdlib/tx';
|
|
74
74
|
|
|
75
|
+
import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
|
|
75
76
|
import type { AddressStore } from '../storage/address_store/address_store.js';
|
|
76
77
|
import type { CapsuleStore } from '../storage/capsule_store/capsule_store.js';
|
|
77
78
|
import type { ContractStore } from '../storage/contract_store/contract_store.js';
|
|
@@ -107,6 +108,7 @@ export class ContractFunctionSimulator {
|
|
|
107
108
|
private capsuleStore: CapsuleStore,
|
|
108
109
|
private privateEventStore: PrivateEventStore,
|
|
109
110
|
private simulator: CircuitSimulator,
|
|
111
|
+
private contractSyncService: ContractSyncService,
|
|
110
112
|
) {
|
|
111
113
|
this.log = createLogger('simulator');
|
|
112
114
|
}
|
|
@@ -186,6 +188,7 @@ export class ContractFunctionSimulator {
|
|
|
186
188
|
this.senderAddressBookStore,
|
|
187
189
|
this.capsuleStore,
|
|
188
190
|
this.privateEventStore,
|
|
191
|
+
this.contractSyncService,
|
|
189
192
|
jobId,
|
|
190
193
|
0, // totalPublicArgsCount
|
|
191
194
|
startSideEffectCounter,
|
|
@@ -85,7 +85,7 @@ export interface IUtilityExecutionOracle {
|
|
|
85
85
|
nullifier: Fr,
|
|
86
86
|
): Promise<NullifierMembershipWitness | undefined>;
|
|
87
87
|
utilityGetBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader | undefined>;
|
|
88
|
-
|
|
88
|
+
utilityTryGetPublicKeysAndPartialAddress(account: AztecAddress): Promise<CompleteAddress | undefined>;
|
|
89
89
|
utilityGetAuthWitness(messageHash: Fr): Promise<Fr[] | undefined>;
|
|
90
90
|
utilityGetNotes(
|
|
91
91
|
owner: AztecAddress | undefined,
|
|
@@ -248,12 +248,19 @@ export class Oracle {
|
|
|
248
248
|
return [witness.map(toACVMField)];
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
async
|
|
251
|
+
async utilityTryGetPublicKeysAndPartialAddress([address]: ACVMField[]): Promise<(ACVMField | ACVMField[])[]> {
|
|
252
252
|
const parsedAddress = AztecAddress.fromField(Fr.fromString(address));
|
|
253
|
-
const
|
|
254
|
-
await this.handlerAsUtility().utilityGetPublicKeysAndPartialAddress(parsedAddress);
|
|
253
|
+
const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(parsedAddress);
|
|
255
254
|
|
|
256
|
-
return
|
|
255
|
+
// We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
|
|
256
|
+
// with two fields: `some` (a boolean) and `value` (a field array in this case).
|
|
257
|
+
if (result === undefined) {
|
|
258
|
+
// No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
|
|
259
|
+
return [toACVMField(0), Array(13).fill(toACVMField(0))];
|
|
260
|
+
} else {
|
|
261
|
+
// Data was found so we set `some` to 1 and return it along with `value`.
|
|
262
|
+
return [toACVMField(1), [...result.publicKeys.toFields(), result.partialAddress].map(toACVMField)];
|
|
263
|
+
}
|
|
257
264
|
}
|
|
258
265
|
|
|
259
266
|
async utilityGetNotes(
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
type TxContext,
|
|
31
31
|
} from '@aztec/stdlib/tx';
|
|
32
32
|
|
|
33
|
-
import {
|
|
33
|
+
import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
|
|
34
34
|
import { NoteService } from '../../notes/note_service.js';
|
|
35
35
|
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
36
36
|
import type { CapsuleStore } from '../../storage/capsule_store/capsule_store.js';
|
|
@@ -93,6 +93,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
93
93
|
senderAddressBookStore: SenderAddressBookStore,
|
|
94
94
|
capsuleStore: CapsuleStore,
|
|
95
95
|
privateEventStore: PrivateEventStore,
|
|
96
|
+
private readonly contractSyncService: ContractSyncService,
|
|
96
97
|
jobId: string,
|
|
97
98
|
private totalPublicCalldataCount: number = 0,
|
|
98
99
|
protected sideEffectCounter: number = 0,
|
|
@@ -242,7 +243,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
242
243
|
sender: AztecAddress,
|
|
243
244
|
recipient: AztecAddress,
|
|
244
245
|
) {
|
|
245
|
-
const senderCompleteAddress = await this.
|
|
246
|
+
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
|
|
246
247
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
247
248
|
return DirectionalAppTaggingSecret.compute(
|
|
248
249
|
senderCompleteAddress,
|
|
@@ -537,13 +538,12 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
537
538
|
|
|
538
539
|
isStaticCall = isStaticCall || this.callContext.isStaticCall;
|
|
539
540
|
|
|
540
|
-
await ensureContractSynced(
|
|
541
|
+
await this.contractSyncService.ensureContractSynced(
|
|
541
542
|
targetContractAddress,
|
|
542
543
|
functionSelector,
|
|
543
544
|
this.utilityExecutor,
|
|
544
|
-
this.aztecNode,
|
|
545
|
-
this.contractStore,
|
|
546
545
|
this.anchorBlockHeader,
|
|
546
|
+
this.jobId,
|
|
547
547
|
);
|
|
548
548
|
|
|
549
549
|
const targetArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(
|
|
@@ -576,6 +576,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
576
576
|
this.senderAddressBookStore,
|
|
577
577
|
this.capsuleStore,
|
|
578
578
|
this.privateEventStore,
|
|
579
|
+
this.contractSyncService,
|
|
579
580
|
this.jobId,
|
|
580
581
|
this.totalPublicCalldataCount,
|
|
581
582
|
sideEffectCounter,
|
|
@@ -88,8 +88,16 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
88
88
|
* @param pkMHash - The master public key hash.
|
|
89
89
|
* @returns A Promise that resolves to nullifier keys.
|
|
90
90
|
* @throws If the keys are not registered in the key store.
|
|
91
|
+
* @throws If scopes are defined and the account is not in the scopes.
|
|
91
92
|
*/
|
|
92
|
-
public utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
93
|
+
public async utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
94
|
+
// If scopes are defined, check that the key belongs to an account in the scopes
|
|
95
|
+
if (this.scopes && this.scopes.length > 0) {
|
|
96
|
+
const [, account] = await this.keyStore.getKeyPrefixAndAccount(pkMHash);
|
|
97
|
+
if (!this.scopes.some(scope => scope.equals(account))) {
|
|
98
|
+
throw new Error(`Key validation request denied: account ${account.toString()} is not in the allowed scopes.`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
93
101
|
return this.keyStore.getKeyValidationRequest(pkMHash, this.contractAddress);
|
|
94
102
|
}
|
|
95
103
|
|
|
@@ -182,14 +190,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
182
190
|
/**
|
|
183
191
|
* Retrieve the complete address associated to a given address.
|
|
184
192
|
* @param account - The account address.
|
|
185
|
-
* @returns A complete address associated with the input address.
|
|
186
|
-
* @throws An error if the account is not registered in the database.
|
|
193
|
+
* @returns A complete address associated with the input address, or `undefined` if not registered.
|
|
187
194
|
*/
|
|
188
|
-
public
|
|
189
|
-
return this.getCompleteAddress(account);
|
|
195
|
+
public utilityTryGetPublicKeysAndPartialAddress(account: AztecAddress): Promise<CompleteAddress | undefined> {
|
|
196
|
+
return this.addressStore.getCompleteAddress(account);
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
protected async
|
|
199
|
+
protected async getCompleteAddressOrFail(account: AztecAddress): Promise<CompleteAddress> {
|
|
193
200
|
const completeAddress = await this.addressStore.getCompleteAddress(account);
|
|
194
201
|
if (!completeAddress) {
|
|
195
202
|
throw new Error(
|
|
@@ -290,8 +297,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
290
297
|
* @returns A boolean indicating whether the nullifier exists in the tree or not.
|
|
291
298
|
*/
|
|
292
299
|
public async utilityCheckNullifierExists(innerNullifier: Fr) {
|
|
293
|
-
const nullifier = await
|
|
294
|
-
|
|
300
|
+
const [nullifier, anchorBlockHash] = await Promise.all([
|
|
301
|
+
siloNullifier(this.contractAddress, innerNullifier!),
|
|
302
|
+
this.anchorBlockHeader.hash(),
|
|
303
|
+
]);
|
|
304
|
+
const [leafIndex] = await this.aztecNode.findLeavesIndexes(anchorBlockHash, MerkleTreeId.NULLIFIER_TREE, [
|
|
305
|
+
nullifier,
|
|
306
|
+
]);
|
|
295
307
|
return leafIndex?.data !== undefined;
|
|
296
308
|
}
|
|
297
309
|
|
|
@@ -363,16 +375,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
363
375
|
this.log.getBindings(),
|
|
364
376
|
);
|
|
365
377
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
// It is acceptable to run the following operations in parallel for several reasons:
|
|
369
|
-
// 1. syncTaggedLogs does not write to the note store — it only stores the pending tagged logs in a capsule array,
|
|
370
|
-
// which is then processed in Noir after this handler returns.
|
|
371
|
-
// 2. Even if syncTaggedLogs did write to the note store, it would not cause inconsistent state.
|
|
372
|
-
await Promise.all([
|
|
373
|
-
logService.syncTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, this.scopes),
|
|
374
|
-
noteService.syncNoteNullifiers(this.contractAddress),
|
|
375
|
-
]);
|
|
378
|
+
await logService.fetchTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, this.scopes);
|
|
376
379
|
}
|
|
377
380
|
|
|
378
381
|
/**
|
|
@@ -544,7 +547,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
544
547
|
|
|
545
548
|
protected async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
|
|
546
549
|
// TODO(#12656): return an app-siloed secret
|
|
547
|
-
const recipientCompleteAddress = await this.
|
|
550
|
+
const recipientCompleteAddress = await this.getCompleteAddressOrFail(address);
|
|
548
551
|
const ivskM = await this.keyStore.getMasterSecretKey(
|
|
549
552
|
recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
|
|
550
553
|
);
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { Logger } from '@aztec/foundation/log';
|
|
2
|
+
import type { FunctionCall, FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
5
|
+
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
6
|
+
|
|
7
|
+
import type { StagedStore } from '../job_coordinator/job_coordinator.js';
|
|
8
|
+
import type { ContractStore } from '../storage/contract_store/contract_store.js';
|
|
9
|
+
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
10
|
+
import { syncState, verifyCurrentClassId } from './helpers.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Service for syncing the private state of contracts and verifying that the PXE holds the current class artifact.
|
|
14
|
+
* It uses a cache to avoid redundant sync operations - the cache is wiped when the anchor block changes.
|
|
15
|
+
*
|
|
16
|
+
* TODO: The StagedStore naming is broken here. Figure out a better name.
|
|
17
|
+
*/
|
|
18
|
+
export class ContractSyncService implements StagedStore {
|
|
19
|
+
readonly storeName = 'contract_sync';
|
|
20
|
+
|
|
21
|
+
// Tracks contracts synced since last wipe. Key is contract address string, value is a promise that resolves when
|
|
22
|
+
// the contract is synced.
|
|
23
|
+
private syncedContracts: Map<string, Promise<void>> = new Map();
|
|
24
|
+
|
|
25
|
+
// Per-job overridden contract addresses - these contracts should not be synced.
|
|
26
|
+
private overriddenContracts: Map<string, Set<string>> = new Map();
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
private aztecNode: AztecNode,
|
|
30
|
+
private contractStore: ContractStore,
|
|
31
|
+
private noteStore: NoteStore,
|
|
32
|
+
private log: Logger,
|
|
33
|
+
) {}
|
|
34
|
+
|
|
35
|
+
/** Sets contracts that should be skipped during sync for a specific job. */
|
|
36
|
+
setOverriddenContracts(jobId: string, addresses: Set<string>): void {
|
|
37
|
+
this.overriddenContracts.set(jobId, addresses);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Ensures a contract's private state is synchronized and that the PXE holds the current class artifact.
|
|
42
|
+
* Uses a cache to avoid redundant sync operations - the cache is wiped when the anchor block changes.
|
|
43
|
+
* @param contractAddress - The address of the contract to sync.
|
|
44
|
+
* @param functionToInvokeAfterSync - The function selector that will be called after sync (used to validate it's
|
|
45
|
+
* not sync_state itself).
|
|
46
|
+
* @param utilityExecutor - Executor function for running the sync_state utility function.
|
|
47
|
+
*/
|
|
48
|
+
async ensureContractSynced(
|
|
49
|
+
contractAddress: AztecAddress,
|
|
50
|
+
functionToInvokeAfterSync: FunctionSelector | null,
|
|
51
|
+
utilityExecutor: (call: FunctionCall) => Promise<any>,
|
|
52
|
+
anchorBlockHeader: BlockHeader,
|
|
53
|
+
jobId: string,
|
|
54
|
+
): Promise<void> {
|
|
55
|
+
const key = contractAddress.toString();
|
|
56
|
+
|
|
57
|
+
// Skip sync if this contract has an override for this job
|
|
58
|
+
const overrides = this.overriddenContracts.get(jobId);
|
|
59
|
+
if (overrides?.has(key)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const existing = this.syncedContracts.get(key);
|
|
64
|
+
if (existing) {
|
|
65
|
+
return existing;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const syncPromise = this.#doSync(
|
|
69
|
+
contractAddress,
|
|
70
|
+
functionToInvokeAfterSync,
|
|
71
|
+
utilityExecutor,
|
|
72
|
+
anchorBlockHeader,
|
|
73
|
+
jobId,
|
|
74
|
+
);
|
|
75
|
+
this.syncedContracts.set(key, syncPromise);
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
await syncPromise;
|
|
79
|
+
} catch (err) {
|
|
80
|
+
// There was an error syncing the contract, so we remove it from the cache so that it can be retried.
|
|
81
|
+
this.syncedContracts.delete(key);
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async #doSync(
|
|
87
|
+
contractAddress: AztecAddress,
|
|
88
|
+
functionToInvokeAfterSync: FunctionSelector | null,
|
|
89
|
+
utilityExecutor: (call: FunctionCall) => Promise<any>,
|
|
90
|
+
anchorBlockHeader: BlockHeader,
|
|
91
|
+
jobId: string,
|
|
92
|
+
): Promise<void> {
|
|
93
|
+
this.log.debug(`Syncing contract ${contractAddress}`);
|
|
94
|
+
await Promise.all([
|
|
95
|
+
syncState(
|
|
96
|
+
contractAddress,
|
|
97
|
+
this.contractStore,
|
|
98
|
+
functionToInvokeAfterSync,
|
|
99
|
+
utilityExecutor,
|
|
100
|
+
this.noteStore,
|
|
101
|
+
this.aztecNode,
|
|
102
|
+
anchorBlockHeader,
|
|
103
|
+
jobId,
|
|
104
|
+
),
|
|
105
|
+
verifyCurrentClassId(contractAddress, this.aztecNode, this.contractStore, anchorBlockHeader),
|
|
106
|
+
]);
|
|
107
|
+
this.log.debug(`Contract ${contractAddress} synced`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Clears sync cache. Called by BlockSynchronizer when anchor block changes. */
|
|
111
|
+
wipe(): void {
|
|
112
|
+
this.log.debug(`Wiping contract sync cache (${this.syncedContracts.size} entries)`);
|
|
113
|
+
this.syncedContracts.clear();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
commit(jobId: string): Promise<void> {
|
|
117
|
+
// Clear overridden contracts for this job
|
|
118
|
+
this.overriddenContracts.delete(jobId);
|
|
119
|
+
return Promise.resolve();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
discardStaged(jobId: string): Promise<void> {
|
|
123
|
+
// We clear the synced contracts cache here because, when the job is discarded, any associated database writes from
|
|
124
|
+
// the sync are also undone.
|
|
125
|
+
this.syncedContracts.clear();
|
|
126
|
+
this.overriddenContracts.delete(jobId);
|
|
127
|
+
return Promise.resolve();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -6,7 +6,9 @@ import { DelayedPublicMutableValues, DelayedPublicMutableValuesWithHash } from '
|
|
|
6
6
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
7
7
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
8
8
|
|
|
9
|
+
import { NoteService } from '../notes/note_service.js';
|
|
9
10
|
import type { ContractStore } from '../storage/contract_store/contract_store.js';
|
|
11
|
+
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Read the current class id of a contract from the execution data provider or AztecNode. If not found, class id
|
|
@@ -41,6 +43,10 @@ export async function syncState(
|
|
|
41
43
|
contractStore: ContractStore,
|
|
42
44
|
functionToInvokeAfterSync: FunctionSelector | null,
|
|
43
45
|
utilityExecutor: (privateSyncCall: FunctionCall) => Promise<any>,
|
|
46
|
+
noteStore: NoteStore,
|
|
47
|
+
aztecNode: AztecNode,
|
|
48
|
+
anchorBlockHeader: BlockHeader,
|
|
49
|
+
jobId: string,
|
|
44
50
|
) {
|
|
45
51
|
// Protocol contracts don't have private state to sync
|
|
46
52
|
if (!isProtocolContract(contractAddress)) {
|
|
@@ -51,16 +57,23 @@ export async function syncState(
|
|
|
51
57
|
);
|
|
52
58
|
}
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
const noteService = new NoteService(noteStore, aztecNode, anchorBlockHeader, jobId);
|
|
61
|
+
|
|
62
|
+
// Both sync_state and syncNoteNullifiers interact with the note store, but running them in parallel is safe
|
|
63
|
+
// because note store is designed to handle concurrent operations.
|
|
64
|
+
await Promise.all([utilityExecutor(syncStateFunctionCall), noteService.syncNoteNullifiers(contractAddress)]);
|
|
55
65
|
}
|
|
56
66
|
}
|
|
57
67
|
|
|
58
68
|
/**
|
|
59
69
|
* Verify that the current class id of a contract obtained from AztecNode is the same as the one in contract data
|
|
60
70
|
* provider (i.e. PXE's own storage).
|
|
71
|
+
* @param contractAddress - The address of the contract to verify.
|
|
72
|
+
* @param aztecNode - The Aztec node to query for storage.
|
|
73
|
+
* @param contractStore - The contract store to fetch the local instance from.
|
|
61
74
|
* @param header - The header of the block at which to verify the current class id.
|
|
62
75
|
*/
|
|
63
|
-
async function verifyCurrentClassId(
|
|
76
|
+
export async function verifyCurrentClassId(
|
|
64
77
|
contractAddress: AztecAddress,
|
|
65
78
|
aztecNode: AztecNode,
|
|
66
79
|
contractStore: ContractStore,
|
|
@@ -78,21 +91,3 @@ async function verifyCurrentClassId(
|
|
|
78
91
|
);
|
|
79
92
|
}
|
|
80
93
|
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Ensures the contract's private state is synchronized and that the PXE holds the current class artifact for
|
|
84
|
-
* the contract.
|
|
85
|
-
*/
|
|
86
|
-
export async function ensureContractSynced(
|
|
87
|
-
contractAddress: AztecAddress,
|
|
88
|
-
functionToInvokeAfterSync: FunctionSelector | null,
|
|
89
|
-
utilityExecutor: (call: FunctionCall) => Promise<any>,
|
|
90
|
-
aztecNode: AztecNode,
|
|
91
|
-
contractStore: ContractStore,
|
|
92
|
-
header: BlockHeader,
|
|
93
|
-
): Promise<void> {
|
|
94
|
-
await Promise.all([
|
|
95
|
-
syncState(contractAddress, contractStore, functionToInvokeAfterSync, utilityExecutor),
|
|
96
|
-
verifyCurrentClassId(contractAddress, aztecNode, contractStore, header),
|
|
97
|
-
]);
|
|
98
|
-
}
|