@aztec/pxe 4.0.0-rc.6 → 4.0.0-rc.8
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/contract_function_simulator/contract_function_simulator.js +1 -1
- 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/oracle/private_execution_oracle.d.ts +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +8 -8
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +4 -7
- 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/debug/pxe_debug_utils.d.ts +2 -2
- 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 +2 -1
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +1 -0
- package/dest/entrypoints/client/lazy/index.d.ts +2 -1
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +1 -0
- package/dest/logs/log_service.d.ts +1 -1
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +4 -4
- package/dest/pxe.d.ts +6 -6
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +17 -13
- 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/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 +3 -3
- 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/contract_function_simulator/contract_function_simulator.ts +1 -1
- package/src/contract_function_simulator/execution_tagging_index_cache.ts +5 -5
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +12 -9
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +8 -7
- package/src/contract_logging.ts +39 -0
- package/src/debug/pxe_debug_utils.ts +4 -4
- package/src/entrypoints/client/bundle/index.ts +1 -0
- package/src/entrypoints/client/lazy/index.ts +1 -0
- package/src/logs/log_service.ts +10 -5
- package/src/pxe.ts +22 -18
- 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/index.ts +1 -1
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +3 -6
- 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"typedocOptions": {
|
|
6
6
|
"entryPoints": [
|
|
@@ -70,19 +70,19 @@
|
|
|
70
70
|
]
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@aztec/bb-prover": "4.0.0-rc.
|
|
74
|
-
"@aztec/bb.js": "4.0.0-rc.
|
|
75
|
-
"@aztec/builder": "4.0.0-rc.
|
|
76
|
-
"@aztec/constants": "4.0.0-rc.
|
|
77
|
-
"@aztec/ethereum": "4.0.0-rc.
|
|
78
|
-
"@aztec/foundation": "4.0.0-rc.
|
|
79
|
-
"@aztec/key-store": "4.0.0-rc.
|
|
80
|
-
"@aztec/kv-store": "4.0.0-rc.
|
|
81
|
-
"@aztec/noir-protocol-circuits-types": "4.0.0-rc.
|
|
82
|
-
"@aztec/noir-types": "4.0.0-rc.
|
|
83
|
-
"@aztec/protocol-contracts": "4.0.0-rc.
|
|
84
|
-
"@aztec/simulator": "4.0.0-rc.
|
|
85
|
-
"@aztec/stdlib": "4.0.0-rc.
|
|
73
|
+
"@aztec/bb-prover": "4.0.0-rc.8",
|
|
74
|
+
"@aztec/bb.js": "4.0.0-rc.8",
|
|
75
|
+
"@aztec/builder": "4.0.0-rc.8",
|
|
76
|
+
"@aztec/constants": "4.0.0-rc.8",
|
|
77
|
+
"@aztec/ethereum": "4.0.0-rc.8",
|
|
78
|
+
"@aztec/foundation": "4.0.0-rc.8",
|
|
79
|
+
"@aztec/key-store": "4.0.0-rc.8",
|
|
80
|
+
"@aztec/kv-store": "4.0.0-rc.8",
|
|
81
|
+
"@aztec/noir-protocol-circuits-types": "4.0.0-rc.8",
|
|
82
|
+
"@aztec/noir-types": "4.0.0-rc.8",
|
|
83
|
+
"@aztec/protocol-contracts": "4.0.0-rc.8",
|
|
84
|
+
"@aztec/simulator": "4.0.0-rc.8",
|
|
85
|
+
"@aztec/stdlib": "4.0.0-rc.8",
|
|
86
86
|
"koa": "^2.16.1",
|
|
87
87
|
"koa-router": "^13.1.1",
|
|
88
88
|
"lodash.omit": "^4.5.0",
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@aztec/merkle-tree": "4.0.0-rc.
|
|
95
|
-
"@aztec/noir-test-contracts.js": "4.0.0-rc.
|
|
94
|
+
"@aztec/merkle-tree": "4.0.0-rc.8",
|
|
95
|
+
"@aztec/noir-test-contracts.js": "4.0.0-rc.8",
|
|
96
96
|
"@jest/globals": "^30.0.0",
|
|
97
97
|
"@types/jest": "^30.0.0",
|
|
98
98
|
"@types/lodash.omit": "^4.5.7",
|
|
@@ -361,7 +361,7 @@ export class ContractFunctionSimulator {
|
|
|
361
361
|
);
|
|
362
362
|
});
|
|
363
363
|
|
|
364
|
-
this.log.verbose(`Utility
|
|
364
|
+
this.log.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
365
365
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
366
366
|
} catch (err) {
|
|
367
367
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
@@ -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
|
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
15
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
16
16
|
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
17
|
-
import { type ContractClassLog,
|
|
17
|
+
import { type ContractClassLog, ExtendedDirectionalAppTaggingSecret, type PreTag } from '@aztec/stdlib/logs';
|
|
18
18
|
import { Tag } from '@aztec/stdlib/logs';
|
|
19
19
|
import { Note, type NoteStatus } from '@aztec/stdlib/note';
|
|
20
20
|
import {
|
|
@@ -216,25 +216,29 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
216
216
|
* @returns An app tag to be used in a log.
|
|
217
217
|
*/
|
|
218
218
|
public async privateGetNextAppTagAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<Tag> {
|
|
219
|
-
const
|
|
219
|
+
const extendedSecret = await this.#calculateExtendedDirectionalAppTaggingSecret(
|
|
220
|
+
this.contractAddress,
|
|
221
|
+
sender,
|
|
222
|
+
recipient,
|
|
223
|
+
);
|
|
220
224
|
|
|
221
|
-
const index = await this.#getIndexToUseForSecret(
|
|
225
|
+
const index = await this.#getIndexToUseForSecret(extendedSecret);
|
|
222
226
|
this.log.debug(
|
|
223
227
|
`Incrementing tagging index for sender: ${sender}, recipient: ${recipient}, contract: ${this.contractAddress} to ${index}`,
|
|
224
228
|
);
|
|
225
|
-
this.taggingIndexCache.setLastUsedIndex(
|
|
229
|
+
this.taggingIndexCache.setLastUsedIndex(extendedSecret, index);
|
|
226
230
|
|
|
227
|
-
return Tag.compute({
|
|
231
|
+
return Tag.compute({ extendedSecret, index });
|
|
228
232
|
}
|
|
229
233
|
|
|
230
|
-
async #
|
|
234
|
+
async #calculateExtendedDirectionalAppTaggingSecret(
|
|
231
235
|
contractAddress: AztecAddress,
|
|
232
236
|
sender: AztecAddress,
|
|
233
237
|
recipient: AztecAddress,
|
|
234
238
|
) {
|
|
235
239
|
const senderCompleteAddress = await this.getCompleteAddressOrFail(sender);
|
|
236
240
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
237
|
-
return
|
|
241
|
+
return ExtendedDirectionalAppTaggingSecret.compute(
|
|
238
242
|
senderCompleteAddress,
|
|
239
243
|
senderIvsk,
|
|
240
244
|
recipient,
|
|
@@ -243,7 +247,7 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
243
247
|
);
|
|
244
248
|
}
|
|
245
249
|
|
|
246
|
-
async #getIndexToUseForSecret(secret:
|
|
250
|
+
async #getIndexToUseForSecret(secret: ExtendedDirectionalAppTaggingSecret): Promise<number> {
|
|
247
251
|
// If we have the tagging index in the cache, we use it. If not we obtain it from the execution data provider.
|
|
248
252
|
const lastUsedIndexInTx = this.taggingIndexCache.getLastUsedIndex(secret);
|
|
249
253
|
|
|
@@ -255,7 +259,6 @@ export class PrivateExecutionOracle extends UtilityExecutionOracle implements IP
|
|
|
255
259
|
// that'd be wasteful as most tagging secrets are not used in each tx.
|
|
256
260
|
await syncSenderTaggingIndexes(
|
|
257
261
|
secret,
|
|
258
|
-
this.contractAddress,
|
|
259
262
|
this.aztecNode,
|
|
260
263
|
this.senderTaggingStore,
|
|
261
264
|
await this.anchorBlockHeader.hash(),
|
|
@@ -3,7 +3,7 @@ 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';
|
|
@@ -21,6 +21,7 @@ import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from
|
|
|
21
21
|
import type { BlockHeader, Capsule } from '@aztec/stdlib/tx';
|
|
22
22
|
|
|
23
23
|
import type { AccessScopes } from '../../access_scopes.js';
|
|
24
|
+
import { createContractLogger, logContractMessage } from '../../contract_logging.js';
|
|
24
25
|
import { EventService } from '../../events/event_service.js';
|
|
25
26
|
import { LogService } from '../../logs/log_service.js';
|
|
26
27
|
import { NoteService } from '../../notes/note_service.js';
|
|
@@ -402,12 +403,13 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
402
403
|
*/
|
|
403
404
|
async #getContractLogger(): Promise<Logger> {
|
|
404
405
|
if (!this.contractLogger) {
|
|
405
|
-
const addrAbbrev = this.contractAddress.toString().slice(0, 10);
|
|
406
|
-
const name = await this.contractStore.getDebugContractName(this.contractAddress);
|
|
407
|
-
const module = name ? `contract_log::${name}(${addrAbbrev})` : `contract_log::${addrAbbrev}`;
|
|
408
406
|
// Purpose of instanceId is to distinguish logs from different instances of the same component. It makes sense
|
|
409
407
|
// to re-use jobId as instanceId here as executions of different PXE jobs are isolated.
|
|
410
|
-
this.contractLogger =
|
|
408
|
+
this.contractLogger = await createContractLogger(
|
|
409
|
+
this.contractAddress,
|
|
410
|
+
addr => this.contractStore.getDebugContractName(addr),
|
|
411
|
+
{ instanceId: this.jobId },
|
|
412
|
+
);
|
|
411
413
|
}
|
|
412
414
|
return this.contractLogger;
|
|
413
415
|
}
|
|
@@ -416,9 +418,8 @@ export class UtilityExecutionOracle implements IMiscOracle, IUtilityExecutionOra
|
|
|
416
418
|
if (!LogLevels[level]) {
|
|
417
419
|
throw new Error(`Invalid log level: ${level}`);
|
|
418
420
|
}
|
|
419
|
-
const levelName = LogLevels[level];
|
|
420
421
|
const logger = await this.#getContractLogger();
|
|
421
|
-
logger[
|
|
422
|
+
logContractMessage(logger, LogLevels[level], message, fields);
|
|
422
423
|
}
|
|
423
424
|
|
|
424
425
|
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
|
+
}
|
|
@@ -18,7 +18,7 @@ import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
|
18
18
|
export class PXEDebugUtils {
|
|
19
19
|
#putJobInQueue!: <T>(job: (jobId: string) => Promise<T>) => Promise<T>;
|
|
20
20
|
#getSimulatorForTx!: (overrides?: { contracts?: ContractOverrides }) => ContractFunctionSimulator;
|
|
21
|
-
#
|
|
21
|
+
#executeUtility!: (
|
|
22
22
|
contractFunctionSimulator: ContractFunctionSimulator,
|
|
23
23
|
call: FunctionCall,
|
|
24
24
|
authWitnesses: AuthWitness[] | undefined,
|
|
@@ -37,7 +37,7 @@ export class PXEDebugUtils {
|
|
|
37
37
|
public setPXEHelpers(
|
|
38
38
|
putJobInQueue: <T>(job: (jobId: string) => Promise<T>) => Promise<T>,
|
|
39
39
|
getSimulatorForTx: (overrides?: { contracts?: ContractOverrides }) => ContractFunctionSimulator,
|
|
40
|
-
|
|
40
|
+
executeUtility: (
|
|
41
41
|
contractFunctionSimulator: ContractFunctionSimulator,
|
|
42
42
|
call: FunctionCall,
|
|
43
43
|
authWitnesses: AuthWitness[] | undefined,
|
|
@@ -47,7 +47,7 @@ export class PXEDebugUtils {
|
|
|
47
47
|
) {
|
|
48
48
|
this.#putJobInQueue = putJobInQueue;
|
|
49
49
|
this.#getSimulatorForTx = getSimulatorForTx;
|
|
50
|
-
this.#
|
|
50
|
+
this.#executeUtility = executeUtility;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
@@ -73,7 +73,7 @@ export class PXEDebugUtils {
|
|
|
73
73
|
filter.contractAddress,
|
|
74
74
|
null,
|
|
75
75
|
async (privateSyncCall, execScopes) =>
|
|
76
|
-
await this.#
|
|
76
|
+
await this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
|
|
77
77
|
anchorBlockHeader,
|
|
78
78
|
jobId,
|
|
79
79
|
filter.scopes,
|
|
@@ -3,6 +3,7 @@ export * from '../../../notes_filter.js';
|
|
|
3
3
|
export * from '../../../pxe.js';
|
|
4
4
|
export * from '../../../config/index.js';
|
|
5
5
|
export * from '../../../error_enriching.js';
|
|
6
|
+
export * from '../../../contract_logging.js';
|
|
6
7
|
export * from '../../../storage/index.js';
|
|
7
8
|
export * from './utils.js';
|
|
8
9
|
export type { PXECreationOptions } from '../../pxe_creation_options.js';
|
|
@@ -4,5 +4,6 @@ export * from '../../../pxe.js';
|
|
|
4
4
|
export * from '../../../config/index.js';
|
|
5
5
|
export * from '../../../storage/index.js';
|
|
6
6
|
export * from '../../../error_enriching.js';
|
|
7
|
+
export * from '../../../contract_logging.js';
|
|
7
8
|
export * from './utils.js';
|
|
8
9
|
export { type PXECreationOptions } from '../../pxe_creation_options.js';
|
package/src/logs/log_service.ts
CHANGED
|
@@ -3,7 +3,13 @@ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundatio
|
|
|
3
3
|
import type { KeyStore } from '@aztec/key-store';
|
|
4
4
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
5
|
import type { AztecNode } from '@aztec/stdlib/interfaces/server';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
ExtendedDirectionalAppTaggingSecret,
|
|
8
|
+
PendingTaggedLog,
|
|
9
|
+
SiloedTag,
|
|
10
|
+
Tag,
|
|
11
|
+
TxScopedL2Log,
|
|
12
|
+
} from '@aztec/stdlib/logs';
|
|
7
13
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
8
14
|
|
|
9
15
|
import type { AccessScopes } from '../access_scopes.js';
|
|
@@ -41,7 +47,7 @@ export class LogService {
|
|
|
41
47
|
logRetrievalRequests.map(async request => {
|
|
42
48
|
const [publicLog, privateLog] = await Promise.all([
|
|
43
49
|
this.#getPublicLogByTag(request.tag, request.contractAddress),
|
|
44
|
-
this.#getPrivateLogByTag(await SiloedTag.
|
|
50
|
+
this.#getPrivateLogByTag(await SiloedTag.computeFromTagAndApp(request.tag, request.contractAddress)),
|
|
45
51
|
]);
|
|
46
52
|
|
|
47
53
|
if (publicLog !== null && privateLog !== null) {
|
|
@@ -130,7 +136,6 @@ export class LogService {
|
|
|
130
136
|
secrets.map(secret =>
|
|
131
137
|
loadPrivateLogsForSenderRecipientPair(
|
|
132
138
|
secret,
|
|
133
|
-
contractAddress,
|
|
134
139
|
this.aztecNode,
|
|
135
140
|
this.recipientTaggingStore,
|
|
136
141
|
anchorBlockNumber,
|
|
@@ -154,7 +159,7 @@ export class LogService {
|
|
|
154
159
|
async #getSecretsForSenders(
|
|
155
160
|
contractAddress: AztecAddress,
|
|
156
161
|
recipient: AztecAddress,
|
|
157
|
-
): Promise<
|
|
162
|
+
): Promise<ExtendedDirectionalAppTaggingSecret[]> {
|
|
158
163
|
const recipientCompleteAddress = await this.addressStore.getCompleteAddress(recipient);
|
|
159
164
|
if (!recipientCompleteAddress) {
|
|
160
165
|
return [];
|
|
@@ -172,7 +177,7 @@ export class LogService {
|
|
|
172
177
|
|
|
173
178
|
return Promise.all(
|
|
174
179
|
deduplicatedSenders.map(sender => {
|
|
175
|
-
return
|
|
180
|
+
return ExtendedDirectionalAppTaggingSecret.compute(
|
|
176
181
|
recipientCompleteAddress,
|
|
177
182
|
recipientIvsk,
|
|
178
183
|
sender,
|
package/src/pxe.ts
CHANGED
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
TxProfileResult,
|
|
48
48
|
TxProvingResult,
|
|
49
49
|
TxSimulationResult,
|
|
50
|
-
|
|
50
|
+
UtilityExecutionResult,
|
|
51
51
|
} from '@aztec/stdlib/tx';
|
|
52
52
|
|
|
53
53
|
import { inspect } from 'util';
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
generateSimulatedProvingResult,
|
|
62
62
|
} from './contract_function_simulator/contract_function_simulator.js';
|
|
63
63
|
import { ProxiedContractStoreFactory } from './contract_function_simulator/proxied_contract_data_source.js';
|
|
64
|
+
import { displayDebugLogs } from './contract_logging.js';
|
|
64
65
|
import { ContractSyncService } from './contract_sync/contract_sync_service.js';
|
|
65
66
|
import { readCurrentClassId } from './contract_sync/helpers.js';
|
|
66
67
|
import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
|
|
@@ -111,8 +112,8 @@ export type SimulateTxOpts = {
|
|
|
111
112
|
scopes: AccessScopes;
|
|
112
113
|
};
|
|
113
114
|
|
|
114
|
-
/** Options for PXE.
|
|
115
|
-
export type
|
|
115
|
+
/** Options for PXE.executeUtility. */
|
|
116
|
+
export type ExecuteUtilityOpts = {
|
|
116
117
|
/** The authentication witnesses required for the function call. */
|
|
117
118
|
authwits?: AuthWitness[];
|
|
118
119
|
/** The accounts whose notes we can access in this call */
|
|
@@ -264,7 +265,7 @@ export class PXE {
|
|
|
264
265
|
debugUtils.setPXEHelpers(
|
|
265
266
|
pxe.#putInJobQueue.bind(pxe),
|
|
266
267
|
pxe.#getSimulatorForTx.bind(pxe),
|
|
267
|
-
pxe.#
|
|
268
|
+
pxe.#executeUtility.bind(pxe),
|
|
268
269
|
);
|
|
269
270
|
|
|
270
271
|
pxe.jobQueue.start();
|
|
@@ -369,7 +370,7 @@ export class PXE {
|
|
|
369
370
|
contractAddress,
|
|
370
371
|
functionSelector,
|
|
371
372
|
(privateSyncCall, execScopes) =>
|
|
372
|
-
this.#
|
|
373
|
+
this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
|
|
373
374
|
anchorBlockHeader,
|
|
374
375
|
jobId,
|
|
375
376
|
scopes,
|
|
@@ -393,16 +394,16 @@ export class PXE {
|
|
|
393
394
|
}
|
|
394
395
|
|
|
395
396
|
/**
|
|
396
|
-
*
|
|
397
|
+
* Execute a utility function call on the given contract.
|
|
397
398
|
* @param contractFunctionSimulator - The simulator to use for the function call.
|
|
398
399
|
* @param call - The function call to execute.
|
|
399
400
|
* @param authWitnesses - Authentication witnesses required for the function call.
|
|
400
401
|
* @param scopes - Optional array of account addresses whose notes can be accessed in this call. Defaults to all
|
|
401
402
|
* accounts if not specified.
|
|
402
403
|
* @param jobId - The job ID for staged writes.
|
|
403
|
-
* @returns The
|
|
404
|
+
* @returns The execution result containing the outputs of the utility function.
|
|
404
405
|
*/
|
|
405
|
-
async #
|
|
406
|
+
async #executeUtility(
|
|
406
407
|
contractFunctionSimulator: ContractFunctionSimulator,
|
|
407
408
|
call: FunctionCall,
|
|
408
409
|
authWitnesses: AuthWitness[] | undefined,
|
|
@@ -946,6 +947,9 @@ export class PXE {
|
|
|
946
947
|
const publicSimulationTimer = new Timer();
|
|
947
948
|
publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
|
|
948
949
|
publicSimulationTime = publicSimulationTimer.ms();
|
|
950
|
+
if (publicOutput?.debugLogs?.length) {
|
|
951
|
+
await displayDebugLogs(publicOutput.debugLogs, addr => this.contractStore.getDebugContractName(addr));
|
|
952
|
+
}
|
|
949
953
|
}
|
|
950
954
|
|
|
951
955
|
let validationTime: number | undefined;
|
|
@@ -1012,16 +1016,16 @@ export class PXE {
|
|
|
1012
1016
|
}
|
|
1013
1017
|
|
|
1014
1018
|
/**
|
|
1015
|
-
*
|
|
1019
|
+
* Executes a contract utility function.
|
|
1016
1020
|
* @param call - The function call containing the function details, arguments, and target contract address.
|
|
1017
1021
|
*/
|
|
1018
|
-
public
|
|
1022
|
+
public executeUtility(
|
|
1019
1023
|
call: FunctionCall,
|
|
1020
|
-
{ authwits, scopes }:
|
|
1021
|
-
): Promise<
|
|
1022
|
-
// We disable concurrent
|
|
1024
|
+
{ authwits, scopes }: ExecuteUtilityOpts = { scopes: 'ALL_SCOPES' },
|
|
1025
|
+
): Promise<UtilityExecutionResult> {
|
|
1026
|
+
// We disable concurrent executions since those might execute oracles which read and write to the PXE stores (e.g.
|
|
1023
1027
|
// to the capsules), and we need to prevent concurrent runs from interfering with one another (e.g. attempting to
|
|
1024
|
-
// delete the same read value, or reading values that another
|
|
1028
|
+
// delete the same read value, or reading values that another execution is currently modifying).
|
|
1025
1029
|
return this.#putInJobQueue(async jobId => {
|
|
1026
1030
|
try {
|
|
1027
1031
|
const totalTimer = new Timer();
|
|
@@ -1036,13 +1040,13 @@ export class PXE {
|
|
|
1036
1040
|
call.to,
|
|
1037
1041
|
call.selector,
|
|
1038
1042
|
(privateSyncCall, execScopes) =>
|
|
1039
|
-
this.#
|
|
1043
|
+
this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
|
|
1040
1044
|
anchorBlockHeader,
|
|
1041
1045
|
jobId,
|
|
1042
1046
|
scopes,
|
|
1043
1047
|
);
|
|
1044
1048
|
|
|
1045
|
-
const executionResult = await this.#
|
|
1049
|
+
const executionResult = await this.#executeUtility(
|
|
1046
1050
|
contractFunctionSimulator,
|
|
1047
1051
|
call,
|
|
1048
1052
|
authwits ?? [],
|
|
@@ -1069,7 +1073,7 @@ export class PXE {
|
|
|
1069
1073
|
const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
|
|
1070
1074
|
throw this.#contextualizeError(
|
|
1071
1075
|
err,
|
|
1072
|
-
`
|
|
1076
|
+
`executeUtility ${to}:${name}(${stringifiedArgs})`,
|
|
1073
1077
|
`scopes=${scopes === 'ALL_SCOPES' ? scopes : scopes.map(s => s.toString()).join(', ')}`,
|
|
1074
1078
|
);
|
|
1075
1079
|
}
|
|
@@ -1107,7 +1111,7 @@ export class PXE {
|
|
|
1107
1111
|
filter.contractAddress,
|
|
1108
1112
|
null,
|
|
1109
1113
|
async (privateSyncCall, execScopes) =>
|
|
1110
|
-
await this.#
|
|
1114
|
+
await this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
|
|
1111
1115
|
anchorBlockHeader,
|
|
1112
1116
|
jobId,
|
|
1113
1117
|
filter.scopes,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ExtendedDirectionalAppTaggingSecret } from '@aztec/stdlib/logs';
|
|
3
3
|
|
|
4
4
|
import type { StagedStore } from '../../job_coordinator/job_coordinator.js';
|
|
5
5
|
|
|
@@ -106,11 +106,11 @@ export class RecipientTaggingStore implements StagedStore {
|
|
|
106
106
|
return Promise.resolve();
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
getHighestAgedIndex(secret:
|
|
109
|
+
getHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
110
110
|
return this.#store.transactionAsync(() => this.#readHighestAgedIndex(jobId, secret.toString()));
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
updateHighestAgedIndex(secret:
|
|
113
|
+
updateHighestAgedIndex(secret: ExtendedDirectionalAppTaggingSecret, index: number, jobId: string): Promise<void> {
|
|
114
114
|
return this.#store.transactionAsync(async () => {
|
|
115
115
|
const currentIndex = await this.#readHighestAgedIndex(jobId, secret.toString());
|
|
116
116
|
if (currentIndex !== undefined && index <= currentIndex) {
|
|
@@ -121,11 +121,15 @@ export class RecipientTaggingStore implements StagedStore {
|
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
getHighestFinalizedIndex(secret:
|
|
124
|
+
getHighestFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
125
125
|
return this.#store.transactionAsync(() => this.#readHighestFinalizedIndex(jobId, secret.toString()));
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
updateHighestFinalizedIndex(
|
|
128
|
+
updateHighestFinalizedIndex(
|
|
129
|
+
secret: ExtendedDirectionalAppTaggingSecret,
|
|
130
|
+
index: number,
|
|
131
|
+
jobId: string,
|
|
132
|
+
): Promise<void> {
|
|
129
133
|
return this.#store.transactionAsync(async () => {
|
|
130
134
|
const currentIndex = await this.#readHighestFinalizedIndex(jobId, secret.toString());
|
|
131
135
|
if (currentIndex !== undefined && index < currentIndex) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ExtendedDirectionalAppTaggingSecret, PreTag } from '@aztec/stdlib/logs';
|
|
3
3
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
4
4
|
|
|
5
5
|
import type { StagedStore } from '../../job_coordinator/job_coordinator.js';
|
|
@@ -154,7 +154,7 @@ export class SenderTaggingStore implements StagedStore {
|
|
|
154
154
|
|
|
155
155
|
// The secrets in pre-tags should be unique because we always store just the highest index per given secret-txHash
|
|
156
156
|
// pair. Below we check that this is the case.
|
|
157
|
-
const secretsSet = new Set(preTags.map(preTag => preTag.
|
|
157
|
+
const secretsSet = new Set(preTags.map(preTag => preTag.extendedSecret.toString()));
|
|
158
158
|
if (secretsSet.size !== preTags.length) {
|
|
159
159
|
return Promise.reject(new Error(`Duplicate secrets found when storing pending indexes`));
|
|
160
160
|
}
|
|
@@ -163,10 +163,10 @@ export class SenderTaggingStore implements StagedStore {
|
|
|
163
163
|
|
|
164
164
|
return this.#store.transactionAsync(async () => {
|
|
165
165
|
// Prefetch all data, start reads during iteration to keep IndexedDB transaction alive
|
|
166
|
-
const preTagReadPromises = preTags.map(({
|
|
167
|
-
const secretStr =
|
|
166
|
+
const preTagReadPromises = preTags.map(({ extendedSecret, index }) => {
|
|
167
|
+
const secretStr = extendedSecret.toString();
|
|
168
168
|
return {
|
|
169
|
-
|
|
169
|
+
extendedSecret,
|
|
170
170
|
secretStr,
|
|
171
171
|
index,
|
|
172
172
|
pending: this.#readPendingIndexes(jobId, secretStr),
|
|
@@ -233,7 +233,7 @@ export class SenderTaggingStore implements StagedStore {
|
|
|
233
233
|
* [startIndex, endIndex). Returns an empty array if no pending indexes exist in the range.
|
|
234
234
|
*/
|
|
235
235
|
getTxHashesOfPendingIndexes(
|
|
236
|
-
secret:
|
|
236
|
+
secret: ExtendedDirectionalAppTaggingSecret,
|
|
237
237
|
startIndex: number,
|
|
238
238
|
endIndex: number,
|
|
239
239
|
jobId: string,
|
|
@@ -252,7 +252,7 @@ export class SenderTaggingStore implements StagedStore {
|
|
|
252
252
|
* @param secret - The secret to get the last finalized index for.
|
|
253
253
|
* @returns The last (highest) finalized index for the given secret.
|
|
254
254
|
*/
|
|
255
|
-
getLastFinalizedIndex(secret:
|
|
255
|
+
getLastFinalizedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
256
256
|
return this.#store.transactionAsync(() => this.#readLastFinalizedIndex(jobId, secret.toString()));
|
|
257
257
|
}
|
|
258
258
|
|
|
@@ -262,7 +262,7 @@ export class SenderTaggingStore implements StagedStore {
|
|
|
262
262
|
* @param secret - The directional app tagging secret to query the last used index for.
|
|
263
263
|
* @returns The last used index.
|
|
264
264
|
*/
|
|
265
|
-
getLastUsedIndex(secret:
|
|
265
|
+
getLastUsedIndex(secret: ExtendedDirectionalAppTaggingSecret, jobId: string): Promise<number | undefined> {
|
|
266
266
|
const secretStr = secret.toString();
|
|
267
267
|
|
|
268
268
|
return this.#store.transactionAsync(async () => {
|
package/src/tagging/index.ts
CHANGED
|
@@ -15,5 +15,5 @@ export { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from './constants.js';
|
|
|
15
15
|
export { getAllPrivateLogsByTags, getAllPublicLogsByTagsFromContract } from './get_all_logs_by_tags.js';
|
|
16
16
|
|
|
17
17
|
// Re-export tagging-related types from stdlib
|
|
18
|
-
export {
|
|
18
|
+
export { ExtendedDirectionalAppTaggingSecret, Tag, SiloedTag } from '@aztec/stdlib/logs';
|
|
19
19
|
export { type PreTag } from '@aztec/stdlib/logs';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
-
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
2
|
import type { BlockHash } from '@aztec/stdlib/block';
|
|
4
3
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
5
|
-
import type {
|
|
4
|
+
import type { ExtendedDirectionalAppTaggingSecret, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
6
5
|
|
|
7
6
|
import type { RecipientTaggingStore } from '../../storage/tagging_store/recipient_tagging_store.js';
|
|
8
7
|
import { UNFINALIZED_TAGGING_INDEXES_WINDOW_LEN } from '../constants.js';
|
|
@@ -10,15 +9,14 @@ import { findHighestIndexes } from './utils/find_highest_indexes.js';
|
|
|
10
9
|
import { loadLogsForRange } from './utils/load_logs_for_range.js';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
|
-
* Loads private logs for
|
|
12
|
+
* Loads private logs for the app-sender-recipient triplet defined by `secret` and updates the highest aged and
|
|
14
13
|
* finalized indexes in the db. At most load logs from blocks up to and including `anchorBlockNumber`.
|
|
15
14
|
*
|
|
16
15
|
* @dev This function can be safely executed "in parallel" for other sender-recipient pairs because the data in
|
|
17
16
|
* in the tagging data provider is indexed by the secret and hence completely disjoint.
|
|
18
17
|
*/
|
|
19
18
|
export async function loadPrivateLogsForSenderRecipientPair(
|
|
20
|
-
secret:
|
|
21
|
-
app: AztecAddress,
|
|
19
|
+
secret: ExtendedDirectionalAppTaggingSecret,
|
|
22
20
|
aztecNode: AztecNode,
|
|
23
21
|
taggingStore: RecipientTaggingStore,
|
|
24
22
|
anchorBlockNumber: BlockNumber,
|
|
@@ -96,7 +94,6 @@ export async function loadPrivateLogsForSenderRecipientPair(
|
|
|
96
94
|
// Get private logs with their block timestamps and corresponding tagging indexes
|
|
97
95
|
const privateLogsWithIndexes = await loadLogsForRange(
|
|
98
96
|
secret,
|
|
99
|
-
app,
|
|
100
97
|
aztecNode,
|
|
101
98
|
start,
|
|
102
99
|
end,
|