@aztec/pxe 0.0.1-commit.2448fdb → 0.0.1-commit.2606882
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/bin/check_oracle_version.js +40 -96
- package/dest/bin/index.d.ts +2 -0
- package/dest/bin/index.d.ts.map +1 -0
- package/dest/bin/index.js +1 -0
- package/dest/bin/oracle_version_helpers.d.ts +26 -0
- package/dest/bin/oracle_version_helpers.d.ts.map +1 -0
- package/dest/bin/oracle_version_helpers.js +93 -0
- package/dest/block_synchronizer/block_stream_source.d.ts +10 -0
- package/dest/block_synchronizer/block_stream_source.d.ts.map +1 -0
- package/dest/block_synchronizer/block_stream_source.js +62 -0
- 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 +21 -11
- package/dest/config/index.d.ts +8 -2
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +13 -15
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +4 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +20 -12
- package/dest/contract_function_simulator/execution_note_cache.d.ts +2 -2
- package/dest/contract_function_simulator/execution_note_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +5 -9
- 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 -7
- package/dest/contract_function_simulator/index.d.ts +13 -2
- package/dest/contract_function_simulator/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.js +10 -0
- package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts +48 -0
- package/dest/contract_function_simulator/noir-structs/bounded_vec.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/bounded_vec.js +45 -0
- package/dest/contract_function_simulator/noir-structs/ephemeral_array.d.ts +37 -0
- package/dest/contract_function_simulator/noir-structs/ephemeral_array.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/ephemeral_array.js +59 -0
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +3 -2
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +3 -2
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +12 -2
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +34 -3
- package/dest/contract_function_simulator/noir-structs/note_data.d.ts +27 -0
- package/dest/contract_function_simulator/noir-structs/note_data.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/note_data.js +3 -0
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +3 -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 +3 -2
- package/dest/contract_function_simulator/noir-structs/option.d.ts +61 -0
- package/dest/contract_function_simulator/noir-structs/option.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/option.js +62 -0
- package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts +11 -0
- package/dest/contract_function_simulator/noir-structs/provided_secret.d.ts.map +1 -0
- package/dest/contract_function_simulator/noir-structs/provided_secret.js +24 -0
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +16 -114
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/interfaces.js +2 -2
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +2 -2
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/note_packing_utils.js +2 -2
- package/dest/contract_function_simulator/oracle/oracle.d.ts +55 -57
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +343 -344
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts +127 -0
- package/dest/contract_function_simulator/oracle/oracle_registry.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/oracle_registry.js +786 -0
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts +139 -0
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/oracle_type_mappings.js +560 -0
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +27 -29
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +55 -47
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +59 -39
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +244 -149
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts +1 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.d.ts.map +1 -1
- package/dest/contract_function_simulator/proxied_contract_data_source.js +35 -67
- package/dest/contract_sync/contract_sync_service.d.ts +4 -6
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
- package/dest/contract_sync/contract_sync_service.js +43 -24
- package/dest/contract_sync/helpers.d.ts +2 -3
- package/dest/contract_sync/helpers.d.ts.map +1 -1
- package/dest/contract_sync/helpers.js +12 -19
- package/dest/debug/pxe_debug_utils.d.ts +1 -6
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +0 -6
- 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 +11 -3
- package/dest/entrypoints/client/lazy/utils.d.ts +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +11 -3
- package/dest/entrypoints/pxe_creation_options.d.ts +7 -1
- package/dest/entrypoints/pxe_creation_options.d.ts.map +1 -1
- package/dest/entrypoints/server/index.d.ts +2 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +1 -0
- package/dest/entrypoints/server/utils.d.ts +3 -2
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +11 -3
- package/dest/events/event_service.d.ts +13 -5
- package/dest/events/event_service.d.ts.map +1 -1
- package/dest/events/event_service.js +30 -9
- package/dest/hooks/authorize_utility_call.d.ts +41 -0
- package/dest/hooks/authorize_utility_call.d.ts.map +1 -0
- package/dest/hooks/authorize_utility_call.js +4 -0
- package/dest/hooks/execution_hooks.d.ts +42 -0
- package/dest/hooks/execution_hooks.d.ts.map +1 -0
- package/dest/hooks/execution_hooks.js +9 -0
- package/dest/hooks/index.d.ts +4 -0
- package/dest/hooks/index.d.ts.map +1 -0
- package/dest/hooks/index.js +1 -0
- 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 +112 -48
- package/dest/messages/message_context_service.d.ts +1 -1
- package/dest/messages/message_context_service.d.ts.map +1 -1
- package/dest/messages/message_context_service.js +28 -9
- package/dest/notes/note_service.d.ts +25 -3
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +80 -65
- package/dest/oracle_version.d.ts +3 -3
- package/dest/oracle_version.js +4 -4
- package/dest/private_kernel/batch_planner.d.ts +47 -0
- package/dest/private_kernel/batch_planner.d.ts.map +1 -0
- package/dest/private_kernel/batch_planner.js +104 -0
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +1 -1
- package/dest/private_kernel/hints/test_utils.d.ts +1 -1
- package/dest/private_kernel/hints/test_utils.d.ts.map +1 -1
- package/dest/private_kernel/hints/test_utils.js +2 -3
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +6 -2
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +148 -52
- package/dest/private_kernel/private_kernel_oracle.d.ts +6 -6
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle.js +12 -7
- package/dest/pxe.d.ts +54 -7
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +126 -84
- package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.d.ts +42 -0
- package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.d.ts.map +1 -0
- package/dest/storage/backwards_compatibility_tests/kv_store_snapshot.js +93 -0
- package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts +15 -0
- package/dest/storage/backwards_compatibility_tests/schema_tests.d.ts.map +1 -0
- package/dest/storage/backwards_compatibility_tests/schema_tests.js +591 -0
- package/dest/storage/backwards_compatibility_tests/store_spy.d.ts +19 -0
- package/dest/storage/backwards_compatibility_tests/store_spy.d.ts.map +1 -0
- package/dest/storage/backwards_compatibility_tests/store_spy.js +63 -0
- 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 +5 -24
- package/dest/storage/metadata.d.ts +1 -1
- package/dest/storage/metadata.js +1 -1
- package/dest/storage/open_pxe_stores.d.ts +33 -0
- package/dest/storage/open_pxe_stores.d.ts.map +1 -0
- package/dest/storage/open_pxe_stores.js +27 -0
- package/dest/storage/private_event_store/stored_private_event.js +1 -1
- 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/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 +3 -3
- package/dest/tagging/get_all_logs_by_tags.d.ts +34 -10
- package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
- package/dest/tagging/get_all_logs_by_tags.js +36 -37
- package/dest/tagging/index.d.ts +5 -4
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +4 -3
- package/dest/tagging/persist_sender_tagging_index_ranges.d.ts +29 -0
- package/dest/tagging/persist_sender_tagging_index_ranges.d.ts.map +1 -0
- package/dest/tagging/persist_sender_tagging_index_ranges.js +42 -0
- package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts +56 -0
- package/dest/tagging/recipient_sync/sync_tagged_private_logs.d.ts.map +1 -0
- package/dest/tagging/recipient_sync/sync_tagged_private_logs.js +163 -0
- package/dest/tagging/recipient_sync/utils/find_highest_indexes.d.ts +3 -3
- package/dest/tagging/recipient_sync/utils/find_highest_indexes.d.ts.map +1 -1
- package/dest/tagging/reconcile_tagging_index_ranges.d.ts +36 -0
- package/dest/tagging/reconcile_tagging_index_ranges.d.ts.map +1 -0
- package/dest/tagging/reconcile_tagging_index_ranges.js +74 -0
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -5
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +26 -14
- package/dest/tagging/sender_sync/utils/get_status_change_of_pending.d.ts +11 -6
- 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 +21 -0
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +4 -4
- 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 +2 -2
- package/package.json +20 -17
- package/src/bin/check_oracle_version.ts +46 -119
- package/src/bin/index.ts +1 -0
- package/src/bin/oracle_version_helpers.ts +121 -0
- package/src/block_synchronizer/block_stream_source.ts +81 -0
- package/src/block_synchronizer/block_synchronizer.ts +22 -12
- package/src/config/index.ts +15 -9
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +34 -11
- package/src/contract_function_simulator/execution_note_cache.ts +1 -1
- package/src/contract_function_simulator/execution_tagging_index_cache.ts +5 -9
- package/src/contract_function_simulator/index.ts +50 -1
- package/src/contract_function_simulator/noir-structs/bounded_vec.ts +55 -0
- package/src/contract_function_simulator/noir-structs/ephemeral_array.ts +66 -0
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +3 -2
- package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +35 -2
- package/src/contract_function_simulator/noir-structs/note_data.ts +27 -0
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +3 -2
- package/src/contract_function_simulator/noir-structs/option.ts +69 -0
- package/src/contract_function_simulator/noir-structs/provided_secret.ts +27 -0
- package/src/contract_function_simulator/oracle/interfaces.ts +12 -204
- package/src/contract_function_simulator/oracle/note_packing_utils.ts +3 -3
- package/src/contract_function_simulator/oracle/oracle.ts +406 -556
- package/src/contract_function_simulator/oracle/oracle_registry.ts +585 -0
- package/src/contract_function_simulator/oracle/oracle_type_mappings.ts +553 -0
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +74 -67
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +350 -304
- package/src/contract_function_simulator/proxied_contract_data_source.ts +40 -70
- package/src/contract_sync/contract_sync_service.ts +56 -43
- package/src/contract_sync/helpers.ts +11 -23
- package/src/debug/pxe_debug_utils.ts +0 -8
- package/src/entrypoints/client/bundle/utils.ts +8 -2
- package/src/entrypoints/client/lazy/utils.ts +8 -2
- package/src/entrypoints/pxe_creation_options.ts +7 -0
- package/src/entrypoints/server/index.ts +1 -0
- package/src/entrypoints/server/utils.ts +13 -3
- package/src/events/event_service.ts +54 -19
- package/src/hooks/authorize_utility_call.ts +44 -0
- package/src/hooks/execution_hooks.ts +48 -0
- package/src/hooks/index.ts +7 -0
- package/src/logs/log_service.ts +137 -92
- package/src/messages/message_context_service.ts +42 -24
- package/src/notes/note_service.ts +115 -91
- package/src/oracle_version.ts +4 -4
- package/src/private_kernel/batch_planner.ts +169 -0
- package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +1 -1
- package/src/private_kernel/hints/test_utils.ts +2 -9
- package/src/private_kernel/private_kernel_execution_prover.ts +236 -73
- package/src/private_kernel/private_kernel_oracle.ts +21 -11
- package/src/pxe.ts +208 -85
- package/src/storage/backwards_compatibility_tests/__snapshots__/AddressStore.json +22 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/AnchorBlockStore.json +3 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/CapsuleStore.json +16 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/ContractStore.json +28 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/KeyStore.json +52 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/L2TipsKVStore.json +46 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/NoteStore.json +36 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/PrivateEventStore.json +44 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/RecipientTaggingStore.json +18 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/SenderAddressBookStore.json +16 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/SenderTaggingStore.json +22 -0
- package/src/storage/backwards_compatibility_tests/__snapshots__/opened_stores.json +97 -0
- package/src/storage/backwards_compatibility_tests/kv_store_snapshot.ts +122 -0
- package/src/storage/backwards_compatibility_tests/schema_tests.ts +712 -0
- package/src/storage/backwards_compatibility_tests/store_spy.ts +73 -0
- package/src/storage/contract_store/contract_store.ts +6 -29
- package/src/storage/metadata.ts +1 -1
- package/src/storage/open_pxe_stores.ts +49 -0
- package/src/storage/private_event_store/stored_private_event.ts +1 -1
- package/src/storage/tagging_store/recipient_tagging_store.ts +5 -9
- package/src/storage/tagging_store/sender_tagging_store.ts +6 -6
- package/src/tagging/get_all_logs_by_tags.ts +78 -50
- package/src/tagging/index.ts +4 -3
- package/src/tagging/persist_sender_tagging_index_ranges.ts +57 -0
- package/src/tagging/recipient_sync/sync_tagged_private_logs.ts +240 -0
- package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
- package/src/tagging/reconcile_tagging_index_ranges.ts +102 -0
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +41 -19
- package/src/tagging/sender_sync/utils/get_status_change_of_pending.ts +23 -8
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +4 -5
- package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts +0 -9
- package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.d.ts.map +0 -1
- package/dest/contract_function_simulator/oracle/legacy_oracle_mappings.js +0 -47
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +0 -14
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +0 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +0 -85
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +0 -14
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +0 -1
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +0 -33
- package/src/contract_function_simulator/oracle/legacy_oracle_mappings.ts +0 -104
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +0 -130
- package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +0 -44
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ARCHIVE_HEIGHT, type NOTE_HASH_TREE_HEIGHT } from '@aztec/constants';
|
|
2
2
|
import type { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { uniqueBy } from '@aztec/foundation/collection';
|
|
3
4
|
import { Aes128 } from '@aztec/foundation/crypto/aes128';
|
|
4
5
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
|
-
import { Point } from '@aztec/foundation/curves/grumpkin';
|
|
6
|
+
import type { Point } from '@aztec/foundation/curves/grumpkin';
|
|
6
7
|
import { LogLevels, type Logger, createLogger } from '@aztec/foundation/log';
|
|
7
|
-
import
|
|
8
|
+
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
8
9
|
import type { KeyStore } from '@aztec/key-store';
|
|
9
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type CircuitSimulator,
|
|
12
|
+
ExecutionError,
|
|
13
|
+
extractCallStack,
|
|
14
|
+
resolveAssertionMessageFromError,
|
|
15
|
+
toACVMWitness,
|
|
16
|
+
witnessMapToFields,
|
|
17
|
+
} from '@aztec/simulator/client';
|
|
18
|
+
import { type FunctionCall, FunctionSelector } from '@aztec/stdlib/abi';
|
|
10
19
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
11
20
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
21
|
import { BlockHash, type L2TipsProvider } from '@aztec/stdlib/block';
|
|
@@ -14,16 +23,30 @@ import type { CompleteAddress, ContractInstance, PartialAddress } from '@aztec/s
|
|
|
14
23
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
15
24
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
16
25
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
26
|
+
import { PublicKeys, computeAddressSecret, hashPublicKey } from '@aztec/stdlib/keys';
|
|
27
|
+
import {
|
|
28
|
+
AppTaggingSecret,
|
|
29
|
+
MessageContext,
|
|
30
|
+
type PendingTaggedLog,
|
|
31
|
+
deriveAppSiloedSharedSecret,
|
|
32
|
+
} from '@aztec/stdlib/logs';
|
|
19
33
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
20
34
|
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
21
35
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
22
|
-
import
|
|
36
|
+
import {
|
|
37
|
+
type BlockHeader,
|
|
38
|
+
type Capsule,
|
|
39
|
+
type IndexedTxEffect,
|
|
40
|
+
type OffchainEffect,
|
|
41
|
+
TxEffect,
|
|
42
|
+
type TxHash,
|
|
43
|
+
} from '@aztec/stdlib/tx';
|
|
23
44
|
|
|
24
45
|
import { createContractLogger, logContractMessage, stripAztecnrLogPrefix } from '../../contract_logging.js';
|
|
25
46
|
import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
|
|
26
47
|
import { EventService } from '../../events/event_service.js';
|
|
48
|
+
import type { UtilityCallAuthorizationRequest } from '../../hooks/authorize_utility_call.js';
|
|
49
|
+
import type { ExecutionHooks } from '../../hooks/index.js';
|
|
27
50
|
import { LogService } from '../../logs/log_service.js';
|
|
28
51
|
import { MessageContextService } from '../../messages/message_context_service.js';
|
|
29
52
|
import { NoteService } from '../../notes/note_service.js';
|
|
@@ -36,14 +59,20 @@ import type { PrivateEventStore } from '../../storage/private_event_store/privat
|
|
|
36
59
|
import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
|
|
37
60
|
import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_address_book_store.js';
|
|
38
61
|
import { EphemeralArrayService } from '../ephemeral_array_service.js';
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
62
|
+
import { BoundedVec } from '../noir-structs/bounded_vec.js';
|
|
63
|
+
import { EphemeralArray } from '../noir-structs/ephemeral_array.js';
|
|
64
|
+
import type { EventValidationRequest } from '../noir-structs/event_validation_request.js';
|
|
65
|
+
import type { LogRetrievalRequest } from '../noir-structs/log_retrieval_request.js';
|
|
66
|
+
import type { LogRetrievalResponse } from '../noir-structs/log_retrieval_response.js';
|
|
67
|
+
import type { NoteData } from '../noir-structs/note_data.js';
|
|
68
|
+
import type { NoteValidationRequest } from '../noir-structs/note_validation_request.js';
|
|
69
|
+
import { Option } from '../noir-structs/option.js';
|
|
70
|
+
import type { ProvidedSecret } from '../noir-structs/provided_secret.js';
|
|
43
71
|
import { UtilityContext } from '../noir-structs/utility_context.js';
|
|
44
72
|
import { pickNotes } from '../pick_notes.js';
|
|
45
|
-
import type { IMiscOracle, IUtilityExecutionOracle
|
|
73
|
+
import type { IMiscOracle, IUtilityExecutionOracle } from './interfaces.js';
|
|
46
74
|
import { MessageLoadOracleInputs } from './message_load_oracle_inputs.js';
|
|
75
|
+
import { Oracle } from './oracle.js';
|
|
47
76
|
|
|
48
77
|
/** Args for UtilityExecutionOracle constructor. */
|
|
49
78
|
export type UtilityExecutionOracleArgs = {
|
|
@@ -67,6 +96,10 @@ export type UtilityExecutionOracleArgs = {
|
|
|
67
96
|
jobId: string;
|
|
68
97
|
log?: ReturnType<typeof createLogger>;
|
|
69
98
|
scopes: AztecAddress[];
|
|
99
|
+
simulator: CircuitSimulator;
|
|
100
|
+
hooks?: ExecutionHooks;
|
|
101
|
+
/** Needed to trigger contract synchronization before nested cross-contract calls. */
|
|
102
|
+
utilityExecutor: (call: FunctionCall, scopes: AztecAddress[]) => Promise<void>;
|
|
70
103
|
};
|
|
71
104
|
|
|
72
105
|
/**
|
|
@@ -103,6 +136,9 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
103
136
|
protected readonly jobId: string;
|
|
104
137
|
protected logger: ReturnType<typeof createLogger>;
|
|
105
138
|
protected readonly scopes: AztecAddress[];
|
|
139
|
+
protected readonly simulator: CircuitSimulator;
|
|
140
|
+
protected readonly hooks: ExecutionHooks | undefined;
|
|
141
|
+
protected readonly utilityExecutor: (call: FunctionCall, scopes: AztecAddress[]) => Promise<void>;
|
|
106
142
|
|
|
107
143
|
constructor(args: UtilityExecutionOracleArgs) {
|
|
108
144
|
this.contractAddress = args.contractAddress;
|
|
@@ -124,29 +160,12 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
124
160
|
this.jobId = args.jobId;
|
|
125
161
|
this.logger = args.log ?? createLogger('simulator:client_view_context');
|
|
126
162
|
this.scopes = args.scopes;
|
|
163
|
+
this.simulator = args.simulator;
|
|
164
|
+
this.hooks = args.hooks;
|
|
165
|
+
this.utilityExecutor = args.utilityExecutor;
|
|
127
166
|
}
|
|
128
167
|
|
|
129
168
|
public assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
130
|
-
// TODO(F-416): Remove this hack on v5 when protocol contracts are redeployed.
|
|
131
|
-
// Protocol contracts/canonical contracts shipped with committed bytecode that cannot be changed. Assert they use
|
|
132
|
-
// the expected pinned version or the current one. We want to allow for both the pinned and the current versions
|
|
133
|
-
// because we want this code to work with both the pinned and unpinned version since some branches do not have the
|
|
134
|
-
// pinned contracts (like e.g. next)
|
|
135
|
-
const LEGACY_ORACLE_VERSION = 12;
|
|
136
|
-
if (isProtocolContract(this.contractAddress)) {
|
|
137
|
-
if (major !== LEGACY_ORACLE_VERSION && major !== ORACLE_VERSION_MAJOR) {
|
|
138
|
-
const hint =
|
|
139
|
-
major > ORACLE_VERSION_MAJOR
|
|
140
|
-
? 'The contract was compiled with a newer version of Aztec.nr than your private environment supports. Upgrade your private environment to a compatible version.'
|
|
141
|
-
: 'The contract was compiled with an older version of Aztec.nr than your private environment supports. Recompile the contract with a compatible version of Aztec.nr.';
|
|
142
|
-
throw new Error(
|
|
143
|
-
`Incompatible private environment version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${LEGACY_ORACLE_VERSION} or ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
this.contractOracleVersion = { major, minor };
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
169
|
if (major !== ORACLE_VERSION_MAJOR) {
|
|
151
170
|
const hint =
|
|
152
171
|
major > ORACLE_VERSION_MAJOR
|
|
@@ -157,7 +176,6 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
157
176
|
);
|
|
158
177
|
}
|
|
159
178
|
|
|
160
|
-
// Major matches - store both major and minor for later diagnostics (e.g. when an oracle is not found)
|
|
161
179
|
this.contractOracleVersion = { major, minor };
|
|
162
180
|
}
|
|
163
181
|
|
|
@@ -201,13 +219,17 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
201
219
|
* @param noteHash - The note hash to find in the note hash tree.
|
|
202
220
|
* @returns The membership witness containing the leaf index and sibling path
|
|
203
221
|
*/
|
|
204
|
-
public getNoteHashMembershipWitness(
|
|
222
|
+
public async getNoteHashMembershipWitness(
|
|
205
223
|
blockHash: BlockHash,
|
|
206
224
|
noteHash: Fr,
|
|
207
|
-
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT
|
|
208
|
-
|
|
225
|
+
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
226
|
+
const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
209
227
|
this.aztecNode.getNoteHashMembershipWitness(blockHash, noteHash),
|
|
210
228
|
);
|
|
229
|
+
if (!witness) {
|
|
230
|
+
throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
|
|
231
|
+
}
|
|
232
|
+
return witness;
|
|
211
233
|
}
|
|
212
234
|
|
|
213
235
|
/**
|
|
@@ -221,16 +243,17 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
221
243
|
* @param blockHash - The block hash to find in the archive tree.
|
|
222
244
|
* @returns The membership witness containing the leaf index and sibling path
|
|
223
245
|
*/
|
|
224
|
-
public getBlockHashMembershipWitness(
|
|
246
|
+
public async getBlockHashMembershipWitness(
|
|
225
247
|
referenceBlockHash: BlockHash,
|
|
226
248
|
blockHash: BlockHash,
|
|
227
|
-
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT
|
|
249
|
+
): Promise<Option<MembershipWitness<typeof ARCHIVE_HEIGHT>>> {
|
|
228
250
|
// Note that we validate that the reference block hash is at or before the anchor block - we don't test the block
|
|
229
251
|
// hash at all. If the block hash did not exist by the reference block hash, then the node will not return the
|
|
230
252
|
// membership witness as there is none.
|
|
231
|
-
|
|
253
|
+
const witness = await this.#queryWithBlockHashNotAfterAnchor(referenceBlockHash, () =>
|
|
232
254
|
this.aztecNode.getBlockHashMembershipWitness(referenceBlockHash, blockHash),
|
|
233
255
|
);
|
|
256
|
+
return witness ? Option.some(witness) : Option.none(MembershipWitness.empty(ARCHIVE_HEIGHT));
|
|
234
257
|
}
|
|
235
258
|
|
|
236
259
|
/**
|
|
@@ -239,13 +262,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
239
262
|
* @param nullifier - Nullifier we try to find witness for.
|
|
240
263
|
* @returns The nullifier membership witness (if found).
|
|
241
264
|
*/
|
|
242
|
-
public getNullifierMembershipWitness(
|
|
243
|
-
blockHash
|
|
244
|
-
nullifier: Fr,
|
|
245
|
-
): Promise<NullifierMembershipWitness | undefined> {
|
|
246
|
-
return this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
265
|
+
public async getNullifierMembershipWitness(blockHash: BlockHash, nullifier: Fr): Promise<NullifierMembershipWitness> {
|
|
266
|
+
const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
247
267
|
this.aztecNode.getNullifierMembershipWitness(blockHash, nullifier),
|
|
248
268
|
);
|
|
269
|
+
if (!witness) {
|
|
270
|
+
throw new Error(`Nullifier membership witness not found at block ${blockHash.toString()}.`);
|
|
271
|
+
}
|
|
272
|
+
return witness;
|
|
249
273
|
}
|
|
250
274
|
|
|
251
275
|
/**
|
|
@@ -257,13 +281,19 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
257
281
|
* list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier
|
|
258
282
|
* we are trying to prove non-inclusion for.
|
|
259
283
|
*/
|
|
260
|
-
public getLowNullifierMembershipWitness(
|
|
284
|
+
public async getLowNullifierMembershipWitness(
|
|
261
285
|
blockHash: BlockHash,
|
|
262
286
|
nullifier: Fr,
|
|
263
|
-
): Promise<NullifierMembershipWitness
|
|
264
|
-
|
|
287
|
+
): Promise<NullifierMembershipWitness> {
|
|
288
|
+
const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
265
289
|
this.aztecNode.getLowNullifierMembershipWitness(blockHash, nullifier),
|
|
266
290
|
);
|
|
291
|
+
if (!witness) {
|
|
292
|
+
throw new Error(
|
|
293
|
+
`Low nullifier witness not found for nullifier ${nullifier} at block hash ${blockHash.toString()}.`,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
return witness;
|
|
267
297
|
}
|
|
268
298
|
|
|
269
299
|
/**
|
|
@@ -272,10 +302,14 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
272
302
|
* @param leafSlot - The slot of the public data tree to get the witness for.
|
|
273
303
|
* @returns - The witness
|
|
274
304
|
*/
|
|
275
|
-
public getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness
|
|
276
|
-
|
|
305
|
+
public async getPublicDataWitness(blockHash: BlockHash, leafSlot: Fr): Promise<PublicDataWitness> {
|
|
306
|
+
const witness = await this.#queryWithBlockHashNotAfterAnchor(blockHash, () =>
|
|
277
307
|
this.aztecNode.getPublicDataWitness(blockHash, leafSlot),
|
|
278
308
|
);
|
|
309
|
+
if (!witness) {
|
|
310
|
+
throw new Error(`Public data witness not found for slot ${leafSlot} at block hash ${blockHash.toString()}.`);
|
|
311
|
+
}
|
|
312
|
+
return witness;
|
|
279
313
|
}
|
|
280
314
|
|
|
281
315
|
/**
|
|
@@ -283,14 +317,22 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
283
317
|
* @param blockNumber - The number of a block of which to get the block header.
|
|
284
318
|
* @returns Block extracted from a block with block number `blockNumber`.
|
|
285
319
|
*/
|
|
286
|
-
public async getBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader
|
|
320
|
+
public async getBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader> {
|
|
287
321
|
const anchorBlockNumber = this.anchorBlockHeader.getBlockNumber();
|
|
288
322
|
if (blockNumber > anchorBlockNumber) {
|
|
289
323
|
throw new Error(`Block number ${blockNumber} is higher than current block ${anchorBlockNumber}`);
|
|
290
324
|
}
|
|
291
325
|
|
|
326
|
+
// Most contracts query state at the "current" block, which is the anchor. Skip the RPC when we can.
|
|
327
|
+
if (blockNumber === anchorBlockNumber) {
|
|
328
|
+
return this.anchorBlockHeader;
|
|
329
|
+
}
|
|
330
|
+
|
|
292
331
|
const block = await this.aztecNode.getBlock(blockNumber);
|
|
293
|
-
|
|
332
|
+
if (!block?.header) {
|
|
333
|
+
throw new Error(`Block header not found for block ${blockNumber}.`);
|
|
334
|
+
}
|
|
335
|
+
return block.header;
|
|
294
336
|
}
|
|
295
337
|
|
|
296
338
|
/**
|
|
@@ -300,12 +342,12 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
300
342
|
*/
|
|
301
343
|
public async getPublicKeysAndPartialAddress(
|
|
302
344
|
account: AztecAddress,
|
|
303
|
-
): Promise<{ publicKeys: PublicKeys; partialAddress: PartialAddress }
|
|
345
|
+
): Promise<Option<{ publicKeys: PublicKeys; partialAddress: PartialAddress }>> {
|
|
304
346
|
const completeAddress = await this.addressStore.getCompleteAddress(account);
|
|
305
347
|
if (!completeAddress) {
|
|
306
|
-
return
|
|
348
|
+
return Option.none({ publicKeys: PublicKeys.default(), partialAddress: Fr.ZERO });
|
|
307
349
|
}
|
|
308
|
-
return { publicKeys: completeAddress.publicKeys, partialAddress: completeAddress.partialAddress };
|
|
350
|
+
return Option.some({ publicKeys: completeAddress.publicKeys, partialAddress: completeAddress.partialAddress });
|
|
309
351
|
}
|
|
310
352
|
|
|
311
353
|
protected async getCompleteAddressOrFail(account: AztecAddress): Promise<CompleteAddress> {
|
|
@@ -337,8 +379,12 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
337
379
|
* @param messageHash - Hash of the message to authenticate.
|
|
338
380
|
* @returns Authentication witness for the requested message hash, or undefined if not found.
|
|
339
381
|
*/
|
|
340
|
-
public getAuthWitness(messageHash: Fr): Promise<Fr[]
|
|
341
|
-
|
|
382
|
+
public getAuthWitness(messageHash: Fr): Promise<Fr[]> {
|
|
383
|
+
const witness = this.authWitnesses.find(w => w.requestHash.equals(messageHash))?.witness;
|
|
384
|
+
if (!witness) {
|
|
385
|
+
throw new Error(`Unknown auth witness for message hash ${messageHash}`);
|
|
386
|
+
}
|
|
387
|
+
return Promise.resolve(witness);
|
|
342
388
|
}
|
|
343
389
|
|
|
344
390
|
/**
|
|
@@ -364,7 +410,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
364
410
|
* @returns Array of note data.
|
|
365
411
|
*/
|
|
366
412
|
public async getNotes(
|
|
367
|
-
owner: AztecAddress
|
|
413
|
+
owner: Option<AztecAddress>,
|
|
368
414
|
storageSlot: Fr,
|
|
369
415
|
numSelects: number,
|
|
370
416
|
selectByIndexes: number[],
|
|
@@ -379,11 +425,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
379
425
|
limit: number,
|
|
380
426
|
offset: number,
|
|
381
427
|
status: NoteStatus,
|
|
382
|
-
|
|
428
|
+
maxNotes: number,
|
|
429
|
+
packedHintedNoteLength: number,
|
|
430
|
+
): Promise<BoundedVec<NoteData>> {
|
|
383
431
|
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
384
432
|
|
|
385
|
-
const dbNotes = await noteService.getNotes(this.contractAddress, owner, storageSlot, status, this.scopes);
|
|
386
|
-
|
|
433
|
+
const dbNotes = await noteService.getNotes(this.contractAddress, owner.value, storageSlot, status, this.scopes);
|
|
434
|
+
const picked = pickNotes<NoteData>(dbNotes, {
|
|
387
435
|
selects: selectByIndexes.slice(0, numSelects).map((index, i) => ({
|
|
388
436
|
selector: { index, offset: selectByOffsets[i], length: selectByLengths[i] },
|
|
389
437
|
value: selectValues[i],
|
|
@@ -396,6 +444,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
396
444
|
limit,
|
|
397
445
|
offset,
|
|
398
446
|
});
|
|
447
|
+
return BoundedVec.from({ data: picked, maxLength: maxNotes, elementSize: packedHintedNoteLength });
|
|
399
448
|
}
|
|
400
449
|
|
|
401
450
|
/**
|
|
@@ -498,7 +547,7 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
498
547
|
return this.aztecnrLogger;
|
|
499
548
|
}
|
|
500
549
|
|
|
501
|
-
public async log(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
550
|
+
public async log(level: number, message: string, _fieldsSize: number, fields: Fr[]): Promise<void> {
|
|
502
551
|
if (!LogLevels[level]) {
|
|
503
552
|
throw new Error(`Invalid log level: ${level}`);
|
|
504
553
|
}
|
|
@@ -509,24 +558,18 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
509
558
|
logContractMessage(logger, LogLevels[level], strippedMessage, fields);
|
|
510
559
|
}
|
|
511
560
|
|
|
512
|
-
|
|
513
|
-
public async getPendingTaggedLogs(
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
this.jobId,
|
|
521
|
-
scope,
|
|
522
|
-
);
|
|
523
|
-
}
|
|
561
|
+
/** Fetches pending tagged logs into a freshly allocated ephemeral array and returns it. */
|
|
562
|
+
public async getPendingTaggedLogs(
|
|
563
|
+
scope: AztecAddress,
|
|
564
|
+
providedSecrets: EphemeralArray<ProvidedSecret>,
|
|
565
|
+
): Promise<EphemeralArray<PendingTaggedLog>> {
|
|
566
|
+
const secrets = providedSecrets
|
|
567
|
+
.readAll(this.ephemeralArrayService)
|
|
568
|
+
.map(ps => new AppTaggingSecret(ps.secret, this.contractAddress, ps.mode));
|
|
524
569
|
|
|
525
|
-
/** Fetches pending tagged logs into a freshly allocated ephemeral array and returns its base slot. */
|
|
526
|
-
public async getPendingTaggedLogsV2(scope: AztecAddress): Promise<Fr> {
|
|
527
570
|
const logService = this.#createLogService();
|
|
528
|
-
const logs = await logService.fetchTaggedLogs(this.contractAddress, scope);
|
|
529
|
-
return this.ephemeralArrayService
|
|
571
|
+
const logs = await logService.fetchTaggedLogs(this.contractAddress, scope, secrets);
|
|
572
|
+
return EphemeralArray.fromValues(this.ephemeralArrayService, logs);
|
|
530
573
|
}
|
|
531
574
|
|
|
532
575
|
#createLogService(): LogService {
|
|
@@ -543,246 +586,85 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
543
586
|
);
|
|
544
587
|
}
|
|
545
588
|
|
|
546
|
-
/**
|
|
547
|
-
* Legacy: validates note/event requests stored in capsule arrays.
|
|
548
|
-
*
|
|
549
|
-
* Deprecated, only kept for backwards compatibility until Alpha v5 rolls out.
|
|
550
|
-
*/
|
|
551
589
|
public async validateAndStoreEnqueuedNotesAndEvents(
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
eventValidationRequestsArrayBaseSlot: Fr,
|
|
555
|
-
maxNotePackedLen: number,
|
|
556
|
-
maxEventSerializedLen: number,
|
|
590
|
+
noteValidationRequests: EphemeralArray<NoteValidationRequest>,
|
|
591
|
+
eventValidationRequests: EphemeralArray<EventValidationRequest>,
|
|
557
592
|
scope: AztecAddress,
|
|
558
593
|
) {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
const noteValidationRequests = (
|
|
565
|
-
await this.capsuleService.readCapsuleArray(
|
|
566
|
-
contractAddress,
|
|
567
|
-
noteValidationRequestsArrayBaseSlot,
|
|
568
|
-
this.jobId,
|
|
569
|
-
scope,
|
|
570
|
-
)
|
|
571
|
-
).map(fields => NoteValidationRequest.fromFields(fields, maxNotePackedLen));
|
|
572
|
-
|
|
573
|
-
const eventValidationRequests = (
|
|
574
|
-
await this.capsuleService.readCapsuleArray(
|
|
575
|
-
contractAddress,
|
|
576
|
-
eventValidationRequestsArrayBaseSlot,
|
|
577
|
-
this.jobId,
|
|
578
|
-
scope,
|
|
579
|
-
)
|
|
580
|
-
).map(fields => EventValidationRequest.fromFields(fields, maxEventSerializedLen));
|
|
581
|
-
|
|
582
|
-
await this.#processValidationRequests(noteValidationRequests, eventValidationRequests, scope);
|
|
583
|
-
|
|
584
|
-
await this.capsuleService.setCapsuleArray(
|
|
585
|
-
contractAddress,
|
|
586
|
-
noteValidationRequestsArrayBaseSlot,
|
|
587
|
-
[],
|
|
588
|
-
this.jobId,
|
|
589
|
-
scope,
|
|
590
|
-
);
|
|
591
|
-
await this.capsuleService.setCapsuleArray(
|
|
592
|
-
contractAddress,
|
|
593
|
-
eventValidationRequestsArrayBaseSlot,
|
|
594
|
-
[],
|
|
595
|
-
this.jobId,
|
|
594
|
+
await this.#processValidationRequests(
|
|
595
|
+
noteValidationRequests.readAll(this.ephemeralArrayService),
|
|
596
|
+
eventValidationRequests.readAll(this.ephemeralArrayService),
|
|
596
597
|
scope,
|
|
597
598
|
);
|
|
598
599
|
}
|
|
599
600
|
|
|
600
|
-
public async validateAndStoreEnqueuedNotesAndEventsV2(
|
|
601
|
-
noteValidationRequestsArrayBaseSlot: Fr,
|
|
602
|
-
eventValidationRequestsArrayBaseSlot: Fr,
|
|
603
|
-
maxNotePackedLen: number,
|
|
604
|
-
maxEventSerializedLen: number,
|
|
605
|
-
scope: AztecAddress,
|
|
606
|
-
) {
|
|
607
|
-
const noteValidationRequests = this.ephemeralArrayService
|
|
608
|
-
.readArrayAt(noteValidationRequestsArrayBaseSlot)
|
|
609
|
-
.map(fields => NoteValidationRequest.fromFields(fields, maxNotePackedLen));
|
|
610
|
-
|
|
611
|
-
const eventValidationRequests = this.ephemeralArrayService
|
|
612
|
-
.readArrayAt(eventValidationRequestsArrayBaseSlot)
|
|
613
|
-
.map(fields => EventValidationRequest.fromFields(fields, maxEventSerializedLen));
|
|
614
|
-
|
|
615
|
-
await this.#processValidationRequests(noteValidationRequests, eventValidationRequests, scope);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/**
|
|
619
|
-
* Dispatches note and event validation requests to the service layer.
|
|
620
|
-
*
|
|
621
|
-
* This function is an auxiliary to support legacy (capsule backed) and new (ephemeral array backed) versions of the
|
|
622
|
-
* `validateAndStoreEnqueuedNotesAndEvents` oracle.
|
|
623
|
-
*/
|
|
624
601
|
async #processValidationRequests(
|
|
625
602
|
noteValidationRequests: NoteValidationRequest[],
|
|
626
603
|
eventValidationRequests: EventValidationRequest[],
|
|
627
604
|
scope: AztecAddress,
|
|
628
605
|
) {
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
request.owner,
|
|
634
|
-
request.storageSlot,
|
|
635
|
-
request.randomness,
|
|
636
|
-
request.noteNonce,
|
|
637
|
-
request.content,
|
|
638
|
-
request.noteHash,
|
|
639
|
-
request.nullifier,
|
|
640
|
-
request.txHash,
|
|
641
|
-
scope,
|
|
642
|
-
),
|
|
643
|
-
);
|
|
606
|
+
const txEffects = await this.#fetchTxEffects([
|
|
607
|
+
...noteValidationRequests.map(r => r.txHash),
|
|
608
|
+
...eventValidationRequests.map(r => r.txHash),
|
|
609
|
+
]);
|
|
644
610
|
|
|
611
|
+
const noteService = new NoteService(this.noteStore, this.aztecNode, this.anchorBlockHeader, this.jobId);
|
|
645
612
|
const eventService = new EventService(this.anchorBlockHeader, this.aztecNode, this.privateEventStore, this.jobId);
|
|
646
|
-
const eventStorePromises = eventValidationRequests.map(request =>
|
|
647
|
-
eventService.validateAndStoreEvent(
|
|
648
|
-
request.contractAddress,
|
|
649
|
-
request.eventTypeId,
|
|
650
|
-
request.randomness,
|
|
651
|
-
request.serializedEvent,
|
|
652
|
-
request.eventCommitment,
|
|
653
|
-
request.txHash,
|
|
654
|
-
scope,
|
|
655
|
-
),
|
|
656
|
-
);
|
|
657
613
|
|
|
658
|
-
await Promise.all([
|
|
614
|
+
await Promise.all([
|
|
615
|
+
noteService.validateAndStoreNotes(noteValidationRequests, scope, txEffects),
|
|
616
|
+
eventService.validateAndStoreEvents(eventValidationRequests, scope, txEffects),
|
|
617
|
+
]);
|
|
659
618
|
}
|
|
660
619
|
|
|
661
620
|
public async getLogsByTag(
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
scope: AztecAddress,
|
|
666
|
-
) {
|
|
667
|
-
// TODO(#10727): allow other contracts to process partial notes
|
|
668
|
-
if (!this.contractAddress.equals(contractAddress)) {
|
|
669
|
-
throw new Error(`Got a note validation request from ${contractAddress}, expected ${this.contractAddress}`);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
// We read all log retrieval requests and process them all concurrently. This makes the process much faster as we
|
|
673
|
-
// don't need to wait for the network round-trip.
|
|
674
|
-
const logRetrievalRequests = (
|
|
675
|
-
await this.capsuleService.readCapsuleArray(contractAddress, logRetrievalRequestsArrayBaseSlot, this.jobId, scope)
|
|
676
|
-
).map(LogRetrievalRequest.fromFields);
|
|
677
|
-
|
|
621
|
+
requests: EphemeralArray<LogRetrievalRequest>,
|
|
622
|
+
): Promise<EphemeralArray<EphemeralArray<LogRetrievalResponse>>> {
|
|
623
|
+
const logRetrievalRequests = requests.readAll(this.ephemeralArrayService);
|
|
678
624
|
const logService = this.#createLogService();
|
|
679
|
-
const maybeLogRetrievalResponses = await logService.fetchLogsByTag(contractAddress, logRetrievalRequests);
|
|
680
625
|
|
|
681
|
-
|
|
682
|
-
await this.capsuleService.setCapsuleArray(
|
|
683
|
-
contractAddress,
|
|
684
|
-
logRetrievalRequestsArrayBaseSlot,
|
|
685
|
-
[],
|
|
686
|
-
this.jobId,
|
|
687
|
-
scope,
|
|
688
|
-
);
|
|
626
|
+
const logRetrievalResponses = await logService.fetchLogsByTag(this.contractAddress, logRetrievalRequests);
|
|
689
627
|
|
|
690
|
-
//
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
logRetrievalResponsesArrayBaseSlot,
|
|
694
|
-
maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption),
|
|
695
|
-
this.jobId,
|
|
696
|
-
scope,
|
|
628
|
+
// Create an inner ephemeral array for each request's matching logs, then wrap all slots in an outer array.
|
|
629
|
+
const innerArrays = logRetrievalResponses.map(responses =>
|
|
630
|
+
EphemeralArray.fromValues(this.ephemeralArrayService, responses),
|
|
697
631
|
);
|
|
698
|
-
}
|
|
699
632
|
|
|
700
|
-
|
|
701
|
-
const logRetrievalRequests = this.ephemeralArrayService
|
|
702
|
-
.readArrayAt(requestArrayBaseSlot)
|
|
703
|
-
.map(LogRetrievalRequest.fromFields);
|
|
704
|
-
const logService = this.#createLogService();
|
|
705
|
-
|
|
706
|
-
const maybeLogRetrievalResponses = await logService.fetchLogsByTag(this.contractAddress, logRetrievalRequests);
|
|
707
|
-
|
|
708
|
-
return this.ephemeralArrayService.newArray(maybeLogRetrievalResponses.map(LogRetrievalResponse.toSerializedOption));
|
|
633
|
+
return EphemeralArray.fromValues(this.ephemeralArrayService, innerArrays);
|
|
709
634
|
}
|
|
710
635
|
|
|
711
|
-
|
|
636
|
+
/** Reads tx hash requests from an ephemeral array, resolves their contexts, and returns the response array. */
|
|
712
637
|
public async getMessageContextsByTxHash(
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
scope: AztecAddress,
|
|
717
|
-
) {
|
|
718
|
-
try {
|
|
719
|
-
if (!this.contractAddress.equals(contractAddress)) {
|
|
720
|
-
throw new Error(`Got a message context request from ${contractAddress}, expected ${this.contractAddress}`);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
// TODO(@mverzilli): this is a prime example of where using an ephemeral array would make much more sense, we don't
|
|
724
|
-
// need scopes here, we just need a bit of shared memory to cross boundaries between Noir and TS.
|
|
725
|
-
// At the same time, we don't want to allow any global scope access other than where backwards compatibility
|
|
726
|
-
// forces us to. Hence we need the scope here to be artificial.
|
|
727
|
-
const requestCapsules = await this.capsuleService.readCapsuleArray(
|
|
728
|
-
contractAddress,
|
|
729
|
-
messageContextRequestsArrayBaseSlot,
|
|
730
|
-
this.jobId,
|
|
731
|
-
scope,
|
|
732
|
-
);
|
|
733
|
-
|
|
734
|
-
const txHashes = requestCapsules.map((fields, i) => {
|
|
735
|
-
if (fields.length !== 1) {
|
|
736
|
-
throw new Error(
|
|
737
|
-
`Malformed message context request at index ${i}: expected 1 field (tx hash), got ${fields.length}`,
|
|
738
|
-
);
|
|
739
|
-
}
|
|
740
|
-
return fields[0];
|
|
741
|
-
});
|
|
742
|
-
|
|
743
|
-
const maybeMessageContexts = await this.messageContextService.getMessageContextsByTxHash(
|
|
744
|
-
txHashes,
|
|
745
|
-
this.anchorBlockHeader.getBlockNumber(),
|
|
746
|
-
);
|
|
747
|
-
|
|
748
|
-
// Leave response in response capsule array.
|
|
749
|
-
await this.capsuleService.setCapsuleArray(
|
|
750
|
-
contractAddress,
|
|
751
|
-
messageContextResponsesArrayBaseSlot,
|
|
752
|
-
maybeMessageContexts.map(MessageContext.toSerializedOption),
|
|
753
|
-
this.jobId,
|
|
754
|
-
scope,
|
|
755
|
-
);
|
|
756
|
-
} finally {
|
|
757
|
-
await this.capsuleService.setCapsuleArray(
|
|
758
|
-
contractAddress,
|
|
759
|
-
messageContextRequestsArrayBaseSlot,
|
|
760
|
-
[],
|
|
761
|
-
this.jobId,
|
|
762
|
-
scope,
|
|
763
|
-
);
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
/** Reads tx hash requests from an ephemeral array, resolves their contexts, and returns the response slot. */
|
|
768
|
-
public async getMessageContextsByTxHashV2(requestArrayBaseSlot: Fr): Promise<Fr> {
|
|
769
|
-
const requestFields = this.ephemeralArrayService.readArrayAt(requestArrayBaseSlot);
|
|
770
|
-
|
|
771
|
-
const txHashes = requestFields.map((fields, i) => {
|
|
772
|
-
if (fields.length !== 1) {
|
|
773
|
-
throw new Error(
|
|
774
|
-
`Malformed message context request at index ${i}: expected 1 field (tx hash), got ${fields.length}`,
|
|
775
|
-
);
|
|
776
|
-
}
|
|
777
|
-
return fields[0];
|
|
778
|
-
});
|
|
638
|
+
requests: EphemeralArray<Fr>,
|
|
639
|
+
): Promise<EphemeralArray<Option<MessageContext>>> {
|
|
640
|
+
const txHashes = requests.readAll(this.ephemeralArrayService);
|
|
779
641
|
|
|
780
642
|
const maybeMessageContexts = await this.messageContextService.getMessageContextsByTxHash(
|
|
781
643
|
txHashes,
|
|
782
644
|
this.anchorBlockHeader.getBlockNumber(),
|
|
783
645
|
);
|
|
784
646
|
|
|
785
|
-
|
|
647
|
+
const options = maybeMessageContexts.map(mc =>
|
|
648
|
+
mc ? Option.some(mc) : Option.none<MessageContext>(MessageContext.empty()),
|
|
649
|
+
);
|
|
650
|
+
return EphemeralArray.fromValues(this.ephemeralArrayService, options);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Fetches the effects of a transaction by its hash. Returns null if the tx is not found or is beyond the anchor
|
|
655
|
+
* block.
|
|
656
|
+
*/
|
|
657
|
+
public async getTxEffect(txHash: TxHash): Promise<Option<TxEffect>> {
|
|
658
|
+
if (txHash.hash.isZero()) {
|
|
659
|
+
throw new Error('Invalid tx hash passed into aztec_utl_getTxEffect oracle handler');
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const receipt = await this.aztecNode.getTxReceipt(txHash, { includeTxEffect: true });
|
|
663
|
+
if (!receipt.isMined() || !receipt.txEffect || receipt.blockNumber > this.anchorBlockHeader.getBlockNumber()) {
|
|
664
|
+
return Option.none(TxEffect.empty());
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return Option.some(receipt.txEffect);
|
|
786
668
|
}
|
|
787
669
|
|
|
788
670
|
public setCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[], scope: AztecAddress): void {
|
|
@@ -793,12 +675,18 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
793
675
|
this.capsuleService.setCapsule(contractAddress, slot, capsule, this.jobId, scope);
|
|
794
676
|
}
|
|
795
677
|
|
|
796
|
-
public getCapsule(
|
|
678
|
+
public async getCapsule(
|
|
679
|
+
contractAddress: AztecAddress,
|
|
680
|
+
slot: Fr,
|
|
681
|
+
tSize: number,
|
|
682
|
+
scope: AztecAddress,
|
|
683
|
+
): Promise<Option<Fr[]>> {
|
|
797
684
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
798
685
|
// TODO(#10727): instead of this check that this.contractAddress is allowed to access the external DB
|
|
799
686
|
throw new Error(`Contract ${contractAddress} is not allowed to access ${this.contractAddress}'s PXE DB`);
|
|
800
687
|
}
|
|
801
|
-
|
|
688
|
+
const values = await this.capsuleService.getCapsule(contractAddress, slot, this.jobId, scope, this.capsules);
|
|
689
|
+
return values ? Option.some(values) : Option.none(new Array(tSize).fill(Fr.ZERO));
|
|
802
690
|
}
|
|
803
691
|
|
|
804
692
|
public deleteCapsule(contractAddress: AztecAddress, slot: Fr, scope: AztecAddress): void {
|
|
@@ -827,38 +715,57 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
827
715
|
* Clears cached sync state for a contract for a set of scopes, forcing re-sync on the next query so that newly
|
|
828
716
|
* stored notes or events are discovered.
|
|
829
717
|
*/
|
|
830
|
-
public setContractSyncCacheInvalid(contractAddress: AztecAddress, scopes: AztecAddress
|
|
718
|
+
public setContractSyncCacheInvalid(contractAddress: AztecAddress, scopes: BoundedVec<AztecAddress>): void {
|
|
831
719
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
832
720
|
throw new Error(`Contract ${this.contractAddress} cannot invalidate sync cache of ${contractAddress}`);
|
|
833
721
|
}
|
|
834
|
-
this.contractSyncService.invalidateContractForScopes(contractAddress, scopes);
|
|
722
|
+
this.contractSyncService.invalidateContractForScopes(contractAddress, scopes.data);
|
|
835
723
|
}
|
|
836
724
|
|
|
837
725
|
// TODO(#11849): consider replacing this oracle with a pure Noir implementation of aes decryption.
|
|
838
|
-
public decryptAes128(
|
|
839
|
-
|
|
840
|
-
|
|
726
|
+
public async decryptAes128(
|
|
727
|
+
ciphertext: BoundedVec<number>,
|
|
728
|
+
iv: Buffer,
|
|
729
|
+
symKey: Buffer,
|
|
730
|
+
): Promise<Option<BoundedVec<number>>> {
|
|
731
|
+
const capacity = ciphertext.maxLength;
|
|
732
|
+
try {
|
|
733
|
+
const aes128 = new Aes128();
|
|
734
|
+
const plaintext = await aes128.decryptBufferCBC(Buffer.from(ciphertext.data), iv, symKey);
|
|
735
|
+
return Option.some(BoundedVec.from<number>({ data: [...plaintext], maxLength: capacity }));
|
|
736
|
+
} catch {
|
|
737
|
+
return Option.none(BoundedVec.empty<number>({ maxLength: capacity }));
|
|
738
|
+
}
|
|
841
739
|
}
|
|
842
740
|
|
|
843
741
|
/**
|
|
844
|
-
* Retrieves
|
|
845
|
-
* @param address - The address
|
|
846
|
-
* @param
|
|
742
|
+
* Retrieves app-siloed shared secrets for multiple ephemeral public keys stored in an ephemeral array.
|
|
743
|
+
* @param address - The recipient address.
|
|
744
|
+
* @param ephPks - Ephemeral array containing the serialized Points.
|
|
847
745
|
* @param contractAddress - The contract address for app-siloing (validated against execution context).
|
|
848
|
-
* @returns
|
|
746
|
+
* @returns A new ephemeral array containing the computed shared secrets.
|
|
849
747
|
*/
|
|
850
|
-
public async
|
|
748
|
+
public async getSharedSecrets(
|
|
749
|
+
address: AztecAddress,
|
|
750
|
+
ephPks: EphemeralArray<Point>,
|
|
751
|
+
contractAddress: AztecAddress,
|
|
752
|
+
): Promise<EphemeralArray<Fr>> {
|
|
851
753
|
if (!contractAddress.equals(this.contractAddress)) {
|
|
852
754
|
throw new Error(
|
|
853
|
-
`
|
|
755
|
+
`getSharedSecrets called with contract address ${contractAddress}, expected ${this.contractAddress}`,
|
|
854
756
|
);
|
|
855
757
|
}
|
|
856
758
|
const recipientCompleteAddress = await this.getCompleteAddressOrFail(address);
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
);
|
|
759
|
+
const ivpkMHash = await hashPublicKey(recipientCompleteAddress.publicKeys.ivpkM);
|
|
760
|
+
const ivskM = await this.keyStore.getMasterSecretKey(ivpkMHash);
|
|
860
761
|
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
861
|
-
|
|
762
|
+
|
|
763
|
+
const ephPkPoints = ephPks.readAll(this.ephemeralArrayService);
|
|
764
|
+
const secrets = await Promise.all(
|
|
765
|
+
ephPkPoints.map(ephPk => deriveAppSiloedSharedSecret(addressSecret, ephPk, this.contractAddress)),
|
|
766
|
+
);
|
|
767
|
+
|
|
768
|
+
return EphemeralArray.fromValues(this.ephemeralArrayService, secrets);
|
|
862
769
|
}
|
|
863
770
|
|
|
864
771
|
public pushEphemeral(slot: Fr, elements: Fr[]): number {
|
|
@@ -894,28 +801,167 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
894
801
|
return Promise.resolve();
|
|
895
802
|
}
|
|
896
803
|
|
|
804
|
+
/** Executes another utility function from within this one and returns its serialized return values. */
|
|
805
|
+
public async callUtilityFunction(
|
|
806
|
+
targetContractAddress: AztecAddress,
|
|
807
|
+
functionSelector: FunctionSelector,
|
|
808
|
+
args: Fr[],
|
|
809
|
+
): Promise<Fr[]> {
|
|
810
|
+
const targetArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(
|
|
811
|
+
targetContractAddress,
|
|
812
|
+
functionSelector,
|
|
813
|
+
);
|
|
814
|
+
|
|
815
|
+
if (!targetContractAddress.equals(this.contractAddress)) {
|
|
816
|
+
const [callerInstance, targetInstance] = await Promise.all([
|
|
817
|
+
this.getContractInstance(this.contractAddress),
|
|
818
|
+
this.getContractInstance(targetContractAddress),
|
|
819
|
+
]);
|
|
820
|
+
const request: UtilityCallAuthorizationRequest = {
|
|
821
|
+
caller: this.contractAddress,
|
|
822
|
+
callerClassId: callerInstance.currentContractClassId,
|
|
823
|
+
target: targetContractAddress,
|
|
824
|
+
targetClassId: targetInstance.currentContractClassId,
|
|
825
|
+
functionSelector,
|
|
826
|
+
functionName: targetArtifact.name,
|
|
827
|
+
args,
|
|
828
|
+
callerContext: this.callerContext,
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
const response = this.hooks
|
|
832
|
+
? await this.hooks.authorizeUtilityCall(request)
|
|
833
|
+
: { authorized: false, reason: 'No execution hooks configured' };
|
|
834
|
+
|
|
835
|
+
if (!response.authorized) {
|
|
836
|
+
const reason = response.reason ? `: ${response.reason}` : '';
|
|
837
|
+
throw new Error(
|
|
838
|
+
`Cross-contract utility call denied${reason}. ${this.contractAddress} attempted to call ` +
|
|
839
|
+
`${targetContractAddress}:${functionSelector} (${targetArtifact.name}). ` +
|
|
840
|
+
`See https://docs.aztec.network/errors/11`,
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
await this.contractSyncService.ensureContractSynced(
|
|
845
|
+
targetContractAddress,
|
|
846
|
+
functionSelector,
|
|
847
|
+
this.utilityExecutor,
|
|
848
|
+
this.anchorBlockHeader,
|
|
849
|
+
this.jobId,
|
|
850
|
+
this.scopes,
|
|
851
|
+
);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
this.logger.debug(
|
|
855
|
+
`Calling nested utility function ${targetContractAddress}:${functionSelector} from ${this.contractAddress}`,
|
|
856
|
+
);
|
|
857
|
+
|
|
858
|
+
const nestedOracle = new UtilityExecutionOracle({
|
|
859
|
+
contractAddress: targetContractAddress,
|
|
860
|
+
authWitnesses: this.authWitnesses,
|
|
861
|
+
capsules: this.capsules,
|
|
862
|
+
anchorBlockHeader: this.anchorBlockHeader,
|
|
863
|
+
contractStore: this.contractStore,
|
|
864
|
+
noteStore: this.noteStore,
|
|
865
|
+
keyStore: this.keyStore,
|
|
866
|
+
addressStore: this.addressStore,
|
|
867
|
+
aztecNode: this.aztecNode,
|
|
868
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
869
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
870
|
+
capsuleService: this.capsuleService,
|
|
871
|
+
privateEventStore: this.privateEventStore,
|
|
872
|
+
messageContextService: this.messageContextService,
|
|
873
|
+
contractSyncService: this.contractSyncService,
|
|
874
|
+
l2TipsStore: this.l2TipsStore,
|
|
875
|
+
jobId: this.jobId,
|
|
876
|
+
scopes: this.scopes,
|
|
877
|
+
simulator: this.simulator,
|
|
878
|
+
hooks: this.hooks,
|
|
879
|
+
utilityExecutor: this.utilityExecutor,
|
|
880
|
+
log: this.logger,
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
const initialWitness = toACVMWitness(0, args);
|
|
884
|
+
const acvmCallback = new Oracle(nestedOracle);
|
|
885
|
+
const acirExecutionResult = await this.simulator
|
|
886
|
+
.executeUserCircuit(initialWitness, targetArtifact, acvmCallback.toACIRCallback())
|
|
887
|
+
.catch((err: Error) => {
|
|
888
|
+
err.message = resolveAssertionMessageFromError(err, targetArtifact);
|
|
889
|
+
throw new ExecutionError(
|
|
890
|
+
err.message,
|
|
891
|
+
{ contractAddress: targetContractAddress, functionSelector },
|
|
892
|
+
extractCallStack(err, targetArtifact.debug),
|
|
893
|
+
{ cause: err },
|
|
894
|
+
);
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
898
|
+
}
|
|
899
|
+
|
|
897
900
|
/** Returns offchain effects collected during execution. */
|
|
898
901
|
public getOffchainEffects(): OffchainEffect[] {
|
|
899
902
|
return this.offchainEffects;
|
|
900
903
|
}
|
|
901
904
|
|
|
905
|
+
/**
|
|
906
|
+
* Fetches tx effects for the given hashes in parallel, deduplicating repeated hashes so each tx is only requested
|
|
907
|
+
* once. Returns a map keyed by `TxHash.toString()`; hashes for which the node has no tx effect are omitted.
|
|
908
|
+
*/
|
|
909
|
+
async #fetchTxEffects(txHashes: TxHash[]): Promise<Map<string, IndexedTxEffect>> {
|
|
910
|
+
const uniqueTxHashes = uniqueBy(txHashes, h => h.toString());
|
|
911
|
+
const fetched = await Promise.all(
|
|
912
|
+
uniqueTxHashes.map(h => this.aztecNode.getTxReceipt(h, { includeTxEffect: true })),
|
|
913
|
+
);
|
|
914
|
+
return new Map(
|
|
915
|
+
uniqueTxHashes
|
|
916
|
+
.map((h, i): [string, IndexedTxEffect | undefined] => {
|
|
917
|
+
const receipt = fetched[i];
|
|
918
|
+
if (!receipt.isMined() || !receipt.txEffect) {
|
|
919
|
+
return [h.toString(), undefined];
|
|
920
|
+
}
|
|
921
|
+
return [
|
|
922
|
+
h.toString(),
|
|
923
|
+
{
|
|
924
|
+
data: receipt.txEffect,
|
|
925
|
+
l2BlockNumber: receipt.blockNumber,
|
|
926
|
+
l2BlockHash: receipt.blockHash,
|
|
927
|
+
txIndexInBlock: receipt.txIndexInBlock,
|
|
928
|
+
slotNumber: receipt.slotNumber,
|
|
929
|
+
},
|
|
930
|
+
];
|
|
931
|
+
})
|
|
932
|
+
.filter((entry): entry is [string, IndexedTxEffect] => entry[1] !== undefined),
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
|
|
902
936
|
/** Runs a query concurrently with a validation that the block hash is not ahead of the anchor block. */
|
|
903
937
|
async #queryWithBlockHashNotAfterAnchor<T>(blockHash: BlockHash, query: () => Promise<T>): Promise<T> {
|
|
938
|
+
// Most contracts query state at the "current" block, which is the anchor. Skip the validation when we can.
|
|
939
|
+
const anchorHash = await this.anchorBlockHeader.hash();
|
|
940
|
+
if (blockHash.equals(anchorHash)) {
|
|
941
|
+
return query();
|
|
942
|
+
}
|
|
943
|
+
|
|
904
944
|
const [response] = await Promise.all([
|
|
905
945
|
query(),
|
|
906
946
|
(async () => {
|
|
907
|
-
const
|
|
947
|
+
const block = await this.aztecNode.getBlock(blockHash);
|
|
948
|
+
const header = block?.header;
|
|
908
949
|
if (!header) {
|
|
909
950
|
throw new Error(`Could not find block header for block hash ${blockHash}`);
|
|
910
951
|
}
|
|
911
952
|
|
|
912
953
|
if (header.getBlockNumber() > this.anchorBlockHeader.getBlockNumber()) {
|
|
913
954
|
throw new Error(
|
|
914
|
-
`Made a node query with a reference block hash ${blockHash} with block number ${header.getBlockNumber()}, which is ahead of the anchor block number ${this.anchorBlockHeader.getBlockNumber()} (from anchor block hash ${
|
|
955
|
+
`Made a node query with a reference block hash ${blockHash} with block number ${header.getBlockNumber()}, which is ahead of the anchor block number ${this.anchorBlockHeader.getBlockNumber()} (from anchor block hash ${anchorHash}).`,
|
|
915
956
|
);
|
|
916
957
|
}
|
|
917
958
|
})(),
|
|
918
959
|
]);
|
|
919
960
|
return response;
|
|
920
961
|
}
|
|
962
|
+
|
|
963
|
+
/** The execution context of the current call. */
|
|
964
|
+
protected get callerContext(): 'private' | 'private view' | 'utility' {
|
|
965
|
+
return 'utility';
|
|
966
|
+
}
|
|
921
967
|
}
|