@aztec/pxe 0.0.1-commit.86469d5 → 0.0.1-commit.87a0206
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 +5 -3
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +6 -4
- 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 +19 -9
- 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} +6 -12
- package/dest/debug/pxe_debug_utils.d.ts +12 -9
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +16 -15
- 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/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +2 -2
- package/dest/pxe.d.ts +13 -2
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +35 -14
- package/dest/storage/contract_store/contract_store.js +5 -5
- 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 +5 -2
- 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 +5 -6
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +21 -9
- package/src/contract_sync/contract_sync_service.ts +129 -0
- package/src/contract_sync/{index.ts → helpers.ts} +6 -32
- package/src/debug/pxe_debug_utils.ts +45 -17
- package/src/entrypoints/server/index.ts +1 -1
- package/src/oracle_version.ts +2 -2
- package/src/pxe.ts +45 -17
- package/src/storage/contract_store/contract_store.ts +4 -4
- package/src/storage/note_store/note_store.ts +4 -0
- package/dest/contract_sync/index.d.ts +0 -24
- 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);
|
|
@@ -252,7 +257,17 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
252
257
|
return await kernelTraceProver.proveWithKernels(txExecutionRequest.toTxRequest(), privateExecutionResult, config);
|
|
253
258
|
}
|
|
254
259
|
// Public API
|
|
255
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Returns the block header up to which the PXE has synced.
|
|
262
|
+
* @returns The synced block header
|
|
263
|
+
*/ getSyncedBlockHeader() {
|
|
264
|
+
return this.anchorBlockStore.getBlockHeader();
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Returns the contract instance for a given address, if it's registered in the PXE.
|
|
268
|
+
* @param address - The contract address.
|
|
269
|
+
* @returns The contract instance if found, undefined otherwise.
|
|
270
|
+
*/ getContractInstance(address) {
|
|
256
271
|
return this.contractStore.getContractInstance(address);
|
|
257
272
|
}
|
|
258
273
|
/**
|
|
@@ -586,13 +601,19 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
586
601
|
// Temporary: in case there are overrides, we have to skip the kernels or validations
|
|
587
602
|
// will fail. Consider handing control to the user/wallet on whether they want to run them
|
|
588
603
|
// or not.
|
|
589
|
-
const
|
|
604
|
+
const overriddenContracts = overrides?.contracts ? new Set(Object.keys(overrides.contracts)) : undefined;
|
|
605
|
+
const hasOverriddenContracts = overriddenContracts !== undefined && overriddenContracts.size > 0;
|
|
606
|
+
const skipKernels = hasOverriddenContracts;
|
|
607
|
+
// Set overridden contracts on the sync service so it knows to skip syncing them
|
|
608
|
+
if (hasOverriddenContracts) {
|
|
609
|
+
this.contractSyncService.setOverriddenContracts(jobId, overriddenContracts);
|
|
610
|
+
}
|
|
590
611
|
// Execution of private functions only; no proving, and no kernel logic.
|
|
591
612
|
const privateExecutionResult = await this.#executePrivate(contractFunctionSimulator, txRequest, scopes, jobId);
|
|
592
613
|
let publicInputs;
|
|
593
614
|
let executionSteps = [];
|
|
594
615
|
if (skipKernels) {
|
|
595
|
-
({ publicInputs, executionSteps } = await generateSimulatedProvingResult(privateExecutionResult, this.contractStore));
|
|
616
|
+
({ publicInputs, executionSteps } = await generateSimulatedProvingResult(privateExecutionResult, (addr, sel)=>this.contractStore.getDebugFunctionName(addr, sel)));
|
|
596
617
|
} else {
|
|
597
618
|
// Kernel logic, plus proving of all private functions and kernels.
|
|
598
619
|
({ publicInputs, executionSteps } = await this.#prove(txRequest, this.proofCreator, privateExecutionResult, {
|
|
@@ -677,7 +698,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
677
698
|
const functionTimer = new Timer();
|
|
678
699
|
const contractFunctionSimulator = this.#getSimulatorForTx();
|
|
679
700
|
const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
|
|
680
|
-
await ensureContractSynced(call.to, call.selector, (privateSyncCall)=>this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
|
|
701
|
+
await this.contractSyncService.ensureContractSynced(call.to, call.selector, (privateSyncCall)=>this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId), anchorBlockHeader, jobId);
|
|
681
702
|
const executionResult = await this.#simulateUtility(contractFunctionSimulator, call, authwits ?? [], scopes, jobId);
|
|
682
703
|
const functionTime = functionTimer.ms();
|
|
683
704
|
const totalTime = totalTimer.ms();
|
|
@@ -727,7 +748,7 @@ import { SenderTaggingStore } from './storage/tagging_store/sender_tagging_store
|
|
|
727
748
|
const anchorBlockHeader = await this.anchorBlockStore.getBlockHeader();
|
|
728
749
|
anchorBlockNumber = anchorBlockHeader.getBlockNumber();
|
|
729
750
|
const contractFunctionSimulator = this.#getSimulatorForTx();
|
|
730
|
-
await ensureContractSynced(filter.contractAddress, null, async (privateSyncCall)=>await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId),
|
|
751
|
+
await this.contractSyncService.ensureContractSynced(filter.contractAddress, null, async (privateSyncCall)=>await this.#simulateUtility(contractFunctionSimulator, privateSyncCall, [], undefined, jobId), anchorBlockHeader, jobId);
|
|
731
752
|
});
|
|
732
753
|
// anchorBlockNumber is set during the job and fixed to whatever it is after a block sync
|
|
733
754
|
const sanitizedFilter = new PrivateEventFilterValidator(anchorBlockNumber).validate(filter);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toArray } from '@aztec/foundation/iterable';
|
|
2
|
-
import { FunctionSelector, FunctionType, contractArtifactFromBuffer, contractArtifactToBuffer, encodeArguments, getFunctionDebugMetadata } from '@aztec/stdlib/abi';
|
|
2
|
+
import { FunctionCall, FunctionSelector, FunctionType, contractArtifactFromBuffer, contractArtifactToBuffer, encodeArguments, getFunctionDebugMetadata } from '@aztec/stdlib/abi';
|
|
3
3
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
4
|
import { SerializableContractInstance, getContractClassFromArtifact } from '@aztec/stdlib/contract';
|
|
5
5
|
import { PrivateFunctionsTree } from './private_functions_tree.js';
|
|
@@ -219,15 +219,15 @@ import { PrivateFunctionsTree } from './private_functions_tree.js';
|
|
|
219
219
|
if (!functionDao) {
|
|
220
220
|
throw new Error(`Unknown function ${functionName} in contract ${contract.name}.`);
|
|
221
221
|
}
|
|
222
|
-
return {
|
|
222
|
+
return FunctionCall.from({
|
|
223
223
|
name: functionDao.name,
|
|
224
|
-
|
|
224
|
+
to,
|
|
225
225
|
selector: await FunctionSelector.fromNameAndParameters(functionDao.name, functionDao.parameters),
|
|
226
226
|
type: functionDao.functionType,
|
|
227
|
-
to,
|
|
228
227
|
hideMsgSender: false,
|
|
229
228
|
isStatic: functionDao.isStatic,
|
|
229
|
+
args: encodeArguments(functionDao, args),
|
|
230
230
|
returnTypes: functionDao.returnTypes
|
|
231
|
-
};
|
|
231
|
+
});
|
|
232
232
|
}
|
|
233
233
|
}
|
|
@@ -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.87a0206",
|
|
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.87a0206",
|
|
74
|
+
"@aztec/bb.js": "0.0.1-commit.87a0206",
|
|
75
|
+
"@aztec/builder": "0.0.1-commit.87a0206",
|
|
76
|
+
"@aztec/constants": "0.0.1-commit.87a0206",
|
|
77
|
+
"@aztec/ethereum": "0.0.1-commit.87a0206",
|
|
78
|
+
"@aztec/foundation": "0.0.1-commit.87a0206",
|
|
79
|
+
"@aztec/key-store": "0.0.1-commit.87a0206",
|
|
80
|
+
"@aztec/kv-store": "0.0.1-commit.87a0206",
|
|
81
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.87a0206",
|
|
82
|
+
"@aztec/noir-types": "0.0.1-commit.87a0206",
|
|
83
|
+
"@aztec/protocol-contracts": "0.0.1-commit.87a0206",
|
|
84
|
+
"@aztec/simulator": "0.0.1-commit.87a0206",
|
|
85
|
+
"@aztec/stdlib": "0.0.1-commit.87a0206",
|
|
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.87a0206",
|
|
95
|
+
"@aztec/noir-test-contracts.js": "0.0.1-commit.87a0206",
|
|
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,
|
|
@@ -356,7 +359,7 @@ class OrderedSideEffect<T> {
|
|
|
356
359
|
*/
|
|
357
360
|
export async function generateSimulatedProvingResult(
|
|
358
361
|
privateExecutionResult: PrivateExecutionResult,
|
|
359
|
-
|
|
362
|
+
debugFunctionNameGetter: (contractAddress: AztecAddress, functionSelector: FunctionSelector) => Promise<string>,
|
|
360
363
|
minRevertibleSideEffectCounterOverride?: number,
|
|
361
364
|
): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
362
365
|
const siloedNoteHashes: OrderedSideEffect<Fr>[] = [];
|
|
@@ -437,7 +440,7 @@ export async function generateSimulatedProvingResult(
|
|
|
437
440
|
: execution.publicInputs.publicTeardownCallRequest;
|
|
438
441
|
|
|
439
442
|
executionSteps.push({
|
|
440
|
-
functionName: await
|
|
443
|
+
functionName: await debugFunctionNameGetter(
|
|
441
444
|
execution.publicInputs.callContext.contractAddress,
|
|
442
445
|
execution.publicInputs.callContext.functionSelector,
|
|
443
446
|
),
|
|
@@ -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,10 @@ 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
|
-
this.noteStore,
|
|
547
545
|
this.anchorBlockHeader,
|
|
548
546
|
this.jobId,
|
|
549
547
|
);
|
|
@@ -578,6 +576,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
578
576
|
this.senderAddressBookStore,
|
|
579
577
|
this.capsuleStore,
|
|
580
578
|
this.privateEventStore,
|
|
579
|
+
this.contractSyncService,
|
|
581
580
|
this.jobId,
|
|
582
581
|
this.totalPublicCalldataCount,
|
|
583
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
|
|
|
@@ -535,7 +547,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
535
547
|
|
|
536
548
|
protected async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
|
|
537
549
|
// TODO(#12656): return an app-siloed secret
|
|
538
|
-
const recipientCompleteAddress = await this.
|
|
550
|
+
const recipientCompleteAddress = await this.getCompleteAddressOrFail(address);
|
|
539
551
|
const ivskM = await this.keyStore.getMasterSecretKey(
|
|
540
552
|
recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
|
|
541
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
|
+
}
|