import { makeBlobAccumulator, makeFinalBlobAccumulator, makeFinalBlobBatchingChallenges, makeSpongeBlob, } from '@aztec/blob-lib/testing'; import { ARCHIVE_HEIGHT, AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED, CHONK_PROOF_LENGTH, CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, DomainSeparator, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH, MAX_CHECKPOINTS_PER_EPOCH, MAX_CONTRACT_CLASS_LOGS_PER_TX, MAX_ENQUEUED_CALLS_PER_CALL, MAX_ENQUEUED_CALLS_PER_TX, MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_HASHES_PER_CALL, MAX_NOTE_HASHES_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIERS_PER_CALL, MAX_NULLIFIERS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_LOGS_PER_CALL, MAX_PRIVATE_LOGS_PER_TX, MAX_PROTOCOL_CONTRACTS, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUM_BASE_PARITY_PER_ROOT_PARITY, NUM_MSGS_PER_BASE_PARITY, PRIVATE_LOG_SIZE_IN_FIELDS, PUBLIC_DATA_TREE_HEIGHT, RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, VK_TREE_HEIGHT, } from '@aztec/constants'; import { type FieldsOf, makeTuple } from '@aztec/foundation/array'; import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { compact } from '@aztec/foundation/collection'; import { Grumpkin } from '@aztec/foundation/crypto/grumpkin'; import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon'; import { SchnorrSignature } from '@aztec/foundation/crypto/schnorr'; import { sha256 } from '@aztec/foundation/crypto/sha256'; import { Fq, Fr } from '@aztec/foundation/curves/bn254'; import { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin'; import { EthAddress } from '@aztec/foundation/eth-address'; import type { Bufferable, Serializable, Tuple } from '@aztec/foundation/serialize'; import { MembershipWitness } from '@aztec/foundation/trees'; import { FunctionSelector } from '../abi/function_selector.js'; import { ContractStorageRead } from '../avm/contract_storage_read.js'; import { ContractStorageUpdateRequest } from '../avm/contract_storage_update_request.js'; import { AvmAccumulatedData, AvmAccumulatedDataArrayLengths, AvmAppendLeavesHint, AvmBytecodeCommitmentHint, AvmCircuitInputs, AvmCircuitPublicInputs, AvmCommitCheckpointHint, AvmContractClassHint, AvmContractDbCommitCheckpointHint, AvmContractDbCreateCheckpointHint, AvmContractDbRevertCheckpointHint, AvmContractInstanceHint, AvmCreateCheckpointHint, AvmDebugFunctionNameHint, AvmExecutionHints, AvmGetLeafPreimageHintNullifierTree, AvmGetLeafPreimageHintPublicDataTree, AvmGetLeafValueHint, AvmGetPreviousValueIndexHint, AvmGetSiblingPathHint, AvmRevertCheckpointHint, AvmSequentialInsertHintNullifierTree, AvmSequentialInsertHintPublicDataTree, AvmTxHint, } from '../avm/index.js'; import { PublicDataRead } from '../avm/public_data_read.js'; import { PublicDataWrite } from '../avm/public_data_write.js'; import { AztecAddress } from '../aztec-address/index.js'; import type { L2Tips } from '../block/l2_block_source.js'; import { type ContractClassPublic, ContractDeploymentData, type ContractInstanceWithAddress, type ExecutablePrivateFunctionWithMembershipProof, type PrivateFunction, SerializableContractInstance, type UtilityFunctionWithMembershipProof, computeContractClassId, computePublicBytecodeCommitment, } from '../contract/index.js'; import { Gas, GasFees, GasSettings } from '../gas/index.js'; import { computeCalldataHash } from '../hash/hash.js'; import { KeyValidationRequest } from '../kernel/hints/key_validation_request.js'; import { KeyValidationRequestAndSeparator } from '../kernel/hints/key_validation_request_and_separator.js'; import { ReadRequest, ScopedReadRequest } from '../kernel/hints/read_request.js'; import { ClaimedLengthArray, PartialPrivateTailPublicInputsForPublic, PartialPrivateTailPublicInputsForRollup, PrivateKernelTailCircuitPublicInputs, PrivateToAvmAccumulatedData, PrivateToAvmAccumulatedDataArrayLengths, PrivateToPublicAccumulatedData, PrivateToPublicKernelCircuitPublicInputs, PrivateToRollupAccumulatedData, } from '../kernel/index.js'; import { CountedLogHash, LogHash, ScopedLogHash } from '../kernel/log_hash.js'; import { NoteHash } from '../kernel/note_hash.js'; import { Nullifier } from '../kernel/nullifier.js'; import { PrivateCallRequest } from '../kernel/private_call_request.js'; import { PrivateCircuitPublicInputs } from '../kernel/private_circuit_public_inputs.js'; import { PrivateLogData } from '../kernel/private_log_data.js'; import { PrivateToRollupKernelCircuitPublicInputs } from '../kernel/private_to_rollup_kernel_circuit_public_inputs.js'; import { CountedPublicCallRequest, PublicCallRequest, PublicCallRequestArrayLengths, } from '../kernel/public_call_request.js'; import { PublicKeys, computeAddress } from '../keys/index.js'; import { ExtendedDirectionalAppTaggingSecret } from '../logs/extended_directional_app_tagging_secret.js'; import { ContractClassLog, ContractClassLogFields } from '../logs/index.js'; import { PrivateLog } from '../logs/private_log.js'; import { FlatPublicLogs, PublicLog } from '../logs/public_log.js'; import { TxScopedL2Log } from '../logs/tx_scoped_l2_log.js'; import { CountedL2ToL1Message, L2ToL1Message, ScopedL2ToL1Message } from '../messaging/l2_to_l1_message.js'; import { ParityBasePrivateInputs } from '../parity/parity_base_private_inputs.js'; import { ParityPublicInputs } from '../parity/parity_public_inputs.js'; import { ParityRootPrivateInputs } from '../parity/parity_root_private_inputs.js'; import { ProofData, ProofDataForFixedVk } from '../proofs/index.js'; import { Proof } from '../proofs/proof.js'; import { makeRecursiveProof } from '../proofs/recursive_proof.js'; import { PrivateBaseRollupHints, PublicBaseRollupHints } from '../rollup/base_rollup_hints.js'; import { BlockConstantData } from '../rollup/block_constant_data.js'; import { BlockMergeRollupPrivateInputs } from '../rollup/block_merge_rollup_private_inputs.js'; import { BlockRollupPublicInputs } from '../rollup/block_rollup_public_inputs.js'; import { BlockRootFirstRollupPrivateInputs, BlockRootSingleTxRollupPrivateInputs, } from '../rollup/block_root_rollup_private_inputs.js'; import { CheckpointConstantData } from '../rollup/checkpoint_constant_data.js'; import { CheckpointHeader } from '../rollup/checkpoint_header.js'; import { CheckpointRollupPublicInputs, FeeRecipient } from '../rollup/checkpoint_rollup_public_inputs.js'; import { EpochConstantData } from '../rollup/epoch_constant_data.js'; import { PrivateTxBaseRollupPrivateInputs } from '../rollup/private_tx_base_rollup_private_inputs.js'; import { PublicChonkVerifierPublicInputs } from '../rollup/public_chonk_verifier_public_inputs.js'; import { PublicTxBaseRollupPrivateInputs } from '../rollup/public_tx_base_rollup_private_inputs.js'; import { RootRollupPublicInputs } from '../rollup/root_rollup_public_inputs.js'; import { TreeSnapshotDiffHints } from '../rollup/tree_snapshot_diff_hints.js'; import { TxMergeRollupPrivateInputs } from '../rollup/tx_merge_rollup_private_inputs.js'; import { TxRollupPublicInputs } from '../rollup/tx_rollup_public_inputs.js'; import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js'; import { MerkleTreeId } from '../trees/merkle_tree_id.js'; import { NullifierLeaf, NullifierLeafPreimage } from '../trees/nullifier_leaf.js'; import { PublicDataTreeLeaf, PublicDataTreeLeafPreimage } from '../trees/public_data_leaf.js'; import { BlockHeader } from '../tx/block_header.js'; import { CallContext } from '../tx/call_context.js'; import { FunctionData } from '../tx/function_data.js'; import { GlobalVariables } from '../tx/global_variables.js'; import { PartialStateReference } from '../tx/partial_state_reference.js'; import { ProtocolContracts } from '../tx/protocol_contracts.js'; import { PublicCallRequestWithCalldata } from '../tx/public_call_request_with_calldata.js'; import { StateReference } from '../tx/state_reference.js'; import { TreeSnapshots } from '../tx/tree_snapshots.js'; import { TxConstantData } from '../tx/tx_constant_data.js'; import { TxContext } from '../tx/tx_context.js'; import { TxHash } from '../tx/tx_hash.js'; import { TxRequest } from '../tx/tx_request.js'; import { Vector } from '../types/index.js'; import { VkData } from '../vks/index.js'; import { VerificationKey, VerificationKeyAsFields, VerificationKeyData } from '../vks/verification_key.js'; /** * Creates an arbitrary side effect object with the given seed. * @param seed - The seed to use for generating the object. * @returns A side effect object. */ function makeLogHash(seed: number) { return new LogHash(fr(seed), seed + 1); } function makeCountedLogHash(seed: number) { return new CountedLogHash(makeLogHash(seed), seed + 0x10); } function makeScopedLogHash(seed: number) { return new ScopedLogHash(makeLogHash(seed), makeAztecAddress(seed + 3)); } function makeNoteHash(seed: number) { return new NoteHash(fr(seed), seed + 1); } function makeNullifier(seed: number) { return new Nullifier(fr(seed), fr(seed + 1), seed + 2); } function makePrivateLog(seed: number) { return new PrivateLog(makeTuple(PRIVATE_LOG_SIZE_IN_FIELDS, fr, seed), PRIVATE_LOG_SIZE_IN_FIELDS); } function makePrivateLogData(seed: number) { return new PrivateLogData(makePrivateLog(seed + 0x100), seed, seed + 1); } function makePublicLog(seed: number) { return new PublicLog( makeAztecAddress(seed), new Array(10).fill(null).map((_, i) => new Fr(seed + i)), ); } /** * Creates an arbitrary tx context with the given seed. * @param seed - The seed to use for generating the tx context. * @returns A tx context. */ export function makeTxContext(seed: number = 1): TxContext { // @todo @LHerskind should probably take value for chainId as it will be verified later. return new TxContext(new Fr(seed), Fr.ZERO, makeGasSettings()); } /** * Creates a default instance of gas settings. No seed value is used to ensure we allocate a sensible amount of gas for testing. */ export function makeGasSettings() { return GasSettings.fallback({ maxFeesPerGas: new GasFees(10, 10) }); } /** * Creates arbitrary selector from the given seed. * @param seed - The seed to use for generating the selector. * @returns A selector. */ export function makeSelector(seed: number): FunctionSelector { return new FunctionSelector(seed); } function makeScopedReadRequest(n: number): ScopedReadRequest { return new ScopedReadRequest(new ReadRequest(new Fr(BigInt(n)), n + 1), makeAztecAddress(n + 2)); } /** * Creates arbitrary KeyValidationRequest from the given seed. * @param seed - The seed to use for generating the KeyValidationRequest. * @returns A KeyValidationRequest. */ function makeKeyValidationRequests(seed: number): KeyValidationRequest { return new KeyValidationRequest(makePoint(seed), fr(seed + 2)); } /** * Creates arbitrary KeyValidationRequestAndSeparator from the given seed. * @param seed - The seed to use for generating the KeyValidationRequestAndSeparator. * @returns A KeyValidationRequestAndSeparator. */ function makeKeyValidationRequestAndSeparators(seed: number): KeyValidationRequestAndSeparator { return new KeyValidationRequestAndSeparator(makeKeyValidationRequests(seed), fr(seed + 4)); } export function makePublicDataWrite(seed = 1) { return new PublicDataWrite(fr(seed), fr(seed + 1)); } /** * Creates arbitrary public data read. * @param seed - The seed to use for generating the public data read. * @returns A public data read. */ export function makePublicDataRead(seed = 1): PublicDataRead { return new PublicDataRead(fr(seed), fr(seed + 1), 0); } /** * Creates empty public data read. * @returns An empty public data read. */ export function makeEmptyPublicDataRead(): PublicDataRead { return new PublicDataRead(fr(0), fr(0), 0); } /** * Creates arbitrary contract storage update request. * @param seed - The seed to use for generating the contract storage update request. * @returns A contract storage update request. */ export function makeContractStorageUpdateRequest(seed = 1): ContractStorageUpdateRequest { return new ContractStorageUpdateRequest(fr(seed), fr(seed + 1), seed + 2); } /** * Creates arbitrary contract storage read. * @param seed - The seed to use for generating the contract storage read. * @returns A contract storage read. */ export function makeContractStorageRead(seed = 1): ContractStorageRead { return new ContractStorageRead(fr(seed), fr(seed + 1), seed + 2); } function makeTxConstantData(seed = 1) { return new TxConstantData( makeBlockHeader(seed), makeTxContext(seed + 0x100), new Fr(seed + 0x200), new Fr(seed + 0x201), ); } function makePaddedTuple( length: N, fn: (i: number) => T, nonPaddedLength = 0, makePadding: () => T, offset = 0, ) { return makeTuple(length, i => (i < nonPaddedLength ? fn(i + offset) : makePadding())); } /** * Creates arbitrary accumulated data. * @param seed - The seed to use for generating the accumulated data. * @returns An accumulated data. */ export function makePrivateToRollupAccumulatedData( seed = 1, { numNoteHashes = MAX_NOTE_HASHES_PER_TX, numNullifiers = MAX_NULLIFIERS_PER_TX, numL2ToL1Messages = MAX_L2_TO_L1_MSGS_PER_TX, numPrivateLogs = MAX_PRIVATE_LOGS_PER_TX, numContractClassLogs = MAX_CONTRACT_CLASS_LOGS_PER_TX, }: { numNoteHashes?: number; numNullifiers?: number; numL2ToL1Messages?: number; numPrivateLogs?: number; numContractClassLogs?: number; } = {}, ): PrivateToRollupAccumulatedData { return new PrivateToRollupAccumulatedData( makePaddedTuple(MAX_NOTE_HASHES_PER_TX, fr, numNoteHashes, Fr.zero, seed + 0x100), makePaddedTuple(MAX_NULLIFIERS_PER_TX, fr, numNullifiers, Fr.zero, seed + 0x200), makePaddedTuple( MAX_L2_TO_L1_MSGS_PER_TX, makeScopedL2ToL1Message, numL2ToL1Messages, ScopedL2ToL1Message.empty, seed + 0x300, ), makePaddedTuple(MAX_PRIVATE_LOGS_PER_TX, makePrivateLog, numPrivateLogs, PrivateLog.empty, seed + 0x400), makePaddedTuple( MAX_CONTRACT_CLASS_LOGS_PER_TX, makeScopedLogHash, numContractClassLogs, ScopedLogHash.empty, seed + 0x500, ), ); } export function makePrivateToPublicAccumulatedData( seed = 1, { numNoteHashes = MAX_NOTE_HASHES_PER_TX, numNullifiers = MAX_NULLIFIERS_PER_TX, numL2ToL1Messages = MAX_L2_TO_L1_MSGS_PER_TX, numPrivateLogs = MAX_PRIVATE_LOGS_PER_TX, numContractClassLogs = MAX_CONTRACT_CLASS_LOGS_PER_TX, numEnqueuedCalls = MAX_ENQUEUED_CALLS_PER_TX, }: { numNoteHashes?: number; numNullifiers?: number; numL2ToL1Messages?: number; numPrivateLogs?: number; numContractClassLogs?: number; numEnqueuedCalls?: number; } = {}, ) { return new PrivateToPublicAccumulatedData( makePaddedTuple(MAX_NOTE_HASHES_PER_TX, fr, numNoteHashes, Fr.zero, seed), makePaddedTuple(MAX_NULLIFIERS_PER_TX, fr, numNullifiers, Fr.zero, seed + 0x100), makePaddedTuple( MAX_L2_TO_L1_MSGS_PER_TX, makeScopedL2ToL1Message, numL2ToL1Messages, ScopedL2ToL1Message.empty, seed + 0x200, ), makePaddedTuple(MAX_PRIVATE_LOGS_PER_TX, makePrivateLog, numPrivateLogs, PrivateLog.empty, seed + 0x300), makePaddedTuple( MAX_CONTRACT_CLASS_LOGS_PER_TX, makeScopedLogHash, numContractClassLogs, ScopedLogHash.empty, seed + 0x400, ), makePaddedTuple( MAX_ENQUEUED_CALLS_PER_TX, makePublicCallRequest, numEnqueuedCalls, PublicCallRequest.empty, seed + 0x500, ), ); } function makePrivateToAvmAccumulatedData(seed = 1) { return new PrivateToAvmAccumulatedData( makeTuple(MAX_NOTE_HASHES_PER_TX, fr, seed), makeTuple(MAX_NULLIFIERS_PER_TX, fr, seed + 0x100), makeTuple(MAX_L2_TO_L1_MSGS_PER_TX, makeScopedL2ToL1Message, seed + 0x200), ); } function makePrivateToAvmAccumulatedDataArrayLengths(seed = 1) { return new PrivateToAvmAccumulatedDataArrayLengths(seed, seed + 1, seed + 2); } function makeAvmAccumulatedData(seed = 1) { return new AvmAccumulatedData( makeTuple(MAX_NOTE_HASHES_PER_TX, fr, seed), makeTuple(MAX_NULLIFIERS_PER_TX, fr, seed + 0x100), makeTuple(MAX_L2_TO_L1_MSGS_PER_TX, makeScopedL2ToL1Message, seed + 0x200), FlatPublicLogs.fromLogs(new Array(20).fill(null).map((_, i) => makePublicLog(seed + i * 256))), makeTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataWrite, seed + 0x400), ); } function makeAvmAccumulatedDataArrayLengths(seed = 1) { return new AvmAccumulatedDataArrayLengths(seed, seed + 1, seed + 2, seed + 3); } export function makeGas(seed = 1) { // Constrain gas values to u32 range const daGas = seed % 2 ** 32; const l2Gas = (seed + 1) % 2 ** 32; return new Gas(daGas, l2Gas); } /** * Creates arbitrary call context. * @param seed - The seed to use for generating the call context. * @returns A call context. */ export function makeCallContext(seed = 0, overrides: Partial> = {}): CallContext { return CallContext.from({ msgSender: makeAztecAddress(seed), contractAddress: makeAztecAddress(seed + 1), functionSelector: makeSelector(seed + 3), isStaticCall: false, ...overrides, }); } /** * Creates arbitrary private kernel tail circuit public inputs. * @param seed - The seed to use for generating the kernel circuit public inputs. * @returns Private kernel tail circuit public inputs. */ export function makePrivateKernelTailCircuitPublicInputs( seed = 1, isForPublic = true, ): PrivateKernelTailCircuitPublicInputs { const forPublic = isForPublic ? new PartialPrivateTailPublicInputsForPublic( makePrivateToPublicAccumulatedData(seed + 0x100), makePrivateToPublicAccumulatedData(seed + 0x200), makePublicCallRequest(seed + 0x400), ) : undefined; const forRollup = !isForPublic ? new PartialPrivateTailPublicInputsForRollup(makePrivateToRollupAccumulatedData(seed + 0x100)) : undefined; return new PrivateKernelTailCircuitPublicInputs( makeTxConstantData(seed + 0x300), makeGas(seed + 0x600), makeAztecAddress(seed + 0x700), BigInt(seed + 0x800), forPublic, forRollup, ); } export function makePrivateToPublicKernelCircuitPublicInputs(seed = 1) { return new PrivateToPublicKernelCircuitPublicInputs( makeTxConstantData(seed), makePrivateToPublicAccumulatedData(seed + 0x200), makePrivateToPublicAccumulatedData(seed + 0x300), makePublicCallRequest(seed + 0x400), makeGas(seed + 0x500), makeAztecAddress(seed + 0x600), BigInt(seed + 0x700), ); } export function makePublicChonkVerifierPublicInputs(seed = 1) { return new PublicChonkVerifierPublicInputs(makePrivateToPublicKernelCircuitPublicInputs(seed), fr(seed + 0x1000)); } export function makeProtocolContracts(seed = 1) { return new ProtocolContracts(makeTuple(MAX_PROTOCOL_CONTRACTS, makeAztecAddress, seed)); } /** * Creates arbitrary public kernel circuit public inputs. * @param seed - The seed to use for generating the kernel circuit public inputs. * @returns Public kernel circuit public inputs. */ export function makePrivateToRollupKernelCircuitPublicInputs(seed = 1): PrivateToRollupKernelCircuitPublicInputs { return new PrivateToRollupKernelCircuitPublicInputs( makeTxConstantData(seed + 0x100), makePrivateToRollupAccumulatedData(seed), makeGas(seed + 0x600), makeAztecAddress(seed + 0x700), BigInt(seed + 0x800), ); } function makeAvmCircuitPublicInputs(seed = 1) { return new AvmCircuitPublicInputs( makeGlobalVariables(seed), makeProtocolContracts(seed + 0x100), makeTreeSnapshots(seed + 0x10), makeGas(seed + 0x20), makeGasSettings(), makeGasFees(seed + 0x30), makeAztecAddress(seed + 0x40), fr(seed + 0x50), makePublicCallRequestArrayLengths(seed + 0x60), makeTuple(MAX_ENQUEUED_CALLS_PER_TX, makePublicCallRequest, seed + 0x100), makeTuple(MAX_ENQUEUED_CALLS_PER_TX, makePublicCallRequest, seed + 0x200), makePublicCallRequest(seed + 0x300), makePrivateToAvmAccumulatedDataArrayLengths(seed + 0x400), makePrivateToAvmAccumulatedDataArrayLengths(seed + 0x410), makePrivateToAvmAccumulatedData(seed + 0x500), makePrivateToAvmAccumulatedData(seed + 0x600), makeTreeSnapshots(seed + 0x700), makeGas(seed + 0x750), makeAvmAccumulatedDataArrayLengths(seed + 0x800), makeAvmAccumulatedData(seed + 0x800), fr(seed + 0x900), false, ); } function makeSiblingPath(seed: number, size: N) { return makeTuple(size, fr, seed); } /** * Creates arbitrary/mocked membership witness where the sibling paths is an array of fields in an ascending order starting from `start`. * @param size - The size of the membership witness. * @param start - The start of the membership witness. * @returns A membership witness. */ export function makeMembershipWitness(size: N, start: number): MembershipWitness { return new MembershipWitness(size, BigInt(start), makeSiblingPath(start, size)); } /** * Creates arbitrary/mocked verification key in fields format. * @returns A verification key as fields object */ export function makeVerificationKeyAsFields(size: number): VerificationKeyAsFields { return VerificationKeyAsFields.makeFake(size); } /** * Creates arbitrary/mocked verification key. * @returns A verification key object */ export function makeVerificationKey(): VerificationKey { return VerificationKey.makeFake(); } /** * Creates an arbitrary point in a curve. * @param seed - Seed to generate the point values. * @returns A point. */ export function makePoint(seed = 1): Point { return new Point(fr(seed), fr(seed + 1), false); } /** * Creates an arbitrary grumpkin scalar. * @param seed - Seed to generate the values. * @returns A GrumpkinScalar. */ export function makeGrumpkinScalar(seed = 1): GrumpkinScalar { return GrumpkinScalar.fromHighLow(fr(seed), fr(seed + 1)); } /** * Makes arbitrary proof. * @param seed - The seed to use for generating/mocking the proof. * @returns A proof. */ export function makeProof(seed = 1) { return new Proof(Buffer.alloc(16, seed), 0); } function makePrivateCallRequest(seed = 1): PrivateCallRequest { return new PrivateCallRequest(makeCallContext(seed + 0x1), fr(seed + 0x3), fr(seed + 0x4), seed + 0x10, seed + 0x11); } export function makePublicCallRequest(seed = 1) { return new PublicCallRequest(makeAztecAddress(seed), makeAztecAddress(seed + 1), false, fr(seed + 0x3)); } export function makePublicCallRequestArrayLengths(seed = 1) { return new PublicCallRequestArrayLengths(seed, seed + 1, seed % 2 === 0); } function makeCountedPublicCallRequest(seed = 1) { return new CountedPublicCallRequest(makePublicCallRequest(seed), seed + 0x100); } /** * Makes arbitrary tx request. * @param seed - The seed to use for generating the tx request. * @returns A tx request. */ export function makeTxRequest(seed = 1): TxRequest { return TxRequest.from({ origin: makeAztecAddress(seed), functionData: new FunctionData(makeSelector(seed + 0x100), /*isPrivate=*/ true), argsHash: fr(seed + 0x200), txContext: makeTxContext(seed + 0x400), salt: fr(seed + 0x500), }); } function makeClaimedLengthArray( arraySize: N, makeItem: (seed: number) => T, seed: number, length = arraySize, ): ClaimedLengthArray { return new ClaimedLengthArray(makeTuple(arraySize, makeItem, seed) as Tuple, length); } /** * Makes arbitrary private circuit public inputs. * @param seed - The seed to use for generating the private circuit public inputs. * @returns A private circuit public inputs. */ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicInputs { return PrivateCircuitPublicInputs.from({ expirationTimestamp: BigInt(seed + 0x31415), callContext: makeCallContext(seed, { isStaticCall: true }), argsHash: fr(seed + 0x100), returnsHash: fr(seed + 0x200), minRevertibleSideEffectCounter: fr(0), noteHashReadRequests: makeClaimedLengthArray( MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, makeScopedReadRequest, seed + 0x300, ), nullifierReadRequests: makeClaimedLengthArray( MAX_NULLIFIER_READ_REQUESTS_PER_CALL, makeScopedReadRequest, seed + 0x310, ), keyValidationRequestsAndSeparators: makeClaimedLengthArray( MAX_KEY_VALIDATION_REQUESTS_PER_CALL, makeKeyValidationRequestAndSeparators, seed + 0x320, ), noteHashes: makeClaimedLengthArray(MAX_NOTE_HASHES_PER_CALL, makeNoteHash, seed + 0x400), nullifiers: makeClaimedLengthArray(MAX_NULLIFIERS_PER_CALL, makeNullifier, seed + 0x500), privateCallRequests: makeClaimedLengthArray( MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, makePrivateCallRequest, seed + 0x600, ), publicCallRequests: makeClaimedLengthArray(MAX_ENQUEUED_CALLS_PER_CALL, makeCountedPublicCallRequest, seed + 0x700), publicTeardownCallRequest: makePublicCallRequest(seed + 0x800), l2ToL1Msgs: makeClaimedLengthArray(MAX_L2_TO_L1_MSGS_PER_CALL, makeCountedL2ToL1Message, seed + 0x800), privateLogs: makeClaimedLengthArray(MAX_PRIVATE_LOGS_PER_CALL, makePrivateLogData, seed + 0x875), contractClassLogsHashes: makeClaimedLengthArray(MAX_CONTRACT_CLASS_LOGS_PER_TX, makeCountedLogHash, seed + 0xa00), startSideEffectCounter: fr(seed + 0x849), endSideEffectCounter: fr(seed + 0x850), expectedNonRevertibleSideEffectCounter: fr(seed + 0x860), expectedRevertibleSideEffectCounter: fr(seed + 0x861), anchorBlockHeader: makeBlockHeader(seed + 0xd00), txContext: makeTxContext(seed + 0x1400), isFeePayer: false, }); } export function makeGlobalVariables(seed = 1, overrides: Partial> = {}): GlobalVariables { return GlobalVariables.from({ chainId: new Fr(seed), version: new Fr(seed + 1), blockNumber: BlockNumber(seed + 2), slotNumber: SlotNumber(seed + 3), timestamp: BigInt(seed + 4), coinbase: EthAddress.fromField(new Fr(seed + 5)), feeRecipient: AztecAddress.fromField(new Fr(seed + 6)), gasFees: new GasFees(seed + 7, seed + 8), ...compact(overrides), }); } function makeGasFees(seed = 1) { return new GasFees(seed, seed + 1); } function makeFeeRecipient(seed = 1) { return new FeeRecipient(EthAddress.fromField(fr(seed)), fr(seed + 1)); } /** * Makes arbitrary append only tree snapshot. * @param seed - The seed to use for generating the append only tree snapshot. * @returns An append only tree snapshot. */ export function makeAppendOnlyTreeSnapshot(seed = 1): AppendOnlyTreeSnapshot { // Constrain nextAvailableLeafIndex to u32 range const nextAvailableLeafIndex = seed % 2 ** 32; return new AppendOnlyTreeSnapshot(fr(seed), nextAvailableLeafIndex); } /** * Makes arbitrary eth address. * @param seed - The seed to use for generating the eth address. * @returns An eth address. */ export function makeEthAddress(seed = 1): EthAddress { return EthAddress.fromField(fr(seed)); } /** * Creates a buffer of a given size filled with a given value. * @param size - The size of the buffer to create. * @param fill - The value to fill the buffer with. * @returns A buffer of a given size filled with a given value. */ export function makeBytes(size = 32, fill = 1): Buffer { return Buffer.alloc(size, fill); } /** * Makes arbitrary aztec address. * @param seed - The seed to use for generating the aztec address. * @returns An aztec address. */ export function makeAztecAddress(seed = 1): AztecAddress { return AztecAddress.fromField(fr(seed)); } /** * Makes arbitrary Schnorr signature. * @param seed - The seed to use for generating the Schnorr signature. * @returns A Schnorr signature. */ export function makeSchnorrSignature(seed = 1): SchnorrSignature { return new SchnorrSignature(Buffer.alloc(SchnorrSignature.SIZE, seed)); } function makeBlockConstantData(seed = 1, globalVariables?: GlobalVariables) { return new BlockConstantData( makeAppendOnlyTreeSnapshot(seed + 0x100), makeAppendOnlyTreeSnapshot(seed + 0x200), fr(seed + 0x300), fr(seed + 0x400), globalVariables ?? makeGlobalVariables(seed + 0x500), fr(seed + 0x600), ); } function makeCheckpointConstantData(seed = 1) { return new CheckpointConstantData( fr(seed), fr(seed + 1), fr(seed + 2), fr(seed + 3), fr(seed + 4), SlotNumber(seed + 5), makeEthAddress(seed + 6), makeAztecAddress(seed + 7), makeGasFees(seed + 8), ); } function makeEpochConstantData(seed = 1) { return new EpochConstantData(fr(seed), fr(seed + 1), fr(seed + 2), fr(seed + 3), fr(seed + 4)); } /** * Makes arbitrary base or merge rollup circuit public inputs. * @param seed - The seed to use for generating the base rollup circuit public inputs. * @param blockNumber - The block number to use for generating the base rollup circuit public inputs. * @returns A base or merge rollup circuit public inputs. */ export function makeTxRollupPublicInputs( seed = 0, globalVariables: GlobalVariables | undefined = undefined, ): TxRollupPublicInputs { return new TxRollupPublicInputs( 1, makeBlockConstantData(seed + 0x200, globalVariables), makePartialStateReference(seed + 0x300), makePartialStateReference(seed + 0x400), makeSpongeBlob(seed + 0x500), makeSpongeBlob(seed + 0x600), fr(seed + 0x901), fr(seed + 0x902), fr(seed + 0x903), ); } /** * Makes arbitrary block merge or block root rollup circuit public inputs. * @param seed - The seed to use for generating the block merge or block root rollup circuit public inputs. * @param blockNumber - The block number to use for generating the block merge or block root rollup circuit public inputs. * @returns A block merge or block root rollup circuit public inputs. */ export function makeBlockRollupPublicInputs(seed = 0): BlockRollupPublicInputs { return new BlockRollupPublicInputs( makeCheckpointConstantData(seed + 0x100), makeAppendOnlyTreeSnapshot(seed + 0x200), makeAppendOnlyTreeSnapshot(seed + 0x300), makeStateReference(seed + 0x400), makeStateReference(seed + 0x500), makeSpongeBlob(seed + 0x600), makeSpongeBlob(seed + 0x700), BigInt(seed + 0x800), fr(seed + 0x820), fr(seed + 0x830), fr(seed + 0x840), fr(seed + 0x850), fr(seed + 0x860), ); } export function makeCheckpointRollupPublicInputs(seed = 0) { return new CheckpointRollupPublicInputs( makeEpochConstantData(seed), makeAppendOnlyTreeSnapshot(seed + 0x100), makeAppendOnlyTreeSnapshot(seed + 0x200), makeAppendOnlyTreeSnapshot(seed + 0x300), makeAppendOnlyTreeSnapshot(seed + 0x350), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => fr(seed), 0x400), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => makeFeeRecipient(seed), 0x500), makeBlobAccumulator(seed + 0x600), makeBlobAccumulator(seed + 0x700), makeFinalBlobBatchingChallenges(seed + 0x800), ); } export function makeParityPublicInputs(seed = 0): ParityPublicInputs { return new ParityPublicInputs( new Fr(BigInt(seed + 0x200)), new Fr(BigInt(seed + 0x300)), new Fr(BigInt(seed + 0x400)), ); } export function makeParityBasePrivateInputs(seed = 0): ParityBasePrivateInputs { return new ParityBasePrivateInputs(makeTuple(NUM_MSGS_PER_BASE_PARITY, fr, seed + 0x3000), new Fr(seed + 0x4000)); } export function makeParityRootPrivateInputs(seed = 0) { return new ParityRootPrivateInputs( makeTuple(NUM_BASE_PARITY_PER_ROOT_PARITY, () => makeProofData(seed, makeParityPublicInputs)), ); } /** * Makes root rollup public inputs. * @param seed - The seed to use for generating the root rollup public inputs. * @param blockNumber - The block number to use in the global variables of a header. * @returns A root rollup public inputs. */ export function makeRootRollupPublicInputs(seed = 0): RootRollupPublicInputs { return new RootRollupPublicInputs( fr(seed + 0x100), fr(seed + 0x200), fr(seed + 0x300), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => fr(seed), 0x400), makeTuple(MAX_CHECKPOINTS_PER_EPOCH, () => makeFeeRecipient(seed), 0x500), makeEpochConstantData(seed + 0x600), makeFinalBlobAccumulator(seed + 0x700), ); } export function makeBlockHeader( seed = 0, overrides: Partial>> & Partial> = {}, ): BlockHeader { return BlockHeader.from({ lastArchive: makeAppendOnlyTreeSnapshot(seed + 0x100), state: makeStateReference(seed + 0x200), spongeBlobHash: fr(seed + 0x300), globalVariables: makeGlobalVariables((seed += 0x700), overrides), totalFees: fr(seed + 0x800), totalManaUsed: fr(seed + 0x900), ...overrides, }); } export function makeCheckpointHeader(seed = 0, overrides: Partial> = {}) { return CheckpointHeader.from({ lastArchiveRoot: fr(seed + 0x100), blockHeadersHash: fr(seed + 0x150), blobsHash: fr(seed + 0x200), inHash: fr(seed + 0x210), epochOutHash: fr(seed + 0x220), slotNumber: SlotNumber(seed + 0x300), timestamp: BigInt(seed + 0x400), coinbase: makeEthAddress(seed + 0x500), feeRecipient: makeAztecAddress(seed + 0x600), gasFees: makeGasFees(seed + 0x700), totalManaUsed: fr(seed + 0x800), ...overrides, }); } /** * Makes arbitrary state reference. * @param seed - The seed to use for generating the state reference. * @returns A state reference. */ export function makeStateReference(seed = 0): StateReference { return new StateReference( makeAppendOnlyTreeSnapshot(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * seed), makePartialStateReference(seed + 1), ); } function makeTreeSnapshots(seed = 0) { return new TreeSnapshots( makeAppendOnlyTreeSnapshot(seed * NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP), makeAppendOnlyTreeSnapshot((seed + 0x10) * MAX_NOTE_HASHES_PER_TX), makeAppendOnlyTreeSnapshot((seed + 0x20) * MAX_NULLIFIERS_PER_TX), makeAppendOnlyTreeSnapshot((seed + 0x30) * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX), ); } /** * Makes arbitrary L2 to L1 message. * @param seed - The seed to use for generating the state reference. * @returns L2 to L1 message. */ export function makeL2ToL1Message(seed = 0): L2ToL1Message { const recipient = EthAddress.fromField(new Fr(seed)); const content = new Fr(seed + 1); return new L2ToL1Message(recipient, content); } function makeCountedL2ToL1Message(seed = 0) { return new CountedL2ToL1Message(makeL2ToL1Message(seed), seed + 2); } export function makeScopedL2ToL1Message(seed = 1) { return new ScopedL2ToL1Message(makeL2ToL1Message(seed), makeAztecAddress(seed + 3)); } /** * Makes arbitrary partial state reference. * @param seed - The seed to use for generating the partial state reference. * @returns A partial state reference. */ export function makePartialStateReference(seed = 0): PartialStateReference { return new PartialStateReference( makeAppendOnlyTreeSnapshot(MAX_NOTE_HASHES_PER_TX * seed), makeAppendOnlyTreeSnapshot(MAX_NULLIFIERS_PER_TX * (seed + 1)), makeAppendOnlyTreeSnapshot(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * (seed + 2)), ); } export function makeTxMergeRollupPrivateInputs(seed = 0): TxMergeRollupPrivateInputs { return new TxMergeRollupPrivateInputs([ makeProofData(seed, makeTxRollupPublicInputs), makeProofData(seed + 0x1000, makeTxRollupPublicInputs), ]); } export function makeBlockRootFirstRollupPrivateInputs(seed = 0) { return new BlockRootFirstRollupPrivateInputs( makeProofData(seed, makeParityPublicInputs), [makeProofData(seed + 0x1000, makeTxRollupPublicInputs), makeProofData(seed + 0x2000, makeTxRollupPublicInputs)], makeAppendOnlyTreeSnapshot(seed + 0x3000), makeSiblingPath(seed + 0x4000, L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH), makeSiblingPath(seed + 0x5000, ARCHIVE_HEIGHT), ); } export function makeBlockRootSingleTxRollupPrivateInputs(seed = 0) { return new BlockRootSingleTxRollupPrivateInputs( makeProofData(seed + 0x1000, makeTxRollupPublicInputs), makeSiblingPath(seed + 0x4000, ARCHIVE_HEIGHT), ); } /** * Makes arbitrary block merge rollup inputs. * @param seed - The seed to use for generating the merge rollup inputs. * @returns A block merge rollup inputs. */ export function makeBlockMergeRollupPrivateInputs(seed = 0) { return new BlockMergeRollupPrivateInputs([ makeProofData(seed, makeBlockRollupPublicInputs), makeProofData(seed + 0x1000, makeBlockRollupPublicInputs), ]); } /** * Makes arbitrary public data tree leaves. * @param seed - The seed to use for generating the public data tree leaf. * @returns A public data tree leaf. */ export function makePublicDataTreeLeaf(seed = 0): PublicDataTreeLeaf { return new PublicDataTreeLeaf(new Fr(seed), new Fr(seed + 1)); } /** * Makes arbitrary nullifier leaf. * @param seed - The seed to use for generating the nullifier leaf. * @returns A nullifier leaf. */ export function makeNullifierLeaf(seed = 0): NullifierLeaf { return new NullifierLeaf(new Fr(seed)); } /** * Makes arbitrary nullifier leaf preimages. * @param seed - The seed to use for generating the nullifier leaf preimage. * @returns A nullifier leaf preimage. */ export function makeNullifierLeafPreimage(seed = 0): NullifierLeafPreimage { return new NullifierLeafPreimage(makeNullifierLeaf(seed), new Fr(seed + 1), BigInt(seed + 2)); } /** * Makes arbitrary public data tree leaf preimages. * @param seed - The seed to use for generating the public data tree leaf preimage. * @returns A public data tree leaf preimage. */ export function makePublicDataTreeLeafPreimage(seed = 0): PublicDataTreeLeafPreimage { return new PublicDataTreeLeafPreimage(makePublicDataTreeLeaf(seed), new Fr(seed + 2), BigInt(seed + 3)); } /** * Creates an instance of TreeSnapshotDiffHints with arbitrary values based on the provided seed. * @param seed - The seed to use for generating the hints. * @returns A TreeSnapshotDiffHints object. */ export function makeTreeSnapshotDiffHints(seed = 1): TreeSnapshotDiffHints { const nullifierPredecessorPreimages = makeTuple( MAX_NULLIFIERS_PER_TX, x => makeNullifierLeafPreimage(x), seed + 0x1000, ); const nullifierPredecessorMembershipWitnesses = makeTuple( MAX_NULLIFIERS_PER_TX, x => makeMembershipWitness(NULLIFIER_TREE_HEIGHT, x), seed + 0x2000, ); const sortedNullifiers = makeTuple(MAX_NULLIFIERS_PER_TX, fr, seed + 0x3000); const sortedNullifierIndexes = makeTuple(MAX_NULLIFIERS_PER_TX, i => i, seed + 0x4000); const noteHashSubtreeRootSiblingPath = makeTuple(NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH, fr, seed + 0x5000); const nullifierSubtreeRootSiblingPath = makeTuple(NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH, fr, seed + 0x6000); const feePayerBalanceMembershipWitness = makeMembershipWitness(PUBLIC_DATA_TREE_HEIGHT, seed + 0x8000); return new TreeSnapshotDiffHints( noteHashSubtreeRootSiblingPath, nullifierPredecessorPreimages, nullifierPredecessorMembershipWitnesses, sortedNullifiers, sortedNullifierIndexes, nullifierSubtreeRootSiblingPath, feePayerBalanceMembershipWitness, ); } function makeVkData(seed = 1) { return new VkData(VerificationKeyData.makeFakeHonk(), seed, makeTuple(VK_TREE_HEIGHT, fr, seed + 0x100)); } export function makeProofData( seed = 0, makePublicInputs: (seed: number) => T, proofSize: PROOF_LENGTH = NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH as PROOF_LENGTH, ) { return new ProofData( makePublicInputs(seed), makeRecursiveProof(proofSize, seed + 0x100), makeVkData(seed + 0x200), ); } function makeProofDataForFixedVk( seed = 0, makePublicInputs: (seed: number) => T, proofSize: PROOF_LENGTH = NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH as PROOF_LENGTH, ) { return new ProofDataForFixedVk(makePublicInputs(seed), makeRecursiveProof(proofSize, seed + 0x100)); } function makeContractClassLogFields(seed = 1) { return new ContractClassLogFields(makeArray(CONTRACT_CLASS_LOG_SIZE_IN_FIELDS, fr, seed)); } function makePrivateBaseRollupHints(seed = 1) { const start = makePartialStateReference(seed + 0x100); const startSpongeBlob = makeSpongeBlob(seed + 0x200); const treeSnapshotDiffHints = makeTreeSnapshotDiffHints(seed + 0x600); const anchorBlockArchiveSiblingPath = makeSiblingPath(seed + 0x9000, ARCHIVE_HEIGHT); const contractClassLogsFields = makeTuple(MAX_CONTRACT_CLASS_LOGS_PER_TX, makeContractClassLogFields, seed + 0x800); const constants = makeBlockConstantData(0x100); const feePayerBalanceLeafPreimage = PublicDataTreeLeafPreimage.empty(); return PrivateBaseRollupHints.from({ start, startSpongeBlob, treeSnapshotDiffHints, feePayerBalanceLeafPreimage, anchorBlockArchiveSiblingPath, contractClassLogsFields, constants, }); } function makePublicBaseRollupHints(seed = 1) { return PublicBaseRollupHints.from({ startSpongeBlob: makeSpongeBlob(seed), lastArchive: makeAppendOnlyTreeSnapshot(seed + 0x1000), anchorBlockArchiveSiblingPath: makeSiblingPath(seed + 0x2000, ARCHIVE_HEIGHT), contractClassLogsFields: makeTuple(MAX_CONTRACT_CLASS_LOGS_PER_TX, makeContractClassLogFields, seed + 0x3000), }); } export function makePrivateTxBaseRollupPrivateInputs(seed = 0) { return PrivateTxBaseRollupPrivateInputs.from({ hidingKernelProofData: makeProofData(seed, makePrivateToRollupKernelCircuitPublicInputs, CHONK_PROOF_LENGTH), hints: makePrivateBaseRollupHints(seed + 0x100), }); } export function makePublicTxBaseRollupPrivateInputs(seed = 0) { const publicChonkVerifierProofData = makeProofData( seed, makePublicChonkVerifierPublicInputs, RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, ); const avmProofData = makeProofDataForFixedVk( seed + 0x100, makeAvmCircuitPublicInputs, AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED, ); const hints = makePublicBaseRollupHints(seed + 0x200); return PublicTxBaseRollupPrivateInputs.from({ publicChonkVerifierProofData, avmProofData, hints, }); } export function makeExecutablePrivateFunctionWithMembershipProof( seed = 0, ): ExecutablePrivateFunctionWithMembershipProof { return { selector: makeSelector(seed), bytecode: makeBytes(100, seed + 1), artifactTreeSiblingPath: makeTuple(3, fr, seed + 2), artifactTreeLeafIndex: seed + 2, privateFunctionTreeSiblingPath: makeTuple(3, fr, seed + 3), privateFunctionTreeLeafIndex: seed + 3, artifactMetadataHash: fr(seed + 4), functionMetadataHash: fr(seed + 5), utilityFunctionsTreeRoot: fr(seed + 6), vkHash: fr(seed + 7), }; } export function makeUtilityFunctionWithMembershipProof(seed = 0): UtilityFunctionWithMembershipProof { return { selector: makeSelector(seed), bytecode: makeBytes(100, seed + 1), artifactTreeSiblingPath: makeTuple(3, fr, seed + 2), artifactTreeLeafIndex: seed + 2, artifactMetadataHash: fr(seed + 4), functionMetadataHash: fr(seed + 5), privateFunctionsArtifactTreeRoot: fr(seed + 6), }; } export async function makeContractClassPublic(seed = 0, publicBytecode?: Buffer): Promise { const artifactHash = fr(seed + 1); const privateFunctionsRoot = fr(seed + 3); const packedBytecode = publicBytecode ?? makeBytes(100, seed + 4); const publicBytecodeCommitment = await computePublicBytecodeCommitment(packedBytecode); const id = await computeContractClassId({ artifactHash, privateFunctionsRoot, publicBytecodeCommitment }); return { id, artifactHash, packedBytecode, privateFunctionsRoot, privateFunctions: [], utilityFunctions: [], version: 1, }; } // eslint-disable-next-line @typescript-eslint/no-unused-vars function makeContractClassPrivateFunction(seed = 0): PrivateFunction { return { selector: FunctionSelector.fromField(fr(seed + 1)), vkHash: fr(seed + 2), }; } export function makeArray(length: number, fn: (i: number) => T, offset = 0) { return Array.from({ length }, (_: any, i: number) => fn(i + offset)); } export function makeArrayAsync(length: number, fn: (i: number) => Promise, offset = 0) { return Promise.all( Array(length) .fill(0) .map((_: any, i: number) => fn(i + offset)), ); } export function makeVector(length: number, fn: (i: number) => T, offset = 0) { return new Vector(makeArray(length, fn, offset)); } export async function makeVectorAsync(length: number, fn: (i: number) => Promise, offset = 0) { return new Vector(await makeArrayAsync(length, fn, offset)); } export function makeMap(size: number, fn: (i: number) => [string, T], offset = 0) { return new Map(makeArray(size, i => fn(i + offset))); } export async function makeMapAsync(size: number, fn: (i: number) => Promise<[string, T]>, offset = 0) { return new Map(await makeArrayAsync(size, i => fn(i + offset))); } export async function makePublicKeys(seed = 0): Promise { const f = (offset: number) => Grumpkin.mul(Grumpkin.generator, new Fq(seed + offset)); return new PublicKeys(await f(0), await f(1), await f(2), await f(3)); } export async function makeContractInstanceFromClassId( classId: Fr, seed = 0, overrides?: { deployer?: AztecAddress; initializationHash?: Fr; publicKeys?: PublicKeys; currentClassId?: Fr; }, ): Promise { const salt = new Fr(seed); const initializationHash = overrides?.initializationHash ?? new Fr(seed + 1); const deployer = overrides?.deployer ?? new AztecAddress(new Fr(seed + 2)); const publicKeys = overrides?.publicKeys ?? (await makePublicKeys(seed + 3)); const saltedInitializationHash = await poseidon2HashWithSeparator( [salt, initializationHash, deployer], DomainSeparator.PARTIAL_ADDRESS, ); const partialAddress = await poseidon2HashWithSeparator( [classId, saltedInitializationHash], DomainSeparator.PARTIAL_ADDRESS, ); const address = await computeAddress(publicKeys, partialAddress); return new SerializableContractInstance({ version: 1, salt, deployer, currentContractClassId: overrides?.currentClassId ?? classId, originalContractClassId: classId, initializationHash, publicKeys, }).withAddress(address); } export function makeAvmGetSiblingPathHint(seed = 0): AvmGetSiblingPathHint { // We want a possibly large index, but non-random. const index = BigInt(`0x${sha256(Buffer.from(seed.toString())).toString('hex')}`) % (1n << 64n); return new AvmGetSiblingPathHint( makeAppendOnlyTreeSnapshot(seed), /*treeId=*/ (seed + 1) % 5, /*index=*/ index, makeArray(seed % 64, i => new Fr(i), seed + 10), ); } export function makeAvmGetPreviousValueIndexHint(seed = 0): AvmGetPreviousValueIndexHint { // We want a possibly large index, but non-random. const index = BigInt(`0x${sha256(Buffer.from(seed.toString())).toString('hex')}`) % (1n << 64n); const value = new Fr(BigInt(`0x${sha256(Buffer.from((seed + 2).toString())).toString('hex')}`) % (1n << 128n)); return new AvmGetPreviousValueIndexHint( makeAppendOnlyTreeSnapshot(seed), /*treeId=*/ (seed + 1) % 5, value, index, /*alreadyPresent=*/ index % 2n === 0n, ); } export function makeAvmGetLeafPreimageHintPublicDataTree(seed = 0): AvmGetLeafPreimageHintPublicDataTree { // We want a possibly large index, but non-random. const index = BigInt(`0x${sha256(Buffer.from(seed.toString())).toString('hex')}`) % (1n << 64n); return new AvmGetLeafPreimageHintPublicDataTree( makeAppendOnlyTreeSnapshot(seed), /*index=*/ index, /*leafPreimage=*/ makePublicDataTreeLeafPreimage(seed + 3), ); } export function makeAvmGetLeafPreimageHintNullifierTree(seed = 0): AvmGetLeafPreimageHintNullifierTree { // We want a possibly large index, but non-random. const index = BigInt(`0x${sha256(Buffer.from(seed.toString())).toString('hex')}`) % (1n << 64n); return new AvmGetLeafPreimageHintNullifierTree( makeAppendOnlyTreeSnapshot(seed), /*index=*/ index, /*leafPreimage=*/ makeNullifierLeafPreimage(seed + 3), ); } export function makeAvmGetLeafValueHint(seed = 0): AvmGetLeafValueHint { // We want a possibly large index, but non-random. const index = BigInt(`0x${sha256(Buffer.from(seed.toString())).toString('hex')}`) % (1n << 64n); return new AvmGetLeafValueHint( makeAppendOnlyTreeSnapshot(seed), /*treeId=*/ (seed + 1) % 5, /*index=*/ index, /*value=*/ new Fr(seed + 3), ); } export function makeAvmSequentialInsertHintPublicDataTree(seed = 0): AvmSequentialInsertHintPublicDataTree { const lowLeavesWitnessData = { leaf: makePublicDataTreeLeafPreimage(seed + 3), index: BigInt(seed + 4), path: makeArray(seed % 64, i => new Fr(i), seed + 5), }; const insertionWitnessData = { leaf: makePublicDataTreeLeafPreimage(seed + 6), index: BigInt(seed + 7), path: makeArray(seed % 64, i => new Fr(i), seed + 8), }; return new AvmSequentialInsertHintPublicDataTree( makeAppendOnlyTreeSnapshot(seed), makeAppendOnlyTreeSnapshot(seed + 1), MerkleTreeId.PUBLIC_DATA_TREE, makePublicDataTreeLeaf(seed + 2), lowLeavesWitnessData, insertionWitnessData, ); } export function makeAvmSequentialInsertHintNullifierTree(seed = 0): AvmSequentialInsertHintNullifierTree { const lowLeavesWitnessData = { leaf: makeNullifierLeafPreimage(seed + 3), index: BigInt(seed + 4), path: makeArray(seed % 64, i => new Fr(i), seed + 5), }; const insertionWitnessData = { leaf: makeNullifierLeafPreimage(seed + 6), index: BigInt(seed + 7), path: makeArray(seed % 64, i => new Fr(i), seed + 8), }; return new AvmSequentialInsertHintNullifierTree( makeAppendOnlyTreeSnapshot(seed), makeAppendOnlyTreeSnapshot(seed + 1), MerkleTreeId.NULLIFIER_TREE, makeNullifierLeaf(seed + 2), lowLeavesWitnessData, insertionWitnessData, ); } export function makeAvmAppendLeavesHint(seed = 0): AvmAppendLeavesHint { return new AvmAppendLeavesHint( makeAppendOnlyTreeSnapshot(seed), makeAppendOnlyTreeSnapshot(seed + 1), // Use NOTE_HASH_TREE or L1_TO_L2_MESSAGE_TREE as mentioned in the comment on AvmAppendLeavesHint seed % 2 === 0 ? MerkleTreeId.NOTE_HASH_TREE : MerkleTreeId.L1_TO_L2_MESSAGE_TREE, makeArray((seed % 5) + 1, i => new Fr(seed + i + 2), 0), ); } export function makeAvmCheckpointActionCreateCheckpointHint(seed = 0): AvmCreateCheckpointHint { return new AvmCreateCheckpointHint( /*actionCounter=*/ seed, /*oldCheckpointId=*/ seed + 1, /*newCheckpointId=*/ seed + 2, ); } export function makeAvmCheckpointActionCommitCheckpointHint(seed = 0): AvmCommitCheckpointHint { return new AvmCommitCheckpointHint( /*actionCounter=*/ seed, /*oldCheckpointId=*/ seed + 1, /*newCheckpointId=*/ seed + 2, ); } export function makeAvmCheckpointActionRevertCheckpointHint(seed = 0): AvmRevertCheckpointHint { return new AvmRevertCheckpointHint( /*actionCounter=*/ seed, /*oldCheckpointId=*/ seed + 1, /*newCheckpointId=*/ seed + 2, /*beforeState=*/ makeTreeSnapshots(seed + 3), /*afterState=*/ makeTreeSnapshots(seed + 7), ); } export function makeAvmContractDbCheckpointActionCreateCheckpointHint(seed = 0): AvmContractDbCreateCheckpointHint { return new AvmContractDbCreateCheckpointHint( /*actionCounter=*/ seed, /*oldCheckpointId=*/ seed + 1, /*newCheckpointId=*/ seed + 2, ); } export function makeAvmContractDbCheckpointActionCommitCheckpointHint(seed = 0): AvmContractDbCommitCheckpointHint { return new AvmContractDbCommitCheckpointHint( /*actionCounter=*/ seed, /*oldCheckpointId=*/ seed + 1, /*newCheckpointId=*/ seed + 2, ); } export function makeAvmContractDbCheckpointActionRevertCheckpointHint(seed = 0): AvmContractDbRevertCheckpointHint { return new AvmContractDbRevertCheckpointHint( /*actionCounter=*/ seed, /*oldCheckpointId=*/ seed + 1, /*newCheckpointId=*/ seed + 2, ); } /** * Makes arbitrary AvmContractInstanceHint. * @param seed - The seed to use for generating the state reference. * @returns AvmContractInstanceHint. */ export function makeAvmContractInstanceHint(seed = 0): AvmContractInstanceHint { return new AvmContractInstanceHint( seed, new AztecAddress(new Fr(seed)), new Fr(seed + 0x2), new AztecAddress(new Fr(seed + 0x3)), new Fr(seed + 0x4), new Fr(seed + 0x5), new Fr(seed + 0x6), new PublicKeys( new Point(new Fr(seed + 0x7), new Fr(seed + 0x8), false), new Point(new Fr(seed + 0x9), new Fr(seed + 0x10), false), new Point(new Fr(seed + 0x11), new Fr(seed + 0x12), false), new Point(new Fr(seed + 0x13), new Fr(seed + 0x14), false), ), ); } /** * Makes arbitrary AvmDebugFunctionNameHint. * @param seed - The seed to use for generating the hint. * @returns AvmDebugFunctionNameHint. */ export function makeAvmDebugFunctionNameHint(seed = 0): AvmDebugFunctionNameHint { return new AvmDebugFunctionNameHint(new AztecAddress(new Fr(seed)), new Fr(seed + 0x2), `function-${seed}`); } /* Makes arbitrary AvmContractClassHint. * @param seed - The seed to use for generating the state reference. * @returns AvmContractClassHint. */ export function makeAvmContractClassHint(seed = 0): AvmContractClassHint { const bytecode = makeBytes(32, seed + 0x5); return new AvmContractClassHint(seed, new Fr(seed), new Fr(seed + 0x2), new Fr(seed + 0x3), bytecode); } export async function makeAvmBytecodeCommitmentHint(seed = 0): Promise { const classId = new Fr(seed + 2); const bytecode = makeBytes(32, seed + 0x5); return new AvmBytecodeCommitmentHint(seed, classId, await computePublicBytecodeCommitment(bytecode)); } export async function makePublicCallRequestWithCalldata(seed = 0): Promise { const calldata = makeArray((seed % 20) + 4, i => new Fr(i), seed + 0x1000); const calldataHash = await computeCalldataHash(calldata); const publicCallRequest = new PublicCallRequest( new AztecAddress(new Fr(seed)), new AztecAddress(new Fr(seed + 1)), false /*isStatic*/, calldataHash, ); return new PublicCallRequestWithCalldata(publicCallRequest, calldata); } export function makeContractClassLog(seed = 0): ContractClassLog { return new ContractClassLog(makeAztecAddress(seed + 0x1000), makeContractClassLogFields(seed + 0x2000), seed % 20); } export function makeContractDeploymentData(seed = 0): ContractDeploymentData { const contractClassLogs = makeArray(seed % 20, i => makeContractClassLog(i), seed + 0x1000); const privateLogs = makeArray(seed % 20, i => makePrivateLog(i), seed + 0x2000); return new ContractDeploymentData(contractClassLogs, privateLogs); } export async function makeAvmTxHint(seed = 0): Promise { return new AvmTxHint( `txhash-${seed}`, makeGasSettings(), makeGasFees(seed + 0x1000), makeContractDeploymentData(seed + 0x2000), makeContractDeploymentData(seed + 0x3000), { noteHashes: makeArray((seed % 20) + 4, i => new Fr(i), seed + 0x1000), nullifiers: makeArray((seed % 20) + 4, i => new Fr(i), seed + 0x2000), l2ToL1Messages: makeArray((seed % 20) + 4, i => makeScopedL2ToL1Message(i), seed + 0x3000), }, { noteHashes: makeArray((seed % 20) + 4, i => new Fr(i), seed + 0x3000), nullifiers: makeArray((seed % 20) + 4, i => new Fr(i), seed + 0x4000), l2ToL1Messages: makeArray((seed % 20) + 4, i => makeScopedL2ToL1Message(i), seed + 0x5000), }, await makeArrayAsync((seed % 20) + 4, i => makePublicCallRequestWithCalldata(i), seed + 0x5000), //setupEnqueuedCalls await makeArrayAsync((seed % 20) + 4, i => makePublicCallRequestWithCalldata(i), seed + 0x6000), // appLogicEnqueuedCalls await makePublicCallRequestWithCalldata(seed + 0x7000), // teardownEnqueuedCall makeGas(seed + 0x8000), // gasUsedByPrivate makeAztecAddress(seed + 0x9000), // feePayer ); } /** * Creates arbitrary AvmExecutionHints. * @param seed - The seed to use for generating the hints. * @returns the execution hints. */ export async function makeAvmExecutionHints( seed = 0, overrides: Partial> = {}, ): Promise { const lengthOffset = 10; const lengthSeedMod = 10; const baseLength = lengthOffset + (seed % lengthSeedMod); const fields = { globalVariables: makeGlobalVariables(seed + 0x4000), tx: await makeAvmTxHint(seed + 0x4100), protocolContracts: new ProtocolContracts(makeTuple(MAX_PROTOCOL_CONTRACTS, makeAztecAddress, seed + 0x4600)), contractInstances: makeArray(baseLength + 2, makeAvmContractInstanceHint, seed + 0x4700), contractClasses: makeArray(baseLength + 5, makeAvmContractClassHint, seed + 0x4900), bytecodeCommitments: await makeArrayAsync(baseLength + 5, makeAvmBytecodeCommitmentHint, seed + 0x4900), debugFunctionNames: makeArray(baseLength + 5, makeAvmDebugFunctionNameHint, seed + 0x4a00), contractDbCreateCheckpointHints: makeArray( baseLength + 5, makeAvmContractDbCheckpointActionCreateCheckpointHint, seed + 0x5900, ), contractDbCommitCheckpointHints: makeArray( baseLength + 5, makeAvmContractDbCheckpointActionCommitCheckpointHint, seed + 0x5b00, ), contractDbRevertCheckpointHints: makeArray( baseLength + 5, makeAvmContractDbCheckpointActionRevertCheckpointHint, seed + 0x5d00, ), startingTreeRoots: makeTreeSnapshots(seed + 0x4900), getSiblingPathHints: makeArray(baseLength + 5, makeAvmGetSiblingPathHint, seed + 0x4b00), getPreviousValueIndexHints: makeArray(baseLength + 5, makeAvmGetPreviousValueIndexHint, seed + 0x4d00), getLeafPreimageHintPublicDataTree: makeArray( baseLength + 5, makeAvmGetLeafPreimageHintPublicDataTree, seed + 0x4f00, ), getLeafPreimageHintNullifierTree: makeArray(baseLength + 5, makeAvmGetLeafPreimageHintNullifierTree, seed + 0x5100), getLeafValueHints: makeArray(baseLength + 5, makeAvmGetLeafValueHint, seed + 0x5300), sequentialInsertHintsPublicDataTree: makeArray( baseLength + 5, makeAvmSequentialInsertHintPublicDataTree, seed + 0x5500, ), sequentialInsertHintsNullifierTree: makeArray( baseLength + 5, makeAvmSequentialInsertHintNullifierTree, seed + 0x5700, ), appendLeavesHints: makeArray(baseLength + 5, makeAvmAppendLeavesHint, seed + 0x5800), createCheckpointHints: makeArray(baseLength + 5, makeAvmCheckpointActionCreateCheckpointHint, seed + 0x5900), commitCheckpointHints: makeArray(baseLength + 5, makeAvmCheckpointActionCommitCheckpointHint, seed + 0x5b00), revertCheckpointHints: makeArray(baseLength + 5, makeAvmCheckpointActionRevertCheckpointHint, seed + 0x5d00), ...overrides, }; return new AvmExecutionHints( fields.globalVariables, fields.tx, fields.protocolContracts, fields.contractInstances, fields.contractClasses, fields.bytecodeCommitments, fields.debugFunctionNames, fields.contractDbCreateCheckpointHints, fields.contractDbCommitCheckpointHints, fields.contractDbRevertCheckpointHints, fields.startingTreeRoots, fields.getSiblingPathHints, fields.getPreviousValueIndexHints, fields.getLeafPreimageHintPublicDataTree, fields.getLeafPreimageHintNullifierTree, fields.getLeafValueHints, fields.sequentialInsertHintsPublicDataTree, fields.sequentialInsertHintsNullifierTree, fields.appendLeavesHints, fields.createCheckpointHints, fields.commitCheckpointHints, fields.revertCheckpointHints, ); } /** * Creates arbitrary AvmCircuitInputs. * @param seed - The seed to use for generating the hints. * @returns the execution hints. */ export async function makeAvmCircuitInputs( seed = 0, overrides: Partial> = {}, ): Promise { const fields = { hints: await makeAvmExecutionHints(seed + 0x3000), publicInputs: makeAvmCircuitPublicInputs(seed + 0x4000), ...overrides, }; return new AvmCircuitInputs(fields.hints, fields.publicInputs); } /** * TODO: Since the max value check is currently disabled this function is pointless. Should it be removed? * Test only. Easy to identify big endian field serialize. * @param n - The number. * @returns The field. */ export function fr(n: number): Fr { return new Fr(BigInt(n)); } /** * Creates a random TxScopedL2Log with private log data. */ export function randomTxScopedPrivateL2Log(opts?: { tag?: Fr; txHash?: TxHash; blockNumber?: number; blockTimestamp?: bigint; noteHashes?: Fr[]; firstNullifier?: Fr; }) { const log = PrivateLog.random(opts?.tag); return new TxScopedL2Log( opts?.txHash ?? TxHash.random(), BlockNumber(opts?.blockNumber ?? 1), opts?.blockTimestamp ?? 1n, log.getEmittedFields(), opts?.noteHashes ?? [Fr.random(), Fr.random()], opts?.firstNullifier ?? Fr.random(), ); } /** * Creates a random TxScopedL2Log with public log data. */ export async function randomTxScopedPublicL2Log(opts?: { txHash?: TxHash; blockNumber?: number; blockTimestamp?: bigint; noteHashes?: Fr[]; firstNullifier?: Fr; }) { const log = await PublicLog.random(); return new TxScopedL2Log( opts?.txHash ?? TxHash.random(), BlockNumber(opts?.blockNumber ?? 1), opts?.blockTimestamp ?? 1n, log.getEmittedFields(), opts?.noteHashes ?? [Fr.random(), Fr.random()], opts?.firstNullifier ?? Fr.random(), ); } /** * Creates L2Tips with all tips pointing to the same block number. * Useful for mocking aztecNode.getL2Tips() in tests. * @param blockNumber - The block number to use for all tips. * @param hash - Optional hash for the block (defaults to empty string). * @param checkpointNumber - Optional checkpoint number (defaults to blockNumber). * @param checkpointHash - Optional checkpoint hash (defaults to block hash). * @returns L2Tips object with all tips at the same block. */ export function makeL2Tips( blockNumber: number | BlockNumber, hash = '', checkpointNumber?: number | CheckpointNumber, checkpointHash?: string, ): L2Tips { const bn = typeof blockNumber === 'number' ? BlockNumber(blockNumber) : blockNumber; const cpn = checkpointNumber !== undefined ? typeof checkpointNumber === 'number' ? CheckpointNumber(checkpointNumber) : checkpointNumber : CheckpointNumber.fromBlockNumber(bn); const cph = checkpointHash ?? hash; return { proposed: { number: bn, hash }, checkpointed: { block: { number: bn, hash }, checkpoint: { number: cpn, hash: cph }, }, proven: { block: { number: bn, hash }, checkpoint: { number: cpn, hash: cph }, }, finalized: { block: { number: bn, hash }, checkpoint: { number: cpn, hash: cph }, }, }; } export async function randomExtendedDirectionalAppTaggingSecret(): Promise { const resolvedApp = await AztecAddress.random(); // Using the fromString method like this is messy as it leaks the underlying serialization format but I don't want to // expose the type's constructor just for tests since in prod the secret is always constructed via compute. Also this // method is tested in extended_directional_app_tagging_secret.test.ts hence all should be fine. return ExtendedDirectionalAppTaggingSecret.fromString(`${Fr.random().toString()}:${resolvedApp.toString()}`); }