@aztec/stdlib 0.83.1 → 0.84.0
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/abi.d.ts +2 -2
- package/dest/abi/abi.d.ts.map +1 -1
- package/dest/abi/abi.js +1 -1
- package/dest/abi/contract_artifact.d.ts.map +1 -1
- package/dest/abi/contract_artifact.js +21 -9
- package/dest/avm/avm.d.ts +1203 -694
- package/dest/avm/avm.d.ts.map +1 -1
- package/dest/avm/avm.js +58 -6
- package/dest/avm/avm_circuit_public_inputs.d.ts +80 -80
- package/dest/avm/avm_proving_request.d.ts +672 -447
- package/dest/avm/avm_proving_request.d.ts.map +1 -1
- package/dest/config/config.d.ts +2 -1
- package/dest/config/config.d.ts.map +1 -1
- package/dest/contract/artifact_hash.d.ts +5 -5
- package/dest/contract/artifact_hash.d.ts.map +1 -1
- package/dest/contract/artifact_hash.js +8 -8
- package/dest/contract/index.d.ts +1 -1
- package/dest/contract/index.d.ts.map +1 -1
- package/dest/contract/index.js +1 -1
- package/dest/contract/interfaces/contract_class.d.ts +23 -19
- package/dest/contract/interfaces/contract_class.d.ts.map +1 -1
- package/dest/contract/interfaces/contract_class.js +4 -4
- package/dest/contract/interfaces/contract_instance.d.ts +2 -2
- package/dest/contract/private_function_membership_proof.d.ts +1 -1
- package/dest/contract/private_function_membership_proof.js +6 -6
- package/dest/contract/utility_function_membership_proof.d.ts +27 -0
- package/dest/contract/utility_function_membership_proof.d.ts.map +1 -0
- package/dest/contract/{unconstrained_function_membership_proof.js → utility_function_membership_proof.js} +13 -13
- package/dest/interfaces/allowed_element.d.ts +53 -0
- package/dest/interfaces/allowed_element.d.ts.map +1 -0
- package/dest/interfaces/allowed_element.js +18 -0
- package/dest/interfaces/configs.d.ts +17 -34
- package/dest/interfaces/configs.d.ts.map +1 -1
- package/dest/interfaces/configs.js +2 -17
- package/dest/interfaces/proving-job.d.ts +672 -447
- package/dest/interfaces/proving-job.d.ts.map +1 -1
- package/dest/interfaces/public_state_source.d.ts +8 -0
- package/dest/interfaces/public_state_source.d.ts.map +1 -0
- package/dest/interfaces/public_state_source.js +1 -0
- package/dest/interfaces/pxe.d.ts +7 -8
- package/dest/interfaces/pxe.d.ts.map +1 -1
- package/dest/interfaces/pxe.js +1 -1
- package/dest/interfaces/server.d.ts +1 -0
- package/dest/interfaces/server.d.ts.map +1 -1
- package/dest/interfaces/server.js +1 -0
- package/dest/logs/tx_scoped_l2_log.d.ts +1 -1
- package/dest/noir/index.d.ts +3 -1
- package/dest/noir/index.d.ts.map +1 -1
- package/dest/noir/index.js +1 -0
- package/dest/note/extended_note.d.ts +3 -3
- package/dest/proofs/proof.d.ts +0 -1
- package/dest/proofs/proof.d.ts.map +1 -1
- package/dest/proofs/proof.js +6 -11
- package/dest/tests/factories.d.ts +4 -3
- package/dest/tests/factories.d.ts.map +1 -1
- package/dest/tests/factories.js +15 -6
- package/dest/trees/database_public_state_source.d.ts +11 -0
- package/dest/trees/database_public_state_source.d.ts.map +1 -0
- package/dest/trees/database_public_state_source.js +18 -0
- package/dest/trees/index.d.ts +1 -0
- package/dest/trees/index.d.ts.map +1 -1
- package/dest/trees/index.js +1 -0
- package/dest/tx/call_context.d.ts +1 -1
- package/dest/tx/tree_snapshots.d.ts +6 -6
- package/package.json +6 -6
- package/src/abi/abi.ts +2 -2
- package/src/abi/contract_artifact.ts +22 -8
- package/src/avm/avm.ts +89 -5
- package/src/config/config.ts +2 -1
- package/src/contract/artifact_hash.ts +9 -9
- package/src/contract/index.ts +1 -1
- package/src/contract/interfaces/contract_class.ts +21 -17
- package/src/contract/private_function_membership_proof.ts +6 -6
- package/src/contract/{unconstrained_function_membership_proof.ts → utility_function_membership_proof.ts} +18 -18
- package/src/interfaces/allowed_element.ts +21 -0
- package/src/interfaces/configs.ts +3 -18
- package/src/interfaces/public_state_source.ts +9 -0
- package/src/interfaces/pxe.ts +8 -9
- package/src/interfaces/server.ts +1 -0
- package/src/noir/index.ts +2 -1
- package/src/proofs/proof.ts +6 -16
- package/src/tests/factories.ts +23 -6
- package/src/trees/database_public_state_source.ts +30 -0
- package/src/trees/index.ts +1 -0
- package/dest/contract/unconstrained_function_membership_proof.d.ts +0 -27
- package/dest/contract/unconstrained_function_membership_proof.d.ts.map +0 -1
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
AZTEC_INTERNAL_ATTRIBUTE,
|
|
22
22
|
AZTEC_PRIVATE_ATTRIBUTE,
|
|
23
23
|
AZTEC_PUBLIC_ATTRIBUTE,
|
|
24
|
+
AZTEC_UTILITY_ATTRIBUTE,
|
|
24
25
|
AZTEC_VIEW_ATTRIBUTE,
|
|
25
26
|
type NoirCompiledContract,
|
|
26
27
|
} from '../noir/index.js';
|
|
@@ -155,14 +156,14 @@ function generateFunctionAbi(fn: NoirCompiledContractFunction, contract: NoirCom
|
|
|
155
156
|
const isInternal = fn.custom_attributes.includes(AZTEC_INTERNAL_ATTRIBUTE);
|
|
156
157
|
const isStatic = fn.custom_attributes.includes(AZTEC_VIEW_ATTRIBUTE);
|
|
157
158
|
|
|
158
|
-
// If the function is not
|
|
159
|
+
// If the function is not a utility function, the first item is inputs or CallContext which we should omit
|
|
159
160
|
let parameters = fn.abi.parameters.map(generateFunctionParameter);
|
|
160
161
|
if (hasKernelFunctionInputs(parameters)) {
|
|
161
162
|
parameters = parameters.slice(1);
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
let returnTypes: AbiType[] = [];
|
|
165
|
-
if (functionType === FunctionType.
|
|
166
|
+
if (functionType === FunctionType.UTILITY) {
|
|
166
167
|
returnTypes = fn.abi.return_type ? [fn.abi.return_type.abi_type] : returnTypes;
|
|
167
168
|
} else {
|
|
168
169
|
const pathToFind = `${contract.name}::${fn.name}_abi`;
|
|
@@ -215,18 +216,31 @@ function generateFunctionArtifact(
|
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
function getFunctionType(fn: NoirCompiledContractFunction): FunctionType {
|
|
218
|
-
if (fn.custom_attributes.
|
|
219
|
+
if (fn.custom_attributes.some(attr => attr.endsWith(AZTEC_PRIVATE_ATTRIBUTE))) {
|
|
219
220
|
return FunctionType.PRIVATE;
|
|
220
|
-
} else if (fn.custom_attributes.
|
|
221
|
+
} else if (fn.custom_attributes.some(attr => attr.endsWith(AZTEC_PUBLIC_ATTRIBUTE))) {
|
|
221
222
|
return FunctionType.PUBLIC;
|
|
222
|
-
} else if (fn.
|
|
223
|
-
return FunctionType.
|
|
223
|
+
} else if (fn.custom_attributes.some(attr => attr.endsWith(AZTEC_UTILITY_ATTRIBUTE))) {
|
|
224
|
+
return FunctionType.UTILITY;
|
|
224
225
|
} else {
|
|
225
|
-
|
|
226
|
-
return FunctionType.PRIVATE;
|
|
226
|
+
throw new Error(`Invalid function type for a noir contract function ${fn.name}`);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
// TODO(https://github.com/noir-lang/noir/issues/7912): Replace the above function with this one once the linked issue
|
|
231
|
+
// is fixed.
|
|
232
|
+
// function getFunctionType(fn: NoirCompiledContractFunction): FunctionType {
|
|
233
|
+
// if (fn.custom_attributes.includes(AZTEC_PRIVATE_ATTRIBUTE)) {
|
|
234
|
+
// return FunctionType.PRIVATE;
|
|
235
|
+
// } else if (fn.custom_attributes.includes(AZTEC_PUBLIC_ATTRIBUTE)) {
|
|
236
|
+
// return FunctionType.PUBLIC;
|
|
237
|
+
// } else if (fn.custom_attributes.includes(AZTEC_UTILITY_ATTRIBUTE)) {
|
|
238
|
+
// return FunctionType.UTILITY;
|
|
239
|
+
// } else {
|
|
240
|
+
// throw new Error(`Invalid function type for a noir contract function ${fn.name}`);
|
|
241
|
+
// }
|
|
242
|
+
// }
|
|
243
|
+
|
|
230
244
|
/**
|
|
231
245
|
* Returns true if the first parameter is kernel function inputs.
|
|
232
246
|
*
|
package/src/avm/avm.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
|
|
|
10
10
|
import { MerkleTreeId } from '../trees/merkle_tree_id.js';
|
|
11
11
|
import { NullifierLeafPreimage } from '../trees/nullifier_leaf.js';
|
|
12
12
|
import { PublicDataTreeLeafPreimage } from '../trees/public_data_leaf.js';
|
|
13
|
+
import type { Tx } from '../tx/index.js';
|
|
13
14
|
import { AvmCircuitPublicInputs } from './avm_circuit_public_inputs.js';
|
|
14
15
|
import { serializeWithMessagePack } from './message_pack.js';
|
|
15
16
|
|
|
@@ -287,9 +288,92 @@ export class AvmEnqueuedCallHint {
|
|
|
287
288
|
}
|
|
288
289
|
}
|
|
289
290
|
|
|
291
|
+
export class AvmTxHint {
|
|
292
|
+
constructor(
|
|
293
|
+
public readonly nonRevertibleAccumulatedData: {
|
|
294
|
+
noteHashes: Fr[];
|
|
295
|
+
nullifiers: Fr[];
|
|
296
|
+
// TODO: add as needed.
|
|
297
|
+
},
|
|
298
|
+
public readonly revertibleAccumulatedData: {
|
|
299
|
+
noteHashes: Fr[];
|
|
300
|
+
nullifiers: Fr[];
|
|
301
|
+
// TODO: add as needed.
|
|
302
|
+
},
|
|
303
|
+
public readonly setupEnqueuedCalls: AvmEnqueuedCallHint[],
|
|
304
|
+
public readonly appLogicEnqueuedCalls: AvmEnqueuedCallHint[],
|
|
305
|
+
// We need this to be null and not undefined because that's what
|
|
306
|
+
// MessagePack expects for an std::optional.
|
|
307
|
+
public readonly teardownEnqueuedCall: AvmEnqueuedCallHint | null,
|
|
308
|
+
) {}
|
|
309
|
+
|
|
310
|
+
static fromTx(tx: Tx): AvmTxHint {
|
|
311
|
+
const setupCallRequests = tx.getNonRevertiblePublicCallRequestsWithCalldata();
|
|
312
|
+
const appLogicCallRequests = tx.getRevertiblePublicCallRequestsWithCalldata();
|
|
313
|
+
const teardownCallRequest = tx.getTeardownPublicCallRequestWithCalldata();
|
|
314
|
+
|
|
315
|
+
return new AvmTxHint(
|
|
316
|
+
{
|
|
317
|
+
noteHashes: tx.data.forPublic!.nonRevertibleAccumulatedData.noteHashes.filter(x => !x.isZero()),
|
|
318
|
+
nullifiers: tx.data.forPublic!.nonRevertibleAccumulatedData.nullifiers.filter(x => !x.isZero()),
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
noteHashes: tx.data.forPublic!.revertibleAccumulatedData.noteHashes.filter(x => !x.isZero()),
|
|
322
|
+
nullifiers: tx.data.forPublic!.revertibleAccumulatedData.nullifiers.filter(x => !x.isZero()),
|
|
323
|
+
},
|
|
324
|
+
setupCallRequests.map(
|
|
325
|
+
call =>
|
|
326
|
+
new AvmEnqueuedCallHint(
|
|
327
|
+
call.request.msgSender,
|
|
328
|
+
call.request.contractAddress,
|
|
329
|
+
call.calldata,
|
|
330
|
+
call.request.isStaticCall,
|
|
331
|
+
),
|
|
332
|
+
),
|
|
333
|
+
appLogicCallRequests.map(
|
|
334
|
+
call =>
|
|
335
|
+
new AvmEnqueuedCallHint(
|
|
336
|
+
call.request.msgSender,
|
|
337
|
+
call.request.contractAddress,
|
|
338
|
+
call.calldata,
|
|
339
|
+
call.request.isStaticCall,
|
|
340
|
+
),
|
|
341
|
+
),
|
|
342
|
+
teardownCallRequest
|
|
343
|
+
? new AvmEnqueuedCallHint(
|
|
344
|
+
teardownCallRequest.request.msgSender,
|
|
345
|
+
teardownCallRequest.request.contractAddress,
|
|
346
|
+
teardownCallRequest.calldata,
|
|
347
|
+
teardownCallRequest.request.isStaticCall,
|
|
348
|
+
)
|
|
349
|
+
: null,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
static empty() {
|
|
354
|
+
return new AvmTxHint({ noteHashes: [], nullifiers: [] }, { noteHashes: [], nullifiers: [] }, [], [], null);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
static get schema() {
|
|
358
|
+
return z.object({
|
|
359
|
+
nonRevertibleAccumulatedData: z.object({
|
|
360
|
+
noteHashes: schemas.Fr.array(),
|
|
361
|
+
nullifiers: schemas.Fr.array(),
|
|
362
|
+
}),
|
|
363
|
+
revertibleAccumulatedData: z.object({
|
|
364
|
+
noteHashes: schemas.Fr.array(),
|
|
365
|
+
nullifiers: schemas.Fr.array(),
|
|
366
|
+
}),
|
|
367
|
+
setupEnqueuedCalls: AvmEnqueuedCallHint.schema.array(),
|
|
368
|
+
appLogicEnqueuedCalls: AvmEnqueuedCallHint.schema.array(),
|
|
369
|
+
teardownEnqueuedCall: AvmEnqueuedCallHint.schema.nullable(),
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
290
374
|
export class AvmExecutionHints {
|
|
291
375
|
constructor(
|
|
292
|
-
public
|
|
376
|
+
public tx: AvmTxHint,
|
|
293
377
|
// Contract hints.
|
|
294
378
|
public readonly contractInstances: AvmContractInstanceHint[] = [],
|
|
295
379
|
public readonly contractClasses: AvmContractClassHint[] = [],
|
|
@@ -305,13 +389,13 @@ export class AvmExecutionHints {
|
|
|
305
389
|
) {}
|
|
306
390
|
|
|
307
391
|
static empty() {
|
|
308
|
-
return new AvmExecutionHints();
|
|
392
|
+
return new AvmExecutionHints(AvmTxHint.empty());
|
|
309
393
|
}
|
|
310
394
|
|
|
311
395
|
static get schema() {
|
|
312
396
|
return z
|
|
313
397
|
.object({
|
|
314
|
-
|
|
398
|
+
tx: AvmTxHint.schema,
|
|
315
399
|
contractInstances: AvmContractInstanceHint.schema.array(),
|
|
316
400
|
contractClasses: AvmContractClassHint.schema.array(),
|
|
317
401
|
bytecodeCommitments: AvmBytecodeCommitmentHint.schema.array(),
|
|
@@ -325,7 +409,7 @@ export class AvmExecutionHints {
|
|
|
325
409
|
})
|
|
326
410
|
.transform(
|
|
327
411
|
({
|
|
328
|
-
|
|
412
|
+
tx,
|
|
329
413
|
contractInstances,
|
|
330
414
|
contractClasses,
|
|
331
415
|
bytecodeCommitments,
|
|
@@ -338,7 +422,7 @@ export class AvmExecutionHints {
|
|
|
338
422
|
sequentialInsertHintsNullifierTree,
|
|
339
423
|
}) =>
|
|
340
424
|
new AvmExecutionHints(
|
|
341
|
-
|
|
425
|
+
tx,
|
|
342
426
|
contractInstances,
|
|
343
427
|
contractClasses,
|
|
344
428
|
bytecodeCommitments,
|
package/src/config/config.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { l1ContractAddressesMapping } from '@aztec/ethereum/l1-contract-addresse
|
|
|
2
2
|
import type { ConfigMappingsType } from '@aztec/foundation/config';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
|
|
5
|
-
export { type
|
|
5
|
+
export { type SequencerConfig, SequencerConfigSchema } from '../interfaces/configs.js';
|
|
6
|
+
export { type AllowedElement } from '../interfaces/allowed_element.js';
|
|
6
7
|
|
|
7
8
|
export const emptyChainConfig: ChainConfig = {
|
|
8
9
|
l1ChainId: 0,
|
|
@@ -21,26 +21,26 @@ const sha256Fr = reduceFn(sha256, Fr);
|
|
|
21
21
|
* sha256(fn.selector, fn.metadata_hash, sha256(fn.bytecode))
|
|
22
22
|
* private_functions_artifact_tree_root = merkleize(private_functions_artifact_leaves)
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
* utility_functions_artifact_leaves = artifact.utility_functions.map fn =>
|
|
25
25
|
* sha256(fn.selector, fn.metadata_hash, sha256(fn.bytecode))
|
|
26
|
-
*
|
|
26
|
+
* utility_functions_artifact_tree_root = merkleize(utility_functions_artifact_leaves)
|
|
27
27
|
*
|
|
28
28
|
* version = 1
|
|
29
29
|
* artifact_hash = sha256(
|
|
30
30
|
* version,
|
|
31
31
|
* private_functions_artifact_tree_root,
|
|
32
|
-
*
|
|
32
|
+
* utility_functions_artifact_tree_root,
|
|
33
33
|
* artifact_metadata,
|
|
34
34
|
* )
|
|
35
35
|
* ```
|
|
36
36
|
* @param artifact - Artifact to calculate the hash for.
|
|
37
37
|
*/
|
|
38
38
|
export async function computeArtifactHash(
|
|
39
|
-
artifact: ContractArtifact | { privateFunctionRoot: Fr;
|
|
39
|
+
artifact: ContractArtifact | { privateFunctionRoot: Fr; utilityFunctionRoot: Fr; metadataHash: Fr },
|
|
40
40
|
): Promise<Fr> {
|
|
41
|
-
if ('privateFunctionRoot' in artifact && '
|
|
42
|
-
const { privateFunctionRoot,
|
|
43
|
-
const preimage = [privateFunctionRoot,
|
|
41
|
+
if ('privateFunctionRoot' in artifact && 'utilityFunctionRoot' in artifact && 'metadataHash' in artifact) {
|
|
42
|
+
const { privateFunctionRoot, utilityFunctionRoot, metadataHash } = artifact;
|
|
43
|
+
const preimage = [privateFunctionRoot, utilityFunctionRoot, metadataHash].map(x => x.toBuffer());
|
|
44
44
|
return sha256Fr(Buffer.concat([numToUInt8(VERSION), ...preimage]));
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -52,9 +52,9 @@ export async function computeArtifactHash(
|
|
|
52
52
|
|
|
53
53
|
export async function computeArtifactHashPreimage(artifact: ContractArtifact) {
|
|
54
54
|
const privateFunctionRoot = await computeArtifactFunctionTreeRoot(artifact, FunctionType.PRIVATE);
|
|
55
|
-
const
|
|
55
|
+
const utilityFunctionRoot = await computeArtifactFunctionTreeRoot(artifact, FunctionType.UTILITY);
|
|
56
56
|
const metadataHash = computeArtifactMetadataHash(artifact);
|
|
57
|
-
return { privateFunctionRoot,
|
|
57
|
+
return { privateFunctionRoot, utilityFunctionRoot, metadataHash };
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function computeArtifactMetadataHash(artifact: ContractArtifact) {
|
package/src/contract/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ export * from './contract_instance.js';
|
|
|
6
6
|
export * from './contract_instance_update.js';
|
|
7
7
|
export * from './private_function.js';
|
|
8
8
|
export * from './private_function_membership_proof.js';
|
|
9
|
-
export * from './
|
|
9
|
+
export * from './utility_function_membership_proof.js';
|
|
10
10
|
export * from './interfaces/index.js';
|
|
11
11
|
export * from './contract_function_dao.js';
|
|
12
12
|
export * from './partial_address.js';
|
|
@@ -15,7 +15,11 @@ const VERSION = 1 as const;
|
|
|
15
15
|
export interface ContractClass {
|
|
16
16
|
/** Version of the contract class. */
|
|
17
17
|
version: typeof VERSION;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Hash of the contract artifact. The specification of this hash is not enforced by the protocol. Should include
|
|
20
|
+
* commitments to code of utility functions and compilation metadata. Intended to be used by clients to verify that
|
|
21
|
+
* an off-chain fetched artifact matches a registered class.
|
|
22
|
+
*/
|
|
19
23
|
artifactHash: Fr;
|
|
20
24
|
/** List of individual private functions, constructors included. */
|
|
21
25
|
privateFunctions: PrivateFunction[];
|
|
@@ -46,25 +50,25 @@ const ExecutablePrivateFunctionSchema = PrivateFunctionSchema.and(
|
|
|
46
50
|
z.object({ bytecode: schemas.Buffer }),
|
|
47
51
|
) satisfies ZodFor<ExecutablePrivateFunction>;
|
|
48
52
|
|
|
49
|
-
/**
|
|
50
|
-
export interface
|
|
53
|
+
/** Utility function definition. */
|
|
54
|
+
export interface UtilityFunction {
|
|
51
55
|
/** Selector of the function. Calculated as the hash of the method name and parameters. The specification of this is not enforced by the protocol. */
|
|
52
56
|
selector: FunctionSelector;
|
|
53
57
|
/** Brillig. */
|
|
54
58
|
bytecode: Buffer;
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
const
|
|
61
|
+
const UtilityFunctionSchema = z.object({
|
|
58
62
|
/** lala */
|
|
59
63
|
selector: FunctionSelector.schema,
|
|
60
64
|
bytecode: schemas.Buffer,
|
|
61
|
-
}) satisfies ZodFor<
|
|
65
|
+
}) satisfies ZodFor<UtilityFunction>;
|
|
62
66
|
|
|
63
67
|
/** Sibling paths and sibling commitments for proving membership of a private function within a contract class. */
|
|
64
68
|
export type PrivateFunctionMembershipProof = {
|
|
65
69
|
artifactMetadataHash: Fr;
|
|
66
70
|
functionMetadataHash: Fr;
|
|
67
|
-
|
|
71
|
+
utilityFunctionsTreeRoot: Fr;
|
|
68
72
|
privateFunctionTreeSiblingPath: Fr[];
|
|
69
73
|
privateFunctionTreeLeafIndex: number;
|
|
70
74
|
artifactTreeSiblingPath: Fr[];
|
|
@@ -74,18 +78,18 @@ export type PrivateFunctionMembershipProof = {
|
|
|
74
78
|
const PrivateFunctionMembershipProofSchema = z.object({
|
|
75
79
|
artifactMetadataHash: schemas.Fr,
|
|
76
80
|
functionMetadataHash: schemas.Fr,
|
|
77
|
-
|
|
81
|
+
utilityFunctionsTreeRoot: schemas.Fr,
|
|
78
82
|
privateFunctionTreeSiblingPath: z.array(schemas.Fr),
|
|
79
83
|
privateFunctionTreeLeafIndex: schemas.Integer,
|
|
80
84
|
artifactTreeSiblingPath: z.array(schemas.Fr),
|
|
81
85
|
artifactTreeLeafIndex: schemas.Integer,
|
|
82
86
|
}) satisfies ZodFor<PrivateFunctionMembershipProof>;
|
|
83
87
|
|
|
84
|
-
/** A private function with a
|
|
88
|
+
/** A private function with a membership proof. */
|
|
85
89
|
export type ExecutablePrivateFunctionWithMembershipProof = ExecutablePrivateFunction & PrivateFunctionMembershipProof;
|
|
86
90
|
|
|
87
|
-
/** Sibling paths and commitments for proving membership of
|
|
88
|
-
export type
|
|
91
|
+
/** Sibling paths and commitments for proving membership of a utility function within a contract class. */
|
|
92
|
+
export type UtilityFunctionMembershipProof = {
|
|
89
93
|
artifactMetadataHash: Fr;
|
|
90
94
|
functionMetadataHash: Fr;
|
|
91
95
|
privateFunctionsArtifactTreeRoot: Fr;
|
|
@@ -93,16 +97,16 @@ export type UnconstrainedFunctionMembershipProof = {
|
|
|
93
97
|
artifactTreeLeafIndex: number;
|
|
94
98
|
};
|
|
95
99
|
|
|
96
|
-
const
|
|
100
|
+
const UtilityFunctionMembershipProofSchema = z.object({
|
|
97
101
|
artifactMetadataHash: schemas.Fr,
|
|
98
102
|
functionMetadataHash: schemas.Fr,
|
|
99
103
|
privateFunctionsArtifactTreeRoot: schemas.Fr,
|
|
100
104
|
artifactTreeSiblingPath: z.array(schemas.Fr),
|
|
101
105
|
artifactTreeLeafIndex: schemas.Integer,
|
|
102
|
-
}) satisfies ZodFor<
|
|
106
|
+
}) satisfies ZodFor<UtilityFunctionMembershipProof>;
|
|
103
107
|
|
|
104
|
-
/**
|
|
105
|
-
export type
|
|
108
|
+
/** A utility function with a membership proof. */
|
|
109
|
+
export type UtilityFunctionWithMembershipProof = UtilityFunction & UtilityFunctionMembershipProof;
|
|
106
110
|
|
|
107
111
|
export const ContractClassSchema = z.object({
|
|
108
112
|
version: z.literal(VERSION),
|
|
@@ -128,10 +132,10 @@ export const ContractClassWithIdSchema = ContractClassSchema.extend({
|
|
|
128
132
|
id: schemas.Fr,
|
|
129
133
|
}) satisfies ZodFor<ContractClassWithId>;
|
|
130
134
|
|
|
131
|
-
/** A contract class with public bytecode information, and optional private and
|
|
135
|
+
/** A contract class with public bytecode information, and optional private and utility functions. */
|
|
132
136
|
export type ContractClassPublic = {
|
|
133
137
|
privateFunctions: ExecutablePrivateFunctionWithMembershipProof[];
|
|
134
|
-
|
|
138
|
+
utilityFunctions: UtilityFunctionWithMembershipProof[];
|
|
135
139
|
} & Pick<ContractClassCommitments, 'id' | 'privateFunctionsRoot'> &
|
|
136
140
|
Omit<ContractClass, 'privateFunctions'>;
|
|
137
141
|
|
|
@@ -143,7 +147,7 @@ export const ContractClassPublicSchema = z
|
|
|
143
147
|
id: schemas.Fr,
|
|
144
148
|
privateFunctionsRoot: schemas.Fr,
|
|
145
149
|
privateFunctions: z.array(ExecutablePrivateFunctionSchema.and(PrivateFunctionMembershipProofSchema)),
|
|
146
|
-
|
|
150
|
+
utilityFunctions: z.array(UtilityFunctionSchema.and(UtilityFunctionMembershipProofSchema)),
|
|
147
151
|
})
|
|
148
152
|
.and(ContractClassSchema.omit({ privateFunctions: true })) satisfies ZodFor<ContractClassPublic>;
|
|
149
153
|
|
|
@@ -51,7 +51,7 @@ export async function createPrivateFunctionMembershipProof(
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Compute preimage for the artifact hash
|
|
54
|
-
const {
|
|
54
|
+
const { utilityFunctionRoot: utilityFunctionsTreeRoot, metadataHash: artifactMetadataHash } =
|
|
55
55
|
await computeArtifactHashPreimage(artifact);
|
|
56
56
|
|
|
57
57
|
// We need two sibling paths because private function information is split across two trees:
|
|
@@ -74,7 +74,7 @@ export async function createPrivateFunctionMembershipProof(
|
|
|
74
74
|
functionLeaf: '0x' + functionLeaf.toString('hex'),
|
|
75
75
|
artifactMetadataHash,
|
|
76
76
|
privateFunctionsTreeRoot: '0x' + functionsTree.root.toString('hex'),
|
|
77
|
-
|
|
77
|
+
utilityFunctionsTreeRoot,
|
|
78
78
|
artifactFunctionTreeSiblingPath: artifactTreeSiblingPath.map(fr => fr.toString()).join(','),
|
|
79
79
|
privateFunctionTreeSiblingPath: functionsTreeSiblingPath.map(fr => fr.toString()).join(','),
|
|
80
80
|
});
|
|
@@ -84,7 +84,7 @@ export async function createPrivateFunctionMembershipProof(
|
|
|
84
84
|
artifactTreeLeafIndex,
|
|
85
85
|
artifactMetadataHash,
|
|
86
86
|
functionMetadataHash,
|
|
87
|
-
|
|
87
|
+
utilityFunctionsTreeRoot,
|
|
88
88
|
privateFunctionTreeSiblingPath: functionsTreeSiblingPath,
|
|
89
89
|
privateFunctionTreeLeafIndex: functionsTreeLeafIndex,
|
|
90
90
|
};
|
|
@@ -106,7 +106,7 @@ export async function createPrivateFunctionMembershipProof(
|
|
|
106
106
|
* // Compute artifact leaf and assert it belongs to the artifact
|
|
107
107
|
* artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode))
|
|
108
108
|
* computed_artifact_private_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path)
|
|
109
|
-
* computed_artifact_hash = sha256(computed_artifact_private_function_tree_root,
|
|
109
|
+
* computed_artifact_hash = sha256(computed_artifact_private_function_tree_root, utility_functions_artifact_tree_root, artifact_metadata_hash)
|
|
110
110
|
* assert computed_artifact_hash == contract_class.artifact_hash
|
|
111
111
|
* ```
|
|
112
112
|
* @param fn - Function to check membership proof for.
|
|
@@ -147,7 +147,7 @@ export async function isValidPrivateFunctionMembershipProof(
|
|
|
147
147
|
const computedArtifactPrivateFunctionTreeRoot = Fr.fromBuffer(computedArtifactPrivateFunctionTreeRootBuffer);
|
|
148
148
|
const computedArtifactHash = await computeArtifactHash({
|
|
149
149
|
privateFunctionRoot: computedArtifactPrivateFunctionTreeRoot,
|
|
150
|
-
|
|
150
|
+
utilityFunctionRoot: fn.utilityFunctionsTreeRoot,
|
|
151
151
|
metadataHash: fn.artifactMetadataHash,
|
|
152
152
|
});
|
|
153
153
|
if (!contractClass.artifactHash.equals(computedArtifactHash)) {
|
|
@@ -156,7 +156,7 @@ export async function isValidPrivateFunctionMembershipProof(
|
|
|
156
156
|
computedArtifactHash,
|
|
157
157
|
computedFunctionArtifactHash: functionArtifactHash,
|
|
158
158
|
computedArtifactPrivateFunctionTreeRoot,
|
|
159
|
-
|
|
159
|
+
utilityFunctionRoot: fn.utilityFunctionsTreeRoot,
|
|
160
160
|
metadataHash: fn.artifactMetadataHash,
|
|
161
161
|
artifactFunctionTreeSiblingPath: fn.artifactTreeSiblingPath.map(fr => fr.toString()).join(','),
|
|
162
162
|
});
|
|
@@ -13,29 +13,29 @@ import {
|
|
|
13
13
|
} from './artifact_hash.js';
|
|
14
14
|
import type {
|
|
15
15
|
ContractClassPublic,
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
UtilityFunctionMembershipProof,
|
|
17
|
+
UtilityFunctionWithMembershipProof,
|
|
18
18
|
} from './interfaces/index.js';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Creates a membership proof for
|
|
21
|
+
* Creates a membership proof for a utility function in a contract class, to be verified via `isValidUtilityFunctionMembershipProof`.
|
|
22
22
|
* @param selector - Selector of the function to create the proof for.
|
|
23
23
|
* @param artifact - Artifact of the contract class where the function is defined.
|
|
24
24
|
*/
|
|
25
|
-
export async function
|
|
25
|
+
export async function createUtilityFunctionMembershipProof(
|
|
26
26
|
selector: FunctionSelector,
|
|
27
27
|
artifact: ContractArtifact,
|
|
28
|
-
): Promise<
|
|
28
|
+
): Promise<UtilityFunctionMembershipProof> {
|
|
29
29
|
const log = createLogger('circuits:function_membership_proof');
|
|
30
30
|
|
|
31
31
|
// Locate function artifact
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
32
|
+
const utilityFunctions = artifact.functions.filter(fn => fn.functionType === FunctionType.UTILITY);
|
|
33
|
+
const utilityFunctionsAndSelectors = await Promise.all(
|
|
34
|
+
utilityFunctions.map(async fn => ({ fn, selector: await FunctionSelector.fromNameAndParameters(fn) })),
|
|
35
35
|
);
|
|
36
|
-
const fn =
|
|
36
|
+
const fn = utilityFunctionsAndSelectors.find(fnAndSelector => selector.equals(fnAndSelector.selector))?.fn;
|
|
37
37
|
if (!fn) {
|
|
38
|
-
throw new Error(`
|
|
38
|
+
throw new Error(`Utility function with selector ${selector.toString()} not found`);
|
|
39
39
|
}
|
|
40
40
|
// Compute preimage for the artifact hash
|
|
41
41
|
const { privateFunctionRoot: privateFunctionsArtifactTreeRoot, metadataHash: artifactMetadataHash } =
|
|
@@ -44,11 +44,11 @@ export async function createUnconstrainedFunctionMembershipProof(
|
|
|
44
44
|
// Compute the sibling path for the "artifact tree"
|
|
45
45
|
const functionMetadataHash = computeFunctionMetadataHash(fn);
|
|
46
46
|
const functionArtifactHash = await computeFunctionArtifactHash({ ...fn, functionMetadataHash });
|
|
47
|
-
const artifactTree = (await computeArtifactFunctionTree(artifact, FunctionType.
|
|
47
|
+
const artifactTree = (await computeArtifactFunctionTree(artifact, FunctionType.UTILITY))!;
|
|
48
48
|
const artifactTreeLeafIndex = artifactTree.getIndex(functionArtifactHash.toBuffer());
|
|
49
49
|
const artifactTreeSiblingPath = artifactTree.getSiblingPath(artifactTreeLeafIndex).map(Fr.fromBuffer);
|
|
50
50
|
|
|
51
|
-
log.debug(`Computed proof for
|
|
51
|
+
log.debug(`Computed proof for utility function with selector ${selector.toString()}`, {
|
|
52
52
|
functionArtifactHash,
|
|
53
53
|
functionMetadataHash,
|
|
54
54
|
artifactMetadataHash,
|
|
@@ -66,7 +66,7 @@ export async function createUnconstrainedFunctionMembershipProof(
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
* Verifies that
|
|
69
|
+
* Verifies that a utility function with a membership proof as emitted by the ClassRegisterer contract is valid,
|
|
70
70
|
* as defined in the protocol specs at contract-deployment/classes:
|
|
71
71
|
*
|
|
72
72
|
* ```
|
|
@@ -75,15 +75,15 @@ export async function createUnconstrainedFunctionMembershipProof(
|
|
|
75
75
|
*
|
|
76
76
|
* // Compute artifact leaf and assert it belongs to the artifact
|
|
77
77
|
* artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode))
|
|
78
|
-
*
|
|
79
|
-
* computed_artifact_hash = sha256(private_functions_artifact_tree_root,
|
|
78
|
+
* computed_artifact_utility_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path, artifact_function_tree_leaf_index)
|
|
79
|
+
* computed_artifact_hash = sha256(private_functions_artifact_tree_root, computed_artifact_utility_function_tree_root, artifact_metadata_hash)
|
|
80
80
|
* assert computed_artifact_hash == contract_class.artifact_hash
|
|
81
81
|
* ```
|
|
82
82
|
* @param fn - Function to check membership proof for.
|
|
83
83
|
* @param contractClass - In which contract class the function is expected to be.
|
|
84
84
|
*/
|
|
85
|
-
export async function
|
|
86
|
-
fn:
|
|
85
|
+
export async function isValidUtilityFunctionMembershipProof(
|
|
86
|
+
fn: UtilityFunctionWithMembershipProof,
|
|
87
87
|
contractClass: Pick<ContractClassPublic, 'artifactHash'>,
|
|
88
88
|
) {
|
|
89
89
|
const log = createLogger('circuits:function_membership_proof');
|
|
@@ -98,7 +98,7 @@ export async function isValidUnconstrainedFunctionMembershipProof(
|
|
|
98
98
|
const computedArtifactFunctionTreeRoot = Fr.fromBuffer(computedArtifactFunctionTreeRootBuffer);
|
|
99
99
|
const computedArtifactHash = await computeArtifactHash({
|
|
100
100
|
privateFunctionRoot: fn.privateFunctionsArtifactTreeRoot,
|
|
101
|
-
|
|
101
|
+
utilityFunctionRoot: computedArtifactFunctionTreeRoot,
|
|
102
102
|
metadataHash: fn.artifactMetadataHash,
|
|
103
103
|
});
|
|
104
104
|
if (!contractClass.artifactHash.equals(computedArtifactHash)) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
import type { FunctionSelector } from '../abi/function_selector.js';
|
|
6
|
+
import type { AztecAddress } from '../aztec-address/index.js';
|
|
7
|
+
import { type ZodFor, schemas } from '../schemas/index.js';
|
|
8
|
+
|
|
9
|
+
type AllowedInstance = { address: AztecAddress };
|
|
10
|
+
type AllowedInstanceFunction = { address: AztecAddress; selector: FunctionSelector };
|
|
11
|
+
type AllowedClass = { classId: Fr };
|
|
12
|
+
type AllowedClassFunction = { classId: Fr; selector: FunctionSelector };
|
|
13
|
+
|
|
14
|
+
export type AllowedElement = AllowedInstance | AllowedInstanceFunction | AllowedClass | AllowedClassFunction;
|
|
15
|
+
|
|
16
|
+
export const AllowedElementSchema = z.union([
|
|
17
|
+
z.object({ address: schemas.AztecAddress, selector: schemas.FunctionSelector }),
|
|
18
|
+
z.object({ address: schemas.AztecAddress }),
|
|
19
|
+
z.object({ classId: schemas.Fr, selector: schemas.FunctionSelector }),
|
|
20
|
+
z.object({ classId: schemas.Fr }),
|
|
21
|
+
]) satisfies ZodFor<AllowedElement>;
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
-
import type { Fr } from '@aztec/foundation/fields';
|
|
3
2
|
|
|
4
3
|
import { z } from 'zod';
|
|
5
4
|
|
|
6
|
-
import type { FunctionSelector } from '../abi/function_selector.js';
|
|
7
5
|
import type { AztecAddress } from '../aztec-address/index.js';
|
|
8
6
|
import { type ZodFor, schemas } from '../schemas/index.js';
|
|
9
|
-
|
|
10
|
-
type AllowedInstance = { address: AztecAddress };
|
|
11
|
-
type AllowedInstanceFunction = { address: AztecAddress; selector: FunctionSelector };
|
|
12
|
-
type AllowedClass = { classId: Fr };
|
|
13
|
-
type AllowedClassFunction = { classId: Fr; selector: FunctionSelector };
|
|
14
|
-
|
|
15
|
-
export type AllowedElement = AllowedInstance | AllowedInstanceFunction | AllowedClass | AllowedClassFunction;
|
|
7
|
+
import { type AllowedElement, AllowedElementSchema } from './allowed_element.js';
|
|
16
8
|
|
|
17
9
|
/**
|
|
18
10
|
* The sequencer configuration.
|
|
@@ -37,7 +29,7 @@ export interface SequencerConfig {
|
|
|
37
29
|
/** The path to the ACVM binary */
|
|
38
30
|
acvmBinaryPath?: string;
|
|
39
31
|
/** The list of functions calls allowed to run in setup */
|
|
40
|
-
|
|
32
|
+
txPublicSetupAllowList?: AllowedElement[];
|
|
41
33
|
/** Max block size */
|
|
42
34
|
maxBlockSizeInBytes?: number;
|
|
43
35
|
/** Payload address to vote for */
|
|
@@ -48,13 +40,6 @@ export interface SequencerConfig {
|
|
|
48
40
|
maxL1TxInclusionTimeIntoSlot?: number;
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
const AllowedElementSchema = z.union([
|
|
52
|
-
z.object({ address: schemas.AztecAddress, selector: schemas.FunctionSelector }),
|
|
53
|
-
z.object({ address: schemas.AztecAddress }),
|
|
54
|
-
z.object({ classId: schemas.Fr, selector: schemas.FunctionSelector }),
|
|
55
|
-
z.object({ classId: schemas.Fr }),
|
|
56
|
-
]) satisfies ZodFor<AllowedElement>;
|
|
57
|
-
|
|
58
43
|
export const SequencerConfigSchema = z.object({
|
|
59
44
|
transactionPollingIntervalMS: z.number().optional(),
|
|
60
45
|
maxTxsPerBlock: z.number().optional(),
|
|
@@ -65,7 +50,7 @@ export const SequencerConfigSchema = z.object({
|
|
|
65
50
|
feeRecipient: schemas.AztecAddress.optional(),
|
|
66
51
|
acvmWorkingDirectory: z.string().optional(),
|
|
67
52
|
acvmBinaryPath: z.string().optional(),
|
|
68
|
-
|
|
53
|
+
txPublicSetupAllowList: z.array(AllowedElementSchema).optional(),
|
|
69
54
|
maxBlockSizeInBytes: z.number().optional(),
|
|
70
55
|
governanceProposerPayload: schemas.EthAddress.optional(),
|
|
71
56
|
maxL1TxInclusionTimeIntoSlot: z.number().optional(),
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
|
|
3
|
+
import type { AztecAddress } from '../aztec-address/index.js';
|
|
4
|
+
|
|
5
|
+
/** Provides a view into public contract state */
|
|
6
|
+
export interface PublicStateSource {
|
|
7
|
+
/** Returns the value for a given slot at a given contract. */
|
|
8
|
+
storageRead: (contractAddress: AztecAddress, slot: Fr) => Promise<Fr>;
|
|
9
|
+
}
|
package/src/interfaces/pxe.ts
CHANGED
|
@@ -264,19 +264,18 @@ export interface PXE {
|
|
|
264
264
|
getCurrentBaseFees(): Promise<GasFees>;
|
|
265
265
|
|
|
266
266
|
/**
|
|
267
|
-
* Simulate the execution of
|
|
268
|
-
* This is useful to inspect contract state, for example fetching a variable value or calling a getter function.
|
|
269
|
-
* The function takes function name and arguments as parameters, along with the contract address
|
|
270
|
-
* and optionally the sender's address.
|
|
267
|
+
* Simulate the execution of a contract utility function.
|
|
271
268
|
*
|
|
272
|
-
* @param functionName - The name of the function to be called
|
|
269
|
+
* @param functionName - The name of the utility contract function to be called.
|
|
273
270
|
* @param args - The arguments to be provided to the function.
|
|
274
271
|
* @param to - The address of the contract to be called.
|
|
272
|
+
* @param authwits - (Optional) The authentication witnesses required for the function call.
|
|
275
273
|
* @param from - (Optional) The msg sender to set for the call.
|
|
276
|
-
* @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will
|
|
277
|
-
*
|
|
274
|
+
* @param scopes - (Optional) The accounts whose notes we can access in this call. Currently optional and will
|
|
275
|
+
* default to all.
|
|
276
|
+
* @returns The result of the utility function call, structured based on the function ABI.
|
|
278
277
|
*/
|
|
279
|
-
|
|
278
|
+
simulateUtility(
|
|
280
279
|
functionName: string,
|
|
281
280
|
args: any[],
|
|
282
281
|
to: AztecAddress,
|
|
@@ -491,7 +490,7 @@ export const PXESchema: ApiSchemaFor<PXE> = {
|
|
|
491
490
|
.returns(z.union([L2Block.schema, z.undefined()])),
|
|
492
491
|
getCurrentBaseFees: z.function().returns(GasFees.schema),
|
|
493
492
|
|
|
494
|
-
|
|
493
|
+
simulateUtility: z
|
|
495
494
|
.function()
|
|
496
495
|
.args(
|
|
497
496
|
z.string(),
|
package/src/interfaces/server.ts
CHANGED