@aztec/pxe 0.0.1-commit.4ad48494d → 0.0.1-commit.4eabbdb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/access_scopes.d.ts +9 -0
- package/dest/access_scopes.d.ts.map +1 -0
- package/dest/access_scopes.js +6 -0
- package/dest/config/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +5 -4
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +4 -4
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +2 -2
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts.map +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +3 -2
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +4 -3
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +1 -1
- package/dest/contract_sync/contract_sync_service.d.ts +4 -3
- package/dest/contract_sync/contract_sync_service.d.ts.map +1 -1
- package/dest/contract_sync/contract_sync_service.js +10 -10
- package/dest/contract_sync/helpers.d.ts +3 -2
- package/dest/contract_sync/helpers.d.ts.map +1 -1
- package/dest/contract_sync/helpers.js +3 -3
- package/dest/debug/pxe_debug_utils.d.ts +5 -4
- package/dest/debug/pxe_debug_utils.d.ts.map +1 -1
- package/dest/debug/pxe_debug_utils.js +4 -4
- package/dest/entrypoints/client/bundle/index.d.ts +3 -1
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +2 -0
- package/dest/entrypoints/client/lazy/index.d.ts +3 -1
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +2 -0
- package/dest/entrypoints/server/index.d.ts +3 -1
- package/dest/entrypoints/server/index.d.ts.map +1 -1
- package/dest/entrypoints/server/index.js +2 -0
- package/dest/logs/log_service.d.ts +3 -2
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +1 -1
- package/dest/notes/note_service.d.ts +4 -3
- package/dest/notes/note_service.d.ts.map +1 -1
- package/dest/notes/note_service.js +3 -2
- package/dest/notes_filter.d.ts +25 -0
- package/dest/notes_filter.d.ts.map +1 -0
- package/dest/notes_filter.js +4 -0
- package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts +4 -0
- package/dest/private_kernel/hints/compute_tx_expiration_timestamp.d.ts.map +1 -0
- package/dest/private_kernel/hints/{compute_tx_include_by_timestamp.js → compute_tx_expiration_timestamp.js} +12 -12
- package/dest/private_kernel/hints/index.d.ts +1 -1
- package/dest/private_kernel/hints/index.js +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +4 -4
- package/dest/private_kernel/private_kernel_execution_prover.js +6 -6
- package/dest/pxe.d.ts +12 -11
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +16 -14
- package/dest/storage/note_store/note_store.d.ts +3 -2
- package/dest/storage/note_store/note_store.d.ts.map +1 -1
- package/dest/storage/note_store/note_store.js +2 -2
- package/dest/tagging/get_all_logs_by_tags.d.ts +1 -1
- package/dest/tagging/get_all_logs_by_tags.d.ts.map +1 -1
- package/dest/tagging/get_all_logs_by_tags.js +17 -3
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +4 -4
- package/dest/tagging/recipient_sync/utils/find_highest_indexes.js +2 -2
- package/package.json +16 -16
- package/src/access_scopes.ts +9 -0
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +8 -8
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +4 -3
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +4 -3
- package/src/contract_sync/contract_sync_service.ts +19 -12
- package/src/contract_sync/helpers.ts +7 -2
- package/src/debug/pxe_debug_utils.ts +9 -8
- package/src/entrypoints/client/bundle/index.ts +2 -0
- package/src/entrypoints/client/lazy/index.ts +2 -0
- package/src/entrypoints/server/index.ts +2 -0
- package/src/logs/log_service.ts +3 -6
- package/src/notes/note_service.ts +4 -3
- package/src/notes_filter.ts +26 -0
- package/src/private_kernel/hints/{compute_tx_include_by_timestamp.ts → compute_tx_expiration_timestamp.ts} +13 -13
- package/src/private_kernel/hints/index.ts +1 -1
- package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +7 -7
- package/src/private_kernel/private_kernel_execution_prover.ts +6 -6
- package/src/pxe.ts +28 -27
- package/src/storage/note_store/note_store.ts +7 -3
- package/src/tagging/get_all_logs_by_tags.ts +28 -4
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +4 -4
- package/src/tagging/recipient_sync/utils/find_highest_indexes.ts +2 -2
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +0 -4
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +0 -1
|
@@ -7,6 +7,7 @@ import { Note, NoteDao, NoteStatus } from '@aztec/stdlib/note';
|
|
|
7
7
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
8
8
|
import type { BlockHeader, TxHash } from '@aztec/stdlib/tx';
|
|
9
9
|
|
|
10
|
+
import type { AccessScopes } from '../access_scopes.js';
|
|
10
11
|
import type { NoteStore } from '../storage/note_store/note_store.js';
|
|
11
12
|
|
|
12
13
|
export class NoteService {
|
|
@@ -31,7 +32,7 @@ export class NoteService {
|
|
|
31
32
|
owner: AztecAddress | undefined,
|
|
32
33
|
storageSlot: Fr,
|
|
33
34
|
status: NoteStatus,
|
|
34
|
-
scopes
|
|
35
|
+
scopes: AccessScopes,
|
|
35
36
|
) {
|
|
36
37
|
const noteDaos = await this.noteStore.getNotes(
|
|
37
38
|
{
|
|
@@ -70,10 +71,10 @@ export class NoteService {
|
|
|
70
71
|
*
|
|
71
72
|
* @param contractAddress - The contract whose notes should be checked and nullified.
|
|
72
73
|
*/
|
|
73
|
-
public async syncNoteNullifiers(contractAddress: AztecAddress): Promise<void> {
|
|
74
|
+
public async syncNoteNullifiers(contractAddress: AztecAddress, scopes: AccessScopes): Promise<void> {
|
|
74
75
|
const anchorBlockHash = await this.anchorBlockHeader.hash();
|
|
75
76
|
|
|
76
|
-
const contractNotes = await this.noteStore.getNotes({ contractAddress }, this.jobId);
|
|
77
|
+
const contractNotes = await this.noteStore.getNotes({ contractAddress, scopes }, this.jobId);
|
|
77
78
|
|
|
78
79
|
if (contractNotes.length === 0) {
|
|
79
80
|
return;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
+
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
4
|
+
|
|
5
|
+
import type { AccessScopes } from './access_scopes.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A filter used to fetch notes.
|
|
9
|
+
* @remarks This filter is applied as an intersection of all its params.
|
|
10
|
+
*/
|
|
11
|
+
export type NotesFilter = {
|
|
12
|
+
/**
|
|
13
|
+
* The contract address the note belongs to.
|
|
14
|
+
* @remarks Providing a contract address is required as we need that information to trigger private state sync.
|
|
15
|
+
*/
|
|
16
|
+
contractAddress: AztecAddress;
|
|
17
|
+
/** The owner of the note. */
|
|
18
|
+
owner?: AztecAddress;
|
|
19
|
+
/** The specific storage location of the note on the contract. */
|
|
20
|
+
storageSlot?: Fr;
|
|
21
|
+
/** The status of the note. Defaults to 'ACTIVE'. */
|
|
22
|
+
status?: NoteStatus;
|
|
23
|
+
/** The siloed nullifier for the note. */
|
|
24
|
+
siloedNullifier?: Fr;
|
|
25
|
+
scopes: AccessScopes;
|
|
26
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MAX_TX_LIFETIME } from '@aztec/constants';
|
|
2
2
|
import type { PrivateKernelCircuitPublicInputs } from '@aztec/stdlib/kernel';
|
|
3
3
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
4
4
|
|
|
@@ -8,12 +8,12 @@ const ROUNDED_DURATIONS = [
|
|
|
8
8
|
1, // 1 second
|
|
9
9
|
];
|
|
10
10
|
|
|
11
|
-
function roundTimestamp(blockTimestamp: bigint,
|
|
11
|
+
function roundTimestamp(blockTimestamp: bigint, expirationTimestamp: bigint): UInt64 {
|
|
12
12
|
return ROUNDED_DURATIONS.reduce((timestamp, duration) => {
|
|
13
13
|
if (timestamp <= blockTimestamp) {
|
|
14
14
|
// The timestamp must be greater than the block timestamp.
|
|
15
15
|
// If it is too small, round it down again using a smaller duration.
|
|
16
|
-
const totalDuration =
|
|
16
|
+
const totalDuration = expirationTimestamp - blockTimestamp;
|
|
17
17
|
const roundedDuration = totalDuration - (totalDuration % BigInt(duration));
|
|
18
18
|
return blockTimestamp + roundedDuration;
|
|
19
19
|
}
|
|
@@ -21,36 +21,36 @@ function roundTimestamp(blockTimestamp: bigint, includeByTimestamp: bigint): UIn
|
|
|
21
21
|
}, 0n);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export function
|
|
24
|
+
export function computeTxExpirationTimestamp(
|
|
25
25
|
previousKernel: PrivateKernelCircuitPublicInputs,
|
|
26
|
-
|
|
26
|
+
txLifetime = MAX_TX_LIFETIME,
|
|
27
27
|
): UInt64 {
|
|
28
|
-
if (
|
|
28
|
+
if (txLifetime > MAX_TX_LIFETIME) {
|
|
29
29
|
throw new Error(
|
|
30
|
-
`Custom
|
|
30
|
+
`Custom tx lifetime cannot be greater than the max allowed. Max allowed: ${MAX_TX_LIFETIME}. Custom value: ${txLifetime}.`,
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const anchorBlockTimestamp = previousKernel.constants.anchorBlockHeader.globalVariables.timestamp;
|
|
35
|
-
const maxTimestamp = anchorBlockTimestamp + BigInt(
|
|
36
|
-
const
|
|
35
|
+
const maxTimestamp = anchorBlockTimestamp + BigInt(txLifetime);
|
|
36
|
+
const expirationTimestamp = previousKernel.expirationTimestamp;
|
|
37
37
|
|
|
38
|
-
// If the
|
|
38
|
+
// If the expirationTimestamp set during the tx execution is greater than or equal to the max allowed duration,
|
|
39
39
|
// use the maximum allowed timestamp.
|
|
40
40
|
// Note: It shouldn't be larger than the max allowed duration, but we check for it anyway.
|
|
41
|
-
if (
|
|
41
|
+
if (expirationTimestamp >= maxTimestamp) {
|
|
42
42
|
return maxTimestamp;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// Round it down to the nearest hour/min/second to reduce precision and avoid revealing the exact value.
|
|
46
46
|
// This makes it harder for others to infer what function calls may have been used to produce a specific timestamp.
|
|
47
|
-
const roundedTimestamp = roundTimestamp(anchorBlockTimestamp,
|
|
47
|
+
const roundedTimestamp = roundTimestamp(anchorBlockTimestamp, expirationTimestamp);
|
|
48
48
|
|
|
49
49
|
// The tx can't be published if the timestamp is the same or less than the anchor block's timestamp.
|
|
50
50
|
// Future blocks will have a greater timestamp, so the tx would never be included.
|
|
51
51
|
if (roundedTimestamp <= anchorBlockTimestamp) {
|
|
52
52
|
throw new Error(
|
|
53
|
-
`Include-by timestamp must be greater than the anchor block timestamp. Anchor block timestamp: ${anchorBlockTimestamp}. Include-by timestamp: ${
|
|
53
|
+
`Include-by timestamp must be greater than the anchor block timestamp. Anchor block timestamp: ${anchorBlockTimestamp}. Include-by timestamp: ${expirationTimestamp}.`,
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './private_kernel_reset_private_inputs_builder.js';
|
|
2
|
-
export * from './
|
|
2
|
+
export * from './compute_tx_expiration_timestamp.js';
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
type PrivateKernelSimulateOutput,
|
|
27
27
|
ReadRequestActionEnum,
|
|
28
28
|
ReadRequestResetActions,
|
|
29
|
-
type
|
|
29
|
+
type ScopedKeyValidationRequestAndSeparator,
|
|
30
30
|
ScopedNoteHash,
|
|
31
31
|
ScopedNullifier,
|
|
32
32
|
ScopedReadRequest,
|
|
@@ -68,9 +68,9 @@ function getNullifierMembershipWitnessResolver(oracle: PrivateKernelOracle) {
|
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
async function
|
|
71
|
+
async function getMasterSecretKeysAndKeyTypeDomainSeparators(
|
|
72
72
|
keyValidationRequests: ClaimedLengthArray<
|
|
73
|
-
|
|
73
|
+
ScopedKeyValidationRequestAndSeparator,
|
|
74
74
|
typeof MAX_KEY_VALIDATION_REQUESTS_PER_TX
|
|
75
75
|
>,
|
|
76
76
|
numRequestsToVerify: number,
|
|
@@ -189,8 +189,8 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
189
189
|
this.previousKernel.validationRequests.nullifierReadRequests,
|
|
190
190
|
this.nullifierResetActions,
|
|
191
191
|
),
|
|
192
|
-
|
|
193
|
-
this.previousKernel.validationRequests.
|
|
192
|
+
getMasterSecretKeysAndKeyTypeDomainSeparators(
|
|
193
|
+
this.previousKernel.validationRequests.scopedKeyValidationRequestsAndSeparators,
|
|
194
194
|
dimensions.KEY_VALIDATION,
|
|
195
195
|
oracle,
|
|
196
196
|
),
|
|
@@ -357,8 +357,8 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
private needsResetNullifierKeys() {
|
|
360
|
-
const numCurr = this.previousKernel.validationRequests.
|
|
361
|
-
const numNext = this.nextIteration ? this.nextIteration.
|
|
360
|
+
const numCurr = this.previousKernel.validationRequests.scopedKeyValidationRequestsAndSeparators.claimedLength;
|
|
361
|
+
const numNext = this.nextIteration ? this.nextIteration.keyValidationRequestsAndSeparators.claimedLength : 0;
|
|
362
362
|
const maxAmountToKeep = !this.nextIteration ? 0 : MAX_KEY_VALIDATION_REQUESTS_PER_TX;
|
|
363
363
|
if (numCurr + numNext <= maxAmountToKeep) {
|
|
364
364
|
return false;
|
|
@@ -260,20 +260,20 @@ export class PrivateKernelExecutionProver {
|
|
|
260
260
|
// TODO: Enable padding once we better understand the final amounts to pad to.
|
|
261
261
|
const paddedSideEffectAmounts = PaddedSideEffectAmounts.empty();
|
|
262
262
|
|
|
263
|
-
// Use the aggregated
|
|
264
|
-
// TODO: Call `
|
|
265
|
-
const
|
|
263
|
+
// Use the aggregated expirationTimestamp set throughout the tx execution.
|
|
264
|
+
// TODO: Call `computeTxExpirationTimestamp` to round the value down and reduce precision, improving privacy.
|
|
265
|
+
const expirationTimestampUpperBound = previousKernelData.publicInputs.expirationTimestamp;
|
|
266
266
|
const anchorBlockTimestamp = previousKernelData.publicInputs.constants.anchorBlockHeader.globalVariables.timestamp;
|
|
267
|
-
if (
|
|
267
|
+
if (expirationTimestampUpperBound <= anchorBlockTimestamp) {
|
|
268
268
|
throw new Error(
|
|
269
|
-
`Include-by timestamp must be greater than the anchor block timestamp. Anchor block timestamp: ${anchorBlockTimestamp}. Include-by timestamp: ${
|
|
269
|
+
`Include-by timestamp must be greater than the anchor block timestamp. Anchor block timestamp: ${anchorBlockTimestamp}. Include-by timestamp: ${expirationTimestampUpperBound}.`,
|
|
270
270
|
);
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
const privateInputs = new PrivateKernelTailCircuitPrivateInputs(
|
|
274
274
|
previousKernelData,
|
|
275
275
|
paddedSideEffectAmounts,
|
|
276
|
-
|
|
276
|
+
expirationTimestampUpperBound,
|
|
277
277
|
);
|
|
278
278
|
|
|
279
279
|
const witgenTimer = new Timer();
|
package/src/pxe.ts
CHANGED
|
@@ -47,11 +47,12 @@ 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';
|
|
54
54
|
|
|
55
|
+
import type { AccessScopes } from './access_scopes.js';
|
|
55
56
|
import { BlockSynchronizer } from './block_synchronizer/index.js';
|
|
56
57
|
import type { PXEConfig } from './config/index.js';
|
|
57
58
|
import { BenchmarkedNodeFactory } from './contract_function_simulator/benchmarked_node.js';
|
|
@@ -93,7 +94,7 @@ export type ProfileTxOpts = {
|
|
|
93
94
|
/** If true, proof generation is skipped during profiling. Defaults to true. */
|
|
94
95
|
skipProofGeneration?: boolean;
|
|
95
96
|
/** Addresses whose private state and keys are accessible during private execution. */
|
|
96
|
-
scopes
|
|
97
|
+
scopes: AccessScopes;
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
/** Options for PXE.simulateTx. */
|
|
@@ -106,16 +107,16 @@ export type SimulateTxOpts = {
|
|
|
106
107
|
skipFeeEnforcement?: boolean;
|
|
107
108
|
/** State overrides for the simulation, such as contract instances and artifacts. */
|
|
108
109
|
overrides?: SimulationOverrides;
|
|
109
|
-
/** Addresses whose private state and keys are accessible during private execution
|
|
110
|
-
scopes
|
|
110
|
+
/** Addresses whose private state and keys are accessible during private execution */
|
|
111
|
+
scopes: AccessScopes;
|
|
111
112
|
};
|
|
112
113
|
|
|
113
|
-
/** Options for PXE.
|
|
114
|
-
export type
|
|
114
|
+
/** Options for PXE.executeUtility. */
|
|
115
|
+
export type ExecuteUtilityOpts = {
|
|
115
116
|
/** The authentication witnesses required for the function call. */
|
|
116
117
|
authwits?: AuthWitness[];
|
|
117
|
-
/** The accounts whose notes we can access in this call
|
|
118
|
-
scopes
|
|
118
|
+
/** The accounts whose notes we can access in this call */
|
|
119
|
+
scopes: AccessScopes;
|
|
119
120
|
};
|
|
120
121
|
|
|
121
122
|
/** Args for PXE.create. */
|
|
@@ -263,7 +264,7 @@ export class PXE {
|
|
|
263
264
|
debugUtils.setPXEHelpers(
|
|
264
265
|
pxe.#putInJobQueue.bind(pxe),
|
|
265
266
|
pxe.#getSimulatorForTx.bind(pxe),
|
|
266
|
-
pxe.#
|
|
267
|
+
pxe.#executeUtility.bind(pxe),
|
|
267
268
|
);
|
|
268
269
|
|
|
269
270
|
pxe.jobQueue.start();
|
|
@@ -357,7 +358,7 @@ export class PXE {
|
|
|
357
358
|
async #executePrivate(
|
|
358
359
|
contractFunctionSimulator: ContractFunctionSimulator,
|
|
359
360
|
txRequest: TxExecutionRequest,
|
|
360
|
-
scopes:
|
|
361
|
+
scopes: AccessScopes,
|
|
361
362
|
jobId: string,
|
|
362
363
|
): Promise<PrivateExecutionResult> {
|
|
363
364
|
const { origin: contractAddress, functionSelector } = txRequest;
|
|
@@ -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,20 +394,20 @@ 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,
|
|
409
|
-
scopes:
|
|
410
|
+
scopes: AccessScopes,
|
|
410
411
|
jobId: string,
|
|
411
412
|
) {
|
|
412
413
|
try {
|
|
@@ -1005,23 +1006,23 @@ export class PXE {
|
|
|
1005
1006
|
inspect(txRequest),
|
|
1006
1007
|
`simulatePublic=${simulatePublic}`,
|
|
1007
1008
|
`skipTxValidation=${skipTxValidation}`,
|
|
1008
|
-
`scopes=${scopes
|
|
1009
|
+
`scopes=${scopes === 'ALL_SCOPES' ? scopes : scopes.map(s => s.toString()).join(', ')}`,
|
|
1009
1010
|
);
|
|
1010
1011
|
}
|
|
1011
1012
|
});
|
|
1012
1013
|
}
|
|
1013
1014
|
|
|
1014
1015
|
/**
|
|
1015
|
-
*
|
|
1016
|
+
* Executes a contract utility function.
|
|
1016
1017
|
* @param call - The function call containing the function details, arguments, and target contract address.
|
|
1017
1018
|
*/
|
|
1018
|
-
public
|
|
1019
|
+
public executeUtility(
|
|
1019
1020
|
call: FunctionCall,
|
|
1020
|
-
{ authwits, scopes }:
|
|
1021
|
-
): Promise<
|
|
1022
|
-
// We disable concurrent
|
|
1021
|
+
{ authwits, scopes }: ExecuteUtilityOpts = { scopes: 'ALL_SCOPES' },
|
|
1022
|
+
): Promise<UtilityExecutionResult> {
|
|
1023
|
+
// We disable concurrent executions since those might execute oracles which read and write to the PXE stores (e.g.
|
|
1023
1024
|
// 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
|
|
1025
|
+
// delete the same read value, or reading values that another execution is currently modifying).
|
|
1025
1026
|
return this.#putInJobQueue(async jobId => {
|
|
1026
1027
|
try {
|
|
1027
1028
|
const totalTimer = new Timer();
|
|
@@ -1036,13 +1037,13 @@ export class PXE {
|
|
|
1036
1037
|
call.to,
|
|
1037
1038
|
call.selector,
|
|
1038
1039
|
(privateSyncCall, execScopes) =>
|
|
1039
|
-
this.#
|
|
1040
|
+
this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
|
|
1040
1041
|
anchorBlockHeader,
|
|
1041
1042
|
jobId,
|
|
1042
1043
|
scopes,
|
|
1043
1044
|
);
|
|
1044
1045
|
|
|
1045
|
-
const executionResult = await this.#
|
|
1046
|
+
const executionResult = await this.#executeUtility(
|
|
1046
1047
|
contractFunctionSimulator,
|
|
1047
1048
|
call,
|
|
1048
1049
|
authwits ?? [],
|
|
@@ -1069,8 +1070,8 @@ export class PXE {
|
|
|
1069
1070
|
const stringifiedArgs = args.map(arg => arg.toString()).join(', ');
|
|
1070
1071
|
throw this.#contextualizeError(
|
|
1071
1072
|
err,
|
|
1072
|
-
`
|
|
1073
|
-
`scopes=${scopes
|
|
1073
|
+
`executeUtility ${to}:${name}(${stringifiedArgs})`,
|
|
1074
|
+
`scopes=${scopes === 'ALL_SCOPES' ? scopes : scopes.map(s => s.toString()).join(', ')}`,
|
|
1074
1075
|
);
|
|
1075
1076
|
}
|
|
1076
1077
|
});
|
|
@@ -1107,7 +1108,7 @@ export class PXE {
|
|
|
1107
1108
|
filter.contractAddress,
|
|
1108
1109
|
null,
|
|
1109
1110
|
async (privateSyncCall, execScopes) =>
|
|
1110
|
-
await this.#
|
|
1111
|
+
await this.#executeUtility(contractFunctionSimulator, privateSyncCall, [], execScopes, jobId),
|
|
1111
1112
|
anchorBlockHeader,
|
|
1112
1113
|
jobId,
|
|
1113
1114
|
filter.scopes,
|
|
@@ -3,9 +3,10 @@ import type { Fr } from '@aztec/foundation/schemas';
|
|
|
3
3
|
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
5
|
import type { DataInBlock } from '@aztec/stdlib/block';
|
|
6
|
-
import { NoteDao, NoteStatus
|
|
6
|
+
import { NoteDao, NoteStatus } from '@aztec/stdlib/note';
|
|
7
7
|
|
|
8
8
|
import type { StagedStore } from '../../job_coordinator/job_coordinator.js';
|
|
9
|
+
import type { NotesFilter } from '../../notes_filter.js';
|
|
9
10
|
import { StoredNote } from './stored_note.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -105,7 +106,7 @@ export class NoteStore implements StagedStore {
|
|
|
105
106
|
* returned once if this is the case)
|
|
106
107
|
*/
|
|
107
108
|
getNotes(filter: NotesFilter, jobId: string): Promise<NoteDao[]> {
|
|
108
|
-
if (filter.scopes !==
|
|
109
|
+
if (filter.scopes !== 'ALL_SCOPES' && filter.scopes.length === 0) {
|
|
109
110
|
return Promise.resolve([]);
|
|
110
111
|
}
|
|
111
112
|
|
|
@@ -179,7 +180,10 @@ export class NoteStore implements StagedStore {
|
|
|
179
180
|
continue;
|
|
180
181
|
}
|
|
181
182
|
|
|
182
|
-
if (
|
|
183
|
+
if (
|
|
184
|
+
filter.scopes !== 'ALL_SCOPES' &&
|
|
185
|
+
note.scopes.intersection(new Set(filter.scopes.map(s => s.toString()))).size === 0
|
|
186
|
+
) {
|
|
183
187
|
continue;
|
|
184
188
|
}
|
|
185
189
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
2
2
|
import type { BlockHash } from '@aztec/stdlib/block';
|
|
3
|
-
import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
|
|
3
|
+
import { MAX_LOGS_PER_TAG, MAX_RPC_LEN } from '@aztec/stdlib/interfaces/api-limit';
|
|
4
4
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
5
5
|
import type { SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
6
6
|
|
|
@@ -31,6 +31,26 @@ async function getAllPages<T>(numTags: number, fetchPage: (page: number) => Prom
|
|
|
31
31
|
return allResultsPerTag;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Splits tags into chunks of MAX_RPC_LEN, fetches logs for each chunk using getAllPages, then stitches the results
|
|
36
|
+
* back into a single array preserving the original tag order.
|
|
37
|
+
*/
|
|
38
|
+
async function getAllPagesInBatches<Tag, T>(
|
|
39
|
+
tags: Tag[],
|
|
40
|
+
fetchAllPagesForBatch: (batch: Tag[]) => Promise<T[][]>,
|
|
41
|
+
): Promise<T[][]> {
|
|
42
|
+
if (tags.length <= MAX_RPC_LEN) {
|
|
43
|
+
return fetchAllPagesForBatch(tags);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const batches: Tag[][] = [];
|
|
47
|
+
for (let i = 0; i < tags.length; i += MAX_RPC_LEN) {
|
|
48
|
+
batches.push(tags.slice(i, i + MAX_RPC_LEN));
|
|
49
|
+
}
|
|
50
|
+
const batchResults = await Promise.all(batches.map(fetchAllPagesForBatch));
|
|
51
|
+
return batchResults.flat();
|
|
52
|
+
}
|
|
53
|
+
|
|
34
54
|
/**
|
|
35
55
|
* Fetches all private logs for the given tags, automatically paginating through all pages.
|
|
36
56
|
* @param aztecNode - The Aztec node to query.
|
|
@@ -44,7 +64,9 @@ export function getAllPrivateLogsByTags(
|
|
|
44
64
|
tags: SiloedTag[],
|
|
45
65
|
anchorBlockHash: BlockHash,
|
|
46
66
|
): Promise<TxScopedL2Log[][]> {
|
|
47
|
-
return
|
|
67
|
+
return getAllPagesInBatches(tags, batch =>
|
|
68
|
+
getAllPages(batch.length, page => aztecNode.getPrivateLogsByTags(batch, page, anchorBlockHash)),
|
|
69
|
+
);
|
|
48
70
|
}
|
|
49
71
|
|
|
50
72
|
/**
|
|
@@ -62,7 +84,9 @@ export function getAllPublicLogsByTagsFromContract(
|
|
|
62
84
|
tags: Tag[],
|
|
63
85
|
anchorBlockHash: BlockHash,
|
|
64
86
|
): Promise<TxScopedL2Log[][]> {
|
|
65
|
-
return
|
|
66
|
-
|
|
87
|
+
return getAllPagesInBatches(tags, batch =>
|
|
88
|
+
getAllPages(batch.length, page =>
|
|
89
|
+
aztecNode.getPublicLogsByTagsFromContract(contractAddress, batch, page, anchorBlockHash),
|
|
90
|
+
),
|
|
67
91
|
);
|
|
68
92
|
}
|
|
@@ -30,7 +30,7 @@ export async function loadPrivateLogsForSenderRecipientPair(
|
|
|
30
30
|
// (highestAgedIndex, highestFinalizedIndex + WINDOW_LEN]
|
|
31
31
|
//
|
|
32
32
|
// highestAgedIndex is the highest index that was used in a tx that is included in a block at least
|
|
33
|
-
// `
|
|
33
|
+
// `MAX_TX_LIFETIME` seconds ago.
|
|
34
34
|
// highestFinalizedIndex is the highest index that was used in a tx that is included in a finalized block.
|
|
35
35
|
//
|
|
36
36
|
// "(" denotes an open end of the range - the index is not included in the range.
|
|
@@ -42,19 +42,19 @@ export async function loadPrivateLogsForSenderRecipientPair(
|
|
|
42
42
|
// ever appear.
|
|
43
43
|
//
|
|
44
44
|
// This relies on the "maximum inclusion timestamp" rule enforced by the kernel and rollup circuits:
|
|
45
|
-
// - a transaction's maximum inclusion timestamp is at most `
|
|
45
|
+
// - a transaction's maximum inclusion timestamp is at most `MAX_TX_LIFETIME` seconds after
|
|
46
46
|
// the timestamp of its anchor block; and
|
|
47
47
|
// - a rollup only includes transactions whose inclusion timestamp is >= the L2 block's timestamp.
|
|
48
48
|
//
|
|
49
49
|
// Suppose some device used index `I` in a transaction anchored to block `B_N` at time `N`, and that block is now at
|
|
50
|
-
// least `
|
|
50
|
+
// least `MAX_TX_LIFETIME` seconds in the past. Then there is no possibility of any *other* device
|
|
51
51
|
// trying to use an index <= `I` while anchoring to a *newer* block than `B_N` because if we were anchoring to
|
|
52
52
|
// a newer block than `B_N` then we would already have seen the log with index `I` and hence the device would have
|
|
53
53
|
// chosen a larger index.
|
|
54
54
|
// If that *other* device would anchor to a block older than `B_N` then that tx could never be included in a block
|
|
55
55
|
// because it would already have been expired.
|
|
56
56
|
//
|
|
57
|
-
// Therefore, once we see that index `I` has been used in a block that is at least `
|
|
57
|
+
// Therefore, once we see that index `I` has been used in a block that is at least `MAX_TX_LIFETIME`
|
|
58
58
|
// seconds old, we can safely stop syncing logs for all indexes <= `I` and set highestAgedIndex = `I`.
|
|
59
59
|
//
|
|
60
60
|
// ## Explanation of the upper bound `highestFinalizedIndex + WINDOW_LEN`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MAX_TX_LIFETIME } from '@aztec/constants';
|
|
2
2
|
import type { TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -16,7 +16,7 @@ export function findHighestIndexes(
|
|
|
16
16
|
const ageInSeconds = currentTimestamp - log.blockTimestamp;
|
|
17
17
|
|
|
18
18
|
if (
|
|
19
|
-
ageInSeconds >= BigInt(
|
|
19
|
+
ageInSeconds >= BigInt(MAX_TX_LIFETIME) &&
|
|
20
20
|
(highestAgedIndex === undefined || taggingIndex > highestAgedIndex)
|
|
21
21
|
) {
|
|
22
22
|
highestAgedIndex = taggingIndex;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { PrivateKernelCircuitPublicInputs } from '@aztec/stdlib/kernel';
|
|
2
|
-
import type { UInt64 } from '@aztec/stdlib/types';
|
|
3
|
-
export declare function computeTxIncludeByTimestamp(previousKernel: PrivateKernelCircuitPublicInputs, maxDuration?: number): UInt64;
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHV0ZV90eF9pbmNsdWRlX2J5X3RpbWVzdGFtcC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3ByaXZhdGVfa2VybmVsL2hpbnRzL2NvbXB1dGVfdHhfaW5jbHVkZV9ieV90aW1lc3RhbXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM3RSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQXFCbEQsd0JBQWdCLDJCQUEyQixDQUN6QyxjQUFjLEVBQUUsZ0NBQWdDLEVBQ2hELFdBQVcsU0FBb0MsR0FDOUMsTUFBTSxDQStCUiJ9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compute_tx_include_by_timestamp.d.ts","sourceRoot":"","sources":["../../../src/private_kernel/hints/compute_tx_include_by_timestamp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAqBlD,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,gCAAgC,EAChD,WAAW,SAAoC,GAC9C,MAAM,CA+BR"}
|