@aztec/pxe 0.0.1-commit.29c6b1a3 → 0.0.1-commit.2e2504e2
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 +5 -3
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +9 -3
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +4 -4
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +9 -9
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +8 -8
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.d.ts +4 -4
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +29 -17
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +4 -3
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +7 -7
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +18 -15
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +28 -33
- 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/entrypoints/client/bundle/utils.d.ts +1 -1
- package/dest/entrypoints/client/bundle/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/utils.js +12 -6
- package/dest/entrypoints/client/lazy/utils.d.ts +2 -2
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +13 -7
- package/dest/entrypoints/pxe_creation_options.d.ts +3 -2
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- 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/entrypoints/server/utils.d.ts +1 -1
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +19 -8
- package/dest/events/event_service.d.ts +4 -5
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +5 -6
- package/dest/job_coordinator/job_coordinator.d.ts +3 -2
- package/dest/job_coordinator/job_coordinator.d.ts.map +1 -1
- package/dest/job_coordinator/job_coordinator.js +3 -2
- package/dest/logs/log_service.d.ts +6 -5
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +10 -15
- package/dest/notes/note_service.d.ts +4 -5
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +6 -7
- package/dest/oracle_version.d.ts +3 -3
- package/dest/oracle_version.d.ts.map +1 -1
- package/dest/oracle_version.js +2 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +3 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +2 -2
- package/dest/pxe.d.ts +2 -1
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +25 -12
- package/dest/storage/address_store/address_store.d.ts +1 -1
- package/dest/storage/address_store/address_store.d.ts.map +1 -1
- package/dest/storage/address_store/address_store.js +12 -11
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts +9 -1
- package/dest/storage/anchor_block_store/anchor_block_store.d.ts.map +1 -1
- package/dest/storage/anchor_block_store/anchor_block_store.js +8 -1
- package/dest/storage/capsule_store/capsule_store.js +6 -8
- package/dest/storage/contract_store/contract_store.d.ts +1 -1
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +22 -13
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/note_store/note_store.d.ts +11 -1
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +143 -105
- package/dest/storage/private_event_store/private_event_store.d.ts +1 -1
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +84 -61
- package/dest/storage/private_event_store/stored_private_event.js +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/recipient_tagging_store.js +31 -19
- package/dest/storage/tagging_store/sender_address_book_store.d.ts +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_address_book_store.js +20 -14
- package/dest/storage/tagging_store/sender_tagging_store.d.ts +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +183 -113
- package/package.json +25 -16
- package/src/block_synchronizer/block_synchronizer.ts +21 -12
- package/src/contract_function_simulator/contract_function_simulator.ts +9 -6
- package/src/contract_function_simulator/oracle/interfaces.ts +9 -9
- package/src/contract_function_simulator/oracle/oracle.ts +32 -15
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +7 -10
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +31 -35
- package/src/contract_sync/contract_sync_service.ts +129 -0
- package/src/contract_sync/{index.ts → helpers.ts} +15 -20
- package/src/entrypoints/client/bundle/utils.ts +7 -14
- package/src/entrypoints/client/lazy/utils.ts +8 -14
- package/src/entrypoints/pxe_creation_options.ts +2 -1
- package/src/entrypoints/server/index.ts +1 -1
- package/src/entrypoints/server/utils.ts +15 -19
- package/src/events/event_service.ts +4 -6
- package/src/job_coordinator/job_coordinator.ts +4 -3
- package/src/logs/log_service.ts +14 -14
- package/src/notes/note_service.ts +5 -7
- package/src/oracle_version.ts +2 -2
- package/src/private_kernel/private_kernel_execution_prover.ts +6 -3
- package/src/pxe.ts +40 -16
- package/src/storage/address_store/address_store.ts +15 -15
- package/src/storage/anchor_block_store/anchor_block_store.ts +8 -0
- package/src/storage/capsule_store/capsule_store.ts +8 -8
- package/src/storage/contract_store/contract_store.ts +22 -11
- package/src/storage/metadata.ts +1 -1
- package/src/storage/note_store/note_store.ts +159 -129
- package/src/storage/private_event_store/private_event_store.ts +102 -81
- package/src/storage/private_event_store/stored_private_event.ts +1 -1
- package/src/storage/tagging_store/recipient_tagging_store.ts +31 -21
- package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
- package/src/storage/tagging_store/sender_tagging_store.ts +210 -126
- package/dest/contract_sync/index.d.ts +0 -23
- package/dest/contract_sync/index.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
-
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
4
4
|
import type { L2TipsKVStore } from '@aztec/kv-store/stores';
|
|
5
5
|
import { BlockHash, L2BlockStream, type L2BlockStreamEvent, type L2BlockStreamEventHandler } from '@aztec/stdlib/block';
|
|
@@ -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,23 +29,27 @@ 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
|
) {
|
|
34
|
-
this.log =
|
|
35
|
-
!loggerOrSuffix || typeof loggerOrSuffix === 'string'
|
|
36
|
-
? createLogger(loggerOrSuffix ? `pxe:block_synchronizer:${loggerOrSuffix}` : `pxe:block_synchronizer`)
|
|
37
|
-
: loggerOrSuffix;
|
|
36
|
+
this.log = createLogger('pxe:block_synchronizer', bindings);
|
|
38
37
|
this.blockStream = this.createBlockStream(config);
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
protected createBlockStream(config: Partial<BlockSynchronizerConfig>): L2BlockStream {
|
|
42
|
-
return new L2BlockStream(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
return new L2BlockStream(
|
|
42
|
+
this.node,
|
|
43
|
+
this.l2TipsStore,
|
|
44
|
+
this,
|
|
45
|
+
createLogger('pxe:block_stream', this.log.getBindings()),
|
|
46
|
+
{
|
|
47
|
+
batchSize: config.l2BlockBatchSize,
|
|
48
|
+
// Skipping finalized blocks makes us sync much faster - we only need to download blocks other than the latest one
|
|
49
|
+
// in order to detect reorgs, and there can be no reorgs on finalized block, making this safe.
|
|
50
|
+
skipFinalized: true,
|
|
51
|
+
},
|
|
52
|
+
);
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
/** Handle events emitted by the block stream. */
|
|
@@ -122,6 +127,10 @@ export class BlockSynchronizer implements L2BlockStreamEventHandler {
|
|
|
122
127
|
|
|
123
128
|
/** Updates the anchor block header to the target block */
|
|
124
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();
|
|
125
134
|
this.log.verbose(`Updated pxe last block to ${blockHeader.getBlockNumber()}`, blockHeader.toInspect());
|
|
126
135
|
await this.anchorBlockStore.setHeader(blockHeader);
|
|
127
136
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
FIXED_AVM_STARTUP_L2_GAS,
|
|
8
8
|
FIXED_DA_GAS,
|
|
9
9
|
FIXED_L2_GAS,
|
|
10
|
+
GeneratorIndex,
|
|
10
11
|
L2_GAS_PER_CONTRACT_CLASS_LOG,
|
|
11
12
|
L2_GAS_PER_PRIVATE_LOG,
|
|
12
13
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
MAX_PRIVATE_LOGS_PER_TX,
|
|
18
19
|
} from '@aztec/constants';
|
|
19
20
|
import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection';
|
|
20
|
-
import {
|
|
21
|
+
import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
|
|
21
22
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
22
23
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
23
24
|
import { Timer } from '@aztec/foundation/timer';
|
|
@@ -71,8 +72,8 @@ import {
|
|
|
71
72
|
getFinalMinRevertibleSideEffectCounter,
|
|
72
73
|
} from '@aztec/stdlib/tx';
|
|
73
74
|
|
|
75
|
+
import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
|
|
74
76
|
import type { AddressStore } from '../storage/address_store/address_store.js';
|
|
75
|
-
import type { AnchorBlockStore } from '../storage/anchor_block_store/anchor_block_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';
|
|
78
79
|
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
@@ -101,13 +102,13 @@ export class ContractFunctionSimulator {
|
|
|
101
102
|
private keyStore: KeyStore,
|
|
102
103
|
private addressStore: AddressStore,
|
|
103
104
|
private aztecNode: AztecNode,
|
|
104
|
-
private anchorBlockStore: AnchorBlockStore,
|
|
105
105
|
private senderTaggingStore: SenderTaggingStore,
|
|
106
106
|
private recipientTaggingStore: RecipientTaggingStore,
|
|
107
107
|
private senderAddressBookStore: SenderAddressBookStore,
|
|
108
108
|
private capsuleStore: CapsuleStore,
|
|
109
109
|
private privateEventStore: PrivateEventStore,
|
|
110
110
|
private simulator: CircuitSimulator,
|
|
111
|
+
private contractSyncService: ContractSyncService,
|
|
111
112
|
) {
|
|
112
113
|
this.log = createLogger('simulator');
|
|
113
114
|
}
|
|
@@ -182,12 +183,12 @@ export class ContractFunctionSimulator {
|
|
|
182
183
|
this.keyStore,
|
|
183
184
|
this.addressStore,
|
|
184
185
|
this.aztecNode,
|
|
185
|
-
this.anchorBlockStore,
|
|
186
186
|
this.senderTaggingStore,
|
|
187
187
|
this.recipientTaggingStore,
|
|
188
188
|
this.senderAddressBookStore,
|
|
189
189
|
this.capsuleStore,
|
|
190
190
|
this.privateEventStore,
|
|
191
|
+
this.contractSyncService,
|
|
191
192
|
jobId,
|
|
192
193
|
0, // totalPublicArgsCount
|
|
193
194
|
startSideEffectCounter,
|
|
@@ -278,7 +279,6 @@ export class ContractFunctionSimulator {
|
|
|
278
279
|
this.keyStore,
|
|
279
280
|
this.addressStore,
|
|
280
281
|
this.aztecNode,
|
|
281
|
-
this.anchorBlockStore,
|
|
282
282
|
this.recipientTaggingStore,
|
|
283
283
|
this.senderAddressBookStore,
|
|
284
284
|
this.capsuleStore,
|
|
@@ -401,7 +401,10 @@ export async function generateSimulatedProvingResult(
|
|
|
401
401
|
|
|
402
402
|
const privateLogsFromExecution = await Promise.all(
|
|
403
403
|
execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
|
|
404
|
-
metadata.log.fields[0] = await
|
|
404
|
+
metadata.log.fields[0] = await poseidon2HashWithSeparator(
|
|
405
|
+
[contractAddress, metadata.log.fields[0]],
|
|
406
|
+
GeneratorIndex.PRIVATE_LOG_FIRST_FIELD,
|
|
407
|
+
);
|
|
405
408
|
return new OrderedSideEffect(metadata.log, metadata.counter);
|
|
406
409
|
}),
|
|
407
410
|
);
|
|
@@ -68,24 +68,24 @@ export interface IUtilityExecutionOracle {
|
|
|
68
68
|
utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest>;
|
|
69
69
|
utilityGetContractInstance(address: AztecAddress): Promise<ContractInstance>;
|
|
70
70
|
utilityGetNoteHashMembershipWitness(
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
anchorBlockHash: BlockHash,
|
|
72
|
+
noteHash: Fr,
|
|
73
73
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined>;
|
|
74
|
-
|
|
74
|
+
utilityGetBlockHashMembershipWitness(
|
|
75
|
+
anchorBlockHash: BlockHash,
|
|
75
76
|
blockHash: BlockHash,
|
|
76
|
-
leafValue: Fr,
|
|
77
77
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined>;
|
|
78
78
|
utilityGetNullifierMembershipWitness(
|
|
79
|
-
|
|
79
|
+
anchorBlockHash: BlockHash,
|
|
80
80
|
nullifier: Fr,
|
|
81
81
|
): Promise<NullifierMembershipWitness | undefined>;
|
|
82
|
-
utilityGetPublicDataWitness(
|
|
82
|
+
utilityGetPublicDataWitness(anchorBlockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness | undefined>;
|
|
83
83
|
utilityGetLowNullifierMembershipWitness(
|
|
84
|
-
|
|
84
|
+
anchorBlockHash: BlockHash,
|
|
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,
|
|
@@ -111,7 +111,7 @@ export interface IUtilityExecutionOracle {
|
|
|
111
111
|
secret: Fr,
|
|
112
112
|
): Promise<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>>;
|
|
113
113
|
utilityStorageRead(
|
|
114
|
-
|
|
114
|
+
anchorBlockHash: BlockHash,
|
|
115
115
|
contractAddress: AztecAddress,
|
|
116
116
|
startStorageSlot: Fr,
|
|
117
117
|
numberOfElements: number,
|
|
@@ -138,29 +138,39 @@ export class Oracle {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
async utilityGetNoteHashMembershipWitness(
|
|
141
|
-
[
|
|
142
|
-
[
|
|
141
|
+
[anchorBlockHash]: ACVMField[],
|
|
142
|
+
[noteHash]: ACVMField[],
|
|
143
143
|
): Promise<(ACVMField | ACVMField[])[]> {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
144
|
+
const parsedAnchorBlockHash = BlockHash.fromString(anchorBlockHash);
|
|
145
|
+
const parsedNoteHash = Fr.fromString(noteHash);
|
|
146
146
|
|
|
147
|
-
const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(
|
|
147
|
+
const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(
|
|
148
|
+
parsedAnchorBlockHash,
|
|
149
|
+
parsedNoteHash,
|
|
150
|
+
);
|
|
148
151
|
if (!witness) {
|
|
149
|
-
throw new Error(
|
|
152
|
+
throw new Error(
|
|
153
|
+
`Note hash ${noteHash} not found in the note hash tree at anchor block hash ${parsedAnchorBlockHash.toString()}.`,
|
|
154
|
+
);
|
|
150
155
|
}
|
|
151
156
|
return witness.toNoirRepresentation();
|
|
152
157
|
}
|
|
153
158
|
|
|
154
|
-
async
|
|
159
|
+
async utilityGetBlockHashMembershipWitness(
|
|
160
|
+
[anchorBlockHash]: ACVMField[],
|
|
155
161
|
[blockHash]: ACVMField[],
|
|
156
|
-
[leafValue]: ACVMField[],
|
|
157
162
|
): Promise<(ACVMField | ACVMField[])[]> {
|
|
163
|
+
const parsedAnchorBlockHash = BlockHash.fromString(anchorBlockHash);
|
|
158
164
|
const parsedBlockHash = BlockHash.fromString(blockHash);
|
|
159
|
-
const parsedLeafValue = Fr.fromString(leafValue);
|
|
160
165
|
|
|
161
|
-
const witness = await this.handlerAsUtility().
|
|
166
|
+
const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(
|
|
167
|
+
parsedAnchorBlockHash,
|
|
168
|
+
parsedBlockHash,
|
|
169
|
+
);
|
|
162
170
|
if (!witness) {
|
|
163
|
-
throw new Error(
|
|
171
|
+
throw new Error(
|
|
172
|
+
`Block hash ${parsedBlockHash.toString()} not found in the archive tree at anchor block ${parsedAnchorBlockHash.toString()}.`,
|
|
173
|
+
);
|
|
164
174
|
}
|
|
165
175
|
return witness.toNoirRepresentation();
|
|
166
176
|
}
|
|
@@ -238,12 +248,19 @@ export class Oracle {
|
|
|
238
248
|
return [witness.map(toACVMField)];
|
|
239
249
|
}
|
|
240
250
|
|
|
241
|
-
async
|
|
251
|
+
async utilityTryGetPublicKeysAndPartialAddress([address]: ACVMField[]): Promise<(ACVMField | ACVMField[])[]> {
|
|
242
252
|
const parsedAddress = AztecAddress.fromField(Fr.fromString(address));
|
|
243
|
-
const
|
|
244
|
-
await this.handlerAsUtility().utilityGetPublicKeysAndPartialAddress(parsedAddress);
|
|
253
|
+
const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(parsedAddress);
|
|
245
254
|
|
|
246
|
-
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
|
+
}
|
|
247
264
|
}
|
|
248
265
|
|
|
249
266
|
async utilityGetNotes(
|
|
@@ -30,10 +30,9 @@ 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
|
-
import type { AnchorBlockStore } from '../../storage/anchor_block_store/anchor_block_store.js';
|
|
37
36
|
import type { CapsuleStore } from '../../storage/capsule_store/capsule_store.js';
|
|
38
37
|
import type { ContractStore } from '../../storage/contract_store/contract_store.js';
|
|
39
38
|
import type { NoteStore } from '../../storage/note_store/note_store.js';
|
|
@@ -89,12 +88,12 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
89
88
|
keyStore: KeyStore,
|
|
90
89
|
addressStore: AddressStore,
|
|
91
90
|
aztecNode: AztecNode,
|
|
92
|
-
anchorBlockStore: AnchorBlockStore,
|
|
93
91
|
private readonly senderTaggingStore: SenderTaggingStore,
|
|
94
92
|
recipientTaggingStore: RecipientTaggingStore,
|
|
95
93
|
senderAddressBookStore: SenderAddressBookStore,
|
|
96
94
|
capsuleStore: CapsuleStore,
|
|
97
95
|
privateEventStore: PrivateEventStore,
|
|
96
|
+
private readonly contractSyncService: ContractSyncService,
|
|
98
97
|
jobId: string,
|
|
99
98
|
private totalPublicCalldataCount: number = 0,
|
|
100
99
|
protected sideEffectCounter: number = 0,
|
|
@@ -113,7 +112,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
113
112
|
keyStore,
|
|
114
113
|
addressStore,
|
|
115
114
|
aztecNode,
|
|
116
|
-
anchorBlockStore,
|
|
117
115
|
recipientTaggingStore,
|
|
118
116
|
senderAddressBookStore,
|
|
119
117
|
capsuleStore,
|
|
@@ -245,7 +243,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
245
243
|
sender: AztecAddress,
|
|
246
244
|
recipient: AztecAddress,
|
|
247
245
|
) {
|
|
248
|
-
const senderCompleteAddress = await this.
|
|
246
|
+
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
|
|
249
247
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
250
248
|
return DirectionalAppTaggingSecret.compute(
|
|
251
249
|
senderCompleteAddress,
|
|
@@ -364,7 +362,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
364
362
|
|
|
365
363
|
const pendingNullifiers = this.noteCache.getNullifiers(this.callContext.contractAddress);
|
|
366
364
|
|
|
367
|
-
const noteService = new NoteService(this.noteStore, this.aztecNode, this.
|
|
365
|
+
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
368
366
|
const dbNotes = await noteService.getNotes(
|
|
369
367
|
this.callContext.contractAddress,
|
|
370
368
|
owner,
|
|
@@ -540,13 +538,12 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
540
538
|
|
|
541
539
|
isStaticCall = isStaticCall || this.callContext.isStaticCall;
|
|
542
540
|
|
|
543
|
-
await ensureContractSynced(
|
|
541
|
+
await this.contractSyncService.ensureContractSynced(
|
|
544
542
|
targetContractAddress,
|
|
545
543
|
functionSelector,
|
|
546
544
|
this.utilityExecutor,
|
|
547
|
-
this.aztecNode,
|
|
548
|
-
this.contractStore,
|
|
549
545
|
this.anchorBlockHeader,
|
|
546
|
+
this.jobId,
|
|
550
547
|
);
|
|
551
548
|
|
|
552
549
|
const targetArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(
|
|
@@ -574,12 +571,12 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
574
571
|
this.keyStore,
|
|
575
572
|
this.addressStore,
|
|
576
573
|
this.aztecNode,
|
|
577
|
-
this.anchorBlockStore,
|
|
578
574
|
this.senderTaggingStore,
|
|
579
575
|
this.recipientTaggingStore,
|
|
580
576
|
this.senderAddressBookStore,
|
|
581
577
|
this.capsuleStore,
|
|
582
578
|
this.privateEventStore,
|
|
579
|
+
this.contractSyncService,
|
|
583
580
|
this.jobId,
|
|
584
581
|
this.totalPublicCalldataCount,
|
|
585
582
|
sideEffectCounter,
|
|
@@ -25,7 +25,6 @@ import { LogService } from '../../logs/log_service.js';
|
|
|
25
25
|
import { NoteService } from '../../notes/note_service.js';
|
|
26
26
|
import { ORACLE_VERSION } from '../../oracle_version.js';
|
|
27
27
|
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
28
|
-
import type { AnchorBlockStore } from '../../storage/anchor_block_store/anchor_block_store.js';
|
|
29
28
|
import type { CapsuleStore } from '../../storage/capsule_store/capsule_store.js';
|
|
30
29
|
import type { ContractStore } from '../../storage/contract_store/contract_store.js';
|
|
31
30
|
import type { NoteStore } from '../../storage/note_store/note_store.js';
|
|
@@ -61,7 +60,6 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
61
60
|
protected readonly keyStore: KeyStore,
|
|
62
61
|
protected readonly addressStore: AddressStore,
|
|
63
62
|
protected readonly aztecNode: AztecNode,
|
|
64
|
-
protected readonly anchorBlockStore: AnchorBlockStore,
|
|
65
63
|
protected readonly recipientTaggingStore: RecipientTaggingStore,
|
|
66
64
|
protected readonly senderAddressBookStore: SenderAddressBookStore,
|
|
67
65
|
protected readonly capsuleStore: CapsuleStore,
|
|
@@ -97,28 +95,34 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
97
95
|
|
|
98
96
|
/**
|
|
99
97
|
* Fetches the index and sibling path of a leaf at a given block from the note hash tree.
|
|
100
|
-
* @param
|
|
101
|
-
*
|
|
98
|
+
* @param anchorBlockHash - The hash of a block that contains the note hash tree root in which to find the membership
|
|
99
|
+
* witness.
|
|
100
|
+
* @param noteHash - The note hash to find in the note hash tree.
|
|
102
101
|
* @returns The membership witness containing the leaf index and sibling path
|
|
103
102
|
*/
|
|
104
103
|
public utilityGetNoteHashMembershipWitness(
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
anchorBlockHash: BlockHash,
|
|
105
|
+
noteHash: Fr,
|
|
107
106
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
108
|
-
return this.aztecNode.getNoteHashMembershipWitness(
|
|
107
|
+
return this.aztecNode.getNoteHashMembershipWitness(anchorBlockHash, noteHash);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
/**
|
|
112
|
-
* Fetches the index and sibling path of a
|
|
113
|
-
*
|
|
114
|
-
*
|
|
111
|
+
* Fetches the index and sibling path of a block hash in the archive tree.
|
|
112
|
+
*
|
|
113
|
+
* Block hashes are the leaves of the archive tree. Each time a new block is added to the chain,
|
|
114
|
+
* its block hash is appended as a new leaf to the archive tree.
|
|
115
|
+
*
|
|
116
|
+
* @param anchorBlockHash - The hash of a block that contains the archive tree root in which to find the membership
|
|
117
|
+
* witness.
|
|
118
|
+
* @param blockHash - The block hash to find in the archive tree.
|
|
115
119
|
* @returns The membership witness containing the leaf index and sibling path
|
|
116
120
|
*/
|
|
117
|
-
public
|
|
121
|
+
public utilityGetBlockHashMembershipWitness(
|
|
122
|
+
anchorBlockHash: BlockHash,
|
|
118
123
|
blockHash: BlockHash,
|
|
119
|
-
leafValue: Fr,
|
|
120
124
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
121
|
-
return this.aztecNode.
|
|
125
|
+
return this.aztecNode.getBlockHashMembershipWitness(anchorBlockHash, blockHash);
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
/**
|
|
@@ -166,7 +170,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
166
170
|
* @returns Block extracted from a block with block number `blockNumber`.
|
|
167
171
|
*/
|
|
168
172
|
public async utilityGetBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader | undefined> {
|
|
169
|
-
const anchorBlockNumber =
|
|
173
|
+
const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber();
|
|
170
174
|
if (blockNumber > anchorBlockNumber) {
|
|
171
175
|
throw new Error(`Block number ${blockNumber} is higher than current block ${anchorBlockNumber}`);
|
|
172
176
|
}
|
|
@@ -178,14 +182,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
178
182
|
/**
|
|
179
183
|
* Retrieve the complete address associated to a given address.
|
|
180
184
|
* @param account - The account address.
|
|
181
|
-
* @returns A complete address associated with the input address.
|
|
182
|
-
* @throws An error if the account is not registered in the database.
|
|
185
|
+
* @returns A complete address associated with the input address, or `undefined` if not registered.
|
|
183
186
|
*/
|
|
184
|
-
public
|
|
185
|
-
return this.getCompleteAddress(account);
|
|
187
|
+
public utilityTryGetPublicKeysAndPartialAddress(account: AztecAddress): Promise<CompleteAddress | undefined> {
|
|
188
|
+
return this.addressStore.getCompleteAddress(account);
|
|
186
189
|
}
|
|
187
190
|
|
|
188
|
-
protected async
|
|
191
|
+
protected async getCompleteAddressOrFail(account: AztecAddress): Promise<CompleteAddress> {
|
|
189
192
|
const completeAddress = await this.addressStore.getCompleteAddress(account);
|
|
190
193
|
if (!completeAddress) {
|
|
191
194
|
throw new Error(
|
|
@@ -262,7 +265,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
262
265
|
offset: number,
|
|
263
266
|
status: NoteStatus,
|
|
264
267
|
): Promise<NoteData[]> {
|
|
265
|
-
const noteService = new NoteService(this.noteStore, this.aztecNode, this.
|
|
268
|
+
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
266
269
|
|
|
267
270
|
const dbNotes = await noteService.getNotes(this.contractAddress, owner, storageSlot, status, this.scopes);
|
|
268
271
|
return pickNotes<NoteData>(dbNotes, {
|
|
@@ -349,25 +352,17 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
349
352
|
public async utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr) {
|
|
350
353
|
const logService = new LogService(
|
|
351
354
|
this.aztecNode,
|
|
352
|
-
this.
|
|
355
|
+
this.anchorBlockHeader,
|
|
353
356
|
this.keyStore,
|
|
354
357
|
this.capsuleStore,
|
|
355
358
|
this.recipientTaggingStore,
|
|
356
359
|
this.senderAddressBookStore,
|
|
357
360
|
this.addressStore,
|
|
358
361
|
this.jobId,
|
|
362
|
+
this.log.getBindings(),
|
|
359
363
|
);
|
|
360
364
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
// It is acceptable to run the following operations in parallel for several reasons:
|
|
364
|
-
// 1. syncTaggedLogs does not write to the note store — it only stores the pending tagged logs in a capsule array,
|
|
365
|
-
// which is then processed in Noir after this handler returns.
|
|
366
|
-
// 2. Even if syncTaggedLogs did write to the note store, it would not cause inconsistent state.
|
|
367
|
-
await Promise.all([
|
|
368
|
-
logService.syncTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, this.scopes),
|
|
369
|
-
noteService.syncNoteNullifiers(this.contractAddress),
|
|
370
|
-
]);
|
|
365
|
+
await logService.fetchTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, this.scopes);
|
|
371
366
|
}
|
|
372
367
|
|
|
373
368
|
/**
|
|
@@ -400,7 +395,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
400
395
|
await this.capsuleStore.readCapsuleArray(contractAddress, eventValidationRequestsArrayBaseSlot, this.jobId)
|
|
401
396
|
).map(EventValidationRequest.fromFields);
|
|
402
397
|
|
|
403
|
-
const noteService = new NoteService(this.noteStore, this.aztecNode, this.
|
|
398
|
+
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
404
399
|
const noteStorePromises = noteValidationRequests.map(request =>
|
|
405
400
|
noteService.validateAndStoreNote(
|
|
406
401
|
request.contractAddress,
|
|
@@ -416,7 +411,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
416
411
|
),
|
|
417
412
|
);
|
|
418
413
|
|
|
419
|
-
const eventService = new EventService(this.
|
|
414
|
+
const eventService = new EventService(this.anchorBlockHeader, this.aztecNode, this.privateEventStore, this.jobId);
|
|
420
415
|
const eventStorePromises = eventValidationRequests.map(request =>
|
|
421
416
|
eventService.validateAndStoreEvent(
|
|
422
417
|
request.contractAddress,
|
|
@@ -454,13 +449,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
454
449
|
|
|
455
450
|
const logService = new LogService(
|
|
456
451
|
this.aztecNode,
|
|
457
|
-
this.
|
|
452
|
+
this.anchorBlockHeader,
|
|
458
453
|
this.keyStore,
|
|
459
454
|
this.capsuleStore,
|
|
460
455
|
this.recipientTaggingStore,
|
|
461
456
|
this.senderAddressBookStore,
|
|
462
457
|
this.addressStore,
|
|
463
458
|
this.jobId,
|
|
459
|
+
this.log.getBindings(),
|
|
464
460
|
);
|
|
465
461
|
|
|
466
462
|
const maybeLogRetrievalResponses = await logService.bulkRetrieveLogs(logRetrievalRequests);
|
|
@@ -538,7 +534,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
538
534
|
|
|
539
535
|
protected async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
|
|
540
536
|
// TODO(#12656): return an app-siloed secret
|
|
541
|
-
const recipientCompleteAddress = await this.
|
|
537
|
+
const recipientCompleteAddress = await this.getCompleteAddressOrFail(address);
|
|
542
538
|
const ivskM = await this.keyStore.getMasterSecretKey(
|
|
543
539
|
recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
|
|
544
540
|
);
|
|
@@ -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
|
+
}
|