@aztec/pxe 0.0.1-commit.3469e52 → 0.0.1-commit.381b1a9
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/bin/check_oracle_version.js +1 -1
- package/dest/block_synchronizer/block_synchronizer.d.ts +9 -5
- package/dest/block_synchronizer/block_synchronizer.d.ts.map +1 -1
- package/dest/block_synchronizer/block_synchronizer.js +62 -16
- package/dest/config/index.d.ts +3 -1
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +17 -0
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +54 -30
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +175 -74
- package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +5 -5
- package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_tagging_index_cache.js +3 -3
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +2 -2
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +3 -3
- 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 +2 -2
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +20 -13
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.d.ts +7 -5
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +51 -29
- package/dest/contract_function_simulator/oracle/private_execution.d.ts +2 -22
- package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution.js +0 -37
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +44 -36
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +94 -30
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +68 -32
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +115 -89
- package/dest/contract_logging.d.ts +22 -0
- package/dest/contract_logging.d.ts.map +1 -0
- package/dest/contract_logging.js +23 -0
- package/dest/contract_sync/contract_sync_service.d.ts +43 -0
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -0
- package/dest/contract_sync/contract_sync_service.js +97 -0
- package/dest/contract_sync/helpers.d.ts +29 -0
- package/dest/contract_sync/helpers.d.ts.map +1 -0
- package/dest/contract_sync/helpers.js +55 -0
- package/dest/debug/pxe_debug_utils.d.ts +24 -10
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +28 -17
- package/dest/entrypoints/client/bundle/index.d.ts +4 -1
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +3 -0
- 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 +21 -7
- package/dest/entrypoints/client/lazy/index.d.ts +4 -1
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +3 -0
- 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 +22 -8
- 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 +4 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +3 -0
- 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 +28 -9
- package/dest/events/event_service.d.ts +5 -6
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +6 -7
- 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 +7 -5
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +28 -32
- package/dest/notes/note_service.d.ts +9 -8
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +17 -16
- 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/oracle_version.d.ts +3 -3
- package/dest/oracle_version.d.ts.map +1 -1
- package/dest/oracle_version.js +4 -3
- 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.d.ts +4 -3
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +129 -68
- package/dest/private_kernel/hints/test_utils.d.ts +122 -0
- package/dest/private_kernel/hints/test_utils.d.ts.map +1 -0
- package/dest/private_kernel/hints/test_utils.js +203 -0
- 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 +21 -13
- package/dest/private_kernel/private_kernel_oracle.d.ts +8 -4
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle.js +7 -3
- package/dest/pxe.d.ts +69 -23
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +102 -66
- 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 +42 -16
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +157 -84
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/note_store/note_store.d.ts +47 -49
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +278 -252
- package/dest/storage/note_store/stored_note.d.ts +16 -0
- package/dest/storage/note_store/stored_note.d.ts.map +1 -0
- package/dest/storage/note_store/stored_note.js +43 -0
- package/dest/storage/private_event_store/private_event_store.d.ts +17 -4
- package/dest/storage/private_event_store/private_event_store.d.ts.map +1 -1
- package/dest/storage/private_event_store/private_event_store.js +198 -147
- package/dest/storage/private_event_store/stored_private_event.d.ts +23 -0
- package/dest/storage/private_event_store/stored_private_event.d.ts.map +1 -0
- package/dest/storage/private_event_store/stored_private_event.js +56 -0
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
- 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 +5 -5
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +184 -114
- package/dest/tagging/get_all_logs_by_tags.d.ts +24 -0
- package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -0
- package/dest/tagging/get_all_logs_by_tags.js +60 -0
- package/dest/tagging/index.d.ts +3 -2
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +2 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +5 -5
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +7 -7
- package/dest/tagging/recipient_sync/utils/find_highest_indexes.js +2 -2
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +7 -7
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +16 -12
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +5 -8
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +3 -6
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.js +5 -8
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +5 -7
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +20 -18
- package/package.json +25 -16
- package/src/access_scopes.ts +9 -0
- package/src/bin/check_oracle_version.ts +1 -0
- package/src/block_synchronizer/block_synchronizer.ts +76 -33
- package/src/config/index.ts +14 -0
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +324 -137
- package/src/contract_function_simulator/execution_tagging_index_cache.ts +5 -5
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +2 -2
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +2 -2
- package/src/contract_function_simulator/oracle/interfaces.ts +24 -12
- package/src/contract_function_simulator/oracle/oracle.ts +56 -26
- package/src/contract_function_simulator/oracle/private_execution.ts +1 -60
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +134 -109
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +181 -98
- package/src/contract_logging.ts +39 -0
- package/src/contract_sync/contract_sync_service.ts +152 -0
- package/src/contract_sync/helpers.ts +98 -0
- package/src/debug/pxe_debug_utils.ts +63 -18
- package/src/entrypoints/client/bundle/index.ts +3 -0
- package/src/entrypoints/client/bundle/utils.ts +16 -15
- package/src/entrypoints/client/lazy/index.ts +3 -0
- package/src/entrypoints/client/lazy/utils.ts +17 -15
- package/src/entrypoints/pxe_creation_options.ts +2 -1
- package/src/entrypoints/server/index.ts +3 -0
- package/src/entrypoints/server/utils.ts +22 -26
- package/src/events/event_service.ts +5 -7
- package/src/job_coordinator/job_coordinator.ts +4 -3
- package/src/logs/log_service.ts +48 -39
- package/src/notes/note_service.ts +24 -22
- package/src/notes_filter.ts +26 -0
- package/src/oracle_version.ts +4 -3
- 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 +164 -117
- package/src/private_kernel/hints/test_utils.ts +325 -0
- package/src/private_kernel/private_kernel_execution_prover.ts +25 -15
- package/src/private_kernel/private_kernel_oracle.ts +9 -9
- package/src/pxe.ts +209 -111
- 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 +186 -96
- package/src/storage/metadata.ts +1 -1
- package/src/storage/note_store/note_store.ts +321 -318
- package/src/storage/note_store/stored_note.ts +48 -0
- package/src/storage/private_event_store/private_event_store.ts +250 -190
- package/src/storage/private_event_store/stored_private_event.ts +73 -0
- package/src/storage/tagging_store/recipient_tagging_store.ts +38 -24
- package/src/storage/tagging_store/sender_address_book_store.ts +20 -14
- package/src/storage/tagging_store/sender_tagging_store.ts +214 -130
- package/src/tagging/get_all_logs_by_tags.ts +92 -0
- package/src/tagging/index.ts +2 -1
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +17 -10
- package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
- package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +17 -16
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +6 -9
- package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +5 -17
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +23 -23
- 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
- package/dest/tree_membership/tree_membership_service.d.ts +0 -50
- package/dest/tree_membership/tree_membership_service.d.ts.map +0 -1
- package/dest/tree_membership/tree_membership_service.js +0 -75
- package/src/tree_membership/tree_membership_service.ts +0 -97
|
@@ -1,35 +1,38 @@
|
|
|
1
|
+
import type { ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
|
|
1
2
|
import type { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import { Aes128 } from '@aztec/foundation/crypto/aes128';
|
|
3
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
5
|
import { Point } from '@aztec/foundation/curves/grumpkin';
|
|
5
|
-
import { LogLevels,
|
|
6
|
+
import { LogLevels, type Logger, createLogger } from '@aztec/foundation/log';
|
|
7
|
+
import type { MembershipWitness } from '@aztec/foundation/trees';
|
|
6
8
|
import type { KeyStore } from '@aztec/key-store';
|
|
7
9
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
8
10
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
-
import {
|
|
10
|
-
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
11
|
+
import { BlockHash } from '@aztec/stdlib/block';
|
|
12
|
+
import type { CompleteAddress, ContractInstance, PartialAddress } from '@aztec/stdlib/contract';
|
|
11
13
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
12
14
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
13
15
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
14
|
-
import { computeAddressSecret } from '@aztec/stdlib/keys';
|
|
16
|
+
import { type PublicKeys, computeAddressSecret } from '@aztec/stdlib/keys';
|
|
15
17
|
import { deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
|
|
18
|
+
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
16
19
|
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
17
20
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
18
21
|
import type { BlockHeader, Capsule } from '@aztec/stdlib/tx';
|
|
19
22
|
|
|
23
|
+
import type { AccessScopes } from '../../access_scopes.js';
|
|
24
|
+
import { createContractLogger, logContractMessage } from '../../contract_logging.js';
|
|
20
25
|
import { EventService } from '../../events/event_service.js';
|
|
21
26
|
import { LogService } from '../../logs/log_service.js';
|
|
22
27
|
import { NoteService } from '../../notes/note_service.js';
|
|
23
28
|
import { ORACLE_VERSION } from '../../oracle_version.js';
|
|
24
29
|
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
25
|
-
import type { AnchorBlockStore } from '../../storage/anchor_block_store/anchor_block_store.js';
|
|
26
30
|
import type { CapsuleStore } from '../../storage/capsule_store/capsule_store.js';
|
|
27
31
|
import type { ContractStore } from '../../storage/contract_store/contract_store.js';
|
|
28
32
|
import type { NoteStore } from '../../storage/note_store/note_store.js';
|
|
29
33
|
import type { PrivateEventStore } from '../../storage/private_event_store/private_event_store.js';
|
|
30
34
|
import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
|
|
31
35
|
import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_address_book_store.js';
|
|
32
|
-
import { TreeMembershipService } from '../../tree_membership/tree_membership_service.js';
|
|
33
36
|
import { EventValidationRequest } from '../noir-structs/event_validation_request.js';
|
|
34
37
|
import { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
|
|
35
38
|
import { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
|
|
@@ -39,6 +42,27 @@ import { pickNotes } from '../pick_notes.js';
|
|
|
39
42
|
import type { IMiscOracle, IUtilityExecutionOracle, NoteData } from './interfaces.js';
|
|
40
43
|
import { MessageLoadOracleInputs } from './message_load_oracle_inputs.js';
|
|
41
44
|
|
|
45
|
+
/** Args for UtilityExecutionOracle constructor. */
|
|
46
|
+
export type UtilityExecutionOracleArgs = {
|
|
47
|
+
contractAddress: AztecAddress;
|
|
48
|
+
/** List of transient auth witnesses to be used during this simulation */
|
|
49
|
+
authWitnesses: AuthWitness[];
|
|
50
|
+
capsules: Capsule[]; // TODO(#12425): Rename to transientCapsules
|
|
51
|
+
anchorBlockHeader: BlockHeader;
|
|
52
|
+
contractStore: ContractStore;
|
|
53
|
+
noteStore: NoteStore;
|
|
54
|
+
keyStore: KeyStore;
|
|
55
|
+
addressStore: AddressStore;
|
|
56
|
+
aztecNode: AztecNode;
|
|
57
|
+
recipientTaggingStore: RecipientTaggingStore;
|
|
58
|
+
senderAddressBookStore: SenderAddressBookStore;
|
|
59
|
+
capsuleStore: CapsuleStore;
|
|
60
|
+
privateEventStore: PrivateEventStore;
|
|
61
|
+
jobId: string;
|
|
62
|
+
log?: ReturnType<typeof createLogger>;
|
|
63
|
+
scopes: AccessScopes;
|
|
64
|
+
};
|
|
65
|
+
|
|
42
66
|
/**
|
|
43
67
|
* The oracle for an execution of utility contract functions.
|
|
44
68
|
*/
|
|
@@ -46,28 +70,43 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
46
70
|
isMisc = true as const;
|
|
47
71
|
isUtility = true as const;
|
|
48
72
|
|
|
49
|
-
private
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
private contractLogger: Logger | undefined;
|
|
74
|
+
|
|
75
|
+
protected readonly contractAddress: AztecAddress;
|
|
76
|
+
protected readonly authWitnesses: AuthWitness[];
|
|
77
|
+
protected readonly capsules: Capsule[];
|
|
78
|
+
protected readonly anchorBlockHeader: BlockHeader;
|
|
79
|
+
protected readonly contractStore: ContractStore;
|
|
80
|
+
protected readonly noteStore: NoteStore;
|
|
81
|
+
protected readonly keyStore: KeyStore;
|
|
82
|
+
protected readonly addressStore: AddressStore;
|
|
83
|
+
protected readonly aztecNode: AztecNode;
|
|
84
|
+
protected readonly recipientTaggingStore: RecipientTaggingStore;
|
|
85
|
+
protected readonly senderAddressBookStore: SenderAddressBookStore;
|
|
86
|
+
protected readonly capsuleStore: CapsuleStore;
|
|
87
|
+
protected readonly privateEventStore: PrivateEventStore;
|
|
88
|
+
protected readonly jobId: string;
|
|
89
|
+
protected log: ReturnType<typeof createLogger>;
|
|
90
|
+
protected readonly scopes: AccessScopes;
|
|
91
|
+
|
|
92
|
+
constructor(args: UtilityExecutionOracleArgs) {
|
|
93
|
+
this.contractAddress = args.contractAddress;
|
|
94
|
+
this.authWitnesses = args.authWitnesses;
|
|
95
|
+
this.capsules = args.capsules;
|
|
96
|
+
this.anchorBlockHeader = args.anchorBlockHeader;
|
|
97
|
+
this.contractStore = args.contractStore;
|
|
98
|
+
this.noteStore = args.noteStore;
|
|
99
|
+
this.keyStore = args.keyStore;
|
|
100
|
+
this.addressStore = args.addressStore;
|
|
101
|
+
this.aztecNode = args.aztecNode;
|
|
102
|
+
this.recipientTaggingStore = args.recipientTaggingStore;
|
|
103
|
+
this.senderAddressBookStore = args.senderAddressBookStore;
|
|
104
|
+
this.capsuleStore = args.capsuleStore;
|
|
105
|
+
this.privateEventStore = args.privateEventStore;
|
|
106
|
+
this.jobId = args.jobId;
|
|
107
|
+
this.log = args.log ?? createLogger('simulator:client_view_context');
|
|
108
|
+
this.scopes = args.scopes;
|
|
109
|
+
}
|
|
71
110
|
|
|
72
111
|
public utilityAssertCompatibleOracleVersion(version: number): void {
|
|
73
112
|
if (version !== ORACLE_VERSION) {
|
|
@@ -88,21 +127,54 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
88
127
|
* @param pkMHash - The master public key hash.
|
|
89
128
|
* @returns A Promise that resolves to nullifier keys.
|
|
90
129
|
* @throws If the keys are not registered in the key store.
|
|
130
|
+
* @throws If scopes are defined and the account is not in the scopes.
|
|
91
131
|
*/
|
|
92
|
-
public utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
132
|
+
public async utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
133
|
+
// If scopes are defined, check that the key belongs to an account in the scopes.
|
|
134
|
+
if (this.scopes !== 'ALL_SCOPES' && this.scopes.length > 0) {
|
|
135
|
+
let hasAccess = false;
|
|
136
|
+
for (let i = 0; i < this.scopes.length && !hasAccess; i++) {
|
|
137
|
+
if (await this.keyStore.accountHasKey(this.scopes[i], pkMHash)) {
|
|
138
|
+
hasAccess = true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (!hasAccess) {
|
|
142
|
+
throw new Error(`Key validation request denied: no scoped account has a key with hash ${pkMHash.toString()}.`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
93
145
|
return this.keyStore.getKeyValidationRequest(pkMHash, this.contractAddress);
|
|
94
146
|
}
|
|
95
147
|
|
|
96
148
|
/**
|
|
97
|
-
* Fetches the index and sibling path of a leaf at a given block from
|
|
98
|
-
* @param
|
|
99
|
-
*
|
|
100
|
-
* @param
|
|
101
|
-
* @returns The index and sibling path
|
|
149
|
+
* Fetches the index and sibling path of a leaf at a given block from the note hash tree.
|
|
150
|
+
* @param anchorBlockHash - The hash of a block that contains the note hash tree root in which to find the membership
|
|
151
|
+
* witness.
|
|
152
|
+
* @param noteHash - The note hash to find in the note hash tree.
|
|
153
|
+
* @returns The membership witness containing the leaf index and sibling path
|
|
102
154
|
*/
|
|
103
|
-
public
|
|
104
|
-
|
|
105
|
-
|
|
155
|
+
public utilityGetNoteHashMembershipWitness(
|
|
156
|
+
anchorBlockHash: BlockHash,
|
|
157
|
+
noteHash: Fr,
|
|
158
|
+
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
159
|
+
return this.aztecNode.getNoteHashMembershipWitness(anchorBlockHash, noteHash);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Fetches the index and sibling path of a block hash in the archive tree.
|
|
164
|
+
*
|
|
165
|
+
* Block hashes are the leaves of the archive tree. Each time a new block is added to the chain,
|
|
166
|
+
* its block hash is appended as a new leaf to the archive tree.
|
|
167
|
+
*
|
|
168
|
+
* @param anchorBlockHash - The hash of a block that contains the archive tree root in which to find the membership
|
|
169
|
+
* witness.
|
|
170
|
+
* @param blockHash - The block hash to find in the archive tree.
|
|
171
|
+
* @returns The membership witness containing the leaf index and sibling path
|
|
172
|
+
*/
|
|
173
|
+
public utilityGetBlockHashMembershipWitness(
|
|
174
|
+
anchorBlockHash: BlockHash,
|
|
175
|
+
blockHash: BlockHash,
|
|
176
|
+
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
177
|
+
return this.aztecNode.getBlockHashMembershipWitness(anchorBlockHash, blockHash);
|
|
106
178
|
}
|
|
107
179
|
|
|
108
180
|
/**
|
|
@@ -111,11 +183,11 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
111
183
|
* @param nullifier - Nullifier we try to find witness for.
|
|
112
184
|
* @returns The nullifier membership witness (if found).
|
|
113
185
|
*/
|
|
114
|
-
public
|
|
115
|
-
blockHash:
|
|
186
|
+
public utilityGetNullifierMembershipWitness(
|
|
187
|
+
blockHash: BlockHash,
|
|
116
188
|
nullifier: Fr,
|
|
117
189
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
118
|
-
return
|
|
190
|
+
return this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier);
|
|
119
191
|
}
|
|
120
192
|
|
|
121
193
|
/**
|
|
@@ -127,12 +199,11 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
127
199
|
* list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier
|
|
128
200
|
* we are trying to prove non-inclusion for.
|
|
129
201
|
*/
|
|
130
|
-
public
|
|
131
|
-
blockHash:
|
|
202
|
+
public utilityGetLowNullifierMembershipWitness(
|
|
203
|
+
blockHash: BlockHash,
|
|
132
204
|
nullifier: Fr,
|
|
133
205
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
134
|
-
|
|
135
|
-
return await treeMembershipService.getLowNullifierMembershipWitness(blockHash, nullifier);
|
|
206
|
+
return this.aztecNode.getLowNullifierMembershipWitness(blockHash, nullifier);
|
|
136
207
|
}
|
|
137
208
|
|
|
138
209
|
/**
|
|
@@ -141,12 +212,8 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
141
212
|
* @param leafSlot - The slot of the public data tree to get the witness for.
|
|
142
213
|
* @returns - The witness
|
|
143
214
|
*/
|
|
144
|
-
public
|
|
145
|
-
blockHash
|
|
146
|
-
leafSlot: Fr,
|
|
147
|
-
): Promise<PublicDataWitness | undefined> {
|
|
148
|
-
const treeMembershipService = new TreeMembershipService(this.aztecNode);
|
|
149
|
-
return await treeMembershipService.getPublicDataWitness(blockHash, leafSlot);
|
|
215
|
+
public utilityGetPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
216
|
+
return this.aztecNode.getPublicDataWitness(blockHash, leafSlot);
|
|
150
217
|
}
|
|
151
218
|
|
|
152
219
|
/**
|
|
@@ -155,7 +222,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
155
222
|
* @returns Block extracted from a block with block number `blockNumber`.
|
|
156
223
|
*/
|
|
157
224
|
public async utilityGetBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader | undefined> {
|
|
158
|
-
const anchorBlockNumber =
|
|
225
|
+
const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber();
|
|
159
226
|
if (blockNumber > anchorBlockNumber) {
|
|
160
227
|
throw new Error(`Block number ${blockNumber} is higher than current block ${anchorBlockNumber}`);
|
|
161
228
|
}
|
|
@@ -165,16 +232,21 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
165
232
|
}
|
|
166
233
|
|
|
167
234
|
/**
|
|
168
|
-
* Retrieve the
|
|
235
|
+
* Retrieve the public keys and partial address associated to a given address.
|
|
169
236
|
* @param account - The account address.
|
|
170
|
-
* @returns
|
|
171
|
-
* @throws An error if the account is not registered in the database.
|
|
237
|
+
* @returns The public keys and partial address, or `undefined` if the account is not registered.
|
|
172
238
|
*/
|
|
173
|
-
public
|
|
174
|
-
|
|
239
|
+
public async utilityTryGetPublicKeysAndPartialAddress(
|
|
240
|
+
account: AztecAddress,
|
|
241
|
+
): Promise<{ publicKeys: PublicKeys; partialAddress: PartialAddress } | undefined> {
|
|
242
|
+
const completeAddress = await this.addressStore.getCompleteAddress(account);
|
|
243
|
+
if (!completeAddress) {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
return { publicKeys: completeAddress.publicKeys, partialAddress: completeAddress.partialAddress };
|
|
175
247
|
}
|
|
176
248
|
|
|
177
|
-
protected async
|
|
249
|
+
protected async getCompleteAddressOrFail(account: AztecAddress): Promise<CompleteAddress> {
|
|
178
250
|
const completeAddress = await this.addressStore.getCompleteAddress(account);
|
|
179
251
|
if (!completeAddress) {
|
|
180
252
|
throw new Error(
|
|
@@ -251,7 +323,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
251
323
|
offset: number,
|
|
252
324
|
status: NoteStatus,
|
|
253
325
|
): Promise<NoteData[]> {
|
|
254
|
-
const noteService = new NoteService(this.noteStore, this.aztecNode, this.
|
|
326
|
+
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
255
327
|
|
|
256
328
|
const dbNotes = await noteService.getNotes(this.contractAddress, owner, storageSlot, status, this.scopes);
|
|
257
329
|
return pickNotes<NoteData>(dbNotes, {
|
|
@@ -275,10 +347,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
275
347
|
* @returns A boolean indicating whether the nullifier exists in the tree or not.
|
|
276
348
|
*/
|
|
277
349
|
public async utilityCheckNullifierExists(innerNullifier: Fr) {
|
|
278
|
-
const nullifier = await
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
350
|
+
const [nullifier, anchorBlockHash] = await Promise.all([
|
|
351
|
+
siloNullifier(this.contractAddress, innerNullifier!),
|
|
352
|
+
this.anchorBlockHeader.hash(),
|
|
353
|
+
]);
|
|
354
|
+
const [leafIndex] = await this.aztecNode.findLeavesIndexes(anchorBlockHash, MerkleTreeId.NULLIFIER_TREE, [
|
|
355
|
+
nullifier,
|
|
356
|
+
]);
|
|
357
|
+
return leafIndex?.data !== undefined;
|
|
282
358
|
}
|
|
283
359
|
|
|
284
360
|
/**
|
|
@@ -290,14 +366,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
290
366
|
* @returns The l1 to l2 membership witness (index of message in the tree and sibling path).
|
|
291
367
|
*/
|
|
292
368
|
public async utilityGetL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) {
|
|
293
|
-
const
|
|
294
|
-
|
|
369
|
+
const [messageIndex, siblingPath] = await getNonNullifiedL1ToL2MessageWitness(
|
|
370
|
+
this.aztecNode,
|
|
295
371
|
contractAddress,
|
|
296
372
|
messageHash,
|
|
297
373
|
secret,
|
|
298
374
|
);
|
|
299
375
|
|
|
300
|
-
// Assuming messageIndex is what you intended to use for the index in MessageLoadOracleInputs
|
|
301
376
|
return new MessageLoadOracleInputs(messageIndex, siblingPath);
|
|
302
377
|
}
|
|
303
378
|
|
|
@@ -309,57 +384,64 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
309
384
|
* @param numberOfElements - Number of elements to read from the starting storage slot.
|
|
310
385
|
*/
|
|
311
386
|
public async utilityStorageRead(
|
|
312
|
-
blockHash:
|
|
387
|
+
blockHash: BlockHash,
|
|
313
388
|
contractAddress: AztecAddress,
|
|
314
389
|
startStorageSlot: Fr,
|
|
315
390
|
numberOfElements: number,
|
|
316
391
|
) {
|
|
317
|
-
const
|
|
392
|
+
const slots = Array(numberOfElements)
|
|
393
|
+
.fill(0)
|
|
394
|
+
.map((_, i) => new Fr(startStorageSlot.value + BigInt(i)));
|
|
318
395
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const storageSlot = new Fr(startStorageSlot.value + i);
|
|
323
|
-
const value = await this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot);
|
|
396
|
+
const values = await Promise.all(
|
|
397
|
+
slots.map(storageSlot => this.aztecNode.getPublicStorageAt(blockHash, contractAddress, storageSlot)),
|
|
398
|
+
);
|
|
324
399
|
|
|
325
|
-
|
|
326
|
-
|
|
400
|
+
this.log.debug(
|
|
401
|
+
`Oracle storage read: slots=[${slots.map(slot => slot.toString()).join(', ')}] address=${contractAddress.toString()} values=[${values.join(', ')}]`,
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
return values;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Returns a per-contract logger whose output is prefixed with `contract_log::<name>(<addrAbbrev>)`.
|
|
409
|
+
*/
|
|
410
|
+
async #getContractLogger(): Promise<Logger> {
|
|
411
|
+
if (!this.contractLogger) {
|
|
412
|
+
// Purpose of instanceId is to distinguish logs from different instances of the same component. It makes sense
|
|
413
|
+
// to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
|
|
414
|
+
this.contractLogger = await createContractLogger(
|
|
415
|
+
this.contractAddress,
|
|
416
|
+
addr => this.contractStore.getDebugContractName(addr),
|
|
417
|
+
{ instanceId: this.jobId },
|
|
327
418
|
);
|
|
328
|
-
values.push(value);
|
|
329
419
|
}
|
|
330
|
-
return
|
|
420
|
+
return this.contractLogger;
|
|
331
421
|
}
|
|
332
422
|
|
|
333
|
-
public
|
|
423
|
+
public async utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
334
424
|
if (!LogLevels[level]) {
|
|
335
|
-
throw new Error(`Invalid
|
|
425
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
336
426
|
}
|
|
337
|
-
const
|
|
338
|
-
|
|
427
|
+
const logger = await this.#getContractLogger();
|
|
428
|
+
logContractMessage(logger, LogLevels[level], message, fields);
|
|
339
429
|
}
|
|
340
430
|
|
|
341
431
|
public async utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr) {
|
|
342
432
|
const logService = new LogService(
|
|
343
433
|
this.aztecNode,
|
|
344
|
-
this.
|
|
434
|
+
this.anchorBlockHeader,
|
|
345
435
|
this.keyStore,
|
|
346
436
|
this.capsuleStore,
|
|
347
437
|
this.recipientTaggingStore,
|
|
348
438
|
this.senderAddressBookStore,
|
|
349
439
|
this.addressStore,
|
|
350
440
|
this.jobId,
|
|
441
|
+
this.log.getBindings(),
|
|
351
442
|
);
|
|
352
443
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// It is acceptable to run the following operations in parallel for several reasons:
|
|
356
|
-
// 1. syncTaggedLogs does not write to the note store — it only stores the pending tagged logs in a capsule array,
|
|
357
|
-
// which is then processed in Noir after this handler returns.
|
|
358
|
-
// 2. Even if syncTaggedLogs did write to the note store, it would not cause inconsistent state.
|
|
359
|
-
await Promise.all([
|
|
360
|
-
logService.syncTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, this.scopes),
|
|
361
|
-
noteService.syncNoteNullifiers(this.contractAddress),
|
|
362
|
-
]);
|
|
444
|
+
await logService.fetchTaggedLogs(this.contractAddress, pendingTaggedLogArrayBaseSlot, this.scopes);
|
|
363
445
|
}
|
|
364
446
|
|
|
365
447
|
/**
|
|
@@ -372,7 +454,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
372
454
|
* @param noteValidationRequestsArrayBaseSlot - The base slot of capsule array containing note validation requests.
|
|
373
455
|
* @param eventValidationRequestsArrayBaseSlot - The base slot of capsule array containing event validation requests.
|
|
374
456
|
*/
|
|
375
|
-
public async
|
|
457
|
+
public async utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
376
458
|
contractAddress: AztecAddress,
|
|
377
459
|
noteValidationRequestsArrayBaseSlot: Fr,
|
|
378
460
|
eventValidationRequestsArrayBaseSlot: Fr,
|
|
@@ -392,9 +474,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
392
474
|
await this.capsuleStore.readCapsuleArray(contractAddress, eventValidationRequestsArrayBaseSlot, this.jobId)
|
|
393
475
|
).map(EventValidationRequest.fromFields);
|
|
394
476
|
|
|
395
|
-
const noteService = new NoteService(this.noteStore, this.aztecNode, this.
|
|
477
|
+
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
396
478
|
const noteStorePromises = noteValidationRequests.map(request =>
|
|
397
|
-
noteService.
|
|
479
|
+
noteService.validateAndStoreNote(
|
|
398
480
|
request.contractAddress,
|
|
399
481
|
request.owner,
|
|
400
482
|
request.storageSlot,
|
|
@@ -408,9 +490,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
408
490
|
),
|
|
409
491
|
);
|
|
410
492
|
|
|
411
|
-
const eventService = new EventService(this.
|
|
493
|
+
const eventService = new EventService(this.anchorBlockHeader, this.aztecNode, this.privateEventStore, this.jobId);
|
|
412
494
|
const eventStorePromises = eventValidationRequests.map(request =>
|
|
413
|
-
eventService.
|
|
495
|
+
eventService.validateAndStoreEvent(
|
|
414
496
|
request.contractAddress,
|
|
415
497
|
request.eventTypeId,
|
|
416
498
|
request.randomness,
|
|
@@ -446,13 +528,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
446
528
|
|
|
447
529
|
const logService = new LogService(
|
|
448
530
|
this.aztecNode,
|
|
449
|
-
this.
|
|
531
|
+
this.anchorBlockHeader,
|
|
450
532
|
this.keyStore,
|
|
451
533
|
this.capsuleStore,
|
|
452
534
|
this.recipientTaggingStore,
|
|
453
535
|
this.senderAddressBookStore,
|
|
454
536
|
this.addressStore,
|
|
455
537
|
this.jobId,
|
|
538
|
+
this.log.getBindings(),
|
|
456
539
|
);
|
|
457
540
|
|
|
458
541
|
const maybeLogRetrievalResponses = await logService.bulkRetrieveLogs(logRetrievalRequests);
|
|
@@ -530,7 +613,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
530
613
|
|
|
531
614
|
protected async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
|
|
532
615
|
// TODO(#12656): return an app-siloed secret
|
|
533
|
-
const recipientCompleteAddress = await this.
|
|
616
|
+
const recipientCompleteAddress = await this.getCompleteAddressOrFail(address);
|
|
534
617
|
const ivskM = await this.keyStore.getMasterSecretKey(
|
|
535
618
|
recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
|
|
536
619
|
);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
|
+
import { type LogLevel, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
import type { DebugLog } from '@aztec/stdlib/logs';
|
|
5
|
+
|
|
6
|
+
/** Resolves a contract address to a human-readable name, if available. */
|
|
7
|
+
export type ContractNameResolver = (address: AztecAddress) => Promise<string | undefined>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates a logger whose output is prefixed with `contract_log::<name>(<addrAbbrev>)`.
|
|
11
|
+
*/
|
|
12
|
+
export async function createContractLogger(
|
|
13
|
+
contractAddress: AztecAddress,
|
|
14
|
+
getContractName: ContractNameResolver,
|
|
15
|
+
options?: { instanceId?: string },
|
|
16
|
+
): Promise<Logger> {
|
|
17
|
+
const addrAbbrev = contractAddress.toString().slice(0, 10);
|
|
18
|
+
const name = await getContractName(contractAddress);
|
|
19
|
+
const module = name ? `contract_log::${name}(${addrAbbrev})` : `contract_log::Unknown(${addrAbbrev})`;
|
|
20
|
+
return createLogger(module, options);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Formats and emits a single contract log message through the given logger.
|
|
25
|
+
*/
|
|
26
|
+
export function logContractMessage(logger: Logger, level: LogLevel, message: string, fields: Fr[]): void {
|
|
27
|
+
logger[level](applyStringFormatting(message, fields));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Displays debug logs collected during public function simulation,
|
|
32
|
+
* using the `contract_log::` prefixed logger format.
|
|
33
|
+
*/
|
|
34
|
+
export async function displayDebugLogs(debugLogs: DebugLog[], getContractName: ContractNameResolver): Promise<void> {
|
|
35
|
+
for (const log of debugLogs) {
|
|
36
|
+
const logger = await createContractLogger(log.contractAddress, getContractName);
|
|
37
|
+
logContractMessage(logger, log.level, log.message, log.fields);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
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 { AccessScopes } from '../access_scopes.js';
|
|
8
|
+
import type { StagedStore } from '../job_coordinator/job_coordinator.js';
|
|
9
|
+
import type { ContractStore } from '../storage/contract_store/contract_store.js';
|
|
10
|
+
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
11
|
+
import { syncState, verifyCurrentClassId } from './helpers.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Service for syncing the private state of contracts and verifying that the PXE holds the current class artifact.
|
|
15
|
+
* It uses a cache to avoid redundant sync operations - the cache is wiped when the anchor block changes.
|
|
16
|
+
*
|
|
17
|
+
* TODO: The StagedStore naming is broken here. Figure out a better name.
|
|
18
|
+
*/
|
|
19
|
+
export class ContractSyncService implements StagedStore {
|
|
20
|
+
readonly storeName = 'contract_sync';
|
|
21
|
+
|
|
22
|
+
// Tracks contracts synced since last wipe. The cache is keyed per individual scope address
|
|
23
|
+
// (`contractAddress:scopeAddress`), or `contractAddress:*` for undefined scopes (all accounts).
|
|
24
|
+
// The value is a promise that resolves when the contract is synced.
|
|
25
|
+
private syncedContracts: Map<string, Promise<void>> = new Map();
|
|
26
|
+
|
|
27
|
+
// Per-job overridden contract addresses - these contracts should not be synced.
|
|
28
|
+
private overriddenContracts: Map<string, Set<string>> = new Map();
|
|
29
|
+
|
|
30
|
+
constructor(
|
|
31
|
+
private aztecNode: AztecNode,
|
|
32
|
+
private contractStore: ContractStore,
|
|
33
|
+
private noteStore: NoteStore,
|
|
34
|
+
private log: Logger,
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
/** Sets contracts that should be skipped during sync for a specific job. */
|
|
38
|
+
setOverriddenContracts(jobId: string, addresses: Set<string>): void {
|
|
39
|
+
this.overriddenContracts.set(jobId, addresses);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Ensures a contract's private state is synchronized and that the PXE holds the current class artifact.
|
|
44
|
+
* Uses a cache to avoid redundant sync operations - the cache is wiped when the anchor block changes.
|
|
45
|
+
* @param contractAddress - The address of the contract to sync.
|
|
46
|
+
* @param functionToInvokeAfterSync - The function selector that will be called after sync (used to validate it's
|
|
47
|
+
* not sync_state itself).
|
|
48
|
+
* @param utilityExecutor - Executor function for running the sync_state utility function.
|
|
49
|
+
* @param scopes - Access scopes to pass through to the utility executor (affects whose account's private state is discovered).
|
|
50
|
+
*/
|
|
51
|
+
async ensureContractSynced(
|
|
52
|
+
contractAddress: AztecAddress,
|
|
53
|
+
functionToInvokeAfterSync: FunctionSelector | null,
|
|
54
|
+
utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<any>,
|
|
55
|
+
anchorBlockHeader: BlockHeader,
|
|
56
|
+
jobId: string,
|
|
57
|
+
scopes: AccessScopes,
|
|
58
|
+
): Promise<void> {
|
|
59
|
+
// Skip sync if this contract has an override for this job (overrides are keyed by contract address only)
|
|
60
|
+
const overrides = this.overriddenContracts.get(jobId);
|
|
61
|
+
if (overrides?.has(contractAddress.toString())) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Skip sync if we already synced for "all scopes", or if we have an empty list of scopes
|
|
66
|
+
const allScopesKey = toKey(contractAddress, 'ALL_SCOPES');
|
|
67
|
+
const allScopesExisting = this.syncedContracts.get(allScopesKey);
|
|
68
|
+
if (allScopesExisting || (scopes !== 'ALL_SCOPES' && scopes.length == 0)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const unsyncedScopes =
|
|
73
|
+
scopes === 'ALL_SCOPES'
|
|
74
|
+
? scopes
|
|
75
|
+
: scopes.filter(scope => !this.syncedContracts.has(toKey(contractAddress, scope)));
|
|
76
|
+
const unsyncedScopesKeys = toKeys(contractAddress, unsyncedScopes);
|
|
77
|
+
|
|
78
|
+
if (unsyncedScopesKeys.length > 0) {
|
|
79
|
+
// Start sync and store the promise for all unsynced scopes
|
|
80
|
+
const promise = this.#doSync(
|
|
81
|
+
contractAddress,
|
|
82
|
+
functionToInvokeAfterSync,
|
|
83
|
+
utilityExecutor,
|
|
84
|
+
anchorBlockHeader,
|
|
85
|
+
jobId,
|
|
86
|
+
unsyncedScopes,
|
|
87
|
+
).catch(err => {
|
|
88
|
+
// There was an error syncing the contract, so we remove it from the cache so that it can be retried.
|
|
89
|
+
unsyncedScopesKeys.forEach(key => this.syncedContracts.delete(key));
|
|
90
|
+
throw err;
|
|
91
|
+
});
|
|
92
|
+
unsyncedScopesKeys.forEach(key => this.syncedContracts.set(key, promise));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const promises = toKeys(contractAddress, scopes).map(key => this.syncedContracts.get(key)!);
|
|
96
|
+
await Promise.all(promises);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async #doSync(
|
|
100
|
+
contractAddress: AztecAddress,
|
|
101
|
+
functionToInvokeAfterSync: FunctionSelector | null,
|
|
102
|
+
utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<any>,
|
|
103
|
+
anchorBlockHeader: BlockHeader,
|
|
104
|
+
jobId: string,
|
|
105
|
+
scopes: AccessScopes,
|
|
106
|
+
): Promise<void> {
|
|
107
|
+
this.log.debug(`Syncing contract ${contractAddress}`);
|
|
108
|
+
await Promise.all([
|
|
109
|
+
syncState(
|
|
110
|
+
contractAddress,
|
|
111
|
+
this.contractStore,
|
|
112
|
+
functionToInvokeAfterSync,
|
|
113
|
+
utilityExecutor,
|
|
114
|
+
this.noteStore,
|
|
115
|
+
this.aztecNode,
|
|
116
|
+
anchorBlockHeader,
|
|
117
|
+
jobId,
|
|
118
|
+
scopes,
|
|
119
|
+
),
|
|
120
|
+
verifyCurrentClassId(contractAddress, this.aztecNode, this.contractStore, anchorBlockHeader),
|
|
121
|
+
]);
|
|
122
|
+
this.log.debug(`Contract ${contractAddress} synced`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Clears sync cache. Called by BlockSynchronizer when anchor block changes. */
|
|
126
|
+
wipe(): void {
|
|
127
|
+
this.log.debug(`Wiping contract sync cache (${this.syncedContracts.size} entries)`);
|
|
128
|
+
this.syncedContracts.clear();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
commit(jobId: string): Promise<void> {
|
|
132
|
+
// Clear overridden contracts for this job
|
|
133
|
+
this.overriddenContracts.delete(jobId);
|
|
134
|
+
return Promise.resolve();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
discardStaged(jobId: string): Promise<void> {
|
|
138
|
+
// We clear the synced contracts cache here because, when the job is discarded, any associated database writes from
|
|
139
|
+
// the sync are also undone.
|
|
140
|
+
this.syncedContracts.clear();
|
|
141
|
+
this.overriddenContracts.delete(jobId);
|
|
142
|
+
return Promise.resolve();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function toKeys(contract: AztecAddress, scopes: AccessScopes) {
|
|
147
|
+
return scopes === 'ALL_SCOPES' ? [toKey(contract, scopes)] : scopes.map(scope => toKey(contract, scope));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function toKey(contract: AztecAddress, scope: AztecAddress | 'ALL_SCOPES') {
|
|
151
|
+
return scope === 'ALL_SCOPES' ? `${contract.toString()}:*` : `${contract.toString()}:${scope.toString()}`;
|
|
152
|
+
}
|