@aztec/pxe 0.0.1-commit.f2ce05ee → 0.0.1-commit.f81dbcf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/access_scopes.d.ts +9 -0
- package/dest/access_scopes.d.ts.map +1 -0
- package/dest/access_scopes.js +6 -0
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +53 -29
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +172 -68
- 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.js +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +2 -2
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
- package/dest/contract_function_simulator/oracle/interfaces.d.ts +8 -4
- package/dest/contract_function_simulator/oracle/interfaces.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.d.ts +2 -2
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +2 -2
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +35 -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 +79 -26
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +38 -16
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +47 -40
- 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 +4 -2
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
- package/dest/contract_sync/contract_sync_service.js +34 -19
- package/dest/contract_sync/helpers.d.ts +3 -2
- package/dest/contract_sync/helpers.d.ts.map +1 -1
- package/dest/contract_sync/helpers.js +3 -3
- package/dest/debug/pxe_debug_utils.d.ts +5 -4
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +4 -4
- package/dest/entrypoints/client/bundle/index.d.ts +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 +9 -1
- 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 +1 -1
- package/dest/entrypoints/client/lazy/utils.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/utils.js +9 -1
- package/dest/entrypoints/server/index.d.ts +3 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +2 -0
- package/dest/entrypoints/server/utils.js +9 -1
- package/dest/logs/log_service.d.ts +3 -2
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +9 -14
- package/dest/notes/note_service.d.ts +4 -3
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +3 -2
- package/dest/notes_filter.d.ts +25 -0
- package/dest/notes_filter.d.ts.map +1 -0
- package/dest/notes_filter.js +4 -0
- package/dest/oracle_version.d.ts +2 -2
- package/dest/oracle_version.js +2 -2
- 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 +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +19 -11
- package/dest/private_kernel/private_kernel_oracle.d.ts +6 -2
- 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 +58 -23
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +63 -52
- package/dest/storage/contract_store/contract_store.d.ts +42 -15
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +140 -64
- package/dest/storage/note_store/note_store.d.ts +3 -3
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +3 -4
- 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 +4 -4
- package/dest/tagging/get_all_logs_by_tags.d.ts +1 -1
- package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
- package/dest/tagging/get_all_logs_by_tags.js +17 -3
- package/dest/tagging/index.d.ts +2 -2
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +4 -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 +6 -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 +12 -11
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -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/load_and_store_new_tagging_indexes.d.ts +4 -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 +14 -15
- package/package.json +16 -16
- package/src/access_scopes.ts +9 -0
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +320 -128
- package/src/contract_function_simulator/execution_tagging_index_cache.ts +5 -5
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
- package/src/contract_function_simulator/oracle/interfaces.ts +6 -3
- package/src/contract_function_simulator/oracle/oracle.ts +2 -2
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +104 -102
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +89 -39
- package/src/contract_logging.ts +39 -0
- package/src/contract_sync/contract_sync_service.ts +49 -26
- package/src/contract_sync/helpers.ts +7 -2
- package/src/debug/pxe_debug_utils.ts +11 -9
- package/src/entrypoints/client/bundle/index.ts +3 -0
- package/src/entrypoints/client/bundle/utils.ts +9 -1
- package/src/entrypoints/client/lazy/index.ts +3 -0
- package/src/entrypoints/client/lazy/utils.ts +9 -1
- package/src/entrypoints/server/index.ts +2 -0
- package/src/entrypoints/server/utils.ts +7 -7
- package/src/logs/log_service.ts +17 -24
- package/src/notes/note_service.ts +4 -3
- package/src/notes_filter.ts +26 -0
- package/src/oracle_version.ts +2 -2
- 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 +19 -12
- package/src/private_kernel/private_kernel_oracle.ts +7 -7
- package/src/pxe.ts +130 -97
- package/src/storage/contract_store/contract_store.ts +170 -71
- package/src/storage/note_store/note_store.ts +8 -5
- package/src/storage/tagging_store/recipient_tagging_store.ts +9 -5
- package/src/storage/tagging_store/sender_tagging_store.ts +8 -8
- package/src/tagging/get_all_logs_by_tags.ts +28 -4
- package/src/tagging/index.ts +1 -1
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +7 -10
- package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
- package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +10 -15
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +4 -9
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +11 -20
- 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
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExtendedDirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* A map that stores the tagging index for a given directional app tagging secret.
|
|
4
|
+
* A map that stores the tagging index for a given extended directional app tagging secret.
|
|
5
5
|
* Note: The directional app tagging secret is unique for a (sender, recipient, contract) tuple while the direction
|
|
6
6
|
* of sender -> recipient matters.
|
|
7
7
|
*/
|
|
8
8
|
export class ExecutionTaggingIndexCache {
|
|
9
9
|
private taggingIndexMap: Map<string, number> = new Map();
|
|
10
10
|
|
|
11
|
-
public getLastUsedIndex(secret:
|
|
11
|
+
public getLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret): number | undefined {
|
|
12
12
|
return this.taggingIndexMap.get(secret.toString());
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
public setLastUsedIndex(secret:
|
|
15
|
+
public setLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number) {
|
|
16
16
|
const currentValue = this.taggingIndexMap.get(secret.toString());
|
|
17
17
|
if (currentValue !== undefined && currentValue !== index - 1) {
|
|
18
18
|
throw new Error(`Invalid tagging index update. Current value: ${currentValue}, new value: ${index}`);
|
|
@@ -25,7 +25,7 @@ export class ExecutionTaggingIndexCache {
|
|
|
25
25
|
*/
|
|
26
26
|
public getUsedPreTags(): PreTag[] {
|
|
27
27
|
return Array.from(this.taggingIndexMap.entries()).map(([secret, index]) => ({
|
|
28
|
-
|
|
28
|
+
extendedSecret: ExtendedDirectionalAppTaggingSecret.fromString(secret),
|
|
29
29
|
index,
|
|
30
30
|
}));
|
|
31
31
|
}
|
|
@@ -5,7 +5,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
5
5
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
6
6
|
|
|
7
7
|
// TODO(#14617): should we compute this from constants? This value is aztec-nr specific.
|
|
8
|
-
const MAX_EVENT_SERIALIZED_LEN =
|
|
8
|
+
const MAX_EVENT_SERIALIZED_LEN = 10;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Intermediate struct used to perform batch event validation by PXE. The `utilityValidateAndStoreEnqueuedNotesAndEvents` oracle
|
|
@@ -4,7 +4,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
4
4
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
6
|
// TODO(#14617): should we compute this from constants? This value is aztec-nr specific.
|
|
7
|
-
export const MAX_NOTE_PACKED_LEN =
|
|
7
|
+
export const MAX_NOTE_PACKED_LEN = 8;
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Intermediate struct used to perform batch note validation by PXE. The `utilityValidateAndStoreEnqueuedNotesAndEvents` oracle
|
|
@@ -6,8 +6,9 @@ import { MembershipWitness } from '@aztec/foundation/trees';
|
|
|
6
6
|
import type { FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
7
7
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
8
|
import { BlockHash } from '@aztec/stdlib/block';
|
|
9
|
-
import type {
|
|
9
|
+
import type { ContractInstance, PartialAddress } from '@aztec/stdlib/contract';
|
|
10
10
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
11
|
+
import type { PublicKeys } from '@aztec/stdlib/keys';
|
|
11
12
|
import type { ContractClassLog, Tag } from '@aztec/stdlib/logs';
|
|
12
13
|
import type { Note, NoteStatus } from '@aztec/stdlib/note';
|
|
13
14
|
import { type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
@@ -54,7 +55,7 @@ export interface IMiscOracle {
|
|
|
54
55
|
|
|
55
56
|
utilityGetRandomField(): Fr;
|
|
56
57
|
utilityAssertCompatibleOracleVersion(version: number): void;
|
|
57
|
-
|
|
58
|
+
utilityLog(level: number, message: string, fields: Fr[]): Promise<void>;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
/**
|
|
@@ -85,7 +86,9 @@ export interface IUtilityExecutionOracle {
|
|
|
85
86
|
nullifier: Fr,
|
|
86
87
|
): Promise<NullifierMembershipWitness | undefined>;
|
|
87
88
|
utilityGetBlockHeader(blockNumber: BlockNumber): Promise<BlockHeader | undefined>;
|
|
88
|
-
utilityTryGetPublicKeysAndPartialAddress(
|
|
89
|
+
utilityTryGetPublicKeysAndPartialAddress(
|
|
90
|
+
account: AztecAddress,
|
|
91
|
+
): Promise<{ publicKeys: PublicKeys; partialAddress: PartialAddress } | undefined>;
|
|
89
92
|
utilityGetAuthWitness(messageHash: Fr): Promise<Fr[] | undefined>;
|
|
90
93
|
utilityGetNotes(
|
|
91
94
|
owner: AztecAddress | undefined,
|
|
@@ -417,7 +417,7 @@ export class Oracle {
|
|
|
417
417
|
return Promise.resolve([]);
|
|
418
418
|
}
|
|
419
419
|
|
|
420
|
-
async
|
|
420
|
+
async utilityLog(
|
|
421
421
|
level: ACVMField[],
|
|
422
422
|
message: ACVMField[],
|
|
423
423
|
_ignoredFieldsSize: ACVMField[],
|
|
@@ -426,7 +426,7 @@ export class Oracle {
|
|
|
426
426
|
const levelFr = Fr.fromString(level[0]);
|
|
427
427
|
const messageStr = message.map(acvmField => String.fromCharCode(Fr.fromString(acvmField).toNumber())).join('');
|
|
428
428
|
const fieldsFr = fields.map(Fr.fromString);
|
|
429
|
-
await this.handlerAsMisc().
|
|
429
|
+
await this.handlerAsMisc().utilityLog(levelFr.toNumber(), messageStr, fieldsFr);
|
|
430
430
|
return [];
|
|
431
431
|
}
|
|
432
432
|
|
|
@@ -2,7 +2,6 @@ import { MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS, PRIVATE_CONTEXT_INPUTS_LENGTH }
|
|
|
2
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { Timer } from '@aztec/foundation/timer';
|
|
5
|
-
import type { KeyStore } from '@aztec/key-store';
|
|
6
5
|
import { type CircuitSimulator, toACVMWitness } from '@aztec/simulator/client';
|
|
7
6
|
import {
|
|
8
7
|
type FunctionAbi,
|
|
@@ -12,33 +11,23 @@ import {
|
|
|
12
11
|
type NoteSelector,
|
|
13
12
|
countArgumentsSize,
|
|
14
13
|
} from '@aztec/stdlib/abi';
|
|
15
|
-
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
16
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
17
15
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
18
|
-
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
19
16
|
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
20
|
-
import { type ContractClassLog,
|
|
17
|
+
import { type ContractClassLog, ExtendedDirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs';
|
|
21
18
|
import { Tag } from '@aztec/stdlib/logs';
|
|
22
19
|
import { Note, type NoteStatus } from '@aztec/stdlib/note';
|
|
23
20
|
import {
|
|
24
|
-
type BlockHeader,
|
|
25
21
|
CallContext,
|
|
26
|
-
Capsule,
|
|
27
22
|
CountedContractClassLog,
|
|
28
23
|
NoteAndSlot,
|
|
29
24
|
PrivateCallExecutionResult,
|
|
30
25
|
type TxContext,
|
|
31
26
|
} from '@aztec/stdlib/tx';
|
|
32
27
|
|
|
28
|
+
import type { AccessScopes } from '../../access_scopes.js';
|
|
33
29
|
import type { ContractSyncService } from '../../contract_sync/contract_sync_service.js';
|
|
34
30
|
import { NoteService } from '../../notes/note_service.js';
|
|
35
|
-
import type { AddressStore } from '../../storage/address_store/address_store.js';
|
|
36
|
-
import type { CapsuleStore } from '../../storage/capsule_store/capsule_store.js';
|
|
37
|
-
import type { ContractStore } from '../../storage/contract_store/contract_store.js';
|
|
38
|
-
import type { NoteStore } from '../../storage/note_store/note_store.js';
|
|
39
|
-
import type { PrivateEventStore } from '../../storage/private_event_store/private_event_store.js';
|
|
40
|
-
import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
|
|
41
|
-
import type { SenderAddressBookStore } from '../../storage/tagging_store/sender_address_book_store.js';
|
|
42
31
|
import type { SenderTaggingStore } from '../../storage/tagging_store/sender_tagging_store.js';
|
|
43
32
|
import { syncSenderTaggingIndexes } from '../../tagging/index.js';
|
|
44
33
|
import type { ExecutionNoteCache } from '../execution_note_cache.js';
|
|
@@ -47,7 +36,25 @@ import type { HashedValuesCache } from '../hashed_values_cache.js';
|
|
|
47
36
|
import { pickNotes } from '../pick_notes.js';
|
|
48
37
|
import type { IPrivateExecutionOracle, NoteData } from './interfaces.js';
|
|
49
38
|
import { executePrivateFunction } from './private_execution.js';
|
|
50
|
-
import { UtilityExecutionOracle } from './utility_execution_oracle.js';
|
|
39
|
+
import { UtilityExecutionOracle, type UtilityExecutionOracleArgs } from './utility_execution_oracle.js';
|
|
40
|
+
|
|
41
|
+
/** Args for PrivateExecutionOracle constructor. */
|
|
42
|
+
export type PrivateExecutionOracleArgs = Omit<UtilityExecutionOracleArgs, 'contractAddress'> & {
|
|
43
|
+
argsHash: Fr;
|
|
44
|
+
txContext: TxContext;
|
|
45
|
+
callContext: CallContext;
|
|
46
|
+
/** Needed to trigger contract synchronization before nested calls */
|
|
47
|
+
utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<void>;
|
|
48
|
+
executionCache: HashedValuesCache;
|
|
49
|
+
noteCache: ExecutionNoteCache;
|
|
50
|
+
taggingIndexCache: ExecutionTaggingIndexCache;
|
|
51
|
+
senderTaggingStore: SenderTaggingStore;
|
|
52
|
+
contractSyncService: ContractSyncService;
|
|
53
|
+
totalPublicCalldataCount?: number;
|
|
54
|
+
sideEffectCounter?: number;
|
|
55
|
+
senderForTags?: AztecAddress;
|
|
56
|
+
simulator?: CircuitSimulator;
|
|
57
|
+
};
|
|
51
58
|
|
|
52
59
|
/**
|
|
53
60
|
* The execution oracle for the private part of a transaction.
|
|
@@ -69,57 +76,39 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
69
76
|
private offchainEffects: { data: Fr[] }[] = [];
|
|
70
77
|
private nestedExecutionResults: PrivateCallExecutionResult[] = [];
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
super(
|
|
106
|
-
callContext.contractAddress,
|
|
107
|
-
authWitnesses,
|
|
108
|
-
capsules,
|
|
109
|
-
anchorBlockHeader,
|
|
110
|
-
contractStore,
|
|
111
|
-
noteStore,
|
|
112
|
-
keyStore,
|
|
113
|
-
addressStore,
|
|
114
|
-
aztecNode,
|
|
115
|
-
recipientTaggingStore,
|
|
116
|
-
senderAddressBookStore,
|
|
117
|
-
capsuleStore,
|
|
118
|
-
privateEventStore,
|
|
119
|
-
jobId,
|
|
120
|
-
log,
|
|
121
|
-
scopes,
|
|
122
|
-
);
|
|
79
|
+
private readonly argsHash: Fr;
|
|
80
|
+
private readonly txContext: TxContext;
|
|
81
|
+
private readonly callContext: CallContext;
|
|
82
|
+
private readonly utilityExecutor: (call: FunctionCall, scopes: AccessScopes) => Promise<void>;
|
|
83
|
+
private readonly executionCache: HashedValuesCache;
|
|
84
|
+
private readonly noteCache: ExecutionNoteCache;
|
|
85
|
+
private readonly taggingIndexCache: ExecutionTaggingIndexCache;
|
|
86
|
+
private readonly senderTaggingStore: SenderTaggingStore;
|
|
87
|
+
private readonly contractSyncService: ContractSyncService;
|
|
88
|
+
private totalPublicCalldataCount: number;
|
|
89
|
+
protected sideEffectCounter: number;
|
|
90
|
+
private senderForTags?: AztecAddress;
|
|
91
|
+
private readonly simulator?: CircuitSimulator;
|
|
92
|
+
|
|
93
|
+
constructor(args: PrivateExecutionOracleArgs) {
|
|
94
|
+
super({
|
|
95
|
+
...args,
|
|
96
|
+
contractAddress: args.callContext.contractAddress,
|
|
97
|
+
log: args.log ?? createLogger('simulator:client_execution_context'),
|
|
98
|
+
});
|
|
99
|
+
this.argsHash = args.argsHash;
|
|
100
|
+
this.txContext = args.txContext;
|
|
101
|
+
this.callContext = args.callContext;
|
|
102
|
+
this.utilityExecutor = args.utilityExecutor;
|
|
103
|
+
this.executionCache = args.executionCache;
|
|
104
|
+
this.noteCache = args.noteCache;
|
|
105
|
+
this.taggingIndexCache = args.taggingIndexCache;
|
|
106
|
+
this.senderTaggingStore = args.senderTaggingStore;
|
|
107
|
+
this.contractSyncService = args.contractSyncService;
|
|
108
|
+
this.totalPublicCalldataCount = args.totalPublicCalldataCount ?? 0;
|
|
109
|
+
this.sideEffectCounter = args.sideEffectCounter ?? 0;
|
|
110
|
+
this.senderForTags = args.senderForTags;
|
|
111
|
+
this.simulator = args.simulator;
|
|
123
112
|
}
|
|
124
113
|
|
|
125
114
|
public getPrivateContextInputs(): PrivateContextInputs {
|
|
@@ -227,25 +216,29 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
227
216
|
* @returns An app tag to be used in a log.
|
|
228
217
|
*/
|
|
229
218
|
public async privateGetNextAppTagAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<Tag> {
|
|
230
|
-
const
|
|
219
|
+
const extendedSecret = await this.#calculateExtendedDirectionalAppTaggingSecret(
|
|
220
|
+
this.contractAddress,
|
|
221
|
+
sender,
|
|
222
|
+
recipient,
|
|
223
|
+
);
|
|
231
224
|
|
|
232
|
-
const index = await this.#getIndexToUseForSecret(
|
|
225
|
+
const index = await this.#getIndexToUseForSecret(extendedSecret);
|
|
233
226
|
this.log.debug(
|
|
234
227
|
`Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${index}`,
|
|
235
228
|
);
|
|
236
|
-
this.taggingIndexCache.setLastUsedIndex(
|
|
229
|
+
this.taggingIndexCache.setLastUsedIndex(extendedSecret, index);
|
|
237
230
|
|
|
238
|
-
return Tag.compute({
|
|
231
|
+
return Tag.compute({ extendedSecret, index });
|
|
239
232
|
}
|
|
240
233
|
|
|
241
|
-
async #
|
|
234
|
+
async #calculateExtendedDirectionalAppTaggingSecret(
|
|
242
235
|
contractAddress: AztecAddress,
|
|
243
236
|
sender: AztecAddress,
|
|
244
237
|
recipient: AztecAddress,
|
|
245
238
|
) {
|
|
246
239
|
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
|
|
247
240
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
248
|
-
return
|
|
241
|
+
return ExtendedDirectionalAppTaggingSecret.compute(
|
|
249
242
|
senderCompleteAddress,
|
|
250
243
|
senderIvsk,
|
|
251
244
|
recipient,
|
|
@@ -254,7 +247,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
254
247
|
);
|
|
255
248
|
}
|
|
256
249
|
|
|
257
|
-
async #getIndexToUseForSecret(secret:
|
|
250
|
+
async #getIndexToUseForSecret(secret: ExtendedDirectionalAppTaggingSecret): Promise<number> {
|
|
258
251
|
// If we have the tagging index in the cache, we use it. If not we obtain it from the execution data provider.
|
|
259
252
|
const lastUsedIndexInTx = this.taggingIndexCache.getLastUsedIndex(secret);
|
|
260
253
|
|
|
@@ -266,7 +259,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
266
259
|
// that'd be wasteful as most tagging secrets are not used in each tx.
|
|
267
260
|
await syncSenderTaggingIndexes(
|
|
268
261
|
secret,
|
|
269
|
-
this.contractAddress,
|
|
270
262
|
this.aztecNode,
|
|
271
263
|
this.senderTaggingStore,
|
|
272
264
|
await this.anchorBlockHeader.hash(),
|
|
@@ -538,12 +530,22 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
538
530
|
|
|
539
531
|
isStaticCall = isStaticCall || this.callContext.isStaticCall;
|
|
540
532
|
|
|
533
|
+
// When scopes are set and the target contract is a registered account (has keys in the keyStore),
|
|
534
|
+
// expand scopes to include it so nested private calls can sync and read the contract's own notes.
|
|
535
|
+
// We only expand for registered accounts because the log service needs the recipient's keys to derive
|
|
536
|
+
// tagging secrets, which are only available for registered accounts.
|
|
537
|
+
const expandedScopes =
|
|
538
|
+
this.scopes !== 'ALL_SCOPES' && (await this.keyStore.hasAccount(targetContractAddress))
|
|
539
|
+
? [...this.scopes, targetContractAddress]
|
|
540
|
+
: this.scopes;
|
|
541
|
+
|
|
541
542
|
await this.contractSyncService.ensureContractSynced(
|
|
542
543
|
targetContractAddress,
|
|
543
544
|
functionSelector,
|
|
544
545
|
this.utilityExecutor,
|
|
545
546
|
this.anchorBlockHeader,
|
|
546
547
|
this.jobId,
|
|
548
|
+
expandedScopes,
|
|
547
549
|
);
|
|
548
550
|
|
|
549
551
|
const targetArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(
|
|
@@ -555,41 +557,41 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
555
557
|
|
|
556
558
|
const derivedCallContext = await this.deriveCallContext(targetContractAddress, targetArtifact, isStaticCall);
|
|
557
559
|
|
|
558
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
560
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
559
561
|
argsHash,
|
|
560
|
-
derivedTxContext,
|
|
561
|
-
derivedCallContext,
|
|
562
|
-
this.anchorBlockHeader,
|
|
563
|
-
this.utilityExecutor,
|
|
564
|
-
this.authWitnesses,
|
|
565
|
-
this.capsules,
|
|
566
|
-
this.executionCache,
|
|
567
|
-
this.noteCache,
|
|
568
|
-
this.taggingIndexCache,
|
|
569
|
-
this.contractStore,
|
|
570
|
-
this.noteStore,
|
|
571
|
-
this.keyStore,
|
|
572
|
-
this.addressStore,
|
|
573
|
-
this.aztecNode,
|
|
574
|
-
this.senderTaggingStore,
|
|
575
|
-
this.recipientTaggingStore,
|
|
576
|
-
this.senderAddressBookStore,
|
|
577
|
-
this.capsuleStore,
|
|
578
|
-
this.privateEventStore,
|
|
579
|
-
this.contractSyncService,
|
|
580
|
-
this.jobId,
|
|
581
|
-
this.totalPublicCalldataCount,
|
|
562
|
+
txContext: derivedTxContext,
|
|
563
|
+
callContext: derivedCallContext,
|
|
564
|
+
anchorBlockHeader: this.anchorBlockHeader,
|
|
565
|
+
utilityExecutor: this.utilityExecutor,
|
|
566
|
+
authWitnesses: this.authWitnesses,
|
|
567
|
+
capsules: this.capsules,
|
|
568
|
+
executionCache: this.executionCache,
|
|
569
|
+
noteCache: this.noteCache,
|
|
570
|
+
taggingIndexCache: this.taggingIndexCache,
|
|
571
|
+
contractStore: this.contractStore,
|
|
572
|
+
noteStore: this.noteStore,
|
|
573
|
+
keyStore: this.keyStore,
|
|
574
|
+
addressStore: this.addressStore,
|
|
575
|
+
aztecNode: this.aztecNode,
|
|
576
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
577
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
578
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
579
|
+
capsuleStore: this.capsuleStore,
|
|
580
|
+
privateEventStore: this.privateEventStore,
|
|
581
|
+
contractSyncService: this.contractSyncService,
|
|
582
|
+
jobId: this.jobId,
|
|
583
|
+
totalPublicCalldataCount: this.totalPublicCalldataCount,
|
|
582
584
|
sideEffectCounter,
|
|
583
|
-
this.log,
|
|
584
|
-
|
|
585
|
-
this.senderForTags,
|
|
586
|
-
this.simulator
|
|
587
|
-
);
|
|
585
|
+
log: this.log,
|
|
586
|
+
scopes: expandedScopes,
|
|
587
|
+
senderForTags: this.senderForTags,
|
|
588
|
+
simulator: this.simulator!,
|
|
589
|
+
});
|
|
588
590
|
|
|
589
591
|
const setupTime = simulatorSetupTimer.ms();
|
|
590
592
|
|
|
591
593
|
const childExecutionResult = await executePrivateFunction(
|
|
592
|
-
this.simulator
|
|
594
|
+
this.simulator!,
|
|
593
595
|
privateExecutionOracle,
|
|
594
596
|
targetArtifact,
|
|
595
597
|
targetContractAddress,
|
|
@@ -3,23 +3,25 @@ import type { BlockNumber } from '@aztec/foundation/branded-types';
|
|
|
3
3
|
import { Aes128 } from '@aztec/foundation/crypto/aes128';
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { Point } from '@aztec/foundation/curves/grumpkin';
|
|
6
|
-
import { LogLevels, type Logger,
|
|
6
|
+
import { LogLevels, type Logger, createLogger } from '@aztec/foundation/log';
|
|
7
7
|
import type { MembershipWitness } from '@aztec/foundation/trees';
|
|
8
8
|
import type { KeyStore } from '@aztec/key-store';
|
|
9
9
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
10
10
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
11
11
|
import { BlockHash } from '@aztec/stdlib/block';
|
|
12
|
-
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
12
|
+
import type { CompleteAddress, ContractInstance, PartialAddress } from '@aztec/stdlib/contract';
|
|
13
13
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
14
14
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
15
15
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
16
|
-
import { computeAddressSecret } from '@aztec/stdlib/keys';
|
|
16
|
+
import { type PublicKeys, computeAddressSecret } from '@aztec/stdlib/keys';
|
|
17
17
|
import { deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
|
|
18
18
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
19
19
|
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
20
20
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
21
21
|
import type { BlockHeader, Capsule } from '@aztec/stdlib/tx';
|
|
22
22
|
|
|
23
|
+
import type { AccessScopes } from '../../access_scopes.js';
|
|
24
|
+
import { createContractLogger, logContractMessage } from '../../contract_logging.js';
|
|
23
25
|
import { EventService } from '../../events/event_service.js';
|
|
24
26
|
import { LogService } from '../../logs/log_service.js';
|
|
25
27
|
import { NoteService } from '../../notes/note_service.js';
|
|
@@ -40,6 +42,27 @@ import { pickNotes } from '../pick_notes.js';
|
|
|
40
42
|
import type { IMiscOracle, IUtilityExecutionOracle, NoteData } from './interfaces.js';
|
|
41
43
|
import { MessageLoadOracleInputs } from './message_load_oracle_inputs.js';
|
|
42
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
|
+
|
|
43
66
|
/**
|
|
44
67
|
* The oracle for an execution of utility contract functions.
|
|
45
68
|
*/
|
|
@@ -49,25 +72,41 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
49
72
|
|
|
50
73
|
private contractLogger: Logger | undefined;
|
|
51
74
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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) {
|
|
@@ -91,11 +130,16 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
91
130
|
* @throws If scopes are defined and the account is not in the scopes.
|
|
92
131
|
*/
|
|
93
132
|
public async utilityGetKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
94
|
-
// If scopes are defined, check that the key belongs to an account in the scopes
|
|
95
|
-
if (this.scopes && this.scopes.length > 0) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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()}.`);
|
|
99
143
|
}
|
|
100
144
|
}
|
|
101
145
|
return this.keyStore.getKeyValidationRequest(pkMHash, this.contractAddress);
|
|
@@ -188,12 +232,18 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
188
232
|
}
|
|
189
233
|
|
|
190
234
|
/**
|
|
191
|
-
* Retrieve the
|
|
235
|
+
* Retrieve the public keys and partial address associated to a given address.
|
|
192
236
|
* @param account - The account address.
|
|
193
|
-
* @returns
|
|
237
|
+
* @returns The public keys and partial address, or `undefined` if the account is not registered.
|
|
194
238
|
*/
|
|
195
|
-
public utilityTryGetPublicKeysAndPartialAddress(
|
|
196
|
-
|
|
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 };
|
|
197
247
|
}
|
|
198
248
|
|
|
199
249
|
protected async getCompleteAddressOrFail(account: AztecAddress): Promise<CompleteAddress> {
|
|
@@ -359,23 +409,23 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
359
409
|
*/
|
|
360
410
|
async #getContractLogger(): Promise<Logger> {
|
|
361
411
|
if (!this.contractLogger) {
|
|
362
|
-
const addrAbbrev = this.contractAddress.toString().slice(0, 10);
|
|
363
|
-
const name = await this.contractStore.getDebugContractName(this.contractAddress);
|
|
364
|
-
const module = name ? `contract_log::${name}(${addrAbbrev})` : `contract_log::${addrAbbrev}`;
|
|
365
412
|
// Purpose of instanceId is to distinguish logs from different instances of the same component. It makes sense
|
|
366
413
|
// to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
|
|
367
|
-
this.contractLogger =
|
|
414
|
+
this.contractLogger = await createContractLogger(
|
|
415
|
+
this.contractAddress,
|
|
416
|
+
addr => this.contractStore.getDebugContractName(addr),
|
|
417
|
+
{ instanceId: this.jobId },
|
|
418
|
+
);
|
|
368
419
|
}
|
|
369
420
|
return this.contractLogger;
|
|
370
421
|
}
|
|
371
422
|
|
|
372
|
-
public async
|
|
423
|
+
public async utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
373
424
|
if (!LogLevels[level]) {
|
|
374
|
-
throw new Error(`Invalid
|
|
425
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
375
426
|
}
|
|
376
|
-
const levelName = LogLevels[level];
|
|
377
427
|
const logger = await this.#getContractLogger();
|
|
378
|
-
logger[
|
|
428
|
+
logContractMessage(logger, LogLevels[level], message, fields);
|
|
379
429
|
}
|
|
380
430
|
|
|
381
431
|
public async utilityFetchTaggedLogs(pendingTaggedLogArrayBaseSlot: Fr) {
|
|
@@ -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
|
+
}
|