diff --git a/l1-contracts/src/core/Decoder.sol b/l1-contracts/src/core/Decoder.sol index 9ee67b693dce..950cab912da3 100644 --- a/l1-contracts/src/core/Decoder.sol +++ b/l1-contracts/src/core/Decoder.sol @@ -26,29 +26,35 @@ pragma solidity >=0.8.18; * | 0x90 | 0x04 | startTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex * | 0x94 | 0x20 | startTreeOfHistoricContractTreeRootsSnapshot.root * | 0xb4 | 0x04 | startTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex - * | 0xb8 | 0x20 | endPrivateDataTreeSnapshot.root - * | 0xd8 | 0x04 | endPrivateDataTreeSnapshot.nextAvailableLeafIndex - * | 0xdc | 0x20 | endNullifierTreeSnapshot.root - * | 0xfc | 0x04 | endNullifierTreeSnapshot.nextAvailableLeafIndex - * | 0x100 | 0x20 | endContractTreeSnapshot.root - * | 0x120 | 0x04 | endContractTreeSnapshot.nextAvailableLeafIndex - * | 0x124 | 0x20 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.root - * | 0x144 | 0x04 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x148 | 0x20 | endTreeOfHistoricContractTreeRootsSnapshot.root - * | 0x168 | 0x04 | endTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex - * | 0x16c | 0x04 | len(newCommitments) denoted x - * | 0x170 | x | newCommits - * | 0x170 + x | 0x04 | len(newNullifiers) denoted y - * | 0x174 + x | y | newNullifiers - * | 0x174 + x + y | 0x04 | len(newContracts) denoted z - * | 0x178 + x + y | z | newContracts - * | 0x178 + x + y + z | z | newContractData + * | 0xb8 | 0x20 | startPublicDataTreeRoot + * | 0xd8 | 0x20 | endPrivateDataTreeSnapshot.root + * | 0xf8 | 0x04 | endPrivateDataTreeSnapshot.nextAvailableLeafIndex + * | 0xfc | 0x20 | endNullifierTreeSnapshot.root + * | 0x11c | 0x04 | endNullifierTreeSnapshot.nextAvailableLeafIndex + * | 0x120 | 0x20 | endContractTreeSnapshot.root + * | 0x140 | 0x04 | endContractTreeSnapshot.nextAvailableLeafIndex + * | 0x144 | 0x20 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.root + * | 0x164 | 0x04 | endTreeOfHistoricPrivateDataTreeRootsSnapshot.nextAvailableLeafIndex + * | 0x168 | 0x20 | endTreeOfHistoricContractTreeRootsSnapshot.root + * | 0x188 | 0x04 | endTreeOfHistoricContractTreeRootsSnapshot.nextAvailableLeafIndex + * | 0x18c | 0x20 | endPublicDataTreeRoot + * | 0x1ac | 0x04 | len(newCommitments) denoted a + * | 0x1b0 | a | newCommitments (each element 32 bytes) + * | 0x1b0 + a | 0x04 | len(newNullifiers) denoted b + * | 0x1b4 + a | b | newNullifiers (each element 32 bytes) + * | 0x1b4 + a + b | 0x04 | len(newPublicDataWrites) denoted c + * | 0x1b8 + a + b | c | newPublicDataWrites (each element 64 bytes) + * | 0x1b8 + a + b + c | 0x04 | len(newContracts) denoted d + * | 0x1bc + a + b + c | v | newContracts (each element 32 bytes) + * | 0x1bc + a + b + c + d | v | newContractData (each element 52 bytes) * |--- |--- | --- - * + * TODO: a,b,c,d are number of elements and not bytes, need to be multiplied by the length of the elements. */ contract Decoder { uint256 internal constant COMMITMENTS_PER_KERNEL = 4; uint256 internal constant NULLIFIERS_PER_KERNEL = 4; + uint256 internal constant PUBLIC_DATA_WRITES_PER_KERNEL = 4; + uint256 internal constant CONTRACTS_PER_KERNEL = 1; // Prime field order uint256 internal constant P = @@ -58,8 +64,8 @@ contract Decoder { * @notice Decodes the inputs and computes values to check state against * @param _l2Block - The L2 block calldata. * @return l2BlockNumber - The L2 block number. - * @return oldStateHash - The state hash expected prior the execution. - * @return newStateHash - The state hash expected after the execution. + * @return startStateHash - The state hash expected prior the execution. + * @return endStateHash - The state hash expected after the execution. * @return publicInputHash - The hash of the public inputs */ function _decode(bytes calldata _l2Block) @@ -67,28 +73,27 @@ contract Decoder { pure returns ( uint256 l2BlockNumber, - bytes32 oldStateHash, - bytes32 newStateHash, + bytes32 startStateHash, + bytes32 endStateHash, bytes32 publicInputHash ) { l2BlockNumber = _getL2BlockNumber(_l2Block); - // Note, for oldStateHash to match the storage, the l2 block number must be new - 1. + // Note, for startStateHash to match the storage, the l2 block number must be new - 1. // Only jumping 1 block at a time. - oldStateHash = _computeStateHash(l2BlockNumber - 1, 0x4, _l2Block); - newStateHash = _computeStateHash(l2BlockNumber, 0xb8, _l2Block); + startStateHash = _computeStateHash(l2BlockNumber - 1, 0x4, _l2Block); + endStateHash = _computeStateHash(l2BlockNumber, 0xd8, _l2Block); publicInputHash = _computePublicInputsHash(_l2Block); } /** * Computes a hash of the public inputs from the calldata * @param _l2Block - The L2 block calldata. - * @return sha256(header[0x4:0x16c], diffRoot) + * @return sha256(header[0x4: 0x1ac], diffRoot) */ function _computePublicInputsHash(bytes calldata _l2Block) internal pure returns (bytes32) { - // Compute the public inputs hash - // header size - block number + one value for the diffRoot - uint256 size = 0x16c - 0x04 + 0x20; + // header size - block number size + one value for the diffRoot + uint256 size = 0x1ac - 0x04 + 0x20; bytes memory temp = new bytes(size); assembly { calldatacopy(add(temp, 0x20), add(_l2Block.offset, 0x04), size) @@ -96,7 +101,7 @@ contract Decoder { bytes32 diffRoot = _computeDiffRoot(_l2Block); assembly { - mstore(add(temp, add(0x20, sub(0x16c, 0x04))), diffRoot) + mstore(add(temp, add(0x20, sub(0x1ac, 0x04))), diffRoot) } return bytes32(uint256(sha256(temp)) % P); @@ -116,7 +121,7 @@ contract Decoder { /** * @notice Computes a state hash * @param _l2BlockNumber - The L2 block number - * @param _offset - The offset into the data, 0x04 for old, 0xb8 for next + * @param _offset - The offset into the data, 0x04 for start, 0xd8 for end * @param _l2Block - The L2 block calldata. * @return The state hash */ @@ -125,7 +130,7 @@ contract Decoder { pure returns (bytes32) { - bytes memory temp = new bytes(0xb8); + bytes memory temp = new bytes(0xd8); assembly { mstore8(add(temp, 0x20), shr(24, _l2BlockNumber)) @@ -134,7 +139,8 @@ contract Decoder { mstore8(add(temp, 0x23), _l2BlockNumber) } assembly { - calldatacopy(add(temp, 0x24), add(_l2Block.offset, _offset), 0xb4) + // Copy header elements (not including block number) for start or end (size 0xd4) + calldatacopy(add(temp, 0x24), add(_l2Block.offset, _offset), 0xd4) } return sha256(temp); @@ -142,7 +148,8 @@ contract Decoder { struct Vars { uint256 commitmentCount; - uint256 kernelCount; + uint256 nullifierCount; + uint256 dataWritesCount; uint256 contractCount; } @@ -152,46 +159,48 @@ contract Decoder { * @return The root of the "diff" tree */ function _computeDiffRoot(bytes calldata _l2Block) internal pure returns (bytes32) { + // Find the lengths of the different inputs Vars memory vars; { - uint256 commitmentCount; assembly { - commitmentCount := and(shr(224, calldataload(add(_l2Block.offset, 0x16c))), 0xffffffff) - } - vars.commitmentCount = commitmentCount; - vars.kernelCount = commitmentCount / COMMITMENTS_PER_KERNEL; - uint256 contractCountOffset = - vars.kernelCount * (COMMITMENTS_PER_KERNEL + NULLIFIERS_PER_KERNEL) * 0x20; + let offset := add(_l2Block.offset, 0x1ac) + let commitmentCount := and(shr(224, calldataload(offset)), 0xffffffff) + offset := add(add(offset, 0x4), mul(commitmentCount, 0x20)) + let nullifierCount := and(shr(224, calldataload(offset)), 0xffffffff) + offset := add(add(offset, 0x4), mul(nullifierCount, 0x20)) + let dataWritesCount := and(shr(224, calldataload(offset)), 0xffffffff) + offset := add(add(offset, 0x4), mul(nullifierCount, 0x40)) + let contractCount := and(shr(224, calldataload(offset)), 0xffffffff) - uint256 newContractCount; - assembly { - newContractCount := - and( - shr(224, calldataload(add(_l2Block.offset, add(0x174, contractCountOffset)))), 0xffffffff - ) + // Store it in vars + mstore(vars, commitmentCount) + mstore(add(vars, 0x20), nullifierCount) + mstore(add(vars, 0x40), dataWritesCount) + mstore(add(vars, 0x60), contractCount) } - vars.contractCount = newContractCount; } - bytes32[] memory baseLeafs = new bytes32[](vars.kernelCount / 2); + bytes32[] memory baseLeafs = new bytes32[]( + vars.commitmentCount / (COMMITMENTS_PER_KERNEL * 2) + ); - uint256 dstCommitmentOffset = COMMITMENTS_PER_KERNEL * 0x20 * 0x2; - uint256 dstContractOffset = dstCommitmentOffset + NULLIFIERS_PER_KERNEL * 0x20 * 0x2; - - uint256 srcCommitmentOffset = 0x170; - uint256 srcNullifierOffset = 0x174 + vars.commitmentCount * 0x20; - uint256 srcContractOffset = - 0x178 + (baseLeafs.length * 2 * (NULLIFIERS_PER_KERNEL + COMMITMENTS_PER_KERNEL) * 0x20); + // Data starts after header. Look at L2 Block Data specification at the top of this file. + uint256 srcCommitmentOffset = 0x1b0; + uint256 srcNullifierOffset = srcCommitmentOffset + 0x4 + vars.commitmentCount * 0x20; + uint256 srcDataOffset = srcNullifierOffset + 0x4 + vars.nullifierCount * 0x20; + uint256 srcContractOffset = srcDataOffset + 0x4 + vars.dataWritesCount * 0x40; uint256 srcContractDataOffset = srcContractOffset + vars.contractCount * 0x20; for (uint256 i = 0; i < baseLeafs.length; i++) { /** * Compute the leaf to insert. * Leaf_i = ( - * newNullifiersKernel1, - * newNullifiersKernel2, * newCommitmentsKernel1, * newCommitmentsKernel2, + * newNullifiersKernel1, + * newNullifiersKernel2, + * newPublicDataWritesKernel1, + * newPublicDataWritesKernel2, * newContractLeafKernel1, * newContractLeafKernel2, * newContractDataKernel1.aztecAddress, @@ -202,54 +211,63 @@ contract Decoder { * Note that we always read data, the l2Block (atm) must therefore include dummy or zero-notes for * Zero values. */ - bytes memory baseLeaf = new bytes(0x2c0); + // Create the leaf to contain commitments (8 * 0x20) + nullifiers (8 * 0x20) + // + new public data writes (8 * 0x40) + contract deployments (2 * 0x60) + bytes memory baseLeaf = new bytes(0x4c0); assembly { - // Adding new nullifiers - calldatacopy(add(baseLeaf, 0x20), add(_l2Block.offset, srcNullifierOffset), mul(0x08, 0x20)) - + let dstOffset := 0x20 // Adding new commitments calldatacopy( - add(baseLeaf, add(0x20, dstCommitmentOffset)), - add(_l2Block.offset, srcCommitmentOffset), - mul(0x08, 0x20) + add(baseLeaf, dstOffset), add(_l2Block.offset, srcCommitmentOffset), mul(0x08, 0x20) ) + dstOffset := add(dstOffset, mul(0x08, 0x20)) - // Adding Contract Leafs + // Adding new nullifiers calldatacopy( - add(baseLeaf, add(0x20, dstContractOffset)), - add(_l2Block.offset, srcContractOffset), - mul(2, 0x20) + add(baseLeaf, dstOffset), add(_l2Block.offset, srcNullifierOffset), mul(0x08, 0x20) ) + dstOffset := add(dstOffset, mul(0x08, 0x20)) - // Kernel1.contract.aztecaddress + // Adding new public data writes + calldatacopy(add(baseLeaf, dstOffset), add(_l2Block.offset, srcDataOffset), mul(0x08, 0x40)) + dstOffset := add(dstOffset, mul(0x08, 0x40)) + + // Adding Contract Leafs calldatacopy( - add(baseLeaf, add(0x20, add(dstContractOffset, 0x40))), - add(_l2Block.offset, srcContractDataOffset), - 0x20 + add(baseLeaf, dstOffset), add(_l2Block.offset, srcContractOffset), mul(2, 0x20) ) + dstOffset := add(dstOffset, mul(2, 0x20)) + + // Kernel1.contract.aztecAddress + calldatacopy(add(baseLeaf, dstOffset), add(_l2Block.offset, srcContractDataOffset), 0x20) + dstOffset := add(dstOffset, 0x20) + // Kernel1.contract.ethAddress padded to 32 bytes + // Add 12 (0xc) bytes of padding to the ethAddress + dstOffset := add(dstOffset, 0xc) calldatacopy( - add(baseLeaf, add(0x20, add(dstContractOffset, 0x6c))), - add(_l2Block.offset, add(srcContractDataOffset, 0x20)), - 0x14 + add(baseLeaf, dstOffset), add(_l2Block.offset, add(srcContractDataOffset, 0x20)), 0x14 ) - // Kernel2.contract.aztecaddress + dstOffset := add(dstOffset, 0x20) + + // Kernel2.contract.aztecAddress calldatacopy( - add(baseLeaf, add(0x20, add(dstContractOffset, 0x80))), - add(_l2Block.offset, add(srcContractDataOffset, 0x34)), - 0x20 + add(baseLeaf, dstOffset), add(_l2Block.offset, add(srcContractDataOffset, 0x34)), 0x20 ) + dstOffset := add(dstOffset, 0x20) + // Kernel2.contract.ethAddress padded to 32 bytes + // Add 12 (0xc) bytes of padding to the ethAddress + dstOffset := add(dstOffset, 0xc) calldatacopy( - add(baseLeaf, add(0x20, add(dstContractOffset, 0xac))), - add(_l2Block.offset, add(srcContractDataOffset, 0x54)), - 0x14 + add(baseLeaf, dstOffset), add(_l2Block.offset, add(srcContractDataOffset, 0x54)), 0x14 ) } srcCommitmentOffset += 2 * COMMITMENTS_PER_KERNEL * 0x20; srcNullifierOffset += 2 * NULLIFIERS_PER_KERNEL * 0x20; + srcDataOffset += 2 * PUBLIC_DATA_WRITES_PER_KERNEL * 0x40; srcContractOffset += 2 * 0x20; srcContractDataOffset += 2 * 0x34; diff --git a/l1-contracts/src/periphery/UnverifiedDataEmitter.sol b/l1-contracts/src/periphery/UnverifiedDataEmitter.sol index 8933f1157d6e..c0285c221ada 100644 --- a/l1-contracts/src/periphery/UnverifiedDataEmitter.sol +++ b/l1-contracts/src/periphery/UnverifiedDataEmitter.sol @@ -13,7 +13,12 @@ contract UnverifiedDataEmitter { * @param portalAddress - The address of the L1 counterparty * @param acir - The acir bytecode of the L2 contract */ - event ContractDeployment(uint256 indexed l2BlockNum, bytes32 indexed aztecAddress, address indexed portalAddress, bytes acir); + event ContractDeployment( + uint256 indexed l2BlockNum, + bytes32 indexed aztecAddress, + address indexed portalAddress, + bytes acir + ); /** * @notice Used to share data which are not required to advance the state but are needed for other purposes diff --git a/l1-contracts/test/Decoder.t.sol b/l1-contracts/test/Decoder.t.sol index 5efef377203d..19f3d8994dc3 100644 --- a/l1-contracts/test/Decoder.t.sol +++ b/l1-contracts/test/Decoder.t.sol @@ -5,60 +5,178 @@ import {Test} from "forge-std/Test.sol"; import {Decoder} from "@aztec3/core/Decoder.sol"; import {Rollup} from "@aztec3/core/Rollup.sol"; +import {DecoderHelper} from "./DecoderHelper.sol"; -contract DecodeHelper is Decoder { - function decode(bytes calldata _l2Block) - external - pure - returns (uint256, bytes32, bytes32, bytes32) - { - return _decode(_l2Block); - } - - function computeDiffRoot(bytes calldata _l2Block) external pure returns (bytes32) { - return _computeDiffRoot(_l2Block); - } -} - -// Blocks generated with https://gist.github.com/LHerskind/dccc762ee539b7b0984bf51af6f51dbb +// Blocks generated using `l2-block-publisher.test.ts` contract DecoderTest is Test { Rollup internal rollup; - DecodeHelper internal helper; + DecoderHelper internal helper; bytes block_1 = - hex"0000000100000000026d27850fe7ca39749085f2a0dbde5776a38f37c982f024c4faec2cd51256a60000000092fda1d4e2f4d04645a5afab97c83831498573057c6274f975881bb93b16b0d60000000090e5ba6910314bb2d7175be5ab6cdd176bde431d3d9cc7ce2672c468ca57aab6000000008071532a7f22610b60a373b954208a01dc1058934e174c241a4825e1b04a59040000000055bcd75383e3c233124ca4b26857cf9d8474c78a063ceedd507726a7bc13254400000020496c61142f126c578fa762940fce65490ecb9dbb408a66b9275601725b16b827000000207728207bac279dbf8b7b5652b8b8c3619f65d007a7534015d0daf0a960e1550d00000008a71730065c0684ba4aa476b4ab3494db58b08ef8813cd0d4a456553ac046bf7a0000000172c52733e1b74bb841e89cfb2f9f6f08956d7d6c685073326442792d88e9cd1b000000019deecf3cb56703b46813472708f3085f00df5371fc20312b815063fa93ac55240000002004cf027a8ea6e124d01b5254a7c75f10aa2c849c016d3c7178f2f5b1b179c9e8830ffba67f219f3effa813a4669c84dec9b19c59c7dbbdc90a2b9ff701ff5045c7f12f133011953b37eb73a884c81b38d9b2ace4b224f81e6999a24b2f482e6a051742efabc5bf8b8649c6ca15ae9ae240483e6e64618ce2754c26d9a2bf2c5c780c2a3ff698bc4c750d5ff8fa74036e5562e8d89890c2dacb6d700f6b12f7dacfecafccd86a18d427d84d4bb8e0719feddd0bd4c248cff5889bb7e475e568784bdb542193a2752c78984436e8033e27030f1367819db683f004942872d3ef1c64dcd775fd8941913a85c0793160540be74e880dcf0649e3811d41d8eddaf1c3f8e487b4111d92ef95b7dd49fdc1591d17a9e5cc18eb547b318b09423c4a84131350f4b91f3c164aff80fe8e90c0a5e42d238fbddc22c0d89a510c1fea0839fedd1823ea7ec85c12461455881532f0fadc1786575ac924cfcc4edc44b4f8cd33ae54270c59b8d76198cc830453034e3a51dc30f6f5628b61c2467670de2dba1768a36430479247742a2238159cfb6328c3f27406d06d196319a993121ac74a89278d21b6e5cc1630f8929f5459a7038378814113a4d28712c670241ec3f76b85ac52e31dc9e22d55d290076829d9562c4e14ffccbeb9368c3ddc9eabf502b8e151a174b3bdbc202f98e4159b5be14fd57bc794523e9b305a284efaff9d06b5507829918a5292f07d2af3786ea18b46783b214ce79d8aaf3f25f05769cbae80bd7d211e94158f08a82cc1e745998074434360473dfa3145c368b08099578f356ea1b726e45ffda553180cd8f867c1656cdee5bd93513a745e7f4db6c78be52463088865aca180f5a5b241883c799d080d9af89cc7255b22ca9e007c54120e6b2d167bb9aa784941eeaea077e688f78c57c8460a2de65a5d6c0e18c751f301a691f1ede68c63593015ac2bc4867438a9082f4eed9778735ba5efe4f40b88af2b874951c60f1e1c89308684a3ef513589ff4f167e8471fbefa9eecc22de2d575625e87f8afb4fc5725780971dc16714d799c6563a7e8f603152aec76143efda4e7a8d72c82aa1a086e4545839636489815beeed36a17d744adc90ff20600691af9f74b64f3d5e83bb78bfbcbb31f969d01ba4e248737839afdc448ad3596fb2c464189b25c23038e1212710bd0667b3ef8ce232ffdeeeb1333d34d96f4c0713e39393e7d4bc660ec93c1c6d7fee494b10116f0380296c91d044b4d2ecb15294b520b8df116d106a42d9a460b6689f56fe8cac679e784ba7c8e64cc954b1ddfc8d811d2a45db2b3ef41269853dfc835fc2cab2d57e90494bf8250c6b90ed87477b1de6f28418e5c7a820aae2b4a1ce80c3f2807f1134e516371c997a414b790a65987e43ad32ab2182a0bc5772f9e42fad34319695e3857152040ab8c0bd64f18f33000000201ce5a42ecad03ede45ee270fd83aaab4bcb5bb11650a3f3cbb0a5b3266e676badba6aed51f14f10aacdaa9969745085353c0daf62dcd0cdaf56b7d8fac4a6a875c014e536d128d30cc6e184f7e4c88c6653aeb98732d82eb04eb9776b798707c461d8fb1bbcc44fe3db8d3845edb9ed468e0ea360b71c3354335d740069f4ec9764291034a710d6ee9845cd37d283153e70d4c85c6ecb202d5b76c5d9885afbcb8daf4c354e7772bbd880e86c3caaf527c9e37d80136285d05c4918d0e469b9a1e8d389d91cf64978d20175de676635e2915c619367e5093b6bd4aed7de6368ed77715c112d9b47d0e3597e1cf250a7e9ccc7c2919c584f62ad3499c6ed42d243c32ef99a2033d3bcaa5014188ca3a93376c1e08e47b48e1a6fc5a27c5e5dd7bbd7dbdd5020f29b66cd21d05a589cd704dbb1d4cf220fda802308472b786acd9346ce2999ffc43ebee8b46e40eef7aa41f88effe0a45c1d45245ac4109ef429cf0a59be7d0784d55cd25a4165a53f741d96a96b4358684d0280fbb8af43cf6afd59522e2f7ff1896296a560b1ed4e9532b41cc8d83c1e62b8b9d8e5d92561a66c9c9b661d27edf5b93931b95abb047650f3ab9d169d5c145d0325c4e913903987f3342cf3761bbcf58724fc13761114c97eaeabdc6d578c8ee39493377e6ae50bd6441f7334b57a96d9a0a6fce410de5d2aea385ee8c82788d3f3901278d49e101ed81d2ae4578d949a0fcf400ec9357c1e7d957c214b9e0b248aef8fdfd4ca50a039b493d87e5b41dde5f2ae56faa39547c924877f00ef56eb0b322c3f52bc1d47dcd12baafabab9f32311f355674550d0fbe51cb47c3ebbdfb9ef02713476f6aec98d64d596126146a4944fd6277065c692c726d6da6eefbd99852dc81765f278af17b49440a2b2730b76ea84cfaaf08a62de1124668551f6f3cc2a33d5d12796883693224bd43e70a979b900e88cc2c24d3db53bdcd82aa17a047674a5eb45a874a95186df03a4eac54a434b7b87943e5acd9561c9e09513f1bb60d96c0472faba31dc35d73affd2ae0757f07cfc23dc6c9e2c4dff4945d46f9d52e8bd9c74aca381af2e59f41640b14898a8f75adf7cfbc6c105844b580fcbc59a4c1f5e315beda39680ff392963fa4551a62e87feda484215a804ea4af55c52c6d7f77c3876615dc42e6476fd974e405fd2d16c086856fc1ad9420a581b770e9cbb807e6f171a2e3c491ac66de2b1adbc0ee3fd18277737340aa9b310342db71f344ac4f10b63cb23d5dd6de4a3566f1e948cddbed83538a7e3450c4870cd26da87e23c0bf66a5f5aa22fbd56984776ecbefbfbe276143d1fdabc2be4893c4cf438c8fea24dca9bcc03a076c56da333cc05213aa27c0f2aeea7583d499e62dbb84eabf6113e8a444dd3c3a04b09263bfe3248780c97ef8c5a6654a7f7c20729fb1a6c82e00000008fc7168914fb3f34b544b555c3079e18f0716b2e43062e1950d3a172dd2cc4e096d91f2f077802f217a1ba3f1b0c58bdb043914986e2ab375c2b2fc9cc069d09ec7b9f210134fce1e78b70e9f9f2a2ac4514bab668e99f0d0106006a62dbbf708fb5175774909691ff8fefd94a11bb37c3818ceb9e3335d7085bcbeb0cc8bf656985fcb53efd11f7e8808aacd0c7c5f244271aeb342f0f12656659960090926f31a61aef1c654db3b36b53d03453288fd92bcb30aefd36460330be3b9814669645e9344aa54e1deda1016d4ef3b3ae6c9da8c0ad19db46ad28bac03d34d7166b6fe280594b84df03effd72731c2f5d92dd2bae2b06ce45832bb3b7e9ae0041166d2a4c0c019fb4c3c865803a447b3895a18d456c66abfab8899db9c3d38b9af457feeae39874c79a99a998a31c0accf85edb4b8e9810f843ac6b8f7200760e95b2d5e0e34105fb39c2a7066865523132cdd40d0cd2f6aef3948e85259513b383a7a6db167d1804d93c99eb78c317288b4ebae14854b841b9825923812f9293d3d85e3942835f3cab7170a5c61bcb021b1cf773e1fe652381fad61f4cb4a43465b630212ca6e0223c2d20f30bc374e78fc79ec8d4fbeb4eae6d431ec0d306ccca543d0ab9ea6fe1724e1cef669e9254c8e036e0d856e241521e33bde0551e84260a5dd29fec18c1716f9a5e7bbc74eabc4dcee065c3770aa78bcb8404408e1b436f23cc3451811f331e0f75c607710a0838a42a373a690dc352d06dd4f5d21388de63678f61b6d02d8f3e9fe7e8a1e64c1a441df94a83295d6f6609580871767d29294e57e943895bf3b85a8b6ea33932379943e80e689b80455026dfe6a5d2f0544c25ee0f11d89d1bef2832080d95c4d39f6048b7e0db6d771154a321d2979ed36bcc70a9ea2fb3583844ff30a11a80197225cf7d1a7e8e4cef24f443c13ff08"; + hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba00000001000000000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000102000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002010000000000000000000000000000000000000000000000000000000000000202000000000000000000000000000000000000000000000000000000000000020300000000000000000000000000000000000000000000000000000000000002040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080200000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000803000000000000000000000000000000000000000000000000000000000000080500000000000000000000000000000000000000000000000000000000000008040000000000000000000000000000000000000000000000000000000000000806000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041b024f6e2e258ac4fa7b3a0d03f9fa242eee6d884ec85d0efd4beca26a88da2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006010202020202020202020202020202020202020202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes block_2 = - hex"0000000200000020496c61142f126c578fa762940fce65490ecb9dbb408a66b9275601725b16b827000000207728207bac279dbf8b7b5652b8b8c3619f65d007a7534015d0daf0a960e1550d00000008a71730065c0684ba4aa476b4ab3494db58b08ef8813cd0d4a456553ac046bf7a0000000172c52733e1b74bb841e89cfb2f9f6f08956d7d6c685073326442792d88e9cd1b000000019deecf3cb56703b46813472708f3085f00df5371fc20312b815063fa93ac552400000020496c61142f126c578fa762940fce65490ecb9dbb408a66b9275601725b16b827000000207728207bac279dbf8b7b5652b8b8c3619f65d007a7534015d0daf0a960e1550d00000008a71730065c0684ba4aa476b4ab3494db58b08ef8813cd0d4a456553ac046bf7a000000022165eb4c24ae6094baac7030a5c34975363d08dffee879e7a977245dc4329755000000024cd0efa11cdedc2f673b57e9b016717b1111854fa17b6cb4385c09eab4f676fe000000000000000000000000"; + hex"000000020283622796e1a2fa4718e254eb46d3f4287b05a5aaee35af02a54f2af8362f97000000101f99db4b9ffa5ab637607ad50c7d10ea3352a53478e14354355a02b6a87a7ab1000000181ba22861f1a04d910c399ce20125a7ef53c3a47e0f51fe1d2c179ea83b8da34e0000000415db3dd5c4e4589c0b7a5942f81c11548dda500600adefeb8c49d13481a88e24000000022309e4044d29f2906c728a7d19672aa7d80f3fbc289d4dd6fcab93f1e197b727000000020a20b604e286954cd8b1622dcbda5ef1c4ad6bfd80a81ad80dcff2f5080d5ba0013ffea42e60a3be0af304384d83ad4411df13f66213997a7f0b7551e242f19d0000002001872181b5fe2c7ea15e1e72f5672bc777d61c807771ff7ae40c9b2aa816323500000028063d7b42d552599d3f3ff8fbc93e55484d49fc20dcc41940e3ebeaac4483a8ba0000000803b6339133ac1ca21463e1e3370ca136862bac1be49bdc6e1e69f73068a22ebe0000000316204b8532027613f551ad0530dc70c1c3be36fb7828a3a6539a100c57d25034000000030aa1281a92ab93a92ea1e45d49ce373a45fdb0b7a988416e63cd0728252a112a0000001000000000000000000000000000000000000000000000000000000000000001020000000000000000000000000000000000000000000000000000000000000103000000000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000001050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000002050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008020000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080300000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000080600000000000000000000000000000000000000000000000000000000000008050000000000000000000000000000000000000000000000000000000000000807000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042ddfdac63df2e340ea582ed2b6c9d23bf04f6e98c281c25c6dd7e87251185b3500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006020303030303030303030303030303030303030303000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + + bytes block_empty_1 = + hex"000000010668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000002d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000082f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd80000000019c36f7bc2e4116d082865cc0b4ac8e16e9efa00ace9fb2222dd1dfd719cb671000000012b36b22912aa963f143c490227bd21e7a44338026b2f6a389cb98e82167c3718000000012b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - bytes block_empty = - hex"000000010dab4f2c5004966607528e2de5e46abc49d68ac863a6f3ad3e3d98332ca8989d000000000d4ee51c2e3c7b242113e4cdc73af511db2393fcc96e2916ad77b07d4dd2ee96000000082c21cd9d652b1d55ae6437893ec4189d5cc48db60f44ecd0ce272e3a0fef45360000000011418b0f96de397c0bdec2dda6dc049c9f9715fa62420e5a6e08f3dd0b68fd36000000012ccf6631cb5d548aa25e0c51b9398c89af35fb00b321d40db6cb8f13f44cce2f000000010dab4f2c5004966607528e2de5e46abc49d68ac863a6f3ad3e3d98332ca8989d000000100d4ee51c2e3c7b242113e4cdc73af511db2393fcc96e2916ad77b07d4dd2ee96000000182c21cd9d652b1d55ae6437893ec4189d5cc48db60f44ecd0ce272e3a0fef4536000000042fe07d4d766850fb0c5f289cb6d71334e2f662146dd7e9693351795a6233b2d00000000211fcecd075e7e86da01708dedfc9671475fe7a879e076d6fe67bf432347eb0300000000200000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes block_empty_2 = + hex"000000020668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000102d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000182f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000004238b20b7bc1d5190f8e928eb2aa2094412588f9cad6c7862f69c09a9b246d6ed0000000225d4ca531bca7d097a93bc47d7aa2c4dbcc8d0d5ecf4138849104e363eb52c03000000022b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb0668938c4a4167faa2b5031e427d74d6e38638d2eef68834b70480c5a93f8e15000000202d39729fd006096882acfbd350c91fd61883578b4fe35b63cdce3c1993a497ea000000282f8dc86ba80d8fcf491fb7a255f4163e4f9601d022ba0be35f13297531073fd800000008236394e84a01824e286653b542a923474253251e86c118f02978d5714538236c000000030aaa66ea64a4b9493d7237d092f8276e31eb3f8b14ae5c5e0a91fa5627745a83000000032b72136df9bc7dc9cbfe6b84ec743e8e1d73dd93aecfa79f18afb86be977d3eb000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; function setUp() public { rollup = new Rollup(); - helper = new DecodeHelper(); + helper = new DecoderHelper(); } - function testDecoderDiffRoot() public { - bytes32 diffRoot = helper.computeDiffRoot(block_1); - assertEq( - 0x260777a20fee44e43d74c60350ebb7a631dabe0a8a1c27ee9a8264b2f5c24c2d, - diffRoot, - "Invalid diff root" - ); - } + function testEmptyBlocks() public { + { + bytes32 diffRoot = helper.computeDiffRoot(block_empty_1); + assertEq( + 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, + diffRoot, + "Invalid diff root" + ); + + ( + uint256 l2BlockNumber, + bytes32 startStateHash, + bytes32 endStateHash, + bytes32 publicInputsHash + ) = helper.decode(block_empty_1); + + assertEq(l2BlockNumber, 1, "Invalid block number"); + assertEq( + startStateHash, + 0xc3c559a71e6e4e6120dc290ac2aefe6739be32216168d5c98899a86f1566d930, + "Invalid start state hash" + ); + assertEq( + endStateHash, + 0x448312391a3205ecaf22d804a780c19890d6425c621e9a731c342f9903a5e71f, + "Invalid end state hash" + ); + assertEq( + publicInputsHash, + 0x2e8af2457a0c7cef1b1d47efa0583f1e0840910ab1a802bff812bbc5e62b7321, + "Invalid public input hash" + ); + + rollup.process(bytes(""), block_empty_1); + + assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); + } + + { + bytes32 diffRoot = helper.computeDiffRoot(block_empty_2); + assertEq( + 0x84036b397b37b2dab7c2d95581275797c8d06b432f3826ada23cca6d87d49b84, + diffRoot, + "Invalid diff root" + ); - function testDecoder() public { - rollup.process(bytes(""), block_1); - rollup.process(bytes(""), block_2); + ( + uint256 l2BlockNumber, + bytes32 startStateHash, + bytes32 endStateHash, + bytes32 publicInputsHash + ) = helper.decode(block_empty_2); + + assertEq(l2BlockNumber, 2, "Invalid block number"); + assertEq( + startStateHash, + 0x448312391a3205ecaf22d804a780c19890d6425c621e9a731c342f9903a5e71f, + "Invalid start state hash" + ); + assertEq( + endStateHash, + 0x2fb8f70b8011dfa8111055c18a0068294d795c2c82701f18b5bf93b3156fe83f, + "Invalid end state hash" + ); + assertEq( + publicInputsHash, + 0x0b0c644c9a7106d293ca833a1cb332a576de6971951c2167408545dd7e31a7bb, + "Invalid public input hash" + ); + + rollup.process(bytes(""), block_empty_2); + + assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); + } } - function testPublicInputHash() public { - (uint256 l2BlockNumber, bytes32 oldStateHash, bytes32 newStateHash, bytes32 publicInputsHash) = - helper.decode(block_empty); - assertEq( - publicInputsHash, - 0x0013b2202a3e48b039cda7eef0976060d86e610d77fc9bb8cd5b0f1b561df48c, - "Invalid public input hash" - ); + function testNonEmptyBlocks() public { + { + bytes32 diffRoot = helper.computeDiffRoot(block_1); + assertEq( + 0x05ab40c0ddda5b1846c6283c0a99ea7da9ebb3ea46f33225e72e0d0333bf251f, + diffRoot, + "Invalid diff root block 1" + ); + + ( + uint256 l2BlockNumber, + bytes32 startStateHash, + bytes32 endStateHash, + bytes32 publicInputsHash + ) = helper.decode(block_1); + + assertEq(l2BlockNumber, 1, "Invalid block number"); + assertEq( + startStateHash, + 0xc3c559a71e6e4e6120dc290ac2aefe6739be32216168d5c98899a86f1566d930, + "Invalid start state hash block 1" + ); + assertEq( + endStateHash, + 0x45faded932e3a828a426370bd7275120c3f4ed27117a6c98c9c762e8b8cec9f6, + "Invalid end state hash block 1" + ); + assertEq( + publicInputsHash, + 0x28b90cb81b273c3ee583750e79bca15e9b01fe01a7eacacf462ee866cefb904a, + "Invalid public input hash block 1" + ); + + rollup.process(bytes(""), block_1); + + assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash block 1"); + } + + { + bytes32 diffRoot = helper.computeDiffRoot(block_2); + assertEq( + 0x04a10b2ce6eb66a3ae547efacc53760ec64fb86c901f9cadb36c104cc532cb99, + diffRoot, + "Invalid diff root block 2" + ); + + ( + uint256 l2BlockNumber, + bytes32 startStateHash, + bytes32 endStateHash, + bytes32 publicInputsHash + ) = helper.decode(block_2); + + assertEq(l2BlockNumber, 2, "Invalid block number"); + assertEq( + startStateHash, + 0x45faded932e3a828a426370bd7275120c3f4ed27117a6c98c9c762e8b8cec9f6, + "Invalid start state hash block 2" + ); + assertEq( + endStateHash, + 0x0b04cfd8792e17a123c3c5c82bd2593e8da745d05296d4e1058708e11489909a, + "Invalid end state hash block 2" + ); + assertEq( + publicInputsHash, + 0x04f8878ba2e56773029c2b246d41f04963cc8b2654bc35a66b72ff79a7a756ec, + "Invalid public input hash block 2" + ); + + rollup.process(bytes(""), block_2); + + assertEq(rollup.rollupStateHash(), endStateHash, "Invalid rollup state hash"); + } } } diff --git a/l1-contracts/test/DecoderHelper.sol b/l1-contracts/test/DecoderHelper.sol new file mode 100644 index 000000000000..90a32fd24bb7 --- /dev/null +++ b/l1-contracts/test/DecoderHelper.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.18; + +import {Decoder} from "@aztec3/core/Decoder.sol"; +import {Rollup} from "@aztec3/core/Rollup.sol"; + +contract DecoderHelper is Decoder { + function decode(bytes calldata _l2Block) + external + pure + returns (uint256, bytes32, bytes32, bytes32) + { + return _decode(_l2Block); + } + + function computeDiffRoot(bytes calldata _l2Block) external pure returns (bytes32) { + return _computeDiffRoot(_l2Block); + } +} diff --git a/yarn-project/l1-contracts/contracts.json b/yarn-project/l1-contracts/contracts.json index dd6a5855d219..327c0e994929 100644 --- a/yarn-project/l1-contracts/contracts.json +++ b/yarn-project/l1-contracts/contracts.json @@ -1,6 +1,10 @@ { "outputPath": "./src/ethereumjs-contracts", "contracts": { + "DecoderHelper": { + "source": "foundry", + "buildFile": "../../l1-contracts/out/DecoderHelper.sol/DecoderHelper.json" + }, "Rollup": { "source": "foundry", "buildFile": "../../l1-contracts/out/Rollup.sol/Rollup.json" diff --git a/yarn-project/l1-contracts/scripts/update-viem-abis.sh b/yarn-project/l1-contracts/scripts/update-viem-abis.sh index 3c3d7029de6c..52bdd3360cc3 100755 --- a/yarn-project/l1-contracts/scripts/update-viem-abis.sh +++ b/yarn-project/l1-contracts/scripts/update-viem-abis.sh @@ -1,9 +1,22 @@ set -euo pipefail; -echo -ne "/**\n * Rollup ABI for viem.\n */\nexport const RollupAbi = " > ./src/viem-abis/RollupAbi.ts; -jq -j '.abi' ../../l1-contracts/out/Rollup.sol/Rollup.json >> ./src/viem-abis/RollupAbi.ts; -echo " as const;" >> ./src/viem-abis/RollupAbi.ts; +echo -ne "/**\n * DecoderHelper ABI for viem.\n */\nexport const DecoderHelperAbi = " > ./src/viem-contracts/DecoderHelper.ts; +jq -j '.abi' ../../l1-contracts/out/DecoderHelper.sol/DecoderHelper.json >> ./src/viem-contracts/DecoderHelper.ts; +echo " as const;" >> ./src/viem-contracts/DecoderHelper.ts; +echo -ne "/**\n * DecoderHelper Bytecode for viem.\n */\nexport const DecoderHelperBytecode = \"" >> ./src/viem-contracts/DecoderHelper.ts; +jq -j '.bytecode.object' ../../l1-contracts/out/DecoderHelper.sol/DecoderHelper.json >> ./src/viem-contracts/DecoderHelper.ts; +echo "\";" >> ./src/viem-contracts/DecoderHelper.ts; -echo -ne "/**\n * UnverifiedDataEmitter ABI for viem.\n */\nexport const UnverifiedDataEmitterAbi = " > ./src/viem-abis/UnverifiedDataEmitterAbi.ts; -jq -j '.abi' ../../l1-contracts/out/UnverifiedDataEmitter.sol/UnverifiedDataEmitter.json >> ./src/viem-abis/UnverifiedDataEmitterAbi.ts; -echo " as const;" >> ./src/viem-abis/UnverifiedDataEmitterAbi.ts; +echo -ne "/**\n * Rollup ABI for viem.\n */\nexport const RollupAbi = " > ./src/viem-contracts/Rollup.ts; +jq -j '.abi' ../../l1-contracts/out/Rollup.sol/Rollup.json >> ./src/viem-contracts/Rollup.ts; +echo " as const;" >> ./src/viem-contracts/Rollup.ts; +echo -ne "/**\n * Rollup Bytecode for viem.\n */\nexport const RollupBytecode = \"" >> ./src/viem-contracts/Rollup.ts; +jq -j '.bytecode.object' ../../l1-contracts/out/Rollup.sol/Rollup.json >> ./src/viem-contracts/Rollup.ts; +echo "\";" >> ./src/viem-contracts/Rollup.ts; + +echo -ne "/**\n * UnverifiedDataEmitter ABI for viem.\n */\nexport const UnverifiedDataEmitterAbi = " > ./src/viem-contracts/UnverifiedDataEmitter.ts; +jq -j '.abi' ../../l1-contracts/out/UnverifiedDataEmitter.sol/UnverifiedDataEmitter.json >> ./src/viem-contracts/UnverifiedDataEmitter.ts; +echo " as const;" >> ./src/viem-contracts/UnverifiedDataEmitter.ts; +echo -ne "/**\n * UnverifiedDataEmitter Bytecode for viem.\n */\nexport const UnverifiedDataEmitterBytecode = \"" >> ./src/viem-contracts/UnverifiedDataEmitter.ts; +jq -j '.bytecode.object' ../../l1-contracts/out/UnverifiedDataEmitter.sol/UnverifiedDataEmitter.json >> ./src/viem-contracts/UnverifiedDataEmitter.ts; +echo "\";" >> ./src/viem-contracts/UnverifiedDataEmitter.ts; \ No newline at end of file diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelper.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelper.ts new file mode 100644 index 000000000000..c942acf16ad2 --- /dev/null +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelper.ts @@ -0,0 +1,36 @@ +// THIS IS GENERATED CODE, DO NOT EDIT! +/* eslint-disable */ +import { EthAddress } from '@aztec/foundation'; +import { EthereumRpc } from '@aztec/ethereum.js/eth_rpc'; +import { Contract, ContractTxReceipt, EventLog, Options, TxCall, TxSend } from '@aztec/ethereum.js/contract'; +import * as Bytes from '@aztec/ethereum.js/contract/bytes.js'; +import abi from './DecoderHelperAbi.js'; +interface DecoderHelperEvents {} +interface DecoderHelperEventLogs {} +interface DecoderHelperTxEventLogs {} +export interface DecoderHelperTransactionReceipt extends ContractTxReceipt {} +interface DecoderHelperMethods { + computeDiffRoot(_l2Block: Bytes.Bytes): TxCall; + decode(_l2Block: Bytes.Bytes): TxCall<{ + 0: bigint; + 1: Bytes.Bytes32; + 2: Bytes.Bytes32; + 3: Bytes.Bytes32; + }>; +} +export interface DecoderHelperDefinition { + methods: DecoderHelperMethods; + events: DecoderHelperEvents; + eventLogs: DecoderHelperEventLogs; +} +export class DecoderHelper extends Contract { + constructor(eth: EthereumRpc, address?: EthAddress, options?: Options) { + super(eth, abi, address, options); + } + deploy(): TxSend { + return super.deployBytecode( + '0x608060405234801561001057600080fd5b506109fb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634f93f40e1461003b578063e5c5e9a314610061575b600080fd5b61004e610049366004610745565b610094565b6040519081526020015b60405180910390f35b61007461006f366004610745565b6100a9565b604080519485526020850193909352918301526060820152608001610058565b60006100a083836100c9565b90505b92915050565b6000806000806100b98686610414565b9299919850965090945092505050565b60006100f66040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061014c600460026107cd565b825161015891906107fa565b67ffffffffffffffff8111156101705761017061080e565b604051908082528060200260200182016040528015610199578160200160208202803683370190505b5082519091506101b0906000906101b19060206107cd565b6101bc836004610824565b6101c69190610824565b90506000846020015160206101db91906107cd565b6101e6836004610824565b6101f09190610824565b905060008560400151604061020591906107cd565b610210836004610824565b61021a9190610824565b905060008660600151602061022f91906107cd565b6102399083610824565b905060005b86518110156103fc57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f8701605401918501013750610305600460026107cd565b6103109060206107cd565b61031a9088610824565b9650610328600460026107cd565b6103339060206107cd565b61033d9087610824565b955061034b600460026107cd565b6103569060406107cd565b6103609086610824565b945061036d604085610824565b935061037a606884610824565b925060028160405161038c9190610837565b602060405180830381855afa1580156103a9573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103cc9190610866565b8883815181106103de576103de61087f565b602090810291909101015250806103f481610895565b91505061023e565b506104068661045a565b9a9950505050505050505050565b813560e01c6000808061043461042b6001866108ae565b600488886105d2565b92506104438460d888886105d2565b915061044f868661067d565b905092959194509250565b6000805b825161046b8260026109a5565b1015610483578061047b81610895565b91505061045e565b60006104908260026109a5565b905080845260005b828110156105ad5760005b8281101561059a5760028682815181106104bf576104bf61087f565b6020026020010151878360016104d59190610824565b815181106104e5576104e561087f565b6020026020010151604051602001610507929190918252602082015260400190565b60408051601f198184030181529082905261052191610837565b602060405180830381855afa15801561053e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105619190610866565b8661056d6002846107fa565b8151811061057d5761057d61087f565b6020908102919091010152610593600282610824565b90506104a3565b50806105a581610895565b915050610498565b50836000815181106105c1576105c161087f565b602002602001015192505050919050565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516106339190610837565b602060405180830381855afa158015610650573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106739190610866565b9695505050505050565b604080516101c88082526102008201909252600091908290826020820181803683370190505090508160048601602083013760006106bb86866100c9565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516106fb9190610837565b602060405180830381855afa158015610718573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061073b9190610866565b61067391906109b1565b6000806020838503121561075857600080fd5b823567ffffffffffffffff8082111561077057600080fd5b818501915085601f83011261078457600080fd5b81358181111561079357600080fd5b8660208285010111156107a557600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176100a3576100a36107b7565b634e487b7160e01b600052601260045260246000fd5b600082610809576108096107e4565b500490565b634e487b7160e01b600052604160045260246000fd5b808201808211156100a3576100a36107b7565b6000825160005b81811015610858576020818601810151858301520161083e565b506000920191825250919050565b60006020828403121561087857600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000600182016108a7576108a76107b7565b5060010190565b818103818111156100a3576100a36107b7565b600181815b808511156108fc5781600019048211156108e2576108e26107b7565b808516156108ef57918102915b93841c93908002906108c6565b509250929050565b600082610913575060016100a3565b81610920575060006100a3565b816001811461093657600281146109405761095c565b60019150506100a3565b60ff841115610951576109516107b7565b50506001821b6100a3565b5060208310610133831016604e8410600b841016171561097f575081810a6100a3565b61098983836108c1565b806000190482111561099d5761099d6107b7565b029392505050565b60006100a08383610904565b6000826109c0576109c06107e4565b50069056fea26469706673582212202ef99c8a34102a8b892857ef4d2ff1773f31770e89ceca60a0bea54a127104f064736f6c63430008120033', + ) as any; + } +} +export var DecoderHelperAbi = abi; diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelperAbi.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelperAbi.ts new file mode 100644 index 000000000000..bc6ba0393e63 --- /dev/null +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/DecoderHelperAbi.ts @@ -0,0 +1,56 @@ +import { ContractAbi } from '@aztec/ethereum.js/contract'; +export default new ContractAbi([ + { + inputs: [ + { + internalType: 'bytes', + name: '_l2Block', + type: 'bytes', + }, + ], + name: 'computeDiffRoot', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_l2Block', + type: 'bytes', + }, + ], + name: 'decode', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'pure', + type: 'function', + }, +]); diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts index 76f69eb86ce2..5277921c1297 100644 --- a/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts @@ -35,7 +35,7 @@ export class Rollup extends Contract { } deploy(): TxSend { return super.deployBytecode( - '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d806102cf83390190565b60805161025d6100726000396000604b015261025d6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461014c565b6100b6565b005b604051823560e01c9081907f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf390600090a250505050565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261011557600080fd5b50813567ffffffffffffffff81111561012d57600080fd5b60208301915083602082850101111561014557600080fd5b9250929050565b60008060006040848603121561016157600080fd5b833567ffffffffffffffff8082111561017957600080fd5b818601915086601f83011261018d57600080fd5b81358181111561019f5761019f6100ed565b604051601f8201601f19908116603f011681019083821181831017156101c7576101c76100ed565b816040528281528960208487010111156101e057600080fd5b82602086016020830137600060208483010152809750505050602086013591508082111561020d57600080fd5b5061021a86828701610103565b949790965093945050505056fea264697066735822122063bf5f2228c31f0838547369bdc2b91bb35be32ee80fa5c2eb53cd176b575a3464736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033', + '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610d5483390190565b608051610cdb61007960003960008181604b015261016b0152610cdb6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461091e565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508181600081518110610149576101496109f9565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b908590600401610a33565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610aad565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610aec565b6004888861027d565b92506102668460d8888861027d565b91506102728686610328565b905092959194509250565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516102de9190610aff565b602060405180830381855afa1580156102fb573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061031e9190610b1b565b9695505050505050565b604080516101c880825261020082019092526000919082908260208201818036833701905050905081600486016020830137600061036686866103fc565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516103a69190610aff565b602060405180830381855afa1580156103c3573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103e69190610b1b565b6103f09190610b4a565b93505050505b92915050565b60006104296040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061047f60046002610b5e565b825161048b9190610b75565b67ffffffffffffffff8111156104a3576104a36108bf565b6040519080825280602002602001820160405280156104cc578160200160208202803683370190505b5082519091506101b0906000906104e4906020610b5e565b6104ef836004610b89565b6104f99190610b89565b905060008460200151602061050e9190610b5e565b610519836004610b89565b6105239190610b89565b90506000856040015160406105389190610b5e565b610543836004610b89565b61054d9190610b89565b90506000866060015160206105629190610b5e565b61056c9083610b89565b905060005b865181101561072f57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f870160540191850101375061063860046002610b5e565b610643906020610b5e565b61064d9088610b89565b965061065b60046002610b5e565b610666906020610b5e565b6106709087610b89565b955061067e60046002610b5e565b610689906040610b5e565b6106939086610b89565b94506106a0604085610b89565b93506106ad606884610b89565b92506002816040516106bf9190610aff565b602060405180830381855afa1580156106dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106ff9190610b1b565b888381518110610711576107116109f9565b6020908102919091010152508061072781610b9c565b915050610571565b5061073986610747565b9a9950505050505050505050565b6000805b8251610758826002610c99565b1015610770578061076881610b9c565b91505061074b565b600061077d826002610c99565b905080845260005b8281101561089a5760005b828110156108875760028682815181106107ac576107ac6109f9565b6020026020010151878360016107c29190610b89565b815181106107d2576107d26109f9565b60200260200101516040516020016107f4929190918252602082015260400190565b60408051601f198184030181529082905261080e91610aff565b602060405180830381855afa15801561082b573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061084e9190610b1b565b8661085a600284610b75565b8151811061086a5761086a6109f9565b6020908102919091010152610880600282610b89565b9050610790565b508061089281610b9c565b915050610785565b50836000815181106108ae576108ae6109f9565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f8401126108e757600080fd5b50813567ffffffffffffffff8111156108ff57600080fd5b60208301915083602082850101111561091757600080fd5b9250929050565b60008060006040848603121561093357600080fd5b833567ffffffffffffffff8082111561094b57600080fd5b818601915086601f83011261095f57600080fd5b813581811115610971576109716108bf565b604051601f8201601f19908116603f01168101908382118183101715610999576109996108bf565b816040528281528960208487010111156109b257600080fd5b8260208601602083013760006020848301015280975050505060208601359150808211156109df57600080fd5b506109ec868287016108d5565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b83811015610a2a578181015183820152602001610a12565b50506000910152565b60408152600083518060408401526020610a538260608601838901610a0f565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610aa15784518252938301936001929092019190830190610a81565b50979650505050505050565b600060208284031215610abf57600080fd5b81518015158114610acf57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156103f6576103f6610ad6565b60008251610b11818460208701610a0f565b9190910192915050565b600060208284031215610b2d57600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610b5957610b59610b34565b500690565b80820281158282048414176103f6576103f6610ad6565b600082610b8457610b84610b34565b500490565b808201808211156103f6576103f6610ad6565b600060018201610bae57610bae610ad6565b5060010190565b600181815b80851115610bf0578160001904821115610bd657610bd6610ad6565b80851615610be357918102915b93841c9390800290610bba565b509250929050565b600082610c07575060016103f6565b81610c14575060006103f6565b8160018114610c2a5760028114610c3457610c50565b60019150506103f6565b60ff841115610c4557610c45610ad6565b50506001821b6103f6565b5060208310610133831016604e8410600b8410161715610c73575081810a6103f6565b610c7d8383610bb5565b8060001904821115610c9157610c91610ad6565b029392505050565b6000610acf8383610bf856fea2646970667358221220ddf248ba6894d5466329c62aa3e8d071d039ec5f5594b21af88ea780d45fefb364736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033', ) as any; } } diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/UnverifiedDataEmitter.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/UnverifiedDataEmitter.ts index 42a394158771..364ecaecf266 100644 --- a/yarn-project/l1-contracts/src/ethereumjs-contracts/UnverifiedDataEmitter.ts +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/UnverifiedDataEmitter.ts @@ -51,7 +51,7 @@ export class UnverifiedDataEmitter extends Contract { return super.deployBytecode( - '0x608060405234801561001057600080fd5b50610258806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063ec1c72ff1461003b578063f3f53b3a14610050575b600080fd5b61004e61004936600461013f565b610063565b005b61004e61005e36600461018b565b6100ac565b336001600160a01b0316837fb72b85ef2a843244f5ea1955248b0ac363732d2e6a98cc3641084dd5718ad8b5848460405161009f9291906101f3565b60405180910390a3505050565b826001600160a01b0316847f30735f52bf1ff4d542583f894902a2775489f644723a4b3cca1de6d6eabd0c4a84846040516100e89291906101f3565b60405180910390a350505050565b60008083601f84011261010857600080fd5b50813567ffffffffffffffff81111561012057600080fd5b60208301915083602082850101111561013857600080fd5b9250929050565b60008060006040848603121561015457600080fd5b83359250602084013567ffffffffffffffff81111561017257600080fd5b61017e868287016100f6565b9497909650939450505050565b600080600080606085870312156101a157600080fd5b8435935060208501356001600160a01b03811681146101bf57600080fd5b9250604085013567ffffffffffffffff8111156101db57600080fd5b6101e7878288016100f6565b95989497509550505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f1916010191905056fea2646970667358221220b4668eba21fe4e02e4a0ab3b4d1c9cdd827470b2961b1e2da0dba0ace9f4331064736f6c63430008120033', + '0x608060405234801561001057600080fd5b50610268806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631beadbf61461003b578063ec1c72ff14610050575b600080fd5b61004e610049366004610141565b610063565b005b61004e61005e3660046101b7565b6100af565b826001600160a01b031684867fc6da1a507344f9e421450cb8075906fe777b6411c1918306f6018ebb4d6b7e3785856040516100a0929190610203565b60405180910390a45050505050565b336001600160a01b0316837fb72b85ef2a843244f5ea1955248b0ac363732d2e6a98cc3641084dd5718ad8b584846040516100eb929190610203565b60405180910390a3505050565b60008083601f84011261010a57600080fd5b50813567ffffffffffffffff81111561012257600080fd5b60208301915083602082850101111561013a57600080fd5b9250929050565b60008060008060006080868803121561015957600080fd5b853594506020860135935060408601356001600160a01b038116811461017e57600080fd5b9250606086013567ffffffffffffffff81111561019a57600080fd5b6101a6888289016100f8565b969995985093965092949392505050565b6000806000604084860312156101cc57600080fd5b83359250602084013567ffffffffffffffff8111156101ea57600080fd5b6101f6868287016100f8565b9497909650939450505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f1916010191905056fea2646970667358221220444c01fee3697b99865e7d7c596fde10e007e4e7e2a1ea003b06c9290c8b67c564736f6c63430008120033', ) as any; } } diff --git a/yarn-project/l1-contracts/src/index.ts b/yarn-project/l1-contracts/src/index.ts index 8dacbcedc253..437c2e2e31a1 100644 --- a/yarn-project/l1-contracts/src/index.ts +++ b/yarn-project/l1-contracts/src/index.ts @@ -17,5 +17,6 @@ export interface L1Addresses { unverifiedDataEmitterContract: EthAddress; } +export * from './ethereumjs-contracts/DecoderHelper.js'; export * from './ethereumjs-contracts/Rollup.js'; export * from './ethereumjs-contracts/UnverifiedDataEmitter.js'; diff --git a/yarn-project/l1-contracts/src/viem-contracts/DecoderHelper.ts b/yarn-project/l1-contracts/src/viem-contracts/DecoderHelper.ts new file mode 100644 index 000000000000..fddfb2ee2717 --- /dev/null +++ b/yarn-project/l1-contracts/src/viem-contracts/DecoderHelper.ts @@ -0,0 +1,63 @@ +/** + * DecoderHelper ABI for viem. + */ +export const DecoderHelperAbi = [ + { + inputs: [ + { + internalType: 'bytes', + name: '_l2Block', + type: 'bytes', + }, + ], + name: 'computeDiffRoot', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_l2Block', + type: 'bytes', + }, + ], + name: 'decode', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'pure', + type: 'function', + }, +] as const; +/** + * DecoderHelper Bytecode for viem. + */ +export const DecoderHelperBytecode = + '0x608060405234801561001057600080fd5b506109fb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634f93f40e1461003b578063e5c5e9a314610061575b600080fd5b61004e610049366004610745565b610094565b6040519081526020015b60405180910390f35b61007461006f366004610745565b6100a9565b604080519485526020850193909352918301526060820152608001610058565b60006100a083836100c9565b90505b92915050565b6000806000806100b98686610414565b9299919850965090945092505050565b60006100f66040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061014c600460026107cd565b825161015891906107fa565b67ffffffffffffffff8111156101705761017061080e565b604051908082528060200260200182016040528015610199578160200160208202803683370190505b5082519091506101b0906000906101b19060206107cd565b6101bc836004610824565b6101c69190610824565b90506000846020015160206101db91906107cd565b6101e6836004610824565b6101f09190610824565b905060008560400151604061020591906107cd565b610210836004610824565b61021a9190610824565b905060008660600151602061022f91906107cd565b6102399083610824565b905060005b86518110156103fc57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f8701605401918501013750610305600460026107cd565b6103109060206107cd565b61031a9088610824565b9650610328600460026107cd565b6103339060206107cd565b61033d9087610824565b955061034b600460026107cd565b6103569060406107cd565b6103609086610824565b945061036d604085610824565b935061037a606884610824565b925060028160405161038c9190610837565b602060405180830381855afa1580156103a9573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103cc9190610866565b8883815181106103de576103de61087f565b602090810291909101015250806103f481610895565b91505061023e565b506104068661045a565b9a9950505050505050505050565b813560e01c6000808061043461042b6001866108ae565b600488886105d2565b92506104438460d888886105d2565b915061044f868661067d565b905092959194509250565b6000805b825161046b8260026109a5565b1015610483578061047b81610895565b91505061045e565b60006104908260026109a5565b905080845260005b828110156105ad5760005b8281101561059a5760028682815181106104bf576104bf61087f565b6020026020010151878360016104d59190610824565b815181106104e5576104e561087f565b6020026020010151604051602001610507929190918252602082015260400190565b60408051601f198184030181529082905261052191610837565b602060405180830381855afa15801561053e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105619190610866565b8661056d6002846107fa565b8151811061057d5761057d61087f565b6020908102919091010152610593600282610824565b90506104a3565b50806105a581610895565b915050610498565b50836000815181106105c1576105c161087f565b602002602001015192505050919050565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516106339190610837565b602060405180830381855afa158015610650573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106739190610866565b9695505050505050565b604080516101c88082526102008201909252600091908290826020820181803683370190505090508160048601602083013760006106bb86866100c9565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516106fb9190610837565b602060405180830381855afa158015610718573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061073b9190610866565b61067391906109b1565b6000806020838503121561075857600080fd5b823567ffffffffffffffff8082111561077057600080fd5b818501915085601f83011261078457600080fd5b81358181111561079357600080fd5b8660208285010111156107a557600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176100a3576100a36107b7565b634e487b7160e01b600052601260045260246000fd5b600082610809576108096107e4565b500490565b634e487b7160e01b600052604160045260246000fd5b808201808211156100a3576100a36107b7565b6000825160005b81811015610858576020818601810151858301520161083e565b506000920191825250919050565b60006020828403121561087857600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000600182016108a7576108a76107b7565b5060010190565b818103818111156100a3576100a36107b7565b600181815b808511156108fc5781600019048211156108e2576108e26107b7565b808516156108ef57918102915b93841c93908002906108c6565b509250929050565b600082610913575060016100a3565b81610920575060006100a3565b816001811461093657600281146109405761095c565b60019150506100a3565b60ff841115610951576109516107b7565b50506001821b6100a3565b5060208310610133831016604e8410600b841016171561097f575081810a6100a3565b61098983836108c1565b806000190482111561099d5761099d6107b7565b029392505050565b60006100a08383610904565b6000826109c0576109c06107e4565b50069056fea26469706673582212202ef99c8a34102a8b892857ef4d2ff1773f31770e89ceca60a0bea54a127104f064736f6c63430008120033'; diff --git a/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts b/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts index 859977a12948..843bfd9b2a7a 100644 --- a/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts +++ b/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts @@ -86,6 +86,8 @@ export const RollupAbi = [ type: 'function', }, ] as const; - +/** + * Rollup Bytecode for viem. + */ export const RollupBytecode = - '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d806102cf83390190565b60805161025d6100726000396000604b015261025d6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461014c565b6100b6565b005b604051823560e01c9081907f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf390600090a250505050565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261011557600080fd5b50813567ffffffffffffffff81111561012d57600080fd5b60208301915083602082850101111561014557600080fd5b9250929050565b60008060006040848603121561016157600080fd5b833567ffffffffffffffff8082111561017957600080fd5b818601915086601f83011261018d57600080fd5b81358181111561019f5761019f6100ed565b604051601f8201601f19908116603f011681019083821181831017156101c7576101c76100ed565b816040528281528960208487010111156101e057600080fd5b82602086016020830137600060208483010152809750505050602086013591508082111561020d57600080fd5b5061021a86828701610103565b949790965093945050505056fea264697066735822122063bf5f2228c31f0838547369bdc2b91bb35be32ee80fa5c2eb53cd176b575a3464736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033'; + '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610d5483390190565b608051610cdb61007960003960008181604b015261016b0152610cdb6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461091e565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508181600081518110610149576101496109f9565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b908590600401610a33565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610aad565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610aec565b6004888861027d565b92506102668460d8888861027d565b91506102728686610328565b905092959194509250565b6040805160d880825261010082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360d485850160248301376002816040516102de9190610aff565b602060405180830381855afa1580156102fb573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061031e9190610b1b565b9695505050505050565b604080516101c880825261020082019092526000919082908260208201818036833701905050905081600486016020830137600061036686866103fc565b90508060046101ac036020018301527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016002836040516103a69190610aff565b602060405180830381855afa1580156103c3573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103e69190610b1b565b6103f09190610b4a565b93505050505b92915050565b60006104296040518060800160405280600081526020016000815260200160008152602001600081525090565b6101ac84013560e090811c808352602090810286016101b0810135831c848301819052918202016101b4810135831c604085810191909152909102016101b80135901c6060820152600061047f60046002610b5e565b825161048b9190610b75565b67ffffffffffffffff8111156104a3576104a36108bf565b6040519080825280602002602001820160405280156104cc578160200160208202803683370190505b5082519091506101b0906000906104e4906020610b5e565b6104ef836004610b89565b6104f99190610b89565b905060008460200151602061050e9190610b5e565b610519836004610b89565b6105239190610b89565b90506000856040015160406105389190610b5e565b610543836004610b89565b61054d9190610b89565b90506000866060015160206105629190610b5e565b61056c9083610b89565b905060005b865181101561072f57604080516104c08082526104e0820190925260009160208201818036833701905050905060206101008d890182840137610100818101918e890190840182013761010081810191610200918f89019185010137610200818101916040918f880191850101376020600202810190506020848e0182840137602c808201916014918f870160200191850101376020810190506020603485018e0182840137602c808201916014918f870160540191850101375061063860046002610b5e565b610643906020610b5e565b61064d9088610b89565b965061065b60046002610b5e565b610666906020610b5e565b6106709087610b89565b955061067e60046002610b5e565b610689906040610b5e565b6106939086610b89565b94506106a0604085610b89565b93506106ad606884610b89565b92506002816040516106bf9190610aff565b602060405180830381855afa1580156106dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106ff9190610b1b565b888381518110610711576107116109f9565b6020908102919091010152508061072781610b9c565b915050610571565b5061073986610747565b9a9950505050505050505050565b6000805b8251610758826002610c99565b1015610770578061076881610b9c565b91505061074b565b600061077d826002610c99565b905080845260005b8281101561089a5760005b828110156108875760028682815181106107ac576107ac6109f9565b6020026020010151878360016107c29190610b89565b815181106107d2576107d26109f9565b60200260200101516040516020016107f4929190918252602082015260400190565b60408051601f198184030181529082905261080e91610aff565b602060405180830381855afa15801561082b573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061084e9190610b1b565b8661085a600284610b75565b8151811061086a5761086a6109f9565b6020908102919091010152610880600282610b89565b9050610790565b508061089281610b9c565b915050610785565b50836000815181106108ae576108ae6109f9565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f8401126108e757600080fd5b50813567ffffffffffffffff8111156108ff57600080fd5b60208301915083602082850101111561091757600080fd5b9250929050565b60008060006040848603121561093357600080fd5b833567ffffffffffffffff8082111561094b57600080fd5b818601915086601f83011261095f57600080fd5b813581811115610971576109716108bf565b604051601f8201601f19908116603f01168101908382118183101715610999576109996108bf565b816040528281528960208487010111156109b257600080fd5b8260208601602083013760006020848301015280975050505060208601359150808211156109df57600080fd5b506109ec868287016108d5565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b83811015610a2a578181015183820152602001610a12565b50506000910152565b60408152600083518060408401526020610a538260608601838901610a0f565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610aa15784518252938301936001929092019190830190610a81565b50979650505050505050565b600060208284031215610abf57600080fd5b81518015158114610acf57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156103f6576103f6610ad6565b60008251610b11818460208701610a0f565b9190910192915050565b600060208284031215610b2d57600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610b5957610b59610b34565b500690565b80820281158282048414176103f6576103f6610ad6565b600082610b8457610b84610b34565b500490565b808201808211156103f6576103f6610ad6565b600060018201610bae57610bae610ad6565b5060010190565b600181815b80851115610bf0578160001904821115610bd657610bd6610ad6565b80851615610be357918102915b93841c9390800290610bba565b509250929050565b600082610c07575060016103f6565b81610c14575060006103f6565b8160018114610c2a5760028114610c3457610c50565b60019150506103f6565b60ff841115610c4557610c45610ad6565b50506001821b6103f6565b5060208310610133831016604e8410600b8410161715610c73575081810a6103f6565b610c7d8383610bb5565b8060001904821115610c9157610c91610ad6565b029392505050565b6000610acf8383610bf856fea2646970667358221220ddf248ba6894d5466329c62aa3e8d071d039ec5f5594b21af88ea780d45fefb364736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033'; diff --git a/yarn-project/l1-contracts/src/viem-contracts/UnverifiedDataEmitter.ts b/yarn-project/l1-contracts/src/viem-contracts/UnverifiedDataEmitter.ts index 11a768fc7aae..eecafc00f2a9 100644 --- a/yarn-project/l1-contracts/src/viem-contracts/UnverifiedDataEmitter.ts +++ b/yarn-project/l1-contracts/src/viem-contracts/UnverifiedDataEmitter.ts @@ -105,6 +105,8 @@ export const UnverifiedDataEmitterAbi = [ type: 'function', }, ] as const; - +/** + * UnverifiedDataEmitter Bytecode for viem. + */ export const UnverifiedDataEmitterBytecode = - '0x608060405234801561001057600080fd5b50610258806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063ec1c72ff1461003b578063f3f53b3a14610050575b600080fd5b61004e61004936600461013f565b610063565b005b61004e61005e36600461018b565b6100ac565b336001600160a01b0316837fb72b85ef2a843244f5ea1955248b0ac363732d2e6a98cc3641084dd5718ad8b5848460405161009f9291906101f3565b60405180910390a3505050565b826001600160a01b0316847f30735f52bf1ff4d542583f894902a2775489f644723a4b3cca1de6d6eabd0c4a84846040516100e89291906101f3565b60405180910390a350505050565b60008083601f84011261010857600080fd5b50813567ffffffffffffffff81111561012057600080fd5b60208301915083602082850101111561013857600080fd5b9250929050565b60008060006040848603121561015457600080fd5b83359250602084013567ffffffffffffffff81111561017257600080fd5b61017e868287016100f6565b9497909650939450505050565b600080600080606085870312156101a157600080fd5b8435935060208501356001600160a01b03811681146101bf57600080fd5b9250604085013567ffffffffffffffff8111156101db57600080fd5b6101e7878288016100f6565b95989497509550505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f1916010191905056fea2646970667358221220b4668eba21fe4e02e4a0ab3b4d1c9cdd827470b2961b1e2da0dba0ace9f4331064736f6c63430008120033'; + '0x608060405234801561001057600080fd5b50610268806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80631beadbf61461003b578063ec1c72ff14610050575b600080fd5b61004e610049366004610141565b610063565b005b61004e61005e3660046101b7565b6100af565b826001600160a01b031684867fc6da1a507344f9e421450cb8075906fe777b6411c1918306f6018ebb4d6b7e3785856040516100a0929190610203565b60405180910390a45050505050565b336001600160a01b0316837fb72b85ef2a843244f5ea1955248b0ac363732d2e6a98cc3641084dd5718ad8b584846040516100eb929190610203565b60405180910390a3505050565b60008083601f84011261010a57600080fd5b50813567ffffffffffffffff81111561012257600080fd5b60208301915083602082850101111561013a57600080fd5b9250929050565b60008060008060006080868803121561015957600080fd5b853594506020860135935060408601356001600160a01b038116811461017e57600080fd5b9250606086013567ffffffffffffffff81111561019a57600080fd5b6101a6888289016100f8565b969995985093965092949392505050565b6000806000604084860312156101cc57600080fd5b83359250602084013567ffffffffffffffff8111156101ea57600080fd5b6101f6868287016100f8565b9497909650939450505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f1916010191905056fea2646970667358221220444c01fee3697b99865e7d7c596fde10e007e4e7e2a1ea003b06c9290c8b67c564736f6c63430008120033'; diff --git a/yarn-project/l1-contracts/src/viem-contracts/index.ts b/yarn-project/l1-contracts/src/viem-contracts/index.ts index 43e94baa5ead..f253ede7ed55 100644 --- a/yarn-project/l1-contracts/src/viem-contracts/index.ts +++ b/yarn-project/l1-contracts/src/viem-contracts/index.ts @@ -1,2 +1,3 @@ +export * from './DecoderHelper.js'; export * from './Rollup.js'; export * from './UnverifiedDataEmitter.js'; diff --git a/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts b/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts index a5fe0f26f0c3..e0b478088c6b 100644 --- a/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts +++ b/yarn-project/sequencer-client/src/test/l2-block-publisher.test.ts @@ -1,11 +1,35 @@ import { EthereumRpc } from '@aztec/ethereum.js/eth_rpc'; import { WalletProvider } from '@aztec/ethereum.js/provider'; -import { Rollup, UnverifiedDataEmitter } from '@aztec/l1-contracts'; +import { DecoderHelper, Rollup, UnverifiedDataEmitter } from '@aztec/l1-contracts'; import { beforeAll, describe, expect, it } from '@jest/globals'; import { EthereumjsTxSender } from '../publisher/ethereumjs-tx-sender.js'; import { L1Publisher } from '../publisher/l1-publisher.js'; import { hexStringToBuffer } from '../utils.js'; -import { L2Block } from '@aztec/types'; +import { Tx } from '@aztec/types'; +import { ProcessedTx, makeEmptyProcessedTx, makeProcessedTx } from '../sequencer/processed_tx.js'; +import { + makeBaseRollupPublicInputs, + makeKernelPublicInputs, + makeRootRollupPublicInputs, +} from '@aztec/circuits.js/factories'; +import { + AppendOnlyTreeSnapshot, + BaseOrMergeRollupPublicInputs, + BaseRollupInputs, + CircuitsWasm, + Fr, + RootRollupPublicInputs, + UInt8Vector, +} from '@aztec/circuits.js'; +import { getVerificationKeys, makeEmptyUnverifiedData } from '../index.js'; +import { MerkleTreeId, MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; +import { createMemDown } from '../block_builder/circuit_block_builder.test.js'; +import { default as levelup } from 'levelup'; +import { CircuitBlockBuilder } from '../block_builder/circuit_block_builder.js'; +import { computeContractLeaf } from '@aztec/circuits.js/abis'; +import flatMap from 'lodash.flatmap'; +import { EmptyRollupProver } from '../prover/empty.js'; +import { WasmRollupCircuitSimulator } from '../simulator/rollup.js'; // Accounts 4 and 5 of Anvil default startup with mnemonic: 'test test test test test test test test test test test junk' const sequencerPK = '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a'; @@ -14,17 +38,38 @@ const anvilHost = process.env.ANVIL_HOST ?? 'http://127.0.0.1:8545'; const chainId = 31337; describe.skip('L1Publisher integration', () => { + let decoderHelper: DecoderHelper; let rollup: Rollup; let unverifiedDataEmitter: UnverifiedDataEmitter; let ethRpc: EthereumRpc; let publisher: L1Publisher; - let l2Block: L2Block; let l2Proof: Buffer; + const emptyProof = new UInt8Vector(Buffer.alloc(32, 0)); + let baseRollupOutputLeft: BaseOrMergeRollupPublicInputs; + let baseRollupOutputRight: BaseOrMergeRollupPublicInputs; + let rootRollupOutput: RootRollupPublicInputs; + let builder: TestSubject; + let builderDb: MerkleTreeOperations; + let expectsDb: MerkleTreeOperations; + let wasm: CircuitsWasm; + beforeAll(async () => { - ({ ethRpc, rollup, unverifiedDataEmitter } = await deployRollup()); + ({ ethRpc, decoderHelper, rollup, unverifiedDataEmitter } = await deployRollup()); + + builderDb = await MerkleTrees.new(levelup(createMemDown())).then(t => t.asLatest()); + expectsDb = await MerkleTrees.new(levelup(createMemDown())).then(t => t.asLatest()); + wasm = await CircuitsWasm.get(); + const vks = getVerificationKeys(); + const simulator = await WasmRollupCircuitSimulator.new(); + const prover = new EmptyRollupProver(); + builder = new TestSubject(builderDb, vks, simulator, prover); + await updateRootTrees(); + await builder.updateRootTrees(); - l2Block = L2Block.random(42); + baseRollupOutputLeft = makeBaseRollupPublicInputs(); + baseRollupOutputRight = makeBaseRollupPublicInputs(); + rootRollupOutput = makeRootRollupPublicInputs(); l2Proof = Buffer.alloc(0); publisher = new L1Publisher( @@ -40,20 +85,120 @@ describe.skip('L1Publisher integration', () => { retryIntervalMs: 100, }, ); - }); + }, 60_000); - it('publishes l2 block data to l1 rollup contract', async () => { - const blockNumber = await ethRpc.blockNumber(); - await publisher.processL2Block(l2Block); + it('Build 2 blocks of 4 txs building on each other', async () => { + const stateInRollup_ = await rollup.methods.rollupStateHash().call(); + expect(hexStringToBuffer(stateInRollup_.toString())).toEqual(Buffer.alloc(32, 0)); - const logs = await rollup.getLogs('L2BlockProcessed', { fromBlock: blockNumber }); - expect(logs).toHaveLength(1); - expect(logs[0].args.blockNum).toEqual(42n); + for (let i = 0; i < 2; i++) { + const tx = await makeProcessedTx( + Tx.createPrivate(makeKernelPublicInputs(1 + i), emptyProof, makeEmptyUnverifiedData()), + ); - const tx = await ethRpc.getTransactionByHash(logs[0].transactionHash!); - const expectedData = rollup.methods.process(l2Proof, l2Block.encode()).encodeABI(); - expect(tx.input).toEqual(expectedData); - }); + const txsLeft = [tx, await makeEmptyProcessedTx()]; + const txsRight = [await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; + + // Set tree roots to proper values in the tx + await setTxHistoricTreeRoots(tx); + + // Calculate what would be the tree roots after the txs from the first base rollup land and update mock circuit output + await updateExpectedTreesFromTxs(txsLeft); + baseRollupOutputLeft.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + baseRollupOutputLeft.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); + baseRollupOutputLeft.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); + + // Same for the two txs on the right + await updateExpectedTreesFromTxs(txsRight); + baseRollupOutputRight.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + baseRollupOutputRight.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); + baseRollupOutputRight.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); + + // And update the root trees now to create proper output to the root rollup circuit + await updateRootTrees(); + rootRollupOutput.endContractTreeSnapshot = await getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + rootRollupOutput.endNullifierTreeSnapshot = await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); + rootRollupOutput.endPrivateDataTreeSnapshot = await getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); + rootRollupOutput.endTreeOfHistoricContractTreeRootsSnapshot = await getTreeSnapshot( + MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, + ); + rootRollupOutput.endTreeOfHistoricPrivateDataTreeRootsSnapshot = await getTreeSnapshot( + MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, + ); + + // Actually build a block! + const txs = [tx, await makeEmptyProcessedTx(), await makeEmptyProcessedTx(), await makeEmptyProcessedTx()]; + // Here we die. + const [block] = await builder.buildL2Block(1 + i, txs); + + // Now we can use the block we built! + const blockNumber = await ethRpc.blockNumber(); + await publisher.processL2Block(block); + const logs = await rollup.getLogs('L2BlockProcessed', { fromBlock: blockNumber + 1 }); + expect(logs).toHaveLength(1); + expect(logs[0].args.blockNum).toEqual(BigInt(i + 1)); + + const ethTx = await ethRpc.getTransactionByHash(logs[0].transactionHash!); + const expectedData = rollup.methods.process(l2Proof, block.encode()).encodeABI(); + expect(ethTx.input).toEqual(expectedData); + + const decodedCalldataHash = await decoderHelper.methods.computeDiffRoot(block.encode()).call(); + const decodedRes = await decoderHelper.methods.decode(block.encode()).call(); + const stateInRollup = await rollup.methods.rollupStateHash().call(); + + // @note There seems to be something wrong here. The Bytes32 returned are actually strings :( + expect(block.number).toEqual(Number(decodedRes[0])); + expect(block.getStartStateHash()).toEqual(hexStringToBuffer(decodedRes[1].toString())); + expect(block.getEndStateHash()).toEqual(hexStringToBuffer(decodedRes[2].toString())); + expect(block.getEndStateHash()).toEqual(hexStringToBuffer(stateInRollup.toString())); + expect(block.getPublicInputsHash().toBuffer()).toEqual(hexStringToBuffer(decodedRes[3].toString())); + expect(block.getCalldataHash()).toEqual(hexStringToBuffer(decodedCalldataHash.toString())); + } + }, 60_000); + + // BELOW IS FUNCTIONS STOLEN FROM `circuit_block_builder.test.ts`. + + const updateRootTrees = async () => { + for (const [newTree, rootTree] of [ + [MerkleTreeId.PRIVATE_DATA_TREE, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE], + [MerkleTreeId.CONTRACT_TREE, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE], + ] as const) { + const newTreeInfo = await expectsDb.getTreeInfo(newTree); + await expectsDb.appendLeaves(rootTree, [newTreeInfo.root]); + } + }; + + // Updates the expectedDb trees based on the new commitments, contracts, and nullifiers from these txs + const updateExpectedTreesFromTxs = async (txs: ProcessedTx[]) => { + const newContracts = flatMap(txs, tx => tx.data.end.newContracts.map(n => computeContractLeaf(wasm, n))); + for (const [tree, leaves] of [ + [MerkleTreeId.PRIVATE_DATA_TREE, flatMap(txs, tx => tx.data.end.newCommitments.map(l => l.toBuffer()))], + [MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer())], + [MerkleTreeId.NULLIFIER_TREE, flatMap(txs, tx => tx.data.end.newNullifiers.map(l => l.toBuffer()))], + ] as const) { + await expectsDb.appendLeaves(tree, leaves); + } + for (const write of txs.flatMap(tx => tx.data.end.stateTransitions)) { + await expectsDb.updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, write.newValue.toBuffer(), write.leafIndex.value); + } + }; + + const setTxHistoricTreeRoots = async (tx: ProcessedTx) => { + for (const [name, id] of [ + ['privateDataTreeRoot', MerkleTreeId.PRIVATE_DATA_TREE], + ['contractTreeRoot', MerkleTreeId.CONTRACT_TREE], + ['nullifierTreeRoot', MerkleTreeId.NULLIFIER_TREE], + ] as const) { + tx.data.constants.historicTreeRoots.privateHistoricTreeRoots[name] = Fr.fromBuffer( + (await builderDb.getTreeInfo(id)).root, + ); + } + }; + + const getTreeSnapshot = async (tree: MerkleTreeId) => { + const treeInfo = await expectsDb.getTreeInfo(tree); + return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size)); + }; }); async function deployRollup() { @@ -64,7 +209,10 @@ async function deployRollup() { const [sequencer, deployer] = provider.getAccounts(); const ethRpc = new EthereumRpc(provider); - // Deploy Rollup and unverifiedDataEmitter contracts + // Deploy DecodeHelper, Rollup and unverifiedDataEmitter contracts + const decoderHelper = new DecoderHelper(ethRpc, undefined, { from: deployer, gas: 1e6 }); + await decoderHelper.deploy().send().getReceipt(); + const deployedRollup = new Rollup(ethRpc, undefined, { from: deployer, gas: 1e6 }); await deployedRollup.deploy().send().getReceipt(); @@ -77,5 +225,16 @@ async function deployRollup() { from: sequencer, }); - return { rollup, deployer, unverifiedDataEmitter, sequencer, ethRpc }; + return { decoderHelper, rollup, deployer, unverifiedDataEmitter, sequencer, ethRpc }; +} + +// Test subject class that exposes internal functions for testing +class TestSubject extends CircuitBlockBuilder { + public buildBaseRollupInput(tx1: ProcessedTx, tx2: ProcessedTx): Promise { + return super.buildBaseRollupInput(tx1, tx2); + } + + public updateRootTrees(): Promise { + return super.updateRootTrees(); + } } diff --git a/yarn-project/types/src/l2_block.ts b/yarn-project/types/src/l2_block.ts index 5f9c44c9e03b..17e97e6e5722 100644 --- a/yarn-project/types/src/l2_block.ts +++ b/yarn-project/types/src/l2_block.ts @@ -7,7 +7,7 @@ import { } from '@aztec/circuits.js'; import { makeAppendOnlyTreeSnapshot } from '@aztec/circuits.js/factories'; import { BufferReader, serializeToBuffer } from '@aztec/circuits.js/utils'; -import { Fr } from '@aztec/foundation'; +import { Fr, sha256, toBigIntBE, toBufferBE } from '@aztec/foundation'; import times from 'lodash.times'; import { ContractData } from './contract_data.js'; import { L2Tx } from './l2_tx.js'; @@ -61,7 +61,7 @@ export class L2Block { public newContractData: ContractData[], ) {} - static random(l2BlockNum: number, txsPerBlock = 1) { + static random(l2BlockNum: number, txsPerBlock = 4) { const newNullifiers = times(KERNEL_NEW_NULLIFIERS_LENGTH * txsPerBlock, Fr.random); const newCommitments = times(KERNEL_NEW_COMMITMENTS_LENGTH * txsPerBlock, Fr.random); const newContracts = times(KERNEL_NEW_CONTRACTS_LENGTH * txsPerBlock, Fr.random); @@ -224,6 +224,131 @@ export class L2Block { }); } + /** + * Computes the public inputs hash for the L2 block. + * The same output as the hash of RootRollupPublicInputs + * @return The public input hash for the L2 block as a field element + */ + getPublicInputsHash() { + const buf = serializeToBuffer( + this.startPrivateDataTreeSnapshot, + this.startNullifierTreeSnapshot, + this.startContractTreeSnapshot, + this.startTreeOfHistoricPrivateDataTreeRootsSnapshot, + this.startTreeOfHistoricContractTreeRootsSnapshot, + this.startPublicDataTreeRoot, + this.endPrivateDataTreeSnapshot, + this.endNullifierTreeSnapshot, + this.endContractTreeSnapshot, + this.endTreeOfHistoricPrivateDataTreeRootsSnapshot, + this.endTreeOfHistoricContractTreeRootsSnapshot, + this.endPublicDataTreeRoot, + this.getCalldataHash(), + ); + const temp = toBigIntBE(sha256(buf)); + // Prime order of BN254 curve + const p = BigInt('21888242871839275222246405745257275088548364400416034343698204186575808495617'); + return Fr.fromBuffer(toBufferBE(temp % p, 32)); + } + + /** + * Computes the start state hash (should equal contract data before block) + * @returns The start state hash for the L2 block + */ + getStartStateHash() { + const inputValue = serializeToBuffer( + this.number - 1, + this.startPrivateDataTreeSnapshot, + this.startNullifierTreeSnapshot, + this.startContractTreeSnapshot, + this.startTreeOfHistoricPrivateDataTreeRootsSnapshot, + this.startTreeOfHistoricContractTreeRootsSnapshot, + this.startPublicDataTreeRoot, + ); + return sha256(inputValue); + } + + /** + * Computes the end state hash (should equal contract data after block) + * @returns The end state hash for the L2 block + */ + getEndStateHash() { + const inputValue = serializeToBuffer( + this.number, + this.endPrivateDataTreeSnapshot, + this.endNullifierTreeSnapshot, + this.endContractTreeSnapshot, + this.endTreeOfHistoricPrivateDataTreeRootsSnapshot, + this.endTreeOfHistoricContractTreeRootsSnapshot, + this.endPublicDataTreeRoot, + ); + return sha256(inputValue); + } + + /** + * Computes the calldata hash for the L2 block + * This calldata hash is also computed by the rollup contract when the block is submitted, + * and inside the circuit, it is part of the public inputs. + * @returns The calldata hash. + */ + getCalldataHash() { + const computeRoot = (leafs: Buffer[]): Buffer => { + const layers: Buffer[][] = [leafs]; + let activeLayer = 0; + + while (layers[activeLayer].length > 1) { + const layer: Buffer[] = []; + const layerLength = layers[activeLayer].length; + + for (let i = 0; i < layerLength; i += 2) { + const left = layers[activeLayer][i]; + const right = layers[activeLayer][i + 1]; + + layer.push(sha256(Buffer.concat([left, right]))); + } + + layers.push(layer); + activeLayer++; + } + + return layers[layers.length - 1][0]; + }; + + const leafCount = this.newCommitments.length / (KERNEL_NEW_COMMITMENTS_LENGTH * 2); + const leafs: Buffer[] = []; + + for (let i = 0; i < leafCount; i++) { + const commitmentPerBase = KERNEL_NEW_COMMITMENTS_LENGTH * 2; + const nullifierPerBase = KERNEL_NEW_NULLIFIERS_LENGTH * 2; + const publicDataWritesPerBase = STATE_TRANSITIONS_LENGTH * 2; // @note why is this constant named differently? + const commitmentBuffer = Buffer.concat( + this.newCommitments.slice(i * commitmentPerBase, (i + 1) * commitmentPerBase).map(x => x.toBuffer()), + ); + const nullifierBuffer = Buffer.concat( + this.newNullifiers.slice(i * nullifierPerBase, (i + 1) * nullifierPerBase).map(x => x.toBuffer()), + ); + const dataWritesBuffer = Buffer.concat( + this.newPublicDataWrites + .slice(i * publicDataWritesPerBase, (i + 1) * publicDataWritesPerBase) + .map(x => x.toBuffer()), + ); + + const inputValue = Buffer.concat([ + commitmentBuffer, + nullifierBuffer, + dataWritesBuffer, + 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(), + ]); + leafs.push(sha256(inputValue)); + } + return computeRoot(leafs); + } + /** * Get the ith transaction in an L2 block. * @param txIndex - The index of the tx in the block.