From 9eef247a7ba986041bff2d7b459ceb811bba21ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Tue, 2 Jan 2024 12:40:48 +0000 Subject: [PATCH] feat: Only one tx per base rollup (#3742) This PR makes the base rollup process only one TX at a time, lowering the min TX per rollup from 4 to 2. --- .../src/core/libraries/ConstantsGen.sol | 32 +- l1-contracts/src/core/libraries/Decoder.sol | 57 +- yarn-project/circuits.js/src/constants.gen.ts | 32 +- .../src/structs/rollup/base_rollup.ts | 55 +- .../circuits.js/src/tests/factories.ts | 87 +-- .../rollup-lib/src/base/base_rollup_inputs.nr | 655 ++++++------------ .../src/crates/rollup-lib/src/merkle_tree.nr | 8 +- .../types/src/abis/membership_witness.nr | 1 - .../src/crates/types/src/constants.nr | 34 +- .../src/type_conversion.ts | 58 +- .../src/types/rollup_base_types.ts | 32 +- .../block_builder/solo_block_builder.test.ts | 13 +- .../src/block_builder/solo_block_builder.ts | 86 +-- .../src/sequencer/sequencer.test.ts | 6 +- .../src/sequencer/sequencer.ts | 4 +- yarn-project/types/src/l2_block.ts | 27 +- 16 files changed, 394 insertions(+), 793 deletions(-) diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index d11aecbc1ab..7dfc0e1a13e 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -39,10 +39,6 @@ library Constants { uint256 internal constant NUM_ENCRYPTED_LOGS_HASHES_PER_TX = 1; uint256 internal constant NUM_UNENCRYPTED_LOGS_HASHES_PER_TX = 1; uint256 internal constant NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; - uint256 internal constant KERNELS_PER_BASE_ROLLUP = 2; - uint256 internal constant MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP = 128; - uint256 internal constant MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP = 32; - uint256 internal constant MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP = 32; uint256 internal constant VK_TREE_HEIGHT = 3; uint256 internal constant FUNCTION_TREE_HEIGHT = 5; uint256 internal constant CONTRACT_TREE_HEIGHT = 16; @@ -51,14 +47,14 @@ library Constants { uint256 internal constant NULLIFIER_TREE_HEIGHT = 20; uint256 internal constant L1_TO_L2_MSG_TREE_HEIGHT = 16; uint256 internal constant ROLLUP_VK_TREE_HEIGHT = 8; - uint256 internal constant CONTRACT_SUBTREE_HEIGHT = 1; - uint256 internal constant CONTRACT_SUBTREE_SIBLING_PATH_LENGTH = 15; - uint256 internal constant NOTE_HASH_SUBTREE_HEIGHT = 7; - uint256 internal constant NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH = 25; - uint256 internal constant NULLIFIER_SUBTREE_HEIGHT = 7; + uint256 internal constant CONTRACT_SUBTREE_HEIGHT = 0; + uint256 internal constant CONTRACT_SUBTREE_SIBLING_PATH_LENGTH = 16; + uint256 internal constant NOTE_HASH_SUBTREE_HEIGHT = 6; + uint256 internal constant NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH = 26; + uint256 internal constant NULLIFIER_SUBTREE_HEIGHT = 6; uint256 internal constant PUBLIC_DATA_SUBTREE_HEIGHT = 4; uint256 internal constant ARCHIVE_HEIGHT = 16; - uint256 internal constant NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH = 13; + uint256 internal constant NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH = 14; uint256 internal constant PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH = 36; uint256 internal constant L1_TO_L2_MSG_SUBTREE_HEIGHT = 4; uint256 internal constant L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12; @@ -86,12 +82,12 @@ library Constants { uint256 internal constant CALL_PRIVATE_FUNCTION_RETURN_SIZE = 161; uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 87; uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 144; - uint256 internal constant COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 4096; - uint256 internal constant NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 4096; - uint256 internal constant PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 2048; - uint256 internal constant CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 64; - uint256 internal constant CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP = 128; - uint256 internal constant CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED = 104; - uint256 internal constant L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP = 128; - uint256 internal constant LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 128; + uint256 internal constant COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048; + uint256 internal constant NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; + uint256 internal constant PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 1024; + uint256 internal constant CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 32; + uint256 internal constant CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP = 64; + uint256 internal constant CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED = 52; + uint256 internal constant L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP = 64; + uint256 internal constant LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 64; } diff --git a/l1-contracts/src/core/libraries/Decoder.sol b/l1-contracts/src/core/libraries/Decoder.sol index c7b51b30b0e..379904f28ff 100644 --- a/l1-contracts/src/core/libraries/Decoder.sol +++ b/l1-contracts/src/core/libraries/Decoder.sol @@ -87,10 +87,8 @@ library Decoder { bytes32[] baseLeaves; bytes32[] l2ToL1Msgs; bytes baseLeaf; - bytes32 encryptedLogsHashKernel1; - bytes32 encryptedLogsHashKernel2; - bytes32 unencryptedLogsHashKernel1; - bytes32 unencryptedLogsHashKernel2; + bytes32 encryptedLogsHash; + bytes32 unencryptedLogsHash; uint256 l1Tol2MsgsCount; } @@ -210,7 +208,7 @@ library Decoder { // Commitments uint256 count = read4(_l2Block, offset); - vars.baseLeaves = new bytes32[](count / (Constants.MAX_NEW_COMMITMENTS_PER_TX * 2)); + vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_COMMITMENTS_PER_TX); offsets.commitment = BLOCK_HEADER_OFFSET + 0x4; offset += 0x4 + count * 0x20; offsets.nullifier = offset + 0x4; // + 0x4 to offset by next read4 @@ -261,24 +259,15 @@ library Decoder { /* * Compute the leaf to insert. * Leaf_i = ( - * newCommitmentsKernel1, - * newCommitmentsKernel2, - * newNullifiersKernel1, - * newNullifiersKernel2, - * newPublicDataWritesKernel1, - * newPublicDataWritesKernel2, - * newL2ToL1MsgsKernel1, - * newL2ToL1MsgsKernel2, - * newContractLeafKernel1, - * newContractLeafKernel2, - * newContractDataKernel1.aztecAddress, - * newContractDataKernel1.ethAddress (padded to 32 bytes), - * newContractDataKernel2.aztecAddress, - * newContractDataKernel2.ethAddress (padded to 32 bytes), ____ - * encryptedLogsHashKernel1, | - * encryptedLogsHashKernel2, |=> Computed below from logs' preimages. - * unencryptedLogsHashKernel1, | - * unencryptedLogsHashKernel2 ____| + * newCommitmentsKernel, + * newNullifiersKernel, + * newPublicDataWritesKernel, + * newL2ToL1MsgsKernel, + * newContractLeafKernel, + * newContractDataKernel.aztecAddress, + * newContractDataKernel.ethAddress (padded to 32 bytes), + * encryptedLogsHash, | + * unencryptedLogsHash, ____|=> Computed below from logs' preimages. * ); * Note that we always read data, the l2Block (atm) must therefore include dummy or zero-notes for * Zero values. @@ -288,14 +277,10 @@ library Decoder { * Compute encrypted and unencrypted logs hashes corresponding to the current leaf. * Note: will advance offsets by the number of bytes processed. */ - (vars.encryptedLogsHashKernel1, offsets.encryptedLogs) = - computeKernelLogsHash(offsets.encryptedLogs, _l2Block); - (vars.encryptedLogsHashKernel2, offsets.encryptedLogs) = + (vars.encryptedLogsHash, offsets.encryptedLogs) = computeKernelLogsHash(offsets.encryptedLogs, _l2Block); - (vars.unencryptedLogsHashKernel1, offsets.unencryptedLogs) = - computeKernelLogsHash(offsets.unencryptedLogs, _l2Block); - (vars.unencryptedLogsHashKernel2, offsets.unencryptedLogs) = + (vars.unencryptedLogsHash, offsets.unencryptedLogs) = computeKernelLogsHash(offsets.unencryptedLogs, _l2Block); // Insertions are split into multiple `bytes.concat` to work around stack too deep. @@ -310,19 +295,11 @@ library Decoder { slice(_l2Block, offsets.contracts, Constants.CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP) ), bytes.concat( - slice(_l2Block, offsets.contractData, 0x20), // newContractDataKernel1.aztecAddress + slice(_l2Block, offsets.contractData, 0x20), // newContractDataKernel.aztecAddress bytes12(0), - slice(_l2Block, offsets.contractData + 0x20, 0x14), // newContractDataKernel1.ethAddress - slice(_l2Block, offsets.contractData + 0x34, 0x20), // newContractDataKernel2.aztecAddress - bytes12(0), - slice(_l2Block, offsets.contractData + 0x54, 0x14) // newContractDataKernel2.ethAddress + slice(_l2Block, offsets.contractData + 0x20, 0x14) // newContractDataKernel.ethAddress ), - bytes.concat( - vars.encryptedLogsHashKernel1, - vars.encryptedLogsHashKernel2, - vars.unencryptedLogsHashKernel1, - vars.unencryptedLogsHashKernel2 - ) + bytes.concat(vars.encryptedLogsHash, vars.unencryptedLogsHash) ); offsets.commitment += Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP; diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index fbe8599a71c..411c2121996 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -25,10 +25,6 @@ export const MAX_PENDING_READ_REQUESTS_PER_TX = 128; export const NUM_ENCRYPTED_LOGS_HASHES_PER_TX = 1; export const NUM_UNENCRYPTED_LOGS_HASHES_PER_TX = 1; export const NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; -export const KERNELS_PER_BASE_ROLLUP = 2; -export const MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP = 128; -export const MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP = 32; -export const MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP = 32; export const VK_TREE_HEIGHT = 3; export const FUNCTION_TREE_HEIGHT = 5; export const CONTRACT_TREE_HEIGHT = 16; @@ -37,14 +33,14 @@ export const PUBLIC_DATA_TREE_HEIGHT = 40; export const NULLIFIER_TREE_HEIGHT = 20; export const L1_TO_L2_MSG_TREE_HEIGHT = 16; export const ROLLUP_VK_TREE_HEIGHT = 8; -export const CONTRACT_SUBTREE_HEIGHT = 1; -export const CONTRACT_SUBTREE_SIBLING_PATH_LENGTH = 15; -export const NOTE_HASH_SUBTREE_HEIGHT = 7; -export const NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH = 25; -export const NULLIFIER_SUBTREE_HEIGHT = 7; +export const CONTRACT_SUBTREE_HEIGHT = 0; +export const CONTRACT_SUBTREE_SIBLING_PATH_LENGTH = 16; +export const NOTE_HASH_SUBTREE_HEIGHT = 6; +export const NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH = 26; +export const NULLIFIER_SUBTREE_HEIGHT = 6; export const PUBLIC_DATA_SUBTREE_HEIGHT = 4; export const ARCHIVE_HEIGHT = 16; -export const NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH = 13; +export const NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH = 14; export const PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH = 36; export const L1_TO_L2_MSG_SUBTREE_HEIGHT = 4; export const L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12; @@ -72,14 +68,14 @@ export const EMPTY_NULLIFIED_COMMITMENT = 1000000; export const CALL_PRIVATE_FUNCTION_RETURN_SIZE = 161; export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 87; export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 144; -export const COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 4096; -export const NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 4096; -export const PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 2048; -export const CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 64; -export const CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP = 128; -export const CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED = 104; -export const L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP = 128; -export const LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 128; +export const COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048; +export const NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; +export const PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 1024; +export const CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 32; +export const CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP = 64; +export const CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED = 52; +export const L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP = 64; +export const LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 64; export enum GeneratorIndex { COMMITMENT = 1, COMMITMENT_NONCE = 2, diff --git a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts index 38d827de360..9352b4fb05f 100644 --- a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts @@ -4,8 +4,7 @@ import { BufferReader, Tuple } from '@aztec/foundation/serialize'; import { ARCHIVE_HEIGHT, CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, - KERNELS_PER_BASE_ROLLUP, - MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, + MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, @@ -98,7 +97,7 @@ export class BaseRollupInputs { /** * Data of the 2 kernels that preceded this base rollup circuit. */ - public kernelData: Tuple, + public kernelData: PreviousKernelData, /** * Snapshot of the note hash tree at the start of the base rollup circuit. */ @@ -123,23 +122,23 @@ export class BaseRollupInputs { /** * The nullifiers to be inserted in the tree, sorted high to low. */ - public sortedNewNullifiers: Tuple, + public sortedNewNullifiers: Tuple, /** * The indexes of the sorted nullifiers to the original ones. */ - public sortednewNullifiersIndexes: Tuple, + public sortednewNullifiersIndexes: Tuple, /** * The nullifiers which need to be updated to perform the batch insertion of the new nullifiers. * See `StandardIndexedTree.batchInsert` function for more details. */ - public lowNullifierLeafPreimages: Tuple, + public lowNullifierLeafPreimages: Tuple, /** * Membership witnesses for the nullifiers which need to be updated to perform the batch insertion of the new * nullifiers. */ public lowNullifierMembershipWitness: Tuple< MembershipWitness, - typeof MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP + typeof MAX_NEW_NULLIFIERS_PER_TX >, /** @@ -157,65 +156,51 @@ export class BaseRollupInputs { /** * The public data writes to be inserted in the tree, sorted high slot to low slot. */ - public sortedPublicDataWrites: Tuple< - Tuple, - typeof KERNELS_PER_BASE_ROLLUP - >, + public sortedPublicDataWrites: Tuple, + /** * The indexes of the sorted public data writes to the original ones. */ - public sortedPublicDataWritesIndexes: Tuple< - Tuple, - typeof KERNELS_PER_BASE_ROLLUP - >, + public sortedPublicDataWritesIndexes: Tuple, /** * The public data writes which need to be updated to perform the batch insertion of the new public data writes. * See `StandardIndexedTree.batchInsert` function for more details. */ public lowPublicDataWritesPreimages: Tuple< - Tuple, - typeof KERNELS_PER_BASE_ROLLUP + PublicDataTreeLeafPreimage, + typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX >, /** * Membership witnesses for the nullifiers which need to be updated to perform the batch insertion of the new * nullifiers. */ public lowPublicDataWritesMembershipWitnesses: Tuple< - Tuple, typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX>, - typeof KERNELS_PER_BASE_ROLLUP + MembershipWitness, + typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX >, /** * Sibling path "pointing to" where the new public data subtree should be inserted into the public data tree. */ - public publicDataWritesSubtreeSiblingPaths: Tuple< - Tuple, - typeof KERNELS_PER_BASE_ROLLUP - >, + public publicDataWritesSubtreeSiblingPath: Tuple, /** * Preimages of leaves which are to be read by the public data reads. */ - public publicDataReadsPreimages: Tuple< - Tuple, - typeof KERNELS_PER_BASE_ROLLUP - >, + public publicDataReadsPreimages: Tuple, /** * Sibling paths of leaves which are to be read by the public data reads. * Each item in the array is the sibling path that corresponds to a read request. */ public publicDataReadsMembershipWitnesses: Tuple< - Tuple, typeof MAX_PUBLIC_DATA_READS_PER_TX>, - typeof KERNELS_PER_BASE_ROLLUP + MembershipWitness, + typeof MAX_PUBLIC_DATA_READS_PER_TX >, /** * Membership witnesses of blocks referred by each of the 2 kernels. */ - public archiveRootMembershipWitnesses: Tuple< - MembershipWitness, - typeof KERNELS_PER_BASE_ROLLUP - >, + public archiveRootMembershipWitness: MembershipWitness, /** * Data which is not modified by the base rollup circuit. */ @@ -245,10 +230,10 @@ export class BaseRollupInputs { fields.sortedPublicDataWritesIndexes, fields.lowPublicDataWritesPreimages, fields.lowPublicDataWritesMembershipWitnesses, - fields.publicDataWritesSubtreeSiblingPaths, + fields.publicDataWritesSubtreeSiblingPath, fields.publicDataReadsPreimages, fields.publicDataReadsMembershipWitnesses, - fields.archiveRootMembershipWitnesses, + fields.archiveRootMembershipWitness, fields.constants, ] as const; } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 87ab8986361..41485ef4431 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -30,7 +30,6 @@ import { FunctionData, FunctionSelector, G1AffineElement, - KERNELS_PER_BASE_ROLLUP, KernelCircuitPublicInputs, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, MAX_NEW_COMMITMENTS_PER_CALL, @@ -38,7 +37,6 @@ import { MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, - MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NULLIFIERS_PER_TX, MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX, @@ -909,7 +907,7 @@ export function makePublicDataTreeLeafPreimage(seed = 0): PublicDataTreeLeafPrei * @returns A base rollup inputs. */ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { - const kernelData = makeTuple(KERNELS_PER_BASE_ROLLUP, x => makePreviousKernelData(seed + (x + 1) * 0x100)); + const kernelData = makePreviousKernelData(seed); const startNoteHashTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x100); const startNullifierTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x200); @@ -918,13 +916,13 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { const startArchiveSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x500); const lowNullifierLeafPreimages = makeTuple( - MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, + MAX_NEW_NULLIFIERS_PER_TX, x => new NullifierLeafPreimage(fr(x), fr(x + 0x100), BigInt(x + 0x200)), seed + 0x1000, ); const lowNullifierMembershipWitness = makeTuple( - MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, + MAX_NEW_NULLIFIERS_PER_TX, x => makeMembershipWitness(NULLIFIER_TREE_HEIGHT, x), seed + 0x2000, ); @@ -933,77 +931,44 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { const newNullifiersSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, fr, seed + 0x4000); const newContractsSubtreeSiblingPath = makeTuple(CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, fr, seed + 0x5000); - const sortedNewNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, fr, seed + 0x6000); - const sortednewNullifiersIndexes = makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => i, seed + 0x7000); + const sortedNewNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, fr, seed + 0x6000); + const sortednewNullifiersIndexes = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => i, seed + 0x7000); const sortedPublicDataWrites = makeTuple( - KERNELS_PER_BASE_ROLLUP, - i => { - return makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataTreeLeaf, seed + 0x8000 + i * 0x100); - }, - 0, - ); - const sortedPublicDataWritesIndexes = makeTuple( - KERNELS_PER_BASE_ROLLUP, - () => makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => i, 0), - 0, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + makePublicDataTreeLeaf, + seed + 0x8000, ); + const sortedPublicDataWritesIndexes = makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => i, 0); + const lowPublicDataWritesPreimages = makeTuple( - KERNELS_PER_BASE_ROLLUP, - i => { - return makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - makePublicDataTreeLeafPreimage, - seed + 0x8200 + i * 0x100, - ); - }, - 0, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + makePublicDataTreeLeafPreimage, + seed + 0x8200, ); const lowPublicDataWritesMembershipWitnesses = makeTuple( - KERNELS_PER_BASE_ROLLUP, - i => { - return makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - i => makeMembershipWitness(PUBLIC_DATA_TREE_HEIGHT, i), - seed + 0x8400 + i * 0x100, - ); - }, - 0, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + i => makeMembershipWitness(PUBLIC_DATA_TREE_HEIGHT, i), + seed + 0x8400, ); - const publicDataWritesSubtreeSiblingPaths = makeTuple( - KERNELS_PER_BASE_ROLLUP, - i => { - return makeTuple(PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, fr, 0x8600 + i * 0x100); - }, - 0, - ); + const publicDataWritesSubtreeSiblingPath = makeTuple(PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, fr, 0x8600); const publicDataReadsPreimages = makeTuple( - KERNELS_PER_BASE_ROLLUP, - i => { - return makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, makePublicDataTreeLeafPreimage, seed + 0x8800 + i * 0x100); - }, - 0, + MAX_PUBLIC_DATA_READS_PER_TX, + makePublicDataTreeLeafPreimage, + seed + 0x8800, ); const publicDataReadsMembershipWitnesses = makeTuple( - KERNELS_PER_BASE_ROLLUP, - i => { - return makeTuple( - MAX_PUBLIC_DATA_READS_PER_TX, - i => makeMembershipWitness(PUBLIC_DATA_TREE_HEIGHT, i), - seed + 0x8a00 + i * 0x100, - ); - }, - 0, + MAX_PUBLIC_DATA_READS_PER_TX, + i => makeMembershipWitness(PUBLIC_DATA_TREE_HEIGHT, i), + seed + 0x8a00, ); - const archiveRootMembershipWitnesses = makeTuple(KERNELS_PER_BASE_ROLLUP, x => - makeMembershipWitness(ARCHIVE_HEIGHT, seed + x * 0x1000 + 0x9000), - ); + const archiveRootMembershipWitness = makeMembershipWitness(ARCHIVE_HEIGHT, seed + 0x9000); const constants = makeConstantBaseRollupData(0x100); @@ -1025,10 +990,10 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { sortedPublicDataWritesIndexes, lowPublicDataWritesPreimages, lowPublicDataWritesMembershipWitnesses, - publicDataWritesSubtreeSiblingPaths, + publicDataWritesSubtreeSiblingPath, publicDataReadsPreimages, publicDataReadsMembershipWitnesses, - archiveRootMembershipWitnesses, + archiveRootMembershipWitness, constants, }); } diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index 086a03f219a..270f7b5fce7 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -10,14 +10,10 @@ use dep::types::abis::public_data_update_request::PublicDataUpdateRequest; use dep::types::abis::public_data_read::PublicDataRead; use dep::types::mocked::{AggregationObject, Proof}; use dep::types::constants::{ - MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP, - MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP, PUBLIC_DATA_TREE_HEIGHT, - KERNELS_PER_BASE_ROLLUP, MAX_NEW_CONTRACTS_PER_TX, NOTE_HASH_SUBTREE_HEIGHT, CONTRACT_SUBTREE_HEIGHT, @@ -39,57 +35,52 @@ use dep::types::abis::membership_witness::{NullifierMembershipWitness, PublicDat use dep::types::abis::membership_witness::ArchiveRootMembershipWitness; struct BaseRollupInputs { - kernel_data: [PreviousKernelData; KERNELS_PER_BASE_ROLLUP], + kernel_data: PreviousKernelData, start_note_hash_tree_snapshot: AppendOnlyTreeSnapshot, start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot, start_contract_tree_snapshot: AppendOnlyTreeSnapshot, start_public_data_tree_snapshot: AppendOnlyTreeSnapshot, archive_snapshot: AppendOnlyTreeSnapshot, - sorted_new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], - sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], - low_nullifier_leaf_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], - low_nullifier_membership_witness: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], + sorted_new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_TX], + sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_TX], + low_nullifier_leaf_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], + low_nullifier_membership_witness: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_TX], // For inserting the new subtrees into their respective trees: // Note: the insertion leaf index can be derived from the above snapshots' `next_available_leaf_index` values. new_commitments_subtree_sibling_path: [Field; NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH], new_nullifiers_subtree_sibling_path: [Field; NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH], - public_data_writes_subtree_sibling_paths: [[Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]; KERNELS_PER_BASE_ROLLUP], + public_data_writes_subtree_sibling_path: [Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], new_contracts_subtree_sibling_path: [Field; CONTRACT_SUBTREE_SIBLING_PATH_LENGTH], - sorted_public_data_writes: [[PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], - sorted_public_data_writes_indexes: [[u32; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], - low_public_data_writes_preimages: [[PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], - low_public_data_writes_witnesses: [[PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], + sorted_public_data_writes: [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + sorted_public_data_writes_indexes: [u32; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + low_public_data_writes_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + low_public_data_writes_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - public_data_reads_preimages: [[PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX]; KERNELS_PER_BASE_ROLLUP], - public_data_reads_witnesses: [[PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX]; KERNELS_PER_BASE_ROLLUP], + public_data_reads_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX], + public_data_reads_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX], - archive_root_membership_witnesses: [ArchiveRootMembershipWitness; KERNELS_PER_BASE_ROLLUP], + archive_root_membership_witness: ArchiveRootMembershipWitness, constants: ConstantRollupData, } impl BaseRollupInputs { pub fn base_rollup_circuit(self) -> BaseOrMergeRollupPublicInputs { - // Verify the previous kernel proofs - for i in 0..KERNELS_PER_BASE_ROLLUP { - let proof = self.kernel_data[i].proof; - assert(verify_kernel_proof(proof), "kernel proof verification failed"); - }; + // Verify the previous kernel proof + assert(verify_kernel_proof(self.kernel_data.proof), "kernel proof verification failed"); // Verify the kernel chain_id and versions - for i in 0..KERNELS_PER_BASE_ROLLUP { - assert(self.kernel_data[i].public_inputs.constants.tx_context.chain_id == - self.constants.global_variables.chain_id, "kernel chain_id does not match the rollup chain_id"); - assert(self.kernel_data[i].public_inputs.constants.tx_context.version == - self.constants.global_variables.version, "kernel version does not match the rollup version"); - }; - + assert(self.kernel_data.public_inputs.constants.tx_context.chain_id == + self.constants.global_variables.chain_id, "kernel chain_id does not match the rollup chain_id"); + assert(self.kernel_data.public_inputs.constants.tx_context.version == + self.constants.global_variables.version, "kernel version does not match the rollup version"); // First we compute the contract tree leaves let contract_leaves = self.calculate_contract_leaves(); - let contracts_tree_subroot = self.calculate_contract_subtree(contract_leaves); + + let contracts_tree_subroot = self.calculate_contract_subtree_root(contract_leaves); let commitments_tree_subroot = self.calculate_commitments_subtree(); @@ -144,67 +135,44 @@ impl BaseRollupInputs { } } - fn calculate_contract_leaves(self) -> [Field; NUM_CONTRACT_LEAVES] { - let mut contract_leaves = [0; NUM_CONTRACT_LEAVES]; - for i in 0..KERNELS_PER_BASE_ROLLUP { - let new_contracts = self.kernel_data[i].public_inputs.end.new_contracts; - - // loop over the new contracts - for j in 0..new_contracts.len() { - let leaf_preimage = new_contracts[j]; - // When there is no contract deployment, we should insert a zero leaf into the tree and ignore the - // member-ship check. This is to ensure that we don't hit "already deployed" errors when we are not - // deploying contracts. e.g., when we are only calling functions on existing contracts. - let to_push = if leaf_preimage.contract_address.to_field() == 0 { - 0 - } else { - leaf_preimage.hash() - }; - contract_leaves[i*new_contracts.len() + j] = to_push; - } + fn calculate_contract_leaves(self) -> [Field; MAX_NEW_CONTRACTS_PER_TX] { + let mut contract_leaves = [0; MAX_NEW_CONTRACTS_PER_TX]; + let new_contracts = self.kernel_data.public_inputs.end.new_contracts; + + // loop over the new contracts + for i in 0..new_contracts.len() { + let leaf_preimage = new_contracts[i]; + // When there is no contract deployment, we should insert a zero leaf into the tree and ignore the + // member-ship check. This is to ensure that we don't hit "already deployed" errors when we are not + // deploying contracts. e.g., when we are only calling functions on existing contracts. + let to_push = if leaf_preimage.contract_address.to_field() == 0 { + 0 + } else { + leaf_preimage.hash() + }; + contract_leaves[i] = to_push; } + contract_leaves } - // TODO(Kev): This should say calculate_contract_subtree_root // Cpp code says calculate_contract_subtree, so I'm leaving it as is for now - fn calculate_contract_subtree(self, leaves : [Field; NUM_CONTRACT_LEAVES]) -> Field { - calculate_subtree(leaves) + fn calculate_contract_subtree_root(self, leaves : [Field; MAX_NEW_CONTRACTS_PER_TX]) -> Field { + assert_eq(leaves.len(), 1); + leaves[0] } // TODO(Kev): This should say calculate_commitments_subtree_root // Cpp code says calculate_commitments_subtree, so I'm leaving it as is for now fn calculate_commitments_subtree(self) -> Field { - let mut commitment_tree_leaves = [0; NOTE_HASH_SUBTREE_WIDTH]; - - for i in 0..KERNELS_PER_BASE_ROLLUP { - let new_commitments = self.kernel_data[i].public_inputs.end.new_commitments; - - // Our commitments size MUST be 4 to calculate our subtrees correctly - assert(new_commitments.len() == MAX_NEW_COMMITMENTS_PER_TX, "New commitments in kernel data must be MAX_NEW_COMMITMENTS_PER_TX (see constants.hpp)"); - - for j in 0..MAX_NEW_COMMITMENTS_PER_TX { - // TODO(Maddiaa): batch insert - commitment_tree_leaves[i * MAX_NEW_COMMITMENTS_PER_TX + j] = new_commitments[j]; - } - } - - calculate_subtree(commitment_tree_leaves) + calculate_subtree(self.kernel_data.public_inputs.end.new_commitments) } fn check_nullifier_tree_non_membership_and_insert_to_tree(self) -> AppendOnlyTreeSnapshot { - let mut new_nullifiers = [0; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP]; - - for i in 0..2 { - for j in 0..MAX_NEW_NULLIFIERS_PER_TX { - new_nullifiers[i * MAX_NEW_NULLIFIERS_PER_TX + j] = self.kernel_data[i].public_inputs.end.new_nullifiers[j]; - } - }; - crate::indexed_tree::batch_insert( self.start_nullifier_tree_snapshot, - new_nullifiers, + self.kernel_data.public_inputs.end.new_nullifiers, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes, self.new_nullifiers_subtree_sibling_path, @@ -263,48 +231,19 @@ impl BaseRollupInputs { // 0, // self.new_public_data_reads_sibling_paths); - let mid_public_data_tree_snapshot = insert_public_data_update_requests( - self.start_public_data_tree_snapshot, - self.kernel_data[0].public_inputs.end.public_data_update_requests.map(|request: PublicDataUpdateRequest| { - PublicDataTreeLeaf { - slot: request.leaf_slot, - value: request.new_value, - } - }), - self.sorted_public_data_writes[0], - self.sorted_public_data_writes_indexes[0], - self.low_public_data_writes_preimages[0], - self.low_public_data_writes_witnesses[0], - self.public_data_writes_subtree_sibling_paths[0], - ); - - - // TODO(#2521) - data read validation should happen against the current state of the tx and not the start state. - // Blocks all interesting usecases that read and write to the same public state in the same tx. - // https://aztecprotocol.slack.com/archives/C02M7VC7TN0/p1695809629015719?thread_ts=1695653252.007339&cid=C02M7VC7TN0 - - - // Process public data reads and public data update requests for right input using the resulting tree root from the - // left one - // validate_public_data_reads( - // mid_public_data_tree_root, - // baseRollupInputs.kernel_data[1].public_inputs.end.public_data_reads, - // MAX_PUBLIC_DATA_READS_PER_TX, - // baseRollupInputs.new_public_data_reads_sibling_paths); - let end_public_data_tree_snapshot = insert_public_data_update_requests( - mid_public_data_tree_snapshot, - self.kernel_data[1].public_inputs.end.public_data_update_requests.map(|request: PublicDataUpdateRequest| { + self.start_public_data_tree_snapshot, + self.kernel_data.public_inputs.end.public_data_update_requests.map(|request: PublicDataUpdateRequest| { PublicDataTreeLeaf { slot: request.leaf_slot, value: request.new_value, } }), - self.sorted_public_data_writes[1], - self.sorted_public_data_writes_indexes[1], - self.low_public_data_writes_preimages[1], - self.low_public_data_writes_witnesses[1], - self.public_data_writes_subtree_sibling_paths[1], + self.sorted_public_data_writes, + self.sorted_public_data_writes_indexes, + self.low_public_data_writes_preimages, + self.low_public_data_writes_witnesses, + self.public_data_writes_subtree_sibling_path, ); end_public_data_tree_snapshot @@ -313,72 +252,74 @@ impl BaseRollupInputs { // Computes the calldata hash for a base rollup // TODO(Kev): move this into components module // TODO(Alvaro): This is too slow for brillig without the array optimization - fn components_compute_kernel_calldata_hash(kernel_data : [PreviousKernelData; KERNELS_PER_BASE_ROLLUP]) -> [Field; NUM_FIELDS_PER_SHA256]{ + fn components_compute_kernel_calldata_hash(kernel_data : PreviousKernelData) -> [Field; NUM_FIELDS_PER_SHA256]{ // Compute calldata hashes - // Consist of 2 kernels - // 2 * MAX_NEW_COMMITMENTS_PER_TX fields for commitments - // 2 * MAX_NEW_NULLIFIERS_PER_TX fields for nullifiers - // 8 public data update requests (4 per kernel) -> 16 fields - // 4 l2 -> l1 messages (2 per kernel) -> 4 fields - // 2 contract deployments (1 per kernel) -> 6 fields - // 2 encrypted logs hashes (1 per kernel) -> 4 fields --> 2 sha256 hashes --> 64 bytes - // 2 unencrypted logs hashes (1 per kernel) -> 4 fields --> 2 sha256 hashes --> 64 bytes + // Consist of + // MAX_NEW_COMMITMENTS_PER_TX fields for commitments + // MAX_NEW_NULLIFIERS_PER_TX fields for nullifiers + // 16 public data update requests -> 32 fields + // 2 l2 -> l1 messages -> 2 fields + // 1 contract deployments -> 3 fields + // 1 encrypted logs hashes -> 2 fields --> 2 sha256 hashes --> 64 bytes + // 1 unencrypted logs hashes -> 2 fields --> 2 sha256 hashes --> 64 bytes let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE]; - for i in 0..KERNELS_PER_BASE_ROLLUP { - let new_commitments = kernel_data[i].public_inputs.end.new_commitments; - let new_nullifiers = kernel_data[i].public_inputs.end.new_nullifiers; - let public_data_update_requests = kernel_data[i].public_inputs.end.public_data_update_requests; - let newL2ToL1msgs = kernel_data[i].public_inputs.end.new_l2_to_l1_msgs; - let encryptedLogsHash = kernel_data[i].public_inputs.end.encrypted_logs_hash; - let unencryptedLogsHash = kernel_data[i].public_inputs.end.unencrypted_logs_hash; + let new_commitments = kernel_data.public_inputs.end.new_commitments; + let new_nullifiers = kernel_data.public_inputs.end.new_nullifiers; + let public_data_update_requests = kernel_data.public_inputs.end.public_data_update_requests; + let newL2ToL1msgs = kernel_data.public_inputs.end.new_l2_to_l1_msgs; + let encryptedLogsHash = kernel_data.public_inputs.end.encrypted_logs_hash; + let unencryptedLogsHash = kernel_data.public_inputs.end.unencrypted_logs_hash; - let mut offset = 0; + let mut offset = 0; - for j in 0..MAX_NEW_COMMITMENTS_PER_TX { - calldata_hash_inputs[offset + i * MAX_NEW_COMMITMENTS_PER_TX + j] = new_commitments[j]; - } - offset += MAX_NEW_COMMITMENTS_PER_TX * 2; + for j in 0..MAX_NEW_COMMITMENTS_PER_TX { + calldata_hash_inputs[offset + j] = new_commitments[j]; + } + offset += MAX_NEW_COMMITMENTS_PER_TX ; - for j in 0..MAX_NEW_NULLIFIERS_PER_TX { - calldata_hash_inputs[offset + i * MAX_NEW_NULLIFIERS_PER_TX + j] = new_nullifiers[j]; - } - offset += MAX_NEW_NULLIFIERS_PER_TX * 2; + for j in 0..MAX_NEW_NULLIFIERS_PER_TX { + calldata_hash_inputs[offset + j] = new_nullifiers[j]; + } + offset += MAX_NEW_NULLIFIERS_PER_TX ; - for j in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { - calldata_hash_inputs[offset + i * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + j * 2] = - public_data_update_requests[j].leaf_slot; - calldata_hash_inputs[offset + i * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + j * 2 + 1] = - public_data_update_requests[j].new_value; - } - offset += MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 * 2; + for j in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { + calldata_hash_inputs[offset + j * 2] = + public_data_update_requests[j].leaf_slot; + calldata_hash_inputs[offset + j * 2 + 1] = + public_data_update_requests[j].new_value; + } + offset += MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2; - for j in 0..MAX_NEW_L2_TO_L1_MSGS_PER_TX { - calldata_hash_inputs[offset + i * MAX_NEW_L2_TO_L1_MSGS_PER_TX + j] = newL2ToL1msgs[j]; - } - offset += MAX_NEW_L2_TO_L1_MSGS_PER_TX * 2; + for j in 0..MAX_NEW_L2_TO_L1_MSGS_PER_TX { + calldata_hash_inputs[offset + j] = newL2ToL1msgs[j]; + } + offset += MAX_NEW_L2_TO_L1_MSGS_PER_TX; - let contract_leaf = kernel_data[i].public_inputs.end.new_contracts[0]; - calldata_hash_inputs[offset + i] = contract_leaf.hash(); + let contract_leaf = kernel_data.public_inputs.end.new_contracts[0]; + calldata_hash_inputs[offset] = contract_leaf.hash(); - offset += MAX_NEW_CONTRACTS_PER_TX * 2; + offset += MAX_NEW_CONTRACTS_PER_TX; - let new_contracts = kernel_data[i].public_inputs.end.new_contracts; - calldata_hash_inputs[offset + i * 2] = new_contracts[0].contract_address.to_field(); - calldata_hash_inputs[offset + i * 2 + 1] = new_contracts[0].portal_contract_address.to_field(); + let new_contracts = kernel_data.public_inputs.end.new_contracts; + calldata_hash_inputs[offset] = new_contracts[0].contract_address.to_field(); + calldata_hash_inputs[offset + 1] = new_contracts[0].portal_contract_address.to_field(); - offset += MAX_NEW_CONTRACTS_PER_TX * 2 * 2; + offset += MAX_NEW_CONTRACTS_PER_TX * 2; - for j in 0..NUM_FIELDS_PER_SHA256 { - calldata_hash_inputs[offset + i * 2 + j] = encryptedLogsHash[j]; - } + for j in 0..NUM_FIELDS_PER_SHA256 { + calldata_hash_inputs[offset + j] = encryptedLogsHash[j]; + } - offset += NUM_ENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256 * 2; + offset += NUM_ENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256; - for j in 0..NUM_FIELDS_PER_SHA256 { - calldata_hash_inputs[offset + i * 2 + j] = unencryptedLogsHash[j]; - } + for j in 0..NUM_FIELDS_PER_SHA256 { + calldata_hash_inputs[offset + j] = unencryptedLogsHash[j]; } + + offset += NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256; + assert_eq(offset, CALLDATA_HASH_INPUT_SIZE); // Sanity check + let mut hash_input_flattened = [0; CALL_DATA_HASH_FULL_FIELDS * 32 + CALL_DATA_HASH_LOG_FIELDS * 16]; for offset in 0..CALL_DATA_HASH_FULL_FIELDS { @@ -406,27 +347,25 @@ impl BaseRollupInputs { // against the blocks tree root from the beginning of a rollup provided in the rollup constants let archive_root = self.constants.archive_snapshot.root; - for i in 0..KERNELS_PER_BASE_ROLLUP { - // Rebuild the block hash - let block_header = self.kernel_data[i].public_inputs.constants.block_header; - let previous_block_hash = block_header.block_hash(); + // Rebuild the block hash + let block_header = self.kernel_data.public_inputs.constants.block_header; + let previous_block_hash = block_header.block_hash(); - let previous_block_hash_witness = self.archive_root_membership_witnesses[i]; + let previous_block_hash_witness = self.archive_root_membership_witness; - // Now check that the previous block hash is in the blocks tree from the beginning of the rollup - components::assert_check_membership( - previous_block_hash, - previous_block_hash_witness.leaf_index, - previous_block_hash_witness.sibling_path, - archive_root - ); - } + // Now check that the previous block hash is in the blocks tree from the beginning of the rollup + components::assert_check_membership( + previous_block_hash, + previous_block_hash_witness.leaf_index, + previous_block_hash_witness.sibling_path, + archive_root + ); } // TODO(Kev): This aggregate_proof method is duplicated in a lot of places fn aggregate_proofs(self) -> AggregationObject { // TODO: for now we simply return the aggregation object from the first proof - self.kernel_data[0].public_inputs.end.aggregation_object + self.kernel_data.public_inputs.end.aggregation_object } } @@ -550,46 +489,39 @@ fn validate_public_data_reads( } } -global NUM_CONTRACT_LEAVES = 2; -#[test] -fn consistent_num_contract_leaves() { - assert( - NUM_CONTRACT_LEAVES == MAX_NEW_CONTRACTS_PER_TX * 2, "num contract leaves incorrect, see calculate_contract_leaves to see how it is computed" - ); -} - -global NOTE_HASH_SUBTREE_WIDTH = 128; #[test] fn consistent_not_hash_subtree_width() { assert_eq( - NOTE_HASH_SUBTREE_WIDTH, 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT) as u32, "note hash subtree width is incorrect" + MAX_NEW_COMMITMENTS_PER_TX, 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT), "note hash subtree width is incorrect" ); } -global CALLDATA_HASH_INPUT_SIZE = 338; +global CALLDATA_HASH_INPUT_SIZE = 169; + #[test] fn consistent_calldata_hash_input_size() { - let expected_size = (MAX_NEW_COMMITMENTS_PER_TX + let expected_size = MAX_NEW_COMMITMENTS_PER_TX + MAX_NEW_NULLIFIERS_PER_TX + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + MAX_NEW_L2_TO_L1_MSGS_PER_TX + MAX_NEW_CONTRACTS_PER_TX * 3 + NUM_ENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256 - + NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256) - * 2; + + NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256; assert(CALLDATA_HASH_INPUT_SIZE == expected_size, "calldata hash input size is incorrect"); } -global CALL_DATA_HASH_LOG_FIELDS = 8; +global CALL_DATA_HASH_LOG_FIELDS = 4; + #[test] fn consistent_call_data_hash_log_fields() { assert_eq( - CALL_DATA_HASH_LOG_FIELDS, NUM_ENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256 * 2 - + NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256 * 2, "calldata hash log fields is incorrect" + CALL_DATA_HASH_LOG_FIELDS, NUM_ENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256 + + NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256, "calldata hash log fields is incorrect" ); } -global CALL_DATA_HASH_FULL_FIELDS = 330; +global CALL_DATA_HASH_FULL_FIELDS = 165; + #[test] fn consistent_call_data_hash_full_fields() { assert_eq( @@ -629,8 +561,6 @@ mod tests { base::base_rollup_inputs::{ CALL_DATA_HASH_FULL_FIELDS, CALL_DATA_HASH_LOG_FIELDS, - NOTE_HASH_SUBTREE_WIDTH, - NUM_CONTRACT_LEAVES, BaseRollupInputs, full_field_less_than, }, @@ -648,10 +578,11 @@ mod tests { CONTRACT_TREE_HEIGHT, CONTRACT_SUBTREE_HEIGHT, ARCHIVE_HEIGHT, - KERNELS_PER_BASE_ROLLUP, - MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, + MAX_NEW_CONTRACTS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NOTE_HASH_TREE_HEIGHT, NOTE_HASH_SUBTREE_HEIGHT, @@ -704,23 +635,13 @@ mod tests { sorted_tuples.sort_via(|a: SortedTuple, b: SortedTuple| is_less_than(b.value, a.value)) } - fn update_public_data_tree_single_kernel( + fn update_public_data_tree( public_data_tree: &mut NonEmptyMerkleTree, kernel_data: &mut PreviousKernelData, snapshot: AppendOnlyTreeSnapshot, public_data_writes: BoundedVec<(u64, PublicDataTreeLeaf), 2>, mut pre_existing_public_data: [PublicDataTreeLeafPreimage; EXISTING_LEAVES] - ) -> ( - [Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], - [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - [u32; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX], - [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX], - [PublicDataTreeLeafPreimage; EXISTING_LEAVES], - [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - ) { + ) -> ([Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [u32; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX], [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX], [PublicDataTreeLeafPreimage; EXISTING_LEAVES]) { let mut subtree_path: [Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH] = dep::std::unsafe::zeroed(); let mut sorted_public_data_writes: [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = dep::std::unsafe::zeroed(); let mut sorted_public_data_writes_indexes: [u32; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = dep::std::unsafe::zeroed(); @@ -791,19 +712,19 @@ mod tests { subtree_path = BaseRollupInputsBuilder::extract_subtree_sibling_path(public_data_tree.get_sibling_path(snapshot.next_available_leaf_index as Field), [0; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]); ( - subtree_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, public_data_reads_preimages, public_data_reads_witnesses, pre_existing_public_data, new_subtree + subtree_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, public_data_reads_preimages, public_data_reads_witnesses, pre_existing_public_data ) } struct BaseRollupInputsBuilder { - kernel_data: [PreviousKernelDataBuilder; KERNELS_PER_BASE_ROLLUP], - pre_existing_notes: [Field; NOTE_HASH_SUBTREE_WIDTH], - pre_existing_nullifiers: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], - pre_existing_contracts: [Field; NUM_CONTRACT_LEAVES], + kernel_data: PreviousKernelDataBuilder, + pre_existing_notes: [Field; MAX_NEW_COMMITMENTS_PER_TX], + pre_existing_nullifiers: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], + pre_existing_contracts: [Field; 2], pre_existing_public_data: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - pre_existing_blocks: [Field; KERNELS_PER_BASE_ROLLUP], - public_data_reads: [BoundedVec; KERNELS_PER_BASE_ROLLUP], - public_data_writes: [BoundedVec<(u64, PublicDataTreeLeaf), MAX_PUBLIC_DATA_WRITES_PER_TEST>; KERNELS_PER_BASE_ROLLUP], + pre_existing_blocks: [Field; 2], + public_data_reads: BoundedVec, + public_data_writes:BoundedVec<(u64, PublicDataTreeLeaf), MAX_PUBLIC_DATA_WRITES_PER_TEST>, new_nullifiers: BoundedVec, constants: ConstantRollupData, } @@ -818,15 +739,11 @@ mod tests { inputs.constants.global_variables.chain_id = 1; inputs.constants.global_variables.version = 0; - inputs.kernel_data = inputs.kernel_data.map(|_| { - let mut builder = PreviousKernelDataBuilder::new(); - let _nullifier = builder.end.new_nullifiers.pop(); - builder.is_public() - }); - - inputs.pre_existing_blocks = inputs.kernel_data.map(|builder: PreviousKernelDataBuilder|{ - builder.block_header.block_hash() - }); + let mut builder = PreviousKernelDataBuilder::new(); + let _nullifier = builder.end.new_nullifiers.pop(); + inputs.kernel_data = builder.is_public(); + + inputs.pre_existing_blocks[0] = inputs.kernel_data.block_header.block_hash(); inputs } @@ -841,24 +758,24 @@ mod tests { fn update_nullifier_tree_with_new_leaves( mut self, - nullifier_tree: &mut NonEmptyMerkleTree, - kernel_data: &mut [PreviousKernelData; KERNELS_PER_BASE_ROLLUP], + nullifier_tree: &mut NonEmptyMerkleTree, + kernel_data: &mut PreviousKernelData, start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot ) -> ( - [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], - [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], - [Field; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], - [u32; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], + [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], + [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_TX], + [Field; MAX_NEW_NULLIFIERS_PER_TX], + [u32; MAX_NEW_NULLIFIERS_PER_TX], ) { - let mut low_nullifier_leaf_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut low_nullifier_membership_witness: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); + let mut low_nullifier_leaf_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX] = dep::std::unsafe::zeroed(); + let mut low_nullifier_membership_witness: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_TX] = dep::std::unsafe::zeroed(); let sorted_new_nullifier_tuples = sort_high_to_low(self.new_nullifiers.storage.map(|insertion: NullifierInsertion| insertion.value), full_field_less_than); - let mut sorted_new_nullifiers = [0; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP]; - let mut sorted_new_nullifiers_indexes = [0; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP]; + let mut sorted_new_nullifiers = [0; MAX_NEW_NULLIFIERS_PER_TX]; + let mut sorted_new_nullifiers_indexes = [0; MAX_NEW_NULLIFIERS_PER_TX]; - for i in 0..MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP { + for i in 0..MAX_NEW_NULLIFIERS_PER_TX { if (i as u32) < (MAX_NEW_NULLIFIERS_PER_TEST as u32) { sorted_new_nullifiers[i] = sorted_new_nullifier_tuples[i].value; sorted_new_nullifiers_indexes[i] = sorted_new_nullifier_tuples[i].original_index; @@ -878,7 +795,7 @@ mod tests { let low_index = self.new_nullifiers.get_unchecked(original_index as Field).existing_index; - kernel_data[0].public_inputs.end.new_nullifiers[original_index] = new_nullifier; + kernel_data.public_inputs.end.new_nullifiers[original_index] = new_nullifier; let mut low_preimage = pre_existing_nullifiers[low_index]; low_nullifier_leaf_preimages[i] = low_preimage; @@ -897,125 +814,9 @@ mod tests { (low_nullifier_leaf_preimages, low_nullifier_membership_witness, sorted_new_nullifiers, sorted_new_nullifiers_indexes) } - - fn update_public_data_tree_with_new_leaves( - mut self, - initial_public_data_tree: &mut NonEmptyMerkleTree, - kernel_data: &mut [PreviousKernelData; KERNELS_PER_BASE_ROLLUP], - start_public_data_tree_snapshot: AppendOnlyTreeSnapshot - ) -> ( - [[Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]; KERNELS_PER_BASE_ROLLUP], // Subtrees paths - [[PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], // sorted_public_data_writes - [[u32; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], // sorted_public_data_writes_indexes - [[PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], // low_public_data_writes_preimages - [[PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP], // low_public_data_writes_witnesses - [[PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX]; KERNELS_PER_BASE_ROLLUP], // public_data_reads_preimages - [[PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX]; KERNELS_PER_BASE_ROLLUP], // public_data_reads_witnesses - ) { - let mut subtree_paths: [[Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]; KERNELS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut sorted_public_data_writes: [[PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut sorted_public_data_writes_indexes: [[u32; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut low_public_data_writes_preimages: [[PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut low_public_data_writes_witnesses: [[PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; KERNELS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut public_data_reads_preimages: [[PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX]; KERNELS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut public_data_reads_witnesses: [[PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX]; KERNELS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - - // First kernel - let mut first_kernel_data = kernel_data[0]; - let ( - first_kernel_subtree_path, - first_kernel_sorted_public_data_writes, - first_kernel_sorted_public_data_writes_indexes, - first_kernel_low_public_data_writes_preimages, - first_kernel_low_public_data_writes_witnesses, - first_kernel_public_data_reads_preimages, - first_kernel_public_data_reads_witnesses, - first_kernel_pre_existing_public_data, - first_kernel_new_subtree - ) = update_public_data_tree_single_kernel( - initial_public_data_tree, - &mut first_kernel_data, - start_public_data_tree_snapshot, - self.public_data_writes[0], - self.pre_existing_public_data, - ); - - subtree_paths[0] = first_kernel_subtree_path; - sorted_public_data_writes[0] = first_kernel_sorted_public_data_writes; - sorted_public_data_writes_indexes[0] = first_kernel_sorted_public_data_writes_indexes; - low_public_data_writes_preimages[0] = first_kernel_low_public_data_writes_preimages; - low_public_data_writes_witnesses[0] = first_kernel_low_public_data_writes_witnesses; - public_data_reads_preimages[0] = first_kernel_public_data_reads_preimages; - public_data_reads_witnesses[0] = first_kernel_public_data_reads_witnesses; - self.pre_existing_public_data = first_kernel_pre_existing_public_data; - kernel_data[0] = first_kernel_data; - - - // Second kernel - let mut middle_public_data = [PublicDataTreeLeafPreimage::default(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX*2]; - for i in 0..middle_public_data.len() { - if (i as u64) < (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX as u64) { - middle_public_data[i] = self.pre_existing_public_data[i]; - }else{ - middle_public_data[i] = first_kernel_new_subtree[i-MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; - } - } - - let mut middle_public_data_tree = NonEmptyMerkleTree::new( - middle_public_data.map(|preimage: PublicDataTreeLeafPreimage| preimage.hash()), - [0; PUBLIC_DATA_TREE_HEIGHT], - [0; PUBLIC_DATA_TREE_HEIGHT - PUBLIC_DATA_SUBTREE_HEIGHT - 1], - [0; PUBLIC_DATA_SUBTREE_HEIGHT + 1] - ); - let middle_public_data_tree_snapshot = AppendOnlyTreeSnapshot { - root: middle_public_data_tree.get_root(), - next_available_leaf_index: middle_public_data_tree.get_next_available_index() as u32, - }; - - - let mut second_kernel_data = kernel_data[1]; - let ( - second_kernel_subtree_path, - second_kernel_sorted_public_data_writes, - second_kernel_sorted_public_data_writes_indexes, - second_kernel_low_public_data_writes_preimages, - second_kernel_low_public_data_writes_witnesses, - second_kernel_public_data_reads_preimages, - second_kernel_public_data_reads_witnesses, - second_kernel_pre_existing_public_data, - second_kernel_new_subtree - ) = update_public_data_tree_single_kernel( - &mut middle_public_data_tree, - &mut second_kernel_data, - middle_public_data_tree_snapshot, - self.public_data_writes[1], - middle_public_data, - ); - - subtree_paths[1] = second_kernel_subtree_path; - sorted_public_data_writes[1] = second_kernel_sorted_public_data_writes; - sorted_public_data_writes_indexes[1] = second_kernel_sorted_public_data_writes_indexes; - low_public_data_writes_preimages[1] = second_kernel_low_public_data_writes_preimages; - low_public_data_writes_witnesses[1] = second_kernel_low_public_data_writes_witnesses; - public_data_reads_preimages[1] = second_kernel_public_data_reads_preimages; - public_data_reads_witnesses[1] = second_kernel_public_data_reads_witnesses; - kernel_data[1] = second_kernel_data; - - ( - subtree_paths, - sorted_public_data_writes, - sorted_public_data_writes_indexes, - low_public_data_writes_preimages, - low_public_data_writes_witnesses, - public_data_reads_preimages, - public_data_reads_witnesses, - ) - } fn build_inputs(mut self) -> BaseRollupInputs { - let mut kernel_data = self.kernel_data.map(|builder: PreviousKernelDataBuilder|{ - builder.finish() - }); + let mut kernel_data = self.kernel_data.finish(); let start_note_hash_tree = NonEmptyMerkleTree::new(self.pre_existing_notes, [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT], [0; NOTE_HASH_SUBTREE_HEIGHT]); let start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { @@ -1068,19 +869,25 @@ mod tests { sorted_new_nullifiers, sorted_new_nullifiers_indexes ) = self.update_nullifier_tree_with_new_leaves(&mut start_nullifier_tree, &mut kernel_data, start_nullifier_tree_snapshot); - + let new_nullifiers_subtree_sibling_path = BaseRollupInputsBuilder::extract_subtree_sibling_path(start_nullifier_tree.get_sibling_path(self.pre_existing_nullifiers.len()), [0; NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH]); let ( - public_data_writes_subtree_sibling_paths, + public_data_writes_subtree_sibling_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, public_data_reads_preimages, - public_data_reads_witnesses - ) = self.update_public_data_tree_with_new_leaves(&mut start_public_data_tree, &mut kernel_data, start_public_data_tree_snapshot); - + public_data_reads_witnesses, + _new_subtree + ) = update_public_data_tree( + &mut start_public_data_tree, + &mut kernel_data, + start_public_data_tree_snapshot, + self.public_data_writes, + self.pre_existing_public_data + ); BaseRollupInputs { kernel_data: kernel_data, @@ -1098,28 +905,21 @@ mod tests { new_commitments_subtree_sibling_path, new_nullifiers_subtree_sibling_path, - public_data_writes_subtree_sibling_paths, + public_data_writes_subtree_sibling_path, new_contracts_subtree_sibling_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, - + public_data_reads_preimages, public_data_reads_witnesses, - - - archive_root_membership_witnesses: [ - ArchiveRootMembershipWitness { - leaf_index: 0, - sibling_path: start_archive.get_sibling_path(0) - }, - ArchiveRootMembershipWitness { - leaf_index: 1, - sibling_path: start_archive.get_sibling_path(1) - }, - ], + + archive_root_membership_witness: ArchiveRootMembershipWitness { + leaf_index: 0, + sibling_path: start_archive.get_sibling_path(0) + }, constants: self.constants, } @@ -1142,7 +942,7 @@ mod tests { unconstrained fn no_new_contract_leaves() { let outputs = BaseRollupInputsBuilder::new().execute(); let expected_start_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: test_compute_empty_root([0; CONTRACT_TREE_HEIGHT]), next_available_leaf_index: 2 }; - let expected_end_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: test_compute_empty_root([0; CONTRACT_TREE_HEIGHT]), next_available_leaf_index: 4 }; + let expected_end_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: test_compute_empty_root([0; CONTRACT_TREE_HEIGHT]), next_available_leaf_index: 3 }; assert(outputs.start_contract_tree_snapshot.eq(expected_start_contract_tree_snapshot)); assert(outputs.end_contract_tree_snapshot.eq(expected_end_contract_tree_snapshot)); } @@ -1156,11 +956,9 @@ mod tests { }; let mut builder = BaseRollupInputsBuilder::new(); - - let mut new_contracts = builder.kernel_data[0].end.new_contracts; + let mut new_contracts = builder.kernel_data.end.new_contracts; new_contracts.push(new_contract); - builder.kernel_data[0].end.new_contracts = new_contracts; - + builder.kernel_data.end.new_contracts = new_contracts; let mut expected_contracts_tree = NonEmptyMerkleTree::new( [0; 4], [0; CONTRACT_TREE_HEIGHT], @@ -1174,7 +972,7 @@ mod tests { assert(outputs.start_contract_tree_snapshot.eq(expected_start_contract_tree_snapshot)); expected_contracts_tree.update_leaf(2, new_contract.hash()); - let expected_end_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_contracts_tree.get_root(), next_available_leaf_index: 4 }; + let expected_end_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_contracts_tree.get_root(), next_available_leaf_index: 3 }; assert(outputs.end_contract_tree_snapshot.eq(expected_end_contract_tree_snapshot)); } @@ -1189,11 +987,9 @@ mod tests { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_contracts = [1,2]; - - let mut new_contracts = builder.kernel_data[0].end.new_contracts; + let mut new_contracts = builder.kernel_data.end.new_contracts; new_contracts.push(new_contract); - builder.kernel_data[0].end.new_contracts = new_contracts; - + builder.kernel_data.end.new_contracts = new_contracts; let mut expected_contracts_tree = NonEmptyMerkleTree::new( [1, 2, 0, 0], [0; CONTRACT_TREE_HEIGHT], @@ -1207,7 +1003,7 @@ mod tests { assert(outputs.start_contract_tree_snapshot.eq(expected_start_contract_tree_snapshot)); expected_contracts_tree.update_leaf(2, new_contract.hash()); - let expected_end_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_contracts_tree.get_root(), next_available_leaf_index: 4 }; + let expected_end_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_contracts_tree.get_root(), next_available_leaf_index: 3 }; assert(outputs.end_contract_tree_snapshot.eq(expected_end_contract_tree_snapshot)); } @@ -1216,34 +1012,35 @@ mod tests { let mut builder = BaseRollupInputsBuilder::new(); let new_commitments = [27, 28, 29, 30, 31, 32]; - let mut new_commitments_vec = builder.kernel_data[0].end.new_commitments; - + let mut new_commitments_vec = builder.kernel_data.end.new_commitments; for i in 0..new_commitments.len() { new_commitments_vec.push(new_commitments[i]); } - - builder.kernel_data[0].end.new_commitments = new_commitments_vec; - + builder.kernel_data.end.new_commitments = new_commitments_vec; let mut expected_commitments_tree = NonEmptyMerkleTree::new( - [0; NOTE_HASH_SUBTREE_WIDTH * 2], + [0; MAX_NEW_COMMITMENTS_PER_TX * 2], [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT - 1], [0; NOTE_HASH_SUBTREE_HEIGHT + 1] ); let outputs = builder.execute(); - - let expected_start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), next_available_leaf_index: NOTE_HASH_SUBTREE_WIDTH }; + let expected_start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { + root: expected_commitments_tree.get_root(), + next_available_leaf_index: MAX_NEW_COMMITMENTS_PER_TX as u32 + }; assert(outputs.start_note_hash_tree_snapshot.eq(expected_start_note_hash_tree_snapshot)); for i in 0..new_commitments.len() { expected_commitments_tree.update_leaf( - (i as u64) + (NOTE_HASH_SUBTREE_WIDTH as u64), + (i as u64) + (MAX_NEW_COMMITMENTS_PER_TX as u64), new_commitments[i] ); } - - let expected_end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), next_available_leaf_index: NOTE_HASH_SUBTREE_WIDTH * 2 }; + let expected_end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { + root: expected_commitments_tree.get_root(), + next_available_leaf_index: (MAX_NEW_COMMITMENTS_PER_TX * 2) as u32 + }; assert(outputs.end_note_hash_tree_snapshot.eq(expected_end_note_hash_tree_snapshot)); } @@ -1290,15 +1087,14 @@ mod tests { }; builder.new_nullifiers.push(NullifierInsertion { existing_index: 0, value: 1 }); - - let mut tree_nullifiers = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP * 2]; + let mut tree_nullifiers = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_TX * 2]; tree_nullifiers[0] = NullifierLeafPreimage { leaf_value : 0, next_value : 1, - next_index : MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP as u32, + next_index : MAX_NEW_NULLIFIERS_PER_TX as u32, }; tree_nullifiers[1] = builder.pre_existing_nullifiers[1]; - tree_nullifiers[MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP] = NullifierLeafPreimage { + tree_nullifiers[MAX_NEW_NULLIFIERS_PER_TX] = NullifierLeafPreimage { leaf_value : 1, next_value : 7, next_index : 1, @@ -1315,10 +1111,7 @@ mod tests { assert( output.end_nullifier_tree_snapshot.eq( - AppendOnlyTreeSnapshot { - root: end_nullifier_tree.get_root(), - next_available_leaf_index: 2 * MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP as u32 - } + AppendOnlyTreeSnapshot { root: end_nullifier_tree.get_root(), next_available_leaf_index: 2 * MAX_NEW_NULLIFIERS_PER_TX as u32 } ) ); } @@ -1344,26 +1137,24 @@ mod tests { } let output = builder.execute(); - - let mut tree_nullifiers = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP * 2]; + let mut tree_nullifiers = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_TX * 2]; tree_nullifiers[0] = builder.pre_existing_nullifiers[0]; tree_nullifiers[1] = NullifierLeafPreimage { leaf_value : 7, next_value : 8, - next_index : MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP as u32, + next_index : MAX_NEW_NULLIFIERS_PER_TX as u32, }; let last_index = builder.new_nullifiers.max_len() - 1; for i in 0..last_index { - tree_nullifiers[MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP + i] = NullifierLeafPreimage { + tree_nullifiers[MAX_NEW_NULLIFIERS_PER_TX + i] = NullifierLeafPreimage { leaf_value : (8 + i) as Field, next_value : (8 + i + 1) as Field, - next_index : (MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP + i) as u32 + 1, + next_index : (MAX_NEW_NULLIFIERS_PER_TX + i) as u32 + 1, }; } - - tree_nullifiers[MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP+last_index] = NullifierLeafPreimage { + tree_nullifiers[MAX_NEW_NULLIFIERS_PER_TX+last_index] = NullifierLeafPreimage { leaf_value : (8 + last_index) as Field, next_value : 0, next_index : 0, @@ -1378,10 +1169,7 @@ mod tests { assert( output.end_nullifier_tree_snapshot.eq( - AppendOnlyTreeSnapshot { - root: end_nullifier_tree.get_root(), - next_available_leaf_index: 2 * MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP as u32 - } + AppendOnlyTreeSnapshot { root: end_nullifier_tree.get_root(), next_available_leaf_index: 2 * MAX_NEW_NULLIFIERS_PER_TX as u32 } ) ); } @@ -1443,9 +1231,7 @@ mod tests { #[test(should_fail_with = "membership check failed")] unconstrained fn compute_membership_archive_negative() { let mut inputs = BaseRollupInputsBuilder::new().build_inputs(); - - inputs.archive_root_membership_witnesses[0].sibling_path[0] = 27; - + inputs.archive_root_membership_witness.sibling_path[0] = 27; let _output = inputs.base_rollup_circuit(); } @@ -1488,10 +1274,7 @@ mod tests { next_slot: 0, next_index: 0, }; - - let mut first_kernel_reads = builder.public_data_reads[0]; - first_kernel_reads.push(0); - builder.public_data_reads[0] = first_kernel_reads; + builder.public_data_reads.push(0); builder.succeeds(); } @@ -1506,11 +1289,7 @@ mod tests { next_slot: 0, next_index: 0, }; - - let mut first_kernel_writes = builder.public_data_writes[0]; - first_kernel_writes.push((0, PublicDataTreeLeaf { slot: 27, value: 29 })); - builder.public_data_writes[0] = first_kernel_writes; - + builder.public_data_writes.push((0, PublicDataTreeLeaf { slot: 27, value: 29 })); let outputs = builder.execute(); let updated_leaf = PublicDataTreeLeafPreimage { slot: 27, value: 29, next_slot: 0, next_index: 0 }; @@ -1553,24 +1332,10 @@ mod tests { next_slot: 0, next_index: 0, }; - - let mut first_kernel_reads = builder.public_data_reads[0]; - let mut first_kernel_writes = builder.public_data_writes[0]; - - first_kernel_reads.push(0); - first_kernel_writes.push((0, PublicDataTreeLeaf { slot: 25, value: 60 })); - - builder.public_data_reads[0] = first_kernel_reads; - builder.public_data_writes[0] = first_kernel_writes; - - let mut second_kernel_reads = builder.public_data_reads[1]; - let mut second_kernel_writes = builder.public_data_writes[1]; - - second_kernel_reads.push(4); - second_kernel_writes.push((0, PublicDataTreeLeaf { slot: 20, value: 90 })); - - builder.public_data_reads[1] = second_kernel_reads; - builder.public_data_writes[1] = second_kernel_writes; + builder.public_data_reads.push(0); + builder.public_data_writes.push((0, PublicDataTreeLeaf { slot: 25, value: 60 })); + builder.public_data_reads.push(4); + builder.public_data_writes.push((0, PublicDataTreeLeaf { slot: 20, value: 90 })); let outputs = builder.execute(); diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/merkle_tree.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/merkle_tree.nr index d9ff3702527..e941bbc369a 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/merkle_tree.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/merkle_tree.nr @@ -42,7 +42,9 @@ pub fn calculate_subtree(leaves: [Field; N]) -> Field { // Would be good if we could use width since the compute_subtree // algorithm uses depth. pub fn calculate_empty_tree_root(depth: Field) -> Field { - if depth == 1 { + if depth == 0 { + 0 + } else if depth == 1 { 0x27b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed } else if depth == 2 { 0x21dbfd1d029bf447152fcf89e355c334610d1632436ba170f738107266a71550 @@ -63,7 +65,7 @@ pub fn calculate_empty_tree_root(depth: Field) -> Field { } else if depth == 10 { 0x00c5ae2526e665e2c7c698c11a06098b7159f720606d50e7660deb55758b0b02 } else { - assert(false, "depth should be between 1 and 10"); + assert(false, "depth should be between 0 and 10"); 0 } } @@ -82,6 +84,8 @@ fn test_merkle_root_interop_test() { #[test] fn test_empty_subroot() { + assert(calculate_empty_tree_root(0) == 0); + let expected_empty_root_2 = calculate_subtree([0; 2]); assert(calculate_empty_tree_root(1) == expected_empty_root_2); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr index d8a1c75d583..cf216fa441d 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr @@ -1,7 +1,6 @@ use crate::constants::{ CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT, - KERNELS_PER_BASE_ROLLUP, NULLIFIER_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, ROLLUP_VK_TREE_HEIGHT, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/constants.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/constants.nr index 5f2115711cd..8da829b90b4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -51,11 +51,6 @@ global NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1; // ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts global NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: Field = 16; -// TODO(961): Use this constant everywhere instead of hard-coded "2". -global KERNELS_PER_BASE_ROLLUP: Field = 2; -global MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP: Field = 128; -global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP: Field = 32; -global MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP: Field = 32; // TREES RELATED CONSTANTS global VK_TREE_HEIGHT: Field = 3; @@ -68,14 +63,14 @@ global L1_TO_L2_MSG_TREE_HEIGHT: Field = 16; global ROLLUP_VK_TREE_HEIGHT: Field = 8; // SUB-TREES RELATED CONSTANTS -global CONTRACT_SUBTREE_HEIGHT: Field = 1; -global CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 15; -global NOTE_HASH_SUBTREE_HEIGHT: Field = 7; -global NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 25; -global NULLIFIER_SUBTREE_HEIGHT: Field = 7; +global CONTRACT_SUBTREE_HEIGHT: Field = 0; +global CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 16; +global NOTE_HASH_SUBTREE_HEIGHT: Field = 6; +global NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 26; +global NULLIFIER_SUBTREE_HEIGHT: Field = 6; global PUBLIC_DATA_SUBTREE_HEIGHT: Field = 4; global ARCHIVE_HEIGHT: Field = 16; -global NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 13; +global NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 14; global PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: Field = 36; global L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4; global L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12; @@ -87,7 +82,6 @@ global NUM_FIELDS_PER_SHA256: Field = 2; global ARGS_HASH_CHUNK_LENGTH: u32 = 32; global ARGS_HASH_CHUNK_COUNT: u32 = 16; - // NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts // Some are defined here because Noir doesn't yet support globals referencing other globals yet. // Move these constants to a noir file once the issue bellow is resolved: @@ -119,14 +113,14 @@ global EMPTY_NULLIFIED_COMMITMENT: Field = 1000000; global CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 161; global PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 87; global PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 144; -global COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 4096; -global NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 4096; -global PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; -global CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; -global CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 128; -global CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 104; -global L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 128; -global LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 128; +global COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; +global NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; +global PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 1024; +global CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32; +global CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; +global CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52; +global L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; +global LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; /** * Enumerate the hash_indices which are used for pedersen hashing. diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.ts index 22e6d7d0163..07f54666801 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.ts @@ -43,7 +43,6 @@ import { NewContractData, NullifierLeafPreimage, OptionallyRevealedData, - PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT, Point, PreviousKernelData, @@ -1376,7 +1375,7 @@ export function mapPublicDataTreePreimageToNoir(preimage: PublicDataTreeLeafPrei */ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupInputsNoir { return { - kernel_data: mapTuple(inputs.kernelData, mapPreviousKernelDataToNoir), + kernel_data: mapPreviousKernelDataToNoir(inputs.kernelData), start_note_hash_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startNoteHashTreeSnapshot), start_nullifier_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startNullifierTreeSnapshot), start_contract_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startContractTreeSnapshot), @@ -1393,67 +1392,28 @@ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupI ), new_commitments_subtree_sibling_path: mapTuple(inputs.newCommitmentsSubtreeSiblingPath, mapFieldToNoir), new_nullifiers_subtree_sibling_path: mapTuple(inputs.newNullifiersSubtreeSiblingPath, mapFieldToNoir), - public_data_writes_subtree_sibling_paths: mapTuple( - inputs.publicDataWritesSubtreeSiblingPaths, - (txPath: Tuple) => { - return mapTuple(txPath, mapFieldToNoir); - }, - ), + public_data_writes_subtree_sibling_path: mapTuple(inputs.publicDataWritesSubtreeSiblingPath, mapFieldToNoir), new_contracts_subtree_sibling_path: mapTuple(inputs.newContractsSubtreeSiblingPath, mapFieldToNoir), - sorted_public_data_writes: mapTuple( - inputs.sortedPublicDataWrites, - (kernelWrites: Tuple) => { - return mapTuple(kernelWrites, mapPublicDataTreeLeafToNoir); - }, - ), + sorted_public_data_writes: mapTuple(inputs.sortedPublicDataWrites, mapPublicDataTreeLeafToNoir), - sorted_public_data_writes_indexes: mapTuple( - inputs.sortedPublicDataWritesIndexes, - (txIndexes: Tuple) => { - return mapTuple(txIndexes, (index: number) => mapNumberToNoir(index)); - }, - ), + sorted_public_data_writes_indexes: mapTuple(inputs.sortedPublicDataWritesIndexes, mapNumberToNoir), - low_public_data_writes_preimages: mapTuple( - inputs.lowPublicDataWritesPreimages, - (txPreimages: Tuple) => { - return mapTuple(txPreimages, mapPublicDataTreePreimageToNoir); - }, - ), + low_public_data_writes_preimages: mapTuple(inputs.lowPublicDataWritesPreimages, mapPublicDataTreePreimageToNoir), low_public_data_writes_witnesses: mapTuple( inputs.lowPublicDataWritesMembershipWitnesses, - ( - txWitnesses: Tuple< - MembershipWitness, - typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - >, - ) => { - return mapTuple(txWitnesses, mapPublicDataMembershipWitnessToNoir); - }, + mapPublicDataMembershipWitnessToNoir, ), - public_data_reads_preimages: mapTuple( - inputs.publicDataReadsPreimages, - (txReadsPreimages: Tuple) => { - return mapTuple(txReadsPreimages, mapPublicDataTreePreimageToNoir); - }, - ), + public_data_reads_preimages: mapTuple(inputs.publicDataReadsPreimages, mapPublicDataTreePreimageToNoir), public_data_reads_witnesses: mapTuple( inputs.publicDataReadsMembershipWitnesses, - ( - txReadsWitnesses: Tuple, typeof MAX_PUBLIC_DATA_READS_PER_TX>, - ) => { - return mapTuple(txReadsWitnesses, mapPublicDataMembershipWitnessToNoir); - }, + mapPublicDataMembershipWitnessToNoir, ), - archive_root_membership_witnesses: mapTuple( - inputs.archiveRootMembershipWitnesses, - mapArchiveRootMembershipWitnessToNoir, - ), + archive_root_membership_witness: mapArchiveRootMembershipWitnessToNoir(inputs.archiveRootMembershipWitness), constants: mapConstantRollupDataToNoir(inputs.constants), }; } diff --git a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts index d085b8f424c..2363aa4b6e4 100644 --- a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts @@ -197,27 +197,27 @@ export interface ConstantRollupData { } export interface BaseRollupInputs { - kernel_data: FixedLengthArray; + kernel_data: PreviousKernelData; start_note_hash_tree_snapshot: AppendOnlyTreeSnapshot; start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot; start_contract_tree_snapshot: AppendOnlyTreeSnapshot; start_public_data_tree_snapshot: AppendOnlyTreeSnapshot; archive_snapshot: AppendOnlyTreeSnapshot; - sorted_new_nullifiers: FixedLengthArray; - sorted_new_nullifiers_indexes: FixedLengthArray; - low_nullifier_leaf_preimages: FixedLengthArray; - low_nullifier_membership_witness: FixedLengthArray; - new_commitments_subtree_sibling_path: FixedLengthArray; - new_nullifiers_subtree_sibling_path: FixedLengthArray; - public_data_writes_subtree_sibling_paths: FixedLengthArray, 2>; - new_contracts_subtree_sibling_path: FixedLengthArray; - sorted_public_data_writes: FixedLengthArray, 2>; - sorted_public_data_writes_indexes: FixedLengthArray, 2>; - low_public_data_writes_preimages: FixedLengthArray, 2>; - low_public_data_writes_witnesses: FixedLengthArray, 2>; - public_data_reads_preimages: FixedLengthArray, 2>; - public_data_reads_witnesses: FixedLengthArray, 2>; - archive_root_membership_witnesses: FixedLengthArray; + sorted_new_nullifiers: FixedLengthArray; + sorted_new_nullifiers_indexes: FixedLengthArray; + low_nullifier_leaf_preimages: FixedLengthArray; + low_nullifier_membership_witness: FixedLengthArray; + new_commitments_subtree_sibling_path: FixedLengthArray; + new_nullifiers_subtree_sibling_path: FixedLengthArray; + public_data_writes_subtree_sibling_path: FixedLengthArray; + new_contracts_subtree_sibling_path: FixedLengthArray; + sorted_public_data_writes: FixedLengthArray; + sorted_public_data_writes_indexes: FixedLengthArray; + low_public_data_writes_preimages: FixedLengthArray; + low_public_data_writes_witnesses: FixedLengthArray; + public_data_reads_preimages: FixedLengthArray; + public_data_reads_witnesses: FixedLengthArray; + archive_root_membership_witness: ArchiveRootMembershipWitness; constants: ConstantRollupData; } diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index 06c550689d7..7ec217ebd61 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -183,18 +183,17 @@ describe('sequencer/solo_block_builder', () => { ), ); - const txsLeft = [tx, await makeEmptyProcessedTx()]; - const txsRight = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; + const txs = [tx, await makeEmptyProcessedTx()]; - // Calculate what would be the tree roots after the txs from the first base rollup land and update mock circuit output - await updateExpectedTreesFromTxs(txsLeft); + // Calculate what would be the tree roots after the first tx and update mock circuit output + await updateExpectedTreesFromTxs([txs[0]]); baseRollupOutputLeft.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); baseRollupOutputLeft.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); baseRollupOutputLeft.endNoteHashTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE); baseRollupOutputLeft.endPublicDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE); - // Same for the two txs on the right - await updateExpectedTreesFromTxs(txsRight); + // Same for the tx on the right + await updateExpectedTreesFromTxs([txs[1]]); baseRollupOutputRight.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); baseRollupOutputRight.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); baseRollupOutputRight.endNoteHashTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE); @@ -215,8 +214,6 @@ describe('sequencer/solo_block_builder', () => { await updateArchive(); rootRollupOutput.endArchiveSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE); - const txs = [...txsLeft, ...txsRight]; - const newNullifiers = flatMap(txs, tx => tx.data.end.newNullifiers); const newCommitments = flatMap(txs, tx => tx.data.end.newCommitments); const newContracts = flatMap(txs, tx => tx.data.end.newContracts).map(cd => computeContractLeaf(cd)); diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index dee982a9ba0..f00b969f745 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -9,7 +9,7 @@ import { GlobalVariables, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, - MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, + MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, @@ -218,8 +218,8 @@ export class SoloBlockBuilder implements BlockBuilder { ): Promise<[RootRollupPublicInputs, Proof]> { // Check that the length of the array of txs is a power of two // See https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 - if (txs.length < 4 || (txs.length & (txs.length - 1)) !== 0) { - throw new Error(`Length of txs for the block should be a power of two and at least four (got ${txs.length})`); + if (txs.length < 2 || (txs.length & (txs.length - 1)) !== 0) { + throw new Error(`Length of txs for the block should be a power of two and at least two (got ${txs.length})`); } // padArrayEnd throws if the array is already full. Otherwise it pads till we reach the required size @@ -227,9 +227,8 @@ export class SoloBlockBuilder implements BlockBuilder { // Run the base rollup circuits for the txs const baseRollupOutputs: [BaseOrMergeRollupPublicInputs, Proof][] = []; - for (const pair of chunk(txs, 2)) { - const [tx1, tx2] = pair; - baseRollupOutputs.push(await this.baseRollupCircuit(tx1, tx2, globalVariables)); + for (const tx of txs) { + baseRollupOutputs.push(await this.baseRollupCircuit(tx, globalVariables)); } // Run merge rollups in layers until we have only two outputs @@ -250,12 +249,11 @@ export class SoloBlockBuilder implements BlockBuilder { } protected async baseRollupCircuit( - tx1: ProcessedTx, - tx2: ProcessedTx, + tx: ProcessedTx, globalVariables: GlobalVariables, ): Promise<[BaseOrMergeRollupPublicInputs, Proof]> { - this.debug(`Running base rollup for ${tx1.hash} ${tx2.hash}`); - const rollupInput = await this.buildBaseRollupInput(tx1, tx2, globalVariables); + this.debug(`Running base rollup for ${tx.hash}`); + const rollupInput = await this.buildBaseRollupInput(tx, globalVariables); const rollupOutput = await this.simulator.baseRollupCircuit(rollupInput); await this.validateTrees(rollupOutput); const proof = await this.prover.getBaseRollupProof(rollupInput, rollupOutput); @@ -662,7 +660,7 @@ export class SoloBlockBuilder implements BlockBuilder { } // Builds the base rollup inputs, updating the contract, nullifier, and data trees in the process - protected async buildBaseRollupInput(left: ProcessedTx, right: ProcessedTx, globalVariables: GlobalVariables) { + protected async buildBaseRollupInput(tx: ProcessedTx, globalVariables: GlobalVariables) { // Get trees info before any changes hit const constants = await this.getConstantRollupData(globalVariables); const startNullifierTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); @@ -692,8 +690,8 @@ export class SoloBlockBuilder implements BlockBuilder { // Update the contract and note hash trees with the new items being inserted to get the new roots // that will be used by the next iteration of the base rollup circuit, skipping the empty ones - const newContracts = flatMap([left, right], tx => tx.data.end.newContracts.map(cd => computeContractLeaf(cd))); - const newCommitments = flatMap([left, right], tx => tx.data.end.newCommitments.map(x => x.toBuffer())); + const newContracts = tx.data.end.newContracts.map(cd => computeContractLeaf(cd)); + const newCommitments = tx.data.end.newCommitments.map(x => x.toBuffer()); await this.db.appendLeaves( MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer()), @@ -701,17 +699,13 @@ export class SoloBlockBuilder implements BlockBuilder { await this.db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, newCommitments); - // The public data tree will be updated serially, first with the left TX and then with the right TX. // The read witnesses for a given TX should be generated before the writes of the same TX are applied. // All reads that refer to writes in the same tx are transient and can be simplified out. - const leftPublicDataReadsInfo = await this.getPublicDataReadsInfo(left); - const leftPublicDataUpdateRequestInfo = await this.processPublicDataUpdateRequests(left); - - const rightPublicDataReadsInfo = await this.getPublicDataReadsInfo(right); - const rightPublicDataUpdateRequestInfo = await this.processPublicDataUpdateRequests(right); + const txPublicDataReadsInfo = await this.getPublicDataReadsInfo(tx); + const txPublicDataUpdateRequestInfo = await this.processPublicDataUpdateRequests(tx); // Update the nullifier tree, capturing the low nullifier info for each individual operation - const newNullifiers = [...left.data.end.newNullifiers, ...right.data.end.newNullifiers]; + const newNullifiers = tx.data.end.newNullifiers; const { lowLeavesWitnessData: nullifierWitnessLeaves, @@ -742,29 +736,14 @@ export class SoloBlockBuilder implements BlockBuilder { startNoteHashTreeSnapshot, startPublicDataTreeSnapshot, archiveSnapshot: startArchiveSnapshot, - sortedPublicDataWrites: [ - leftPublicDataUpdateRequestInfo.sortedPublicDataWrites, - rightPublicDataUpdateRequestInfo.sortedPublicDataWrites, - ], - sortedPublicDataWritesIndexes: [ - leftPublicDataUpdateRequestInfo.sortedPublicDataWritesIndexes, - rightPublicDataUpdateRequestInfo.sortedPublicDataWritesIndexes, - ], - lowPublicDataWritesPreimages: [ - leftPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages, - rightPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages, - ], - lowPublicDataWritesMembershipWitnesses: [ - leftPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses, - rightPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses, - ], - publicDataWritesSubtreeSiblingPaths: [ - leftPublicDataUpdateRequestInfo.newPublicDataSubtreeSiblingPath, - rightPublicDataUpdateRequestInfo.newPublicDataSubtreeSiblingPath, - ], - - sortedNewNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => Fr.fromBuffer(sortedNewNullifiers[i])), - sortednewNullifiersIndexes: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => sortednewNullifiersIndexes[i]), + sortedPublicDataWrites: txPublicDataUpdateRequestInfo.sortedPublicDataWrites, + sortedPublicDataWritesIndexes: txPublicDataUpdateRequestInfo.sortedPublicDataWritesIndexes, + lowPublicDataWritesPreimages: txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages, + lowPublicDataWritesMembershipWitnesses: txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses, + publicDataWritesSubtreeSiblingPath: txPublicDataUpdateRequestInfo.newPublicDataSubtreeSiblingPath, + + sortedNewNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortedNewNullifiers[i])), + sortednewNullifiersIndexes: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => sortednewNullifiersIndexes[i]), newCommitmentsSubtreeSiblingPath, newContractsSubtreeSiblingPath, @@ -772,31 +751,22 @@ export class SoloBlockBuilder implements BlockBuilder { i < newNullifiersSubtreeSiblingPathArray.length ? newNullifiersSubtreeSiblingPathArray[i] : Fr.ZERO, ), - publicDataReadsPreimages: [ - leftPublicDataReadsInfo.newPublicDataReadsPreimages, - rightPublicDataReadsInfo.newPublicDataReadsPreimages, - ], + publicDataReadsPreimages: txPublicDataReadsInfo.newPublicDataReadsPreimages, - publicDataReadsMembershipWitnesses: [ - leftPublicDataReadsInfo.newPublicDataReadsWitnesses, - rightPublicDataReadsInfo.newPublicDataReadsWitnesses, - ], + publicDataReadsMembershipWitnesses: txPublicDataReadsInfo.newPublicDataReadsWitnesses, - lowNullifierLeafPreimages: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => + lowNullifierLeafPreimages: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => i < nullifierWitnessLeaves.length ? (nullifierWitnessLeaves[i].leafPreimage as NullifierLeafPreimage) : NullifierLeafPreimage.empty(), ), - lowNullifierMembershipWitness: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => + lowNullifierMembershipWitness: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => i < lowNullifierMembershipWitnesses.length ? lowNullifierMembershipWitnesses[i] : this.makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT), ), - kernelData: [this.getKernelDataFor(left), this.getKernelDataFor(right)], - archiveRootMembershipWitnesses: [ - await this.getHistoricalTreesMembershipWitnessFor(left), - await this.getHistoricalTreesMembershipWitnessFor(right), - ], + kernelData: this.getKernelDataFor(tx), + archiveRootMembershipWitness: await this.getHistoricalTreesMembershipWitnessFor(tx), }); } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 694f4ee61b7..663b3e5d2f2 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -101,7 +101,7 @@ describe('sequencer', () => { await sequencer.initialSync(); await sequencer.work(); - const expectedTxHashes = [...(await Tx.getHashes([tx])), ...times(3, () => TxHash.ZERO)]; + const expectedTxHashes = [...(await Tx.getHashes([tx])), ...times(1, () => TxHash.ZERO)]; expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( new GlobalVariables(chainId, version, new Fr(lastBlockNumber + 1), Fr.ZERO), @@ -138,7 +138,7 @@ describe('sequencer', () => { await sequencer.initialSync(); await sequencer.work(); - const expectedTxHashes = [...(await Tx.getHashes([txs[0], txs[2]])), TxHash.ZERO, TxHash.ZERO]; + const expectedTxHashes = await Tx.getHashes([txs[0], txs[2]]); expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( new GlobalVariables(chainId, version, new Fr(lastBlockNumber + 1), Fr.ZERO), @@ -171,7 +171,7 @@ describe('sequencer', () => { await sequencer.initialSync(); await sequencer.work(); - const expectedTxHashes = [...(await Tx.getHashes([txs[0], txs[2]])), TxHash.ZERO, TxHash.ZERO]; + const expectedTxHashes = await Tx.getHashes([txs[0], txs[2]]); expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( new GlobalVariables(chainId, version, new Fr(lastBlockNumber + 1), Fr.ZERO), diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index cd70ffca8ee..a847fd19c80 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -338,8 +338,8 @@ export class Sequencer { emptyTx: ProcessedTx, globalVariables: GlobalVariables, ) { - // Pad the txs array with empty txs to be a power of two, at least 4 - const txsTargetSize = Math.max(ceilPowerOfTwo(txs.length), 4); + // Pad the txs array with empty txs to be a power of two, at least 2 + const txsTargetSize = Math.max(ceilPowerOfTwo(txs.length), 2); const emptyTxCount = txsTargetSize - txs.length; const allTxs = [...txs, ...times(emptyTxCount, () => emptyTx)]; diff --git a/yarn-project/types/src/l2_block.ts b/yarn-project/types/src/l2_block.ts index 9117a01b3e4..2a84683a063 100644 --- a/yarn-project/types/src/l2_block.ts +++ b/yarn-project/types/src/l2_block.ts @@ -674,14 +674,14 @@ export class L2Block { return layers[layers.length - 1][0]; }; - const leafCount = this.newCommitments.length / (MAX_NEW_COMMITMENTS_PER_TX * 2); + const leafCount = this.newCommitments.length / MAX_NEW_COMMITMENTS_PER_TX; const leafs: Buffer[] = []; for (let i = 0; i < leafCount; i++) { - const commitmentsPerBase = MAX_NEW_COMMITMENTS_PER_TX * 2; - const nullifiersPerBase = MAX_NEW_NULLIFIERS_PER_TX * 2; - const publicDataUpdateRequestsPerBase = MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2; - const l2ToL1MsgsPerBase = MAX_NEW_L2_TO_L1_MSGS_PER_TX * 2; + const commitmentsPerBase = MAX_NEW_COMMITMENTS_PER_TX; + const nullifiersPerBase = MAX_NEW_NULLIFIERS_PER_TX; + const publicDataUpdateRequestsPerBase = MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; + const l2ToL1MsgsPerBase = MAX_NEW_L2_TO_L1_MSGS_PER_TX; const commitmentsBuffer = Buffer.concat( this.newCommitments.slice(i * commitmentsPerBase, (i + 1) * commitmentsPerBase).map(x => x.toBuffer()), ); @@ -696,27 +696,20 @@ export class L2Block { const newL2ToL1MsgsBuffer = Buffer.concat( this.newL2ToL1Msgs.slice(i * l2ToL1MsgsPerBase, (i + 1) * l2ToL1MsgsPerBase).map(x => x.toBuffer()), ); - const encryptedLogsHashKernel0 = L2Block.computeKernelLogsHash(this.newEncryptedLogs.txLogs[i * 2]); - const encryptedLogsHashKernel1 = L2Block.computeKernelLogsHash(this.newEncryptedLogs.txLogs[i * 2 + 1]); + const encryptedLogsHashKernel0 = L2Block.computeKernelLogsHash(this.newEncryptedLogs.txLogs[i]); - const unencryptedLogsHashKernel0 = L2Block.computeKernelLogsHash(this.newUnencryptedLogs.txLogs[i * 2]); - const unencryptedLogsHashKernel1 = L2Block.computeKernelLogsHash(this.newUnencryptedLogs.txLogs[i * 2 + 1]); + const unencryptedLogsHashKernel0 = L2Block.computeKernelLogsHash(this.newUnencryptedLogs.txLogs[i]); const inputValue = Buffer.concat([ commitmentsBuffer, nullifiersBuffer, publicDataUpdateRequestsBuffer, newL2ToL1MsgsBuffer, - this.newContracts[i * 2].toBuffer(), - this.newContracts[i * 2 + 1].toBuffer(), - this.newContractData[i * 2].contractAddress.toBuffer(), - this.newContractData[i * 2].portalContractAddress.toBuffer32(), - this.newContractData[i * 2 + 1].contractAddress.toBuffer(), - this.newContractData[i * 2 + 1].portalContractAddress.toBuffer32(), + this.newContracts[i].toBuffer(), + this.newContractData[i].contractAddress.toBuffer(), + this.newContractData[i].portalContractAddress.toBuffer32(), encryptedLogsHashKernel0, - encryptedLogsHashKernel1, unencryptedLogsHashKernel0, - unencryptedLogsHashKernel1, ]); leafs.push(sha256(inputValue)); }