@aztec/stdlib 4.1.0-rc.2 → 4.1.0-rc.3
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/abi/decoder.d.ts +2 -2
- package/dest/abi/decoder.d.ts.map +1 -1
- package/dest/abi/decoder.js +6 -1
- package/dest/abi/encoder.d.ts +1 -1
- package/dest/abi/encoder.d.ts.map +1 -1
- package/dest/abi/encoder.js +28 -1
- package/dest/abi/event_metadata_definition.d.ts +3 -1
- package/dest/abi/event_metadata_definition.d.ts.map +1 -1
- package/dest/abi/event_metadata_definition.js +1 -1
- package/dest/abi/utils.d.ts +14 -1
- package/dest/abi/utils.d.ts.map +1 -1
- package/dest/abi/utils.js +15 -0
- package/dest/block/l2_block_source.d.ts +7 -5
- package/dest/block/l2_block_source.d.ts.map +1 -1
- package/dest/epoch-helpers/index.d.ts +5 -1
- package/dest/epoch-helpers/index.d.ts.map +1 -1
- package/dest/epoch-helpers/index.js +4 -2
- package/dest/interfaces/archiver.js +2 -2
- package/dest/interfaces/aztec-node-admin.d.ts +4 -1
- package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
- package/dest/interfaces/aztec-node.d.ts +2 -2
- package/dest/interfaces/aztec-node.d.ts.map +1 -1
- package/dest/interfaces/aztec-node.js +2 -0
- package/dest/interfaces/block-builder.d.ts +11 -9
- package/dest/interfaces/block-builder.d.ts.map +1 -1
- package/dest/interfaces/block-builder.js +6 -4
- package/dest/interfaces/merkle_tree_operations.d.ts +9 -19
- package/dest/interfaces/merkle_tree_operations.d.ts.map +1 -1
- package/dest/interfaces/prover-client.d.ts +6 -1
- package/dest/interfaces/prover-client.d.ts.map +1 -1
- package/dest/interfaces/prover-client.js +7 -1
- package/dest/kernel/hints/build_note_hash_read_request_hints.d.ts +3 -3
- package/dest/kernel/hints/build_note_hash_read_request_hints.d.ts.map +1 -1
- package/dest/kernel/hints/build_note_hash_read_request_hints.js +13 -10
- package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts +3 -3
- package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts.map +1 -1
- package/dest/kernel/hints/build_nullifier_read_request_hints.js +13 -10
- package/dest/kernel/hints/build_transient_data_hints.d.ts +5 -2
- package/dest/kernel/hints/build_transient_data_hints.d.ts.map +1 -1
- package/dest/kernel/hints/build_transient_data_hints.js +9 -3
- package/dest/logs/log_filter.d.ts +4 -1
- package/dest/logs/log_filter.d.ts.map +1 -1
- package/dest/logs/log_filter.js +2 -1
- package/dest/logs/public_log.d.ts +4 -3
- package/dest/logs/public_log.d.ts.map +1 -1
- package/dest/logs/public_log.js +2 -1
- package/dest/messaging/l2_to_l1_membership.d.ts +32 -6
- package/dest/messaging/l2_to_l1_membership.d.ts.map +1 -1
- package/dest/messaging/l2_to_l1_membership.js +69 -26
- package/dest/p2p/checkpoint_proposal.d.ts +1 -1
- package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
- package/dest/p2p/checkpoint_proposal.js +13 -11
- package/dest/p2p/peer_error.d.ts +3 -1
- package/dest/p2p/peer_error.d.ts.map +1 -1
- package/dest/p2p/peer_error.js +5 -0
- package/dest/tx/tx_receipt.d.ts +7 -2
- package/dest/tx/tx_receipt.d.ts.map +1 -1
- package/dest/tx/tx_receipt.js +6 -3
- package/dest/update-checker/package_version.d.ts +2 -2
- package/dest/update-checker/package_version.d.ts.map +1 -1
- package/dest/update-checker/package_version.js +16 -3
- package/dest/validators/errors.d.ts +6 -1
- package/dest/validators/errors.d.ts.map +1 -1
- package/dest/validators/errors.js +7 -0
- package/dest/versioning/versioning.d.ts +4 -2
- package/dest/versioning/versioning.d.ts.map +1 -1
- package/dest/versioning/versioning.js +4 -1
- package/package.json +9 -9
- package/src/abi/decoder.ts +14 -2
- package/src/abi/encoder.ts +41 -1
- package/src/abi/event_metadata_definition.ts +2 -0
- package/src/abi/utils.ts +25 -0
- package/src/block/l2_block_source.ts +6 -4
- package/src/epoch-helpers/index.ts +3 -0
- package/src/interfaces/archiver.ts +2 -2
- package/src/interfaces/aztec-node.ts +9 -1
- package/src/interfaces/block-builder.ts +13 -11
- package/src/interfaces/merkle_tree_operations.ts +8 -18
- package/src/interfaces/prover-client.ts +8 -0
- package/src/kernel/hints/build_note_hash_read_request_hints.ts +14 -18
- package/src/kernel/hints/build_nullifier_read_request_hints.ts +15 -18
- package/src/kernel/hints/build_transient_data_hints.ts +17 -2
- package/src/logs/log_filter.ts +5 -0
- package/src/logs/public_log.ts +4 -2
- package/src/messaging/l2_to_l1_membership.ts +98 -33
- package/src/p2p/checkpoint_proposal.ts +23 -20
- package/src/p2p/peer_error.ts +7 -0
- package/src/tx/tx_receipt.ts +6 -1
- package/src/update-checker/package_version.ts +19 -6
- package/src/validators/errors.ts +9 -0
- package/src/versioning/versioning.ts +4 -1
package/src/abi/encoder.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
2
|
|
|
3
3
|
import type { AbiType, FunctionAbi } from './abi.js';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
isAddressStruct,
|
|
6
|
+
isBoundedVecStruct,
|
|
7
|
+
isFunctionSelectorStruct,
|
|
8
|
+
isOptionStruct,
|
|
9
|
+
isWrappedFieldStruct,
|
|
10
|
+
} from './utils.js';
|
|
5
11
|
|
|
6
12
|
/**
|
|
7
13
|
* Encodes arguments for a function call.
|
|
@@ -43,6 +49,32 @@ class ArgumentEncoder {
|
|
|
43
49
|
* @param name - Name.
|
|
44
50
|
*/
|
|
45
51
|
private encodeArgument(abiType: AbiType, arg: any, name?: string) {
|
|
52
|
+
if (isOptionStruct(abiType)) {
|
|
53
|
+
const optionType = abiType as Extract<AbiType, { kind: 'struct' }>;
|
|
54
|
+
const [isSomeField, valueField] = optionType.fields;
|
|
55
|
+
|
|
56
|
+
if (arg === undefined || arg === null) {
|
|
57
|
+
this.encodeArgument(isSomeField.type, false, `${name}._is_some`);
|
|
58
|
+
this.#encodeDefaultValue(valueField.type);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (typeof arg === 'object' && '_is_some' in arg) {
|
|
63
|
+
this.encodeArgument(isSomeField.type, arg._is_some, `${name}._is_some`);
|
|
64
|
+
|
|
65
|
+
if (arg._is_some) {
|
|
66
|
+
this.encodeArgument(valueField.type, arg._value, `${name}._value`);
|
|
67
|
+
} else {
|
|
68
|
+
this.#encodeDefaultValue(valueField.type);
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.encodeArgument(isSomeField.type, true, `${name}._is_some`);
|
|
74
|
+
this.encodeArgument(valueField.type, arg, `${name}._value`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
46
78
|
if (arg === undefined || arg == null) {
|
|
47
79
|
throw new Error(`Undefined argument ${name ?? 'unnamed'} of type ${abiType.kind}`);
|
|
48
80
|
}
|
|
@@ -227,6 +259,14 @@ class ArgumentEncoder {
|
|
|
227
259
|
this.encodeArgument(lenField.type, arg.length, 'len');
|
|
228
260
|
}
|
|
229
261
|
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Appends the flattened zero value for an ABI type.
|
|
265
|
+
* Option::None still serializes the wrapped value, so we need to zero-fill its footprint.
|
|
266
|
+
*/
|
|
267
|
+
#encodeDefaultValue(abiType: AbiType) {
|
|
268
|
+
this.flattened.push(...new Array(ArgumentEncoder.typeSize(abiType)).fill(Fr.ZERO));
|
|
269
|
+
}
|
|
230
270
|
}
|
|
231
271
|
|
|
232
272
|
/**
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { AbiType } from './abi.js';
|
|
2
2
|
import type { EventSelector } from './event_selector.js';
|
|
3
3
|
|
|
4
|
+
/** Metadata for a contract event, used to decode emitted event logs back into structured data. */
|
|
4
5
|
export type EventMetadataDefinition = {
|
|
5
6
|
eventSelector: EventSelector;
|
|
6
7
|
abiType: AbiType;
|
|
8
|
+
/** Names of the event's struct members (not serialized Noir Field elements). */
|
|
7
9
|
fieldNames: string[];
|
|
8
10
|
};
|
package/src/abi/utils.ts
CHANGED
|
@@ -81,6 +81,31 @@ export function isBoundedVecStruct(abiType: AbiType) {
|
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Returns whether the ABI type is Noir's std::option::Option lowered to a struct.
|
|
86
|
+
* @param abiType - Type to check.
|
|
87
|
+
* @returns A boolean indicating whether the ABI type is an Option struct.
|
|
88
|
+
*/
|
|
89
|
+
export function isOptionStruct(abiType: AbiType) {
|
|
90
|
+
return (
|
|
91
|
+
abiType.kind === 'struct' &&
|
|
92
|
+
abiType.path === 'std::option::Option' &&
|
|
93
|
+
abiType.fields.length === 2 &&
|
|
94
|
+
abiType.fields[0].name === '_is_some' &&
|
|
95
|
+
abiType.fields[1].name === '_value'
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Returns whether `null` or `undefined` can be mapped to a valid ABI value for this type.
|
|
101
|
+
*
|
|
102
|
+
* @param abiType - Type to check.
|
|
103
|
+
* @returns A boolean indicating whether nullish values are valid shorthand for this ABI type.
|
|
104
|
+
*/
|
|
105
|
+
export function canBeMappedFromNullOrUndefined(abiType: AbiType) {
|
|
106
|
+
return isOptionStruct(abiType);
|
|
107
|
+
}
|
|
108
|
+
|
|
84
109
|
/**
|
|
85
110
|
* Returns a bigint by parsing a serialized 2's complement signed int.
|
|
86
111
|
* @param b - The signed int as a buffer
|
|
@@ -176,14 +176,16 @@ export interface L2BlockSource {
|
|
|
176
176
|
getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined>;
|
|
177
177
|
|
|
178
178
|
/**
|
|
179
|
-
* Returns the
|
|
179
|
+
* Returns the last L2 slot number that has been fully synchronized from L1.
|
|
180
|
+
* An L2 slot is fully synced when all L1 blocks that fall within its time range have been processed.
|
|
180
181
|
*/
|
|
181
|
-
|
|
182
|
+
getSyncedL2SlotNumber(): Promise<SlotNumber | undefined>;
|
|
182
183
|
|
|
183
184
|
/**
|
|
184
|
-
* Returns the
|
|
185
|
+
* Returns the last L2 epoch number that has been fully synchronized from L1.
|
|
186
|
+
* An epoch is fully synced when all its L2 slots have been fully synced.
|
|
185
187
|
*/
|
|
186
|
-
|
|
188
|
+
getSyncedL2EpochNumber(): Promise<EpochNumber | undefined>;
|
|
187
189
|
|
|
188
190
|
/**
|
|
189
191
|
* Returns all checkpointed block headers for a given epoch.
|
|
@@ -12,6 +12,7 @@ export type L1RollupConstants = {
|
|
|
12
12
|
ethereumSlotDuration: number;
|
|
13
13
|
proofSubmissionEpochs: number;
|
|
14
14
|
targetCommitteeSize: number;
|
|
15
|
+
rollupManaLimit: number;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export const EmptyL1RollupConstants: L1RollupConstants = {
|
|
@@ -22,6 +23,7 @@ export const EmptyL1RollupConstants: L1RollupConstants = {
|
|
|
22
23
|
ethereumSlotDuration: 1,
|
|
23
24
|
proofSubmissionEpochs: 1,
|
|
24
25
|
targetCommitteeSize: 48,
|
|
26
|
+
rollupManaLimit: Number.MAX_SAFE_INTEGER,
|
|
25
27
|
};
|
|
26
28
|
|
|
27
29
|
export const L1RollupConstantsSchema = zodFor<L1RollupConstants>()(
|
|
@@ -33,6 +35,7 @@ export const L1RollupConstantsSchema = zodFor<L1RollupConstants>()(
|
|
|
33
35
|
ethereumSlotDuration: z.number(),
|
|
34
36
|
proofSubmissionEpochs: z.number(),
|
|
35
37
|
targetCommitteeSize: z.number(),
|
|
38
|
+
rollupManaLimit: z.number(),
|
|
36
39
|
}),
|
|
37
40
|
);
|
|
38
41
|
|
|
@@ -114,8 +114,8 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
|
|
|
114
114
|
getL2BlockByArchive: z.function().args(schemas.Fr).returns(L2Block.schema.optional()),
|
|
115
115
|
getTxEffect: z.function().args(TxHash.schema).returns(indexedTxSchema().optional()),
|
|
116
116
|
getSettledTxReceipt: z.function().args(TxHash.schema).returns(TxReceipt.schema.optional()),
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
getSyncedL2SlotNumber: z.function().args().returns(schemas.SlotNumber.optional()),
|
|
118
|
+
getSyncedL2EpochNumber: z.function().args().returns(EpochNumberSchema.optional()),
|
|
119
119
|
getCheckpointsForEpoch: z.function().args(EpochNumberSchema).returns(z.array(Checkpoint.schema)),
|
|
120
120
|
getCheckpointsDataForEpoch: z.function().args(EpochNumberSchema).returns(z.array(CheckpointDataSchema)),
|
|
121
121
|
getCheckpointedBlocksForEpoch: z.function().args(EpochNumberSchema).returns(z.array(CheckpointedL2Block.schema)),
|
|
@@ -25,6 +25,7 @@ import { CheckpointedL2Block } from '../block/checkpointed_l2_block.js';
|
|
|
25
25
|
import { type DataInBlock, dataInBlockSchemaFor } from '../block/in_block.js';
|
|
26
26
|
import { L2Block } from '../block/l2_block.js';
|
|
27
27
|
import { type L2BlockSource, type L2Tips, L2TipsSchema } from '../block/l2_block_source.js';
|
|
28
|
+
import { CheckpointDataSchema } from '../checkpoint/checkpoint_data.js';
|
|
28
29
|
import { PublishedCheckpoint } from '../checkpoint/published_checkpoint.js';
|
|
29
30
|
import {
|
|
30
31
|
type ContractClassPublic,
|
|
@@ -74,7 +75,12 @@ import { type WorldStateSyncStatus, WorldStateSyncStatusSchema } from './world_s
|
|
|
74
75
|
export interface AztecNode
|
|
75
76
|
extends Pick<
|
|
76
77
|
L2BlockSource,
|
|
77
|
-
|
|
78
|
+
| 'getBlocks'
|
|
79
|
+
| 'getCheckpoints'
|
|
80
|
+
| 'getBlockHeader'
|
|
81
|
+
| 'getL2Tips'
|
|
82
|
+
| 'getCheckpointedBlocks'
|
|
83
|
+
| 'getCheckpointsDataForEpoch'
|
|
78
84
|
> {
|
|
79
85
|
/**
|
|
80
86
|
* Returns the tips of the L2 chain.
|
|
@@ -567,6 +573,8 @@ export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {
|
|
|
567
573
|
.args(BlockNumberPositiveSchema, z.number().gt(0).lte(MAX_RPC_BLOCKS_LEN))
|
|
568
574
|
.returns(z.array(CheckpointedL2Block.schema)),
|
|
569
575
|
|
|
576
|
+
getCheckpointsDataForEpoch: z.function().args(EpochNumberSchema).returns(z.array(CheckpointDataSchema)),
|
|
577
|
+
|
|
570
578
|
getCurrentMinFees: z.function().returns(GasFees.schema),
|
|
571
579
|
|
|
572
580
|
getMaxPriorityFees: z.function().returns(GasFees.schema),
|
|
@@ -53,7 +53,7 @@ export interface PublicProcessorValidator {
|
|
|
53
53
|
nullifierCache?: { addNullifiers: (nullifiers: Buffer[]) => void };
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
export type FullNodeBlockBuilderConfig = Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'> &
|
|
56
|
+
export type FullNodeBlockBuilderConfig = Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration' | 'rollupManaLimit'> &
|
|
57
57
|
Pick<ChainConfig, 'l1ChainId' | 'rollupVersion'> &
|
|
58
58
|
Pick<
|
|
59
59
|
SequencerConfig,
|
|
@@ -64,10 +64,7 @@ export type FullNodeBlockBuilderConfig = Pick<L1RollupConstants, 'l1GenesisTime'
|
|
|
64
64
|
| 'maxTxsPerCheckpoint'
|
|
65
65
|
| 'maxL2BlockGas'
|
|
66
66
|
| 'maxDABlockGas'
|
|
67
|
-
|
|
68
|
-
/** Total L2 gas (mana) allowed per checkpoint. Fetched from L1 getManaLimit(). */
|
|
69
|
-
rollupManaLimit: number;
|
|
70
|
-
};
|
|
67
|
+
>;
|
|
71
68
|
|
|
72
69
|
export const FullNodeBlockBuilderConfigKeys: (keyof FullNodeBlockBuilderConfig)[] = [
|
|
73
70
|
'l1GenesisTime',
|
|
@@ -84,11 +81,15 @@ export const FullNodeBlockBuilderConfigKeys: (keyof FullNodeBlockBuilderConfig)[
|
|
|
84
81
|
'rollupManaLimit',
|
|
85
82
|
] as const;
|
|
86
83
|
|
|
87
|
-
/** Thrown when
|
|
88
|
-
export class
|
|
89
|
-
constructor(
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
/** Thrown when the number of successfully processed transactions is below the required minimum. */
|
|
85
|
+
export class InsufficientValidTxsError extends Error {
|
|
86
|
+
constructor(
|
|
87
|
+
public readonly processedCount: number,
|
|
88
|
+
public readonly minRequired: number,
|
|
89
|
+
public readonly failedTxs: FailedTx[],
|
|
90
|
+
) {
|
|
91
|
+
super(`Insufficient valid txs: got ${processedCount} but need ${minRequired}`);
|
|
92
|
+
this.name = 'InsufficientValidTxsError';
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
@@ -103,11 +104,12 @@ export type BuildBlockInCheckpointResult = {
|
|
|
103
104
|
|
|
104
105
|
/** Interface for building blocks within a checkpoint context. */
|
|
105
106
|
export interface ICheckpointBlockBuilder {
|
|
107
|
+
/** Builds a single block within this checkpoint. Throws InsufficientValidTxsError if fewer than minValidTxs succeed. */
|
|
106
108
|
buildBlock(
|
|
107
109
|
pendingTxs: Iterable<Tx> | AsyncIterable<Tx>,
|
|
108
110
|
blockNumber: BlockNumber,
|
|
109
111
|
timestamp: bigint,
|
|
110
|
-
opts: PublicProcessorLimits,
|
|
112
|
+
opts: PublicProcessorLimits & { minValidTxs?: number },
|
|
111
113
|
): Promise<BuildBlockInCheckpointResult>;
|
|
112
114
|
}
|
|
113
115
|
|
|
@@ -225,30 +225,20 @@ export interface MerkleTreeReadOperations {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
export interface MerkleTreeCheckpointOperations {
|
|
228
|
-
/**
|
|
229
|
-
|
|
230
|
-
*/
|
|
231
|
-
createCheckpoint(): Promise<void>;
|
|
228
|
+
/** Checkpoints the current fork state. Returns the depth of the new checkpoint. */
|
|
229
|
+
createCheckpoint(): Promise<number>;
|
|
232
230
|
|
|
233
|
-
/**
|
|
234
|
-
* Commits the current checkpoint
|
|
235
|
-
*/
|
|
231
|
+
/** Commits the current checkpoint. */
|
|
236
232
|
commitCheckpoint(): Promise<void>;
|
|
237
233
|
|
|
238
|
-
/**
|
|
239
|
-
* Reverts the current checkpoint
|
|
240
|
-
*/
|
|
234
|
+
/** Reverts the current checkpoint. */
|
|
241
235
|
revertCheckpoint(): Promise<void>;
|
|
242
236
|
|
|
243
|
-
/**
|
|
244
|
-
|
|
245
|
-
*/
|
|
246
|
-
commitAllCheckpoints(): Promise<void>;
|
|
237
|
+
/** Commits all checkpoints above the given depth, leaving checkpoint depth at the given value. */
|
|
238
|
+
commitAllCheckpointsTo(depth: number): Promise<void>;
|
|
247
239
|
|
|
248
|
-
/**
|
|
249
|
-
|
|
250
|
-
*/
|
|
251
|
-
revertAllCheckpoints(): Promise<void>;
|
|
240
|
+
/** Reverts all checkpoints above the given depth, leaving checkpoint depth at the given value. */
|
|
241
|
+
revertAllCheckpointsTo(depth: number): Promise<void>;
|
|
252
242
|
}
|
|
253
243
|
|
|
254
244
|
export interface MerkleTreeWriteOperations
|
|
@@ -23,6 +23,8 @@ export type ActualProverConfig = {
|
|
|
23
23
|
* When true, jobs are explicitly cancelled with the broker, which prevents reuse.
|
|
24
24
|
*/
|
|
25
25
|
cancelJobsOnStop: boolean;
|
|
26
|
+
/** Max concurrent jobs the orchestrator serializes and enqueues to the broker. */
|
|
27
|
+
enqueueConcurrency: number;
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -53,6 +55,7 @@ export const ProverConfigSchema = zodFor<ProverConfig>()(
|
|
|
53
55
|
proofStore: z.string().optional(),
|
|
54
56
|
failedProofStore: z.string().optional(),
|
|
55
57
|
cancelJobsOnStop: z.boolean(),
|
|
58
|
+
enqueueConcurrency: z.number(),
|
|
56
59
|
}),
|
|
57
60
|
);
|
|
58
61
|
|
|
@@ -107,6 +110,11 @@ export const proverConfigMappings: ConfigMappingsType<ProverConfig> = {
|
|
|
107
110
|
'When true, jobs are explicitly cancelled with the broker, which prevents reuse.',
|
|
108
111
|
...booleanConfigHelper(false),
|
|
109
112
|
},
|
|
113
|
+
enqueueConcurrency: {
|
|
114
|
+
env: 'PROVER_ENQUEUE_CONCURRENCY',
|
|
115
|
+
description: 'Max concurrent jobs the orchestrator serializes and enqueues to the broker.',
|
|
116
|
+
...numberConfigHelper(50),
|
|
117
|
+
},
|
|
110
118
|
};
|
|
111
119
|
|
|
112
120
|
function parseProverId(str?: string) {
|
|
@@ -11,7 +11,6 @@ import type { ScopedNoteHash } from '../note_hash.js';
|
|
|
11
11
|
import { NoteHashReadRequestHintsBuilder } from './note_hash_read_request_hints.js';
|
|
12
12
|
import type { ScopedReadRequest } from './read_request.js';
|
|
13
13
|
import { PendingReadHint, ReadRequestActionEnum, ReadRequestResetActions } from './read_request_hints.js';
|
|
14
|
-
import { ScopedValueCache } from './scoped_value_cache.js';
|
|
15
14
|
|
|
16
15
|
export function isValidNoteHashReadRequest(readRequest: ScopedReadRequest, noteHash: ScopedNoteHash) {
|
|
17
16
|
return (
|
|
@@ -24,7 +23,6 @@ export function isValidNoteHashReadRequest(readRequest: ScopedReadRequest, noteH
|
|
|
24
23
|
export function getNoteHashReadRequestResetActions(
|
|
25
24
|
noteHashReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>,
|
|
26
25
|
noteHashes: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
|
|
27
|
-
futureNoteHashes: ScopedNoteHash[],
|
|
28
26
|
): ReadRequestResetActions<typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX> {
|
|
29
27
|
const resetActions = ReadRequestResetActions.empty(MAX_NOTE_HASH_READ_REQUESTS_PER_TX);
|
|
30
28
|
|
|
@@ -36,24 +34,23 @@ export function getNoteHashReadRequestResetActions(
|
|
|
36
34
|
noteHashMap.set(value, arr);
|
|
37
35
|
});
|
|
38
36
|
|
|
39
|
-
const futureNoteHashMap = new ScopedValueCache(futureNoteHashes);
|
|
40
|
-
|
|
41
37
|
for (let i = 0; i < noteHashReadRequests.claimedLength; ++i) {
|
|
42
38
|
const readRequest = noteHashReadRequests.array[i];
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
.
|
|
46
|
-
?.find(n => isValidNoteHashReadRequest(readRequest, n.noteHash));
|
|
47
|
-
|
|
48
|
-
if (pendingNoteHash !== undefined) {
|
|
49
|
-
resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
|
|
50
|
-
resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNoteHash.index));
|
|
51
|
-
} else if (
|
|
52
|
-
!futureNoteHashMap
|
|
53
|
-
.get(readRequest)
|
|
54
|
-
.find(futureNoteHash => isValidNoteHashReadRequest(readRequest, futureNoteHash))
|
|
55
|
-
) {
|
|
40
|
+
if (readRequest.contractAddress.isZero()) {
|
|
41
|
+
// Settled read: empty contract address means resolve against the note hash tree.
|
|
56
42
|
resetActions.actions[i] = ReadRequestActionEnum.READ_AS_SETTLED;
|
|
43
|
+
} else {
|
|
44
|
+
// Pending read: non-empty contract address means match against a pending note hash.
|
|
45
|
+
const pendingNoteHash = noteHashMap
|
|
46
|
+
.get(readRequest.value.toBigInt())
|
|
47
|
+
?.find(n => isValidNoteHashReadRequest(readRequest, n.noteHash));
|
|
48
|
+
|
|
49
|
+
if (pendingNoteHash) {
|
|
50
|
+
resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
|
|
51
|
+
resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNoteHash.index));
|
|
52
|
+
}
|
|
53
|
+
// Otherwise, the read request may be resolved by a future note hash. Leave as NOOP.
|
|
57
54
|
}
|
|
58
55
|
}
|
|
59
56
|
|
|
@@ -115,11 +112,10 @@ export async function buildNoteHashReadRequestHints<PENDING extends number, SETT
|
|
|
115
112
|
},
|
|
116
113
|
noteHashReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>,
|
|
117
114
|
noteHashes: ClaimedLengthArray<ScopedNoteHash, typeof MAX_NOTE_HASHES_PER_TX>,
|
|
118
|
-
futureNoteHashes: ScopedNoteHash[],
|
|
119
115
|
maxPending: PENDING = MAX_NOTE_HASH_READ_REQUESTS_PER_TX as PENDING,
|
|
120
116
|
maxSettled: SETTLED = MAX_NOTE_HASH_READ_REQUESTS_PER_TX as SETTLED,
|
|
121
117
|
) {
|
|
122
|
-
const resetActions = getNoteHashReadRequestResetActions(noteHashReadRequests, noteHashes
|
|
118
|
+
const resetActions = getNoteHashReadRequestResetActions(noteHashReadRequests, noteHashes);
|
|
123
119
|
return await buildNoteHashReadRequestHintsFromResetActions(
|
|
124
120
|
oracle,
|
|
125
121
|
noteHashReadRequests,
|
|
@@ -12,7 +12,6 @@ import type { ScopedNullifier } from '../nullifier.js';
|
|
|
12
12
|
import { NullifierReadRequestHintsBuilder } from './nullifier_read_request_hints.js';
|
|
13
13
|
import { ScopedReadRequest } from './read_request.js';
|
|
14
14
|
import { PendingReadHint, ReadRequestActionEnum, ReadRequestResetActions } from './read_request_hints.js';
|
|
15
|
-
import { ScopedValueCache } from './scoped_value_cache.js';
|
|
16
15
|
|
|
17
16
|
export function isValidNullifierReadRequest(readRequest: ScopedReadRequest, nullifier: ScopedNullifier) {
|
|
18
17
|
return (
|
|
@@ -30,7 +29,6 @@ interface NullifierMembershipWitnessWithPreimage {
|
|
|
30
29
|
export function getNullifierReadRequestResetActions(
|
|
31
30
|
nullifierReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
|
|
32
31
|
nullifiers: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
|
|
33
|
-
futureNullifiers: ScopedNullifier[],
|
|
34
32
|
): ReadRequestResetActions<typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX> {
|
|
35
33
|
const resetActions = ReadRequestResetActions.empty(MAX_NULLIFIER_READ_REQUESTS_PER_TX);
|
|
36
34
|
|
|
@@ -42,23 +40,23 @@ export function getNullifierReadRequestResetActions(
|
|
|
42
40
|
nullifierMap.set(value, arr);
|
|
43
41
|
});
|
|
44
42
|
|
|
45
|
-
const futureNullifiersMap = new ScopedValueCache(futureNullifiers);
|
|
46
|
-
|
|
47
43
|
for (let i = 0; i < nullifierReadRequests.claimedLength; ++i) {
|
|
48
44
|
const readRequest = nullifierReadRequests.array[i];
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (pendingNullifier !== undefined) {
|
|
54
|
-
resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
|
|
55
|
-
resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNullifier.index));
|
|
56
|
-
} else if (
|
|
57
|
-
!futureNullifiersMap
|
|
58
|
-
.get(readRequest)
|
|
59
|
-
.some(futureNullifier => isValidNullifierReadRequest(readRequest, futureNullifier))
|
|
60
|
-
) {
|
|
45
|
+
|
|
46
|
+
if (readRequest.contractAddress.isZero()) {
|
|
47
|
+
// Settled read: empty contract address means resolve against the nullifier tree.
|
|
61
48
|
resetActions.actions[i] = ReadRequestActionEnum.READ_AS_SETTLED;
|
|
49
|
+
} else {
|
|
50
|
+
// Pending read: non-empty contract address means match against a pending nullifier.
|
|
51
|
+
const pendingNullifier = nullifierMap
|
|
52
|
+
.get(readRequest.value.toBigInt())
|
|
53
|
+
?.find(({ nullifier }) => isValidNullifierReadRequest(readRequest, nullifier));
|
|
54
|
+
|
|
55
|
+
if (pendingNullifier) {
|
|
56
|
+
resetActions.actions[i] = ReadRequestActionEnum.READ_AS_PENDING;
|
|
57
|
+
resetActions.pendingReadHints.push(new PendingReadHint(i, pendingNullifier.index));
|
|
58
|
+
}
|
|
59
|
+
// Otherwise, the read request may be resolved by a future nullifier. Leave as NOOP.
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
@@ -111,11 +109,10 @@ export async function buildNullifierReadRequestHints<PENDING extends number, SET
|
|
|
111
109
|
},
|
|
112
110
|
nullifierReadRequests: ClaimedLengthArray<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
|
|
113
111
|
nullifiers: ClaimedLengthArray<ScopedNullifier, typeof MAX_NULLIFIERS_PER_TX>,
|
|
114
|
-
futureNullifiers: ScopedNullifier[],
|
|
115
112
|
maxPending: PENDING = MAX_NULLIFIER_READ_REQUESTS_PER_TX as PENDING,
|
|
116
113
|
maxSettled: SETTLED = MAX_NULLIFIER_READ_REQUESTS_PER_TX as SETTLED,
|
|
117
114
|
) {
|
|
118
|
-
const resetActions = getNullifierReadRequestResetActions(nullifierReadRequests, nullifiers
|
|
115
|
+
const resetActions = getNullifierReadRequestResetActions(nullifierReadRequests, nullifiers);
|
|
119
116
|
return await buildNullifierReadRequestHintsFromResetActions(
|
|
120
117
|
oracle,
|
|
121
118
|
nullifierReadRequests,
|
|
@@ -4,6 +4,7 @@ import type { Tuple } from '@aztec/foundation/serialize';
|
|
|
4
4
|
import type { ClaimedLengthArray } from '../claimed_length_array.js';
|
|
5
5
|
import type { ScopedNoteHash } from '../note_hash.js';
|
|
6
6
|
import type { ScopedNullifier } from '../nullifier.js';
|
|
7
|
+
import type { PrivateLogData, ScopedPrivateLogData } from '../private_log_data.js';
|
|
7
8
|
import { isValidNoteHashReadRequest } from './build_note_hash_read_request_hints.js';
|
|
8
9
|
import { isValidNullifierReadRequest } from './build_nullifier_read_request_hints.js';
|
|
9
10
|
import type { ScopedReadRequest } from './read_request.js';
|
|
@@ -15,11 +16,13 @@ export function buildTransientDataHints<NOTE_HASHES_LEN extends number, NULLIFIE
|
|
|
15
16
|
nullifiers: ClaimedLengthArray<ScopedNullifier, NULLIFIERS_LEN>,
|
|
16
17
|
futureNoteHashReads: ScopedReadRequest[],
|
|
17
18
|
futureNullifierReads: ScopedReadRequest[],
|
|
19
|
+
futureLogs: PrivateLogData[],
|
|
18
20
|
noteHashNullifierCounterMap: Map<number, number>,
|
|
19
21
|
splitCounter: number,
|
|
20
22
|
): { numTransientData: number; hints: Tuple<TransientDataSquashingHint, NULLIFIERS_LEN> } {
|
|
21
23
|
const futureNoteHashReadsMap = new ScopedValueCache(futureNoteHashReads);
|
|
22
24
|
const futureNullifierReadsMap = new ScopedValueCache(futureNullifierReads);
|
|
25
|
+
const futureLogNoteHashCounters = new Set(futureLogs.filter(l => l.noteHashCounter > 0).map(l => l.noteHashCounter));
|
|
23
26
|
|
|
24
27
|
const nullifierIndexMap: Map<number, number> = new Map();
|
|
25
28
|
nullifiers.getActiveItems().forEach((n, i) => nullifierIndexMap.set(n.counter, i));
|
|
@@ -28,10 +31,12 @@ export function buildTransientDataHints<NOTE_HASHES_LEN extends number, NULLIFIE
|
|
|
28
31
|
for (let noteHashIndex = 0; noteHashIndex < noteHashes.claimedLength; noteHashIndex++) {
|
|
29
32
|
const noteHash = noteHashes.array[noteHashIndex];
|
|
30
33
|
const noteHashNullifierCounter = noteHashNullifierCounterMap.get(noteHash.counter);
|
|
31
|
-
// The note hash might not be linked to a nullifier or it might be read in the future
|
|
34
|
+
// The note hash might not be linked to a nullifier, or it might be read in the future, or a future log might be
|
|
35
|
+
// linked to it.
|
|
32
36
|
if (
|
|
33
37
|
!noteHashNullifierCounter ||
|
|
34
|
-
futureNoteHashReadsMap.get(noteHash).find(read => isValidNoteHashReadRequest(read, noteHash))
|
|
38
|
+
futureNoteHashReadsMap.get(noteHash).find(read => isValidNoteHashReadRequest(read, noteHash)) ||
|
|
39
|
+
futureLogNoteHashCounters.has(noteHash.counter)
|
|
35
40
|
) {
|
|
36
41
|
continue;
|
|
37
42
|
}
|
|
@@ -77,3 +82,13 @@ export function buildTransientDataHints<NOTE_HASHES_LEN extends number, NULLIFIE
|
|
|
77
82
|
hints: padArrayEnd(hints, noActionHint, nullifiers.array.length as NULLIFIERS_LEN),
|
|
78
83
|
};
|
|
79
84
|
}
|
|
85
|
+
|
|
86
|
+
/** Counts private logs that are linked to squashed note hashes and would be removed along with them. */
|
|
87
|
+
export function countSquashedLogs<NOTE_HASHES_LEN extends number, LOGS_LEN extends number>(
|
|
88
|
+
noteHashes: ClaimedLengthArray<ScopedNoteHash, NOTE_HASHES_LEN>,
|
|
89
|
+
privateLogs: ClaimedLengthArray<ScopedPrivateLogData, LOGS_LEN>,
|
|
90
|
+
squashingHints: TransientDataSquashingHint[],
|
|
91
|
+
): number {
|
|
92
|
+
const squashedNoteHashCounters = new Set(squashingHints.map(h => noteHashes.array[h.noteHashIndex].counter));
|
|
93
|
+
return privateLogs.getActiveItems().filter(l => squashedNoteHashCounters.has(l.inner.noteHashCounter)).length;
|
|
94
|
+
}
|
package/src/logs/log_filter.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
|
+
|
|
1
3
|
import { z } from 'zod';
|
|
2
4
|
|
|
3
5
|
import type { AztecAddress } from '../aztec-address/index.js';
|
|
@@ -20,6 +22,8 @@ export type LogFilter = {
|
|
|
20
22
|
afterLog?: LogId;
|
|
21
23
|
/** The contract address to filter logs by. */
|
|
22
24
|
contractAddress?: AztecAddress;
|
|
25
|
+
/** The tag (first field of the log) to filter logs by. */
|
|
26
|
+
tag?: Fr;
|
|
23
27
|
};
|
|
24
28
|
|
|
25
29
|
export const LogFilterSchema: ZodFor<LogFilter> = z.object({
|
|
@@ -28,4 +32,5 @@ export const LogFilterSchema: ZodFor<LogFilter> = z.object({
|
|
|
28
32
|
toBlock: schemas.Integer.optional(),
|
|
29
33
|
afterLog: LogId.schema.optional(),
|
|
30
34
|
contractAddress: schemas.AztecAddress.optional(),
|
|
35
|
+
tag: schemas.Fr.optional(),
|
|
31
36
|
});
|
package/src/logs/public_log.ts
CHANGED
|
@@ -120,8 +120,8 @@ export class FlatPublicLogs {
|
|
|
120
120
|
|
|
121
121
|
export class PublicLog {
|
|
122
122
|
constructor(
|
|
123
|
-
public contractAddress: AztecAddress,
|
|
124
|
-
public fields: Fr[],
|
|
123
|
+
public readonly contractAddress: AztecAddress,
|
|
124
|
+
public readonly fields: Fr[],
|
|
125
125
|
) {}
|
|
126
126
|
|
|
127
127
|
static from(fields: FieldsOf<PublicLog>) {
|
|
@@ -146,7 +146,9 @@ export class PublicLog {
|
|
|
146
146
|
return this.fields.length + PUBLIC_LOG_HEADER_LENGTH;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
/** Returns the serialized log (field as in noir field and not a struct field). */
|
|
149
150
|
getEmittedFields() {
|
|
151
|
+
// We slice from 0 to return a shallow copy.
|
|
150
152
|
return this.fields.slice(0);
|
|
151
153
|
}
|
|
152
154
|
|