@aztec/pxe 0.0.1-commit.4d79d1f2d → 0.0.1-commit.4eabbdb
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/access_scopes.d.ts +9 -0
- package/dest/access_scopes.d.ts.map +1 -0
- package/dest/access_scopes.js +6 -0
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +8 -6
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +107 -37
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +2 -2
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +3 -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 +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +4 -3
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +1 -1
- package/dest/contract_sync/contract_sync_service.d.ts +4 -3
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
- package/dest/contract_sync/contract_sync_service.js +10 -10
- package/dest/contract_sync/helpers.d.ts +3 -2
- package/dest/contract_sync/helpers.d.ts.map +1 -1
- package/dest/contract_sync/helpers.js +3 -3
- package/dest/debug/pxe_debug_utils.d.ts +5 -4
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +4 -4
- package/dest/entrypoints/client/bundle/index.d.ts +3 -1
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +2 -0
- package/dest/entrypoints/client/lazy/index.d.ts +3 -1
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +2 -0
- package/dest/entrypoints/server/index.d.ts +3 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +2 -0
- package/dest/logs/log_service.d.ts +3 -2
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +1 -1
- package/dest/notes/note_service.d.ts +4 -3
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +3 -2
- package/dest/notes_filter.d.ts +25 -0
- package/dest/notes_filter.d.ts.map +1 -0
- package/dest/notes_filter.js +4 -0
- package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts +4 -0
- package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts.map +1 -0
- package/dest/private_kernel/hints/{compute_tx_include_by_timestamp.js → compute_tx_expiration_timestamp.js} +12 -12
- package/dest/private_kernel/hints/index.d.ts +1 -1
- package/dest/private_kernel/hints/index.js +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +4 -4
- package/dest/private_kernel/private_kernel_execution_prover.js +6 -6
- package/dest/pxe.d.ts +12 -11
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +17 -15
- package/dest/storage/note_store/note_store.d.ts +3 -2
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +2 -2
- package/dest/tagging/get_all_logs_by_tags.d.ts +1 -1
- package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
- package/dest/tagging/get_all_logs_by_tags.js +17 -3
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +4 -4
- package/dest/tagging/recipient_sync/utils/find_highest_indexes.js +2 -2
- package/package.json +16 -16
- package/src/access_scopes.ts +9 -0
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +213 -55
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +4 -3
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +4 -3
- package/src/contract_sync/contract_sync_service.ts +19 -12
- package/src/contract_sync/helpers.ts +7 -2
- package/src/debug/pxe_debug_utils.ts +9 -8
- package/src/entrypoints/client/bundle/index.ts +2 -0
- package/src/entrypoints/client/lazy/index.ts +2 -0
- package/src/entrypoints/server/index.ts +2 -0
- package/src/logs/log_service.ts +3 -6
- package/src/notes/note_service.ts +4 -3
- package/src/notes_filter.ts +26 -0
- package/src/private_kernel/hints/{compute_tx_include_by_timestamp.ts → compute_tx_expiration_timestamp.ts} +13 -13
- package/src/private_kernel/hints/index.ts +1 -1
- package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +7 -7
- package/src/private_kernel/private_kernel_execution_prover.ts +6 -6
- package/src/pxe.ts +29 -27
- package/src/storage/note_store/note_store.ts +7 -3
- package/src/tagging/get_all_logs_by_tags.ts +28 -4
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +4 -4
- package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +0 -4
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +0 -1
|
@@ -2,23 +2,25 @@ import {
|
|
|
2
2
|
AVM_EMITNOTEHASH_BASE_L2_GAS,
|
|
3
3
|
AVM_EMITNULLIFIER_BASE_L2_GAS,
|
|
4
4
|
AVM_SENDL2TOL1MSG_BASE_L2_GAS,
|
|
5
|
-
|
|
6
|
-
DA_GAS_PER_BYTE,
|
|
5
|
+
DA_GAS_PER_FIELD,
|
|
7
6
|
FIXED_AVM_STARTUP_L2_GAS,
|
|
8
7
|
FIXED_DA_GAS,
|
|
9
8
|
FIXED_L2_GAS,
|
|
10
|
-
GeneratorIndex,
|
|
11
9
|
L2_GAS_PER_CONTRACT_CLASS_LOG,
|
|
10
|
+
L2_GAS_PER_L2_TO_L1_MSG,
|
|
11
|
+
L2_GAS_PER_NOTE_HASH,
|
|
12
|
+
L2_GAS_PER_NULLIFIER,
|
|
12
13
|
L2_GAS_PER_PRIVATE_LOG,
|
|
13
14
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
14
15
|
MAX_ENQUEUED_CALLS_PER_TX,
|
|
15
16
|
MAX_L2_TO_L1_MSGS_PER_TX,
|
|
16
17
|
MAX_NOTE_HASHES_PER_TX,
|
|
18
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
17
19
|
MAX_NULLIFIERS_PER_TX,
|
|
20
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
18
21
|
MAX_PRIVATE_LOGS_PER_TX,
|
|
19
22
|
} from '@aztec/constants';
|
|
20
23
|
import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection';
|
|
21
|
-
import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
|
|
22
24
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
23
25
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
24
26
|
import { Timer } from '@aztec/foundation/timer';
|
|
@@ -38,25 +40,36 @@ import type { FunctionCall } from '@aztec/stdlib/abi';
|
|
|
38
40
|
import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
39
41
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
40
42
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
43
|
+
import type { BlockParameter } from '@aztec/stdlib/block';
|
|
41
44
|
import { Gas } from '@aztec/stdlib/gas';
|
|
42
45
|
import {
|
|
43
46
|
computeNoteHashNonce,
|
|
44
47
|
computeProtocolNullifier,
|
|
48
|
+
computeSiloedPrivateLogFirstField,
|
|
45
49
|
computeUniqueNoteHash,
|
|
46
50
|
siloNoteHash,
|
|
47
51
|
siloNullifier,
|
|
48
52
|
} from '@aztec/stdlib/hash';
|
|
49
53
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
50
54
|
import {
|
|
55
|
+
ClaimedLengthArray,
|
|
51
56
|
PartialPrivateTailPublicInputsForPublic,
|
|
52
57
|
PartialPrivateTailPublicInputsForRollup,
|
|
53
58
|
type PrivateExecutionStep,
|
|
54
59
|
type PrivateKernelExecutionProofOutput,
|
|
55
60
|
PrivateKernelTailCircuitPublicInputs,
|
|
61
|
+
PrivateLogData,
|
|
56
62
|
PrivateToPublicAccumulatedData,
|
|
57
63
|
PrivateToRollupAccumulatedData,
|
|
58
64
|
PublicCallRequest,
|
|
65
|
+
ReadRequestActionEnum,
|
|
59
66
|
ScopedLogHash,
|
|
67
|
+
ScopedNoteHash,
|
|
68
|
+
ScopedNullifier,
|
|
69
|
+
ScopedReadRequest,
|
|
70
|
+
buildTransientDataHints,
|
|
71
|
+
getNoteHashReadRequestResetActions,
|
|
72
|
+
getNullifierReadRequestResetActions,
|
|
60
73
|
} from '@aztec/stdlib/kernel';
|
|
61
74
|
import { PrivateLog } from '@aztec/stdlib/logs';
|
|
62
75
|
import { ScopedL2ToL1Message } from '@aztec/stdlib/messaging';
|
|
@@ -69,9 +82,11 @@ import {
|
|
|
69
82
|
TxConstantData,
|
|
70
83
|
TxExecutionRequest,
|
|
71
84
|
collectNested,
|
|
85
|
+
collectNoteHashNullifierCounterMap,
|
|
72
86
|
getFinalMinRevertibleSideEffectCounter,
|
|
73
87
|
} from '@aztec/stdlib/tx';
|
|
74
88
|
|
|
89
|
+
import type { AccessScopes } from '../access_scopes.js';
|
|
75
90
|
import type { ContractSyncService } from '../contract_sync/contract_sync_service.js';
|
|
76
91
|
import type { AddressStore } from '../storage/address_store/address_store.js';
|
|
77
92
|
import type { CapsuleStore } from '../storage/capsule_store/capsule_store.js';
|
|
@@ -102,8 +117,8 @@ export type ContractSimulatorRunOpts = {
|
|
|
102
117
|
anchorBlockHeader: BlockHeader;
|
|
103
118
|
/** The address used as a tagging sender when emitting private logs. */
|
|
104
119
|
senderForTags?: AztecAddress;
|
|
105
|
-
/** The accounts whose notes we can access in this call.
|
|
106
|
-
scopes
|
|
120
|
+
/** The accounts whose notes we can access in this call. */
|
|
121
|
+
scopes: AccessScopes;
|
|
107
122
|
/** The job ID for staged writes. */
|
|
108
123
|
jobId: string;
|
|
109
124
|
};
|
|
@@ -296,7 +311,7 @@ export class ContractFunctionSimulator {
|
|
|
296
311
|
call: FunctionCall,
|
|
297
312
|
authwits: AuthWitness[],
|
|
298
313
|
anchorBlockHeader: BlockHeader,
|
|
299
|
-
scopes:
|
|
314
|
+
scopes: AccessScopes,
|
|
300
315
|
jobId: string,
|
|
301
316
|
): Promise<Fr[]> {
|
|
302
317
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
@@ -345,7 +360,7 @@ export class ContractFunctionSimulator {
|
|
|
345
360
|
);
|
|
346
361
|
});
|
|
347
362
|
|
|
348
|
-
this.log.verbose(`Utility
|
|
363
|
+
this.log.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
349
364
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
350
365
|
} catch (err) {
|
|
351
366
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
@@ -387,7 +402,8 @@ class OrderedSideEffect<T> {
|
|
|
387
402
|
* (allowing state overrides) and is much faster, while still generating a valid
|
|
388
403
|
* output that can be sent to the node for public simulation
|
|
389
404
|
* @param privateExecutionResult - The result of the private execution.
|
|
390
|
-
* @param
|
|
405
|
+
* @param debugFunctionNameGetter - A provider for contract data in order to get function names and debug info.
|
|
406
|
+
* @param node - AztecNode for verifying settled read requests against the note hash and nullifier trees.
|
|
391
407
|
* @param minRevertibleSideEffectCounterOverride - Optional override for the min revertible side effect counter.
|
|
392
408
|
* Used by TXE to simulate account contract behavior (setting the counter before app execution).
|
|
393
409
|
* @returns The simulated proving result.
|
|
@@ -395,16 +411,24 @@ class OrderedSideEffect<T> {
|
|
|
395
411
|
export async function generateSimulatedProvingResult(
|
|
396
412
|
privateExecutionResult: PrivateExecutionResult,
|
|
397
413
|
debugFunctionNameGetter: (contractAddress: AztecAddress, functionSelector: FunctionSelector) => Promise<string>,
|
|
414
|
+
node: AztecNode,
|
|
398
415
|
minRevertibleSideEffectCounterOverride?: number,
|
|
399
416
|
): Promise<PrivateKernelExecutionProofOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
400
|
-
const
|
|
401
|
-
const nullifiers: OrderedSideEffect<Fr>[] = [];
|
|
402
|
-
const taggedPrivateLogs: OrderedSideEffect<PrivateLog>[] = [];
|
|
417
|
+
const taggedPrivateLogs: OrderedSideEffect<PrivateLogData>[] = [];
|
|
403
418
|
const l2ToL1Messages: OrderedSideEffect<ScopedL2ToL1Message>[] = [];
|
|
404
419
|
const contractClassLogsHashes: OrderedSideEffect<ScopedLogHash>[] = [];
|
|
405
420
|
const publicCallRequests: OrderedSideEffect<PublicCallRequest>[] = [];
|
|
406
421
|
const executionSteps: PrivateExecutionStep[] = [];
|
|
407
422
|
|
|
423
|
+
// Unsiloed scoped arrays — used for squashing, read request verification,
|
|
424
|
+
// and siloed at the end only for the surviving items
|
|
425
|
+
const scopedNoteHashes: ScopedNoteHash[] = [];
|
|
426
|
+
const scopedNullifiers: ScopedNullifier[] = [];
|
|
427
|
+
|
|
428
|
+
// Read requests for verification
|
|
429
|
+
const noteHashReadRequests: ScopedReadRequest[] = [];
|
|
430
|
+
const nullifierReadRequests: ScopedReadRequest[] = [];
|
|
431
|
+
|
|
408
432
|
let publicTeardownCallRequest;
|
|
409
433
|
|
|
410
434
|
const executions = [privateExecutionResult.entrypoint];
|
|
@@ -415,38 +439,25 @@ export async function generateSimulatedProvingResult(
|
|
|
415
439
|
|
|
416
440
|
const { contractAddress } = execution.publicInputs.callContext;
|
|
417
441
|
|
|
418
|
-
|
|
419
|
-
execution.publicInputs.noteHashes
|
|
420
|
-
.getActiveItems()
|
|
421
|
-
.filter(noteHash => !noteHash.isEmpty())
|
|
422
|
-
.map(
|
|
423
|
-
async noteHash =>
|
|
424
|
-
new OrderedSideEffect(await siloNoteHash(contractAddress, noteHash.value), noteHash.counter),
|
|
425
|
-
),
|
|
426
|
-
);
|
|
427
|
-
|
|
428
|
-
const nullifiersFromExecution = await Promise.all(
|
|
429
|
-
execution.publicInputs.nullifiers
|
|
442
|
+
scopedNoteHashes.push(
|
|
443
|
+
...execution.publicInputs.noteHashes
|
|
430
444
|
.getActiveItems()
|
|
431
|
-
.
|
|
432
|
-
|
|
433
|
-
new OrderedSideEffect(await siloNullifier(contractAddress, nullifier.value), nullifier.counter),
|
|
434
|
-
),
|
|
445
|
+
.filter(nh => !nh.isEmpty())
|
|
446
|
+
.map(nh => nh.scope(contractAddress)),
|
|
435
447
|
);
|
|
448
|
+
scopedNullifiers.push(...execution.publicInputs.nullifiers.getActiveItems().map(n => n.scope(contractAddress)));
|
|
436
449
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
[contractAddress, metadata.log.fields[0]
|
|
441
|
-
|
|
442
|
-
)
|
|
443
|
-
|
|
444
|
-
}),
|
|
450
|
+
taggedPrivateLogs.push(
|
|
451
|
+
...(await Promise.all(
|
|
452
|
+
execution.publicInputs.privateLogs.getActiveItems().map(async metadata => {
|
|
453
|
+
metadata.log.fields[0] = await computeSiloedPrivateLogFirstField(contractAddress, metadata.log.fields[0]);
|
|
454
|
+
return new OrderedSideEffect(metadata, metadata.counter);
|
|
455
|
+
}),
|
|
456
|
+
)),
|
|
445
457
|
);
|
|
446
458
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
nullifiers.push(...nullifiersFromExecution);
|
|
459
|
+
noteHashReadRequests.push(...execution.publicInputs.noteHashReadRequests.getActiveItems());
|
|
460
|
+
nullifierReadRequests.push(...execution.publicInputs.nullifierReadRequests.getActiveItems());
|
|
450
461
|
l2ToL1Messages.push(
|
|
451
462
|
...execution.publicInputs.l2ToL1Msgs
|
|
452
463
|
.getActiveItems()
|
|
@@ -486,6 +497,47 @@ export async function generateSimulatedProvingResult(
|
|
|
486
497
|
});
|
|
487
498
|
}
|
|
488
499
|
|
|
500
|
+
const noteHashNullifierCounterMap = collectNoteHashNullifierCounterMap(privateExecutionResult);
|
|
501
|
+
const minRevertibleSideEffectCounter =
|
|
502
|
+
minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
|
|
503
|
+
|
|
504
|
+
const scopedNoteHashesCLA = new ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>(
|
|
505
|
+
padArrayEnd(scopedNoteHashes, ScopedNoteHash.empty(), MAX_NOTE_HASHES_PER_TX),
|
|
506
|
+
scopedNoteHashes.length,
|
|
507
|
+
);
|
|
508
|
+
const scopedNullifiersCLA = new ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>(
|
|
509
|
+
padArrayEnd(scopedNullifiers, ScopedNullifier.empty(), MAX_NULLIFIERS_PER_TX),
|
|
510
|
+
scopedNullifiers.length,
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
const { filteredNoteHashes, filteredNullifiers, filteredPrivateLogs } = squashTransientSideEffects(
|
|
514
|
+
taggedPrivateLogs,
|
|
515
|
+
scopedNoteHashesCLA,
|
|
516
|
+
scopedNullifiersCLA,
|
|
517
|
+
noteHashNullifierCounterMap,
|
|
518
|
+
minRevertibleSideEffectCounter,
|
|
519
|
+
);
|
|
520
|
+
|
|
521
|
+
await verifyReadRequests(
|
|
522
|
+
node,
|
|
523
|
+
await privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader.hash(),
|
|
524
|
+
noteHashReadRequests,
|
|
525
|
+
nullifierReadRequests,
|
|
526
|
+
scopedNoteHashesCLA,
|
|
527
|
+
scopedNullifiersCLA,
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
const siloedNoteHashes = await Promise.all(
|
|
531
|
+
filteredNoteHashes
|
|
532
|
+
.sort((a, b) => a.counter - b.counter)
|
|
533
|
+
.map(async nh => new OrderedSideEffect(await siloNoteHash(nh.contractAddress, nh.value), nh.counter)),
|
|
534
|
+
);
|
|
535
|
+
const siloedNullifiers = await Promise.all(
|
|
536
|
+
filteredNullifiers
|
|
537
|
+
.sort((a, b) => a.counter - b.counter)
|
|
538
|
+
.map(async n => new OrderedSideEffect(await siloNullifier(n.contractAddress, n.value), n.counter)),
|
|
539
|
+
);
|
|
540
|
+
|
|
489
541
|
const constantData = new TxConstantData(
|
|
490
542
|
privateExecutionResult.entrypoint.publicInputs.anchorBlockHeader,
|
|
491
543
|
privateExecutionResult.entrypoint.publicInputs.txContext,
|
|
@@ -502,11 +554,9 @@ export async function generateSimulatedProvingResult(
|
|
|
502
554
|
const getEffect = <T>(orderedSideEffect: OrderedSideEffect<T>) => orderedSideEffect.sideEffect;
|
|
503
555
|
|
|
504
556
|
const isPrivateOnlyTx = privateExecutionResult.publicFunctionCalldata.length === 0;
|
|
505
|
-
const minRevertibleSideEffectCounter =
|
|
506
|
-
minRevertibleSideEffectCounterOverride ?? getFinalMinRevertibleSideEffectCounter(privateExecutionResult);
|
|
507
557
|
|
|
508
558
|
const [nonRevertibleNullifiers, revertibleNullifiers] = splitOrderedSideEffects(
|
|
509
|
-
|
|
559
|
+
siloedNullifiers,
|
|
510
560
|
minRevertibleSideEffectCounter,
|
|
511
561
|
);
|
|
512
562
|
const nonceGenerator = privateExecutionResult.firstNullifier;
|
|
@@ -520,7 +570,7 @@ export async function generateSimulatedProvingResult(
|
|
|
520
570
|
// We must make the note hashes unique by using the
|
|
521
571
|
// nonce generator and their index in the tx.
|
|
522
572
|
const uniqueNoteHashes = await Promise.all(
|
|
523
|
-
siloedNoteHashes.
|
|
573
|
+
siloedNoteHashes.map(async (orderedSideEffect, i) => {
|
|
524
574
|
const siloedNoteHash = orderedSideEffect.sideEffect;
|
|
525
575
|
const nonce = await computeNoteHashNonce(nonceGenerator, i);
|
|
526
576
|
const uniqueNoteHash = await computeUniqueNoteHash(nonce, siloedNoteHash);
|
|
@@ -535,18 +585,18 @@ export async function generateSimulatedProvingResult(
|
|
|
535
585
|
ScopedL2ToL1Message.empty(),
|
|
536
586
|
MAX_L2_TO_L1_MSGS_PER_TX,
|
|
537
587
|
),
|
|
538
|
-
padArrayEnd(
|
|
588
|
+
padArrayEnd(filteredPrivateLogs.sort(sortByCounter).map(getEffect), PrivateLog.empty(), MAX_PRIVATE_LOGS_PER_TX),
|
|
539
589
|
padArrayEnd(
|
|
540
590
|
contractClassLogsHashes.sort(sortByCounter).map(getEffect),
|
|
541
591
|
ScopedLogHash.empty(),
|
|
542
592
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
543
593
|
),
|
|
544
594
|
);
|
|
545
|
-
gasUsed = meterGasUsed(accumulatedDataForRollup);
|
|
595
|
+
gasUsed = meterGasUsed(accumulatedDataForRollup, isPrivateOnlyTx);
|
|
546
596
|
inputsForRollup = new PartialPrivateTailPublicInputsForRollup(accumulatedDataForRollup);
|
|
547
597
|
} else {
|
|
548
598
|
const [nonRevertibleNoteHashes, revertibleNoteHashes] = splitOrderedSideEffects(
|
|
549
|
-
siloedNoteHashes
|
|
599
|
+
siloedNoteHashes,
|
|
550
600
|
minRevertibleSideEffectCounter,
|
|
551
601
|
);
|
|
552
602
|
const nonRevertibleUniqueNoteHashes = await Promise.all(
|
|
@@ -560,7 +610,7 @@ export async function generateSimulatedProvingResult(
|
|
|
560
610
|
minRevertibleSideEffectCounter,
|
|
561
611
|
);
|
|
562
612
|
const [nonRevertibleTaggedPrivateLogs, revertibleTaggedPrivateLogs] = splitOrderedSideEffects(
|
|
563
|
-
|
|
613
|
+
filteredPrivateLogs,
|
|
564
614
|
minRevertibleSideEffectCounter,
|
|
565
615
|
);
|
|
566
616
|
const [nonRevertibleContractClassLogHashes, revertibleContractClassLogHashes] = splitOrderedSideEffects(
|
|
@@ -589,9 +639,9 @@ export async function generateSimulatedProvingResult(
|
|
|
589
639
|
padArrayEnd(revertibleContractClassLogHashes, ScopedLogHash.empty(), MAX_CONTRACT_CLASS_LOGS_PER_TX),
|
|
590
640
|
padArrayEnd(revertiblePublicCallRequests, PublicCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_TX),
|
|
591
641
|
);
|
|
592
|
-
gasUsed = meterGasUsed(revertibleData).add(meterGasUsed(nonRevertibleData));
|
|
642
|
+
gasUsed = meterGasUsed(revertibleData, isPrivateOnlyTx).add(meterGasUsed(nonRevertibleData, isPrivateOnlyTx));
|
|
593
643
|
if (publicTeardownCallRequest) {
|
|
594
|
-
gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
|
|
644
|
+
gasUsed = gasUsed.add(privateExecutionResult.entrypoint.publicInputs.txContext.gasSettings.teardownGasLimits);
|
|
595
645
|
}
|
|
596
646
|
|
|
597
647
|
inputsForPublic = new PartialPrivateTailPublicInputsForPublic(
|
|
@@ -605,7 +655,7 @@ export async function generateSimulatedProvingResult(
|
|
|
605
655
|
constantData,
|
|
606
656
|
/*gasUsed=*/ gasUsed.add(Gas.from({ l2Gas: FIXED_L2_GAS, daGas: FIXED_DA_GAS })),
|
|
607
657
|
/*feePayer=*/ AztecAddress.zero(),
|
|
608
|
-
/*
|
|
658
|
+
/*expirationTimestamp=*/ 0n,
|
|
609
659
|
hasPublicCalls ? inputsForPublic : undefined,
|
|
610
660
|
!hasPublicCalls ? inputsForRollup : undefined,
|
|
611
661
|
);
|
|
@@ -617,6 +667,111 @@ export async function generateSimulatedProvingResult(
|
|
|
617
667
|
};
|
|
618
668
|
}
|
|
619
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Squashes transient note hashes and nullifiers, mimicking the behavior
|
|
672
|
+
* of the reset kernels. Returns the filtered (surviving) scoped items and private logs.
|
|
673
|
+
*/
|
|
674
|
+
function squashTransientSideEffects(
|
|
675
|
+
taggedPrivateLogs: OrderedSideEffect<PrivateLogData>[],
|
|
676
|
+
scopedNoteHashesCLA: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
|
|
677
|
+
scopedNullifiersCLA: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
|
|
678
|
+
noteHashNullifierCounterMap: Map<number, number>,
|
|
679
|
+
minRevertibleSideEffectCounter: number,
|
|
680
|
+
) {
|
|
681
|
+
const { numTransientData, hints: transientDataHints } = buildTransientDataHints(
|
|
682
|
+
scopedNoteHashesCLA,
|
|
683
|
+
scopedNullifiersCLA,
|
|
684
|
+
/*futureNoteHashReads=*/ [],
|
|
685
|
+
/*futureNullifierReads=*/ [],
|
|
686
|
+
noteHashNullifierCounterMap,
|
|
687
|
+
minRevertibleSideEffectCounter,
|
|
688
|
+
);
|
|
689
|
+
|
|
690
|
+
const squashedNoteHashCounters = new Set<number>();
|
|
691
|
+
const squashedNullifierCounters = new Set<number>();
|
|
692
|
+
for (let i = 0; i < numTransientData; i++) {
|
|
693
|
+
const hint = transientDataHints[i];
|
|
694
|
+
squashedNoteHashCounters.add(scopedNoteHashesCLA.array[hint.noteHashIndex].counter);
|
|
695
|
+
squashedNullifierCounters.add(scopedNullifiersCLA.array[hint.nullifierIndex].counter);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return {
|
|
699
|
+
filteredNoteHashes: scopedNoteHashesCLA.getActiveItems().filter(nh => !squashedNoteHashCounters.has(nh.counter)),
|
|
700
|
+
filteredNullifiers: scopedNullifiersCLA.getActiveItems().filter(n => !squashedNullifierCounters.has(n.counter)),
|
|
701
|
+
filteredPrivateLogs: taggedPrivateLogs
|
|
702
|
+
.filter(item => !squashedNoteHashCounters.has(item.sideEffect.noteHashCounter))
|
|
703
|
+
.map(item => new OrderedSideEffect(item.sideEffect.log, item.counter)),
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Verifies settled read requests by checking membership in the note hash and nullifier trees
|
|
709
|
+
* at the tx's anchor block, mimicking the behavior of the kernels
|
|
710
|
+
*/
|
|
711
|
+
async function verifyReadRequests(
|
|
712
|
+
node: Pick<AztecNode, 'getNoteHashMembershipWitness' | 'getNullifierMembershipWitness'>,
|
|
713
|
+
anchorBlockHash: BlockParameter,
|
|
714
|
+
noteHashReadRequests: ScopedReadRequest[],
|
|
715
|
+
nullifierReadRequests: ScopedReadRequest[],
|
|
716
|
+
scopedNoteHashesCLA: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
|
|
717
|
+
scopedNullifiersCLA: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
|
|
718
|
+
) {
|
|
719
|
+
const noteHashReadRequestsCLA = new ClaimedLengthArray<ScopedReadRequest, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>(
|
|
720
|
+
padArrayEnd(noteHashReadRequests, ScopedReadRequest.empty(), MAX_NOTE_HASH_READ_REQUESTS_PER_TX),
|
|
721
|
+
noteHashReadRequests.length,
|
|
722
|
+
);
|
|
723
|
+
const nullifierReadRequestsCLA = new ClaimedLengthArray<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>(
|
|
724
|
+
padArrayEnd(nullifierReadRequests, ScopedReadRequest.empty(), MAX_NULLIFIER_READ_REQUESTS_PER_TX),
|
|
725
|
+
nullifierReadRequests.length,
|
|
726
|
+
);
|
|
727
|
+
|
|
728
|
+
const noteHashResetActions = getNoteHashReadRequestResetActions(
|
|
729
|
+
noteHashReadRequestsCLA,
|
|
730
|
+
scopedNoteHashesCLA,
|
|
731
|
+
/*futureNoteHashes=*/ [],
|
|
732
|
+
);
|
|
733
|
+
const nullifierResetActions = getNullifierReadRequestResetActions(
|
|
734
|
+
nullifierReadRequestsCLA,
|
|
735
|
+
scopedNullifiersCLA,
|
|
736
|
+
/*futureNullifiers=*/ [],
|
|
737
|
+
);
|
|
738
|
+
|
|
739
|
+
const settledNoteHashReads: { index: number; value: Fr }[] = [];
|
|
740
|
+
for (let i = 0; i < noteHashResetActions.actions.length; i++) {
|
|
741
|
+
if (noteHashResetActions.actions[i] === ReadRequestActionEnum.READ_AS_SETTLED) {
|
|
742
|
+
settledNoteHashReads.push({ index: i, value: noteHashReadRequests[i].value });
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
const settledNullifierReads: { index: number; value: Fr }[] = [];
|
|
747
|
+
for (let i = 0; i < nullifierResetActions.actions.length; i++) {
|
|
748
|
+
if (nullifierResetActions.actions[i] === ReadRequestActionEnum.READ_AS_SETTLED) {
|
|
749
|
+
settledNullifierReads.push({ index: i, value: nullifierReadRequests[i].value });
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const [noteHashWitnesses, nullifierWitnesses] = await Promise.all([
|
|
754
|
+
Promise.all(settledNoteHashReads.map(({ value }) => node.getNoteHashMembershipWitness(anchorBlockHash, value))),
|
|
755
|
+
Promise.all(settledNullifierReads.map(({ value }) => node.getNullifierMembershipWitness(anchorBlockHash, value))),
|
|
756
|
+
]);
|
|
757
|
+
|
|
758
|
+
for (let i = 0; i < settledNoteHashReads.length; i++) {
|
|
759
|
+
if (!noteHashWitnesses[i]) {
|
|
760
|
+
throw new Error(
|
|
761
|
+
`Note hash read request at index ${settledNoteHashReads[i].index} is reading an unknown note hash: ${settledNoteHashReads[i].value}`,
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
for (let i = 0; i < settledNullifierReads.length; i++) {
|
|
767
|
+
if (!nullifierWitnesses[i]) {
|
|
768
|
+
throw new Error(
|
|
769
|
+
`Nullifier read request at index ${settledNullifierReads[i].index} is reading an unknown nullifier: ${settledNullifierReads[i].value}`,
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
620
775
|
function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertibleSideEffectCounter: number) {
|
|
621
776
|
const revertibleSideEffects: T[] = [];
|
|
622
777
|
const nonRevertibleSideEffects: T[] = [];
|
|
@@ -630,21 +785,24 @@ function splitOrderedSideEffects<T>(effects: OrderedSideEffect<T>[], minRevertib
|
|
|
630
785
|
return [nonRevertibleSideEffects, revertibleSideEffects];
|
|
631
786
|
}
|
|
632
787
|
|
|
633
|
-
function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData) {
|
|
788
|
+
function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccumulatedData, isPrivateOnlyTx: boolean) {
|
|
634
789
|
let meteredDAFields = 0;
|
|
635
790
|
let meteredL2Gas = 0;
|
|
636
791
|
|
|
637
792
|
const numNoteHashes = arrayNonEmptyLength(data.noteHashes, hash => hash.isEmpty());
|
|
638
793
|
meteredDAFields += numNoteHashes;
|
|
639
|
-
|
|
794
|
+
const noteHashBaseGas = isPrivateOnlyTx ? L2_GAS_PER_NOTE_HASH : AVM_EMITNOTEHASH_BASE_L2_GAS;
|
|
795
|
+
meteredL2Gas += numNoteHashes * noteHashBaseGas;
|
|
640
796
|
|
|
641
797
|
const numNullifiers = arrayNonEmptyLength(data.nullifiers, nullifier => nullifier.isEmpty());
|
|
642
798
|
meteredDAFields += numNullifiers;
|
|
643
|
-
|
|
799
|
+
const nullifierBaseGas = isPrivateOnlyTx ? L2_GAS_PER_NULLIFIER : AVM_EMITNULLIFIER_BASE_L2_GAS;
|
|
800
|
+
meteredL2Gas += numNullifiers * nullifierBaseGas;
|
|
644
801
|
|
|
645
802
|
const numL2toL1Messages = arrayNonEmptyLength(data.l2ToL1Msgs, msg => msg.isEmpty());
|
|
646
803
|
meteredDAFields += numL2toL1Messages;
|
|
647
|
-
|
|
804
|
+
const l2ToL1MessageBaseGas = isPrivateOnlyTx ? L2_GAS_PER_L2_TO_L1_MSG : AVM_SENDL2TOL1MSG_BASE_L2_GAS;
|
|
805
|
+
meteredL2Gas += numL2toL1Messages * l2ToL1MessageBaseGas;
|
|
648
806
|
|
|
649
807
|
const numPrivatelogs = arrayNonEmptyLength(data.privateLogs, log => log.isEmpty());
|
|
650
808
|
// Every private log emits its length as an additional field
|
|
@@ -659,7 +817,7 @@ function meterGasUsed(data: PrivateToRollupAccumulatedData | PrivateToPublicAccu
|
|
|
659
817
|
);
|
|
660
818
|
meteredL2Gas += numContractClassLogs * L2_GAS_PER_CONTRACT_CLASS_LOG;
|
|
661
819
|
|
|
662
|
-
const meteredDAGas = meteredDAFields *
|
|
820
|
+
const meteredDAGas = meteredDAFields * DA_GAS_PER_FIELD;
|
|
663
821
|
|
|
664
822
|
if ((data as PrivateToPublicAccumulatedData).publicCallRequests) {
|
|
665
823
|
const dataForPublic = data as PrivateToPublicAccumulatedData;
|
|
@@ -5,7 +5,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
5
5
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
6
6
|
|
|
7
7
|
// TODO(#14617): should we compute this from constants? This value is aztec-nr specific.
|
|
8
|
-
const MAX_EVENT_SERIALIZED_LEN =
|
|
8
|
+
const MAX_EVENT_SERIALIZED_LEN = 11;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Intermediate struct used to perform batch event validation by PXE. The `utilityValidateAndStoreEnqueuedNotesAndEvents` oracle
|
|
@@ -4,7 +4,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
4
4
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
6
|
// TODO(#14617): should we compute this from constants? This value is aztec-nr specific.
|
|
7
|
-
export const MAX_NOTE_PACKED_LEN =
|
|
7
|
+
export const MAX_NOTE_PACKED_LEN = 9;
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Intermediate struct used to perform batch note validation by PXE. The `utilityValidateAndStoreEnqueuedNotesAndEvents` oracle
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
type TxContext,
|
|
26
26
|
} from '@aztec/stdlib/tx';
|
|
27
27
|
|
|
28
|
+
import type { AccessScopes } from '../../access_scopes.js';
|
|
28
29
|
import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
|
|
29
30
|
import { NoteService } from '../../notes/note_service.js';
|
|
30
31
|
import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js';
|
|
@@ -43,7 +44,7 @@ export type PrivateExecutionOracleArgs = Omit<UtilityExecutionOracleArgs, 'contr
|
|
|
43
44
|
txContext: TxContext;
|
|
44
45
|
callContext: CallContext;
|
|
45
46
|
/** Needed to trigger contract synchronization before nested calls */
|
|
46
|
-
utilityExecutor: (call: FunctionCall, scopes:
|
|
47
|
+
utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<void>;
|
|
47
48
|
executionCache: HashedValuesCache;
|
|
48
49
|
noteCache: ExecutionNoteCache;
|
|
49
50
|
taggingIndexCache: ExecutionTaggingIndexCache;
|
|
@@ -78,7 +79,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
78
79
|
private readonly argsHash: Fr;
|
|
79
80
|
private readonly txContext: TxContext;
|
|
80
81
|
private readonly callContext: CallContext;
|
|
81
|
-
private readonly utilityExecutor: (call: FunctionCall, scopes:
|
|
82
|
+
private readonly utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<void>;
|
|
82
83
|
private readonly executionCache: HashedValuesCache;
|
|
83
84
|
private readonly noteCache: ExecutionNoteCache;
|
|
84
85
|
private readonly taggingIndexCache: ExecutionTaggingIndexCache;
|
|
@@ -531,7 +532,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
531
532
|
// We only expand for registered accounts because the log service needs the recipient's keys to derive
|
|
532
533
|
// tagging secrets, which are only available for registered accounts.
|
|
533
534
|
const expandedScopes =
|
|
534
|
-
this.scopes && (await this.keyStore.hasAccount(targetContractAddress))
|
|
535
|
+
this.scopes !== 'ALL_SCOPES' && (await this.keyStore.hasAccount(targetContractAddress))
|
|
535
536
|
? [...this.scopes, targetContractAddress]
|
|
536
537
|
: this.scopes;
|
|
537
538
|
|
|
@@ -20,6 +20,7 @@ import type { NoteStatus } from '@aztec/stdlib/note';
|
|
|
20
20
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
21
21
|
import type { BlockHeader, Capsule } from '@aztec/stdlib/tx';
|
|
22
22
|
|
|
23
|
+
import type { AccessScopes } from '../../access_scopes.js';
|
|
23
24
|
import { EventService } from '../../events/event_service.js';
|
|
24
25
|
import { LogService } from '../../logs/log_service.js';
|
|
25
26
|
import { NoteService } from '../../notes/note_service.js';
|
|
@@ -58,7 +59,7 @@ export type UtilityExecutionOracleArgs = {
|
|
|
58
59
|
privateEventStore: PrivateEventStore;
|
|
59
60
|
jobId: string;
|
|
60
61
|
log?: ReturnType<typeof createLogger>;
|
|
61
|
-
scopes
|
|
62
|
+
scopes: AccessScopes;
|
|
62
63
|
};
|
|
63
64
|
|
|
64
65
|
/**
|
|
@@ -85,7 +86,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
85
86
|
protected readonly privateEventStore: PrivateEventStore;
|
|
86
87
|
protected readonly jobId: string;
|
|
87
88
|
protected log: ReturnType<typeof createLogger>;
|
|
88
|
-
protected readonly scopes
|
|
89
|
+
protected readonly scopes: AccessScopes;
|
|
89
90
|
|
|
90
91
|
constructor(args: UtilityExecutionOracleArgs) {
|
|
91
92
|
this.contractAddress = args.contractAddress;
|
|
@@ -129,7 +130,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
129
130
|
*/
|
|
130
131
|
public async utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
131
132
|
// If scopes are defined, check that the key belongs to an account in the scopes.
|
|
132
|
-
if (this.scopes && this.scopes.length > 0) {
|
|
133
|
+
if (this.scopes !== 'ALL_SCOPES' && this.scopes.length > 0) {
|
|
133
134
|
let hasAccess = false;
|
|
134
135
|
for (let i = 0; i < this.scopes.length && !hasAccess; i++) {
|
|
135
136
|
if (await this.keyStore.accountHasKey(this.scopes[i], pkMHash)) {
|
|
@@ -4,6 +4,7 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
4
4
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
5
5
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
6
6
|
|
|
7
|
+
import type { AccessScopes } from '../access_scopes.js';
|
|
7
8
|
import type { StagedStore } from '../job_coordinator/job_coordinator.js';
|
|
8
9
|
import type { ContractStore } from '../storage/contract_store/contract_store.js';
|
|
9
10
|
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
@@ -45,15 +46,15 @@ export class ContractSyncService implements StagedStore {
|
|
|
45
46
|
* @param functionToInvokeAfterSync - The function selector that will be called after sync (used to validate it's
|
|
46
47
|
* not sync_state itself).
|
|
47
48
|
* @param utilityExecutor - Executor function for running the sync_state utility function.
|
|
48
|
-
* @param scopes -
|
|
49
|
+
* @param scopes - Access scopes to pass through to the utility executor (affects whose account's private state is discovered).
|
|
49
50
|
*/
|
|
50
51
|
async ensureContractSynced(
|
|
51
52
|
contractAddress: AztecAddress,
|
|
52
53
|
functionToInvokeAfterSync: FunctionSelector | null,
|
|
53
|
-
utilityExecutor: (call: FunctionCall, scopes:
|
|
54
|
+
utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<any>,
|
|
54
55
|
anchorBlockHeader: BlockHeader,
|
|
55
56
|
jobId: string,
|
|
56
|
-
scopes:
|
|
57
|
+
scopes: AccessScopes,
|
|
57
58
|
): Promise<void> {
|
|
58
59
|
// Skip sync if this contract has an override for this job (overrides are keyed by contract address only)
|
|
59
60
|
const overrides = this.overriddenContracts.get(jobId);
|
|
@@ -62,13 +63,16 @@ export class ContractSyncService implements StagedStore {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
// Skip sync if we already synced for "all scopes", or if we have an empty list of scopes
|
|
65
|
-
const allScopesKey = toKey(contractAddress,
|
|
66
|
+
const allScopesKey = toKey(contractAddress, 'ALL_SCOPES');
|
|
66
67
|
const allScopesExisting = this.syncedContracts.get(allScopesKey);
|
|
67
|
-
if (allScopesExisting || (scopes && scopes.length == 0)) {
|
|
68
|
+
if (allScopesExisting || (scopes !== 'ALL_SCOPES' && scopes.length == 0)) {
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
const unsyncedScopes =
|
|
72
|
+
const unsyncedScopes =
|
|
73
|
+
scopes === 'ALL_SCOPES'
|
|
74
|
+
? scopes
|
|
75
|
+
: scopes.filter(scope => !this.syncedContracts.has(toKey(contractAddress, scope)));
|
|
72
76
|
const unsyncedScopesKeys = toKeys(contractAddress, unsyncedScopes);
|
|
73
77
|
|
|
74
78
|
if (unsyncedScopesKeys.length > 0) {
|
|
@@ -76,9 +80,10 @@ export class ContractSyncService implements StagedStore {
|
|
|
76
80
|
const promise = this.#doSync(
|
|
77
81
|
contractAddress,
|
|
78
82
|
functionToInvokeAfterSync,
|
|
79
|
-
|
|
83
|
+
utilityExecutor,
|
|
80
84
|
anchorBlockHeader,
|
|
81
85
|
jobId,
|
|
86
|
+
unsyncedScopes,
|
|
82
87
|
).catch(err => {
|
|
83
88
|
// There was an error syncing the contract, so we remove it from the cache so that it can be retried.
|
|
84
89
|
unsyncedScopesKeys.forEach(key => this.syncedContracts.delete(key));
|
|
@@ -94,9 +99,10 @@ export class ContractSyncService implements StagedStore {
|
|
|
94
99
|
async #doSync(
|
|
95
100
|
contractAddress: AztecAddress,
|
|
96
101
|
functionToInvokeAfterSync: FunctionSelector | null,
|
|
97
|
-
utilityExecutor: (call: FunctionCall) => Promise<any>,
|
|
102
|
+
utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<any>,
|
|
98
103
|
anchorBlockHeader: BlockHeader,
|
|
99
104
|
jobId: string,
|
|
105
|
+
scopes: AccessScopes,
|
|
100
106
|
): Promise<void> {
|
|
101
107
|
this.log.debug(`Syncing contract ${contractAddress}`);
|
|
102
108
|
await Promise.all([
|
|
@@ -109,6 +115,7 @@ export class ContractSyncService implements StagedStore {
|
|
|
109
115
|
this.aztecNode,
|
|
110
116
|
anchorBlockHeader,
|
|
111
117
|
jobId,
|
|
118
|
+
scopes,
|
|
112
119
|
),
|
|
113
120
|
verifyCurrentClassId(contractAddress, this.aztecNode, this.contractStore, anchorBlockHeader),
|
|
114
121
|
]);
|
|
@@ -136,10 +143,10 @@ export class ContractSyncService implements StagedStore {
|
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
|
|
139
|
-
function toKeys(contract: AztecAddress, scopes:
|
|
140
|
-
return scopes ===
|
|
146
|
+
function toKeys(contract: AztecAddress, scopes: AccessScopes) {
|
|
147
|
+
return scopes === 'ALL_SCOPES' ? [toKey(contract, scopes)] : scopes.map(scope => toKey(contract, scope));
|
|
141
148
|
}
|
|
142
149
|
|
|
143
|
-
function toKey(contract: AztecAddress, scope: AztecAddress |
|
|
144
|
-
return scope ===
|
|
150
|
+
function toKey(contract: AztecAddress, scope: AztecAddress | 'ALL_SCOPES') {
|
|
151
|
+
return scope === 'ALL_SCOPES' ? `${contract.toString()}:*` : `${contract.toString()}:${scope.toString()}`;
|
|
145
152
|
}
|