diff --git a/README.md b/README.md index 6e3e06aba..0a9b851d0 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,9 @@ See [LICENSE-MIT](LICENSE-MIT) for details. - [Website](https://zksync.io/) - [GitHub](https://github.com/matter-labs) -- [ZK Credo](https://github.com/zksync/credo) - [Twitter](https://twitter.com/zksync) - [Twitter for Devs](https://twitter.com/zkSyncDevs) -- [Discord](https://join.zksync.dev/) -- [Mirror](https://zksync.mirror.xyz/) +- [Discord](https://discord.gg/px2ar7w) ## Disclaimer diff --git a/ethereum/contracts/zksync/Verifier.sol b/ethereum/contracts/zksync/Verifier.sol index 0924ee2e7..28416bf9c 100644 --- a/ethereum/contracts/zksync/Verifier.sol +++ b/ethereum/contracts/zksync/Verifier.sol @@ -284,38 +284,38 @@ contract Verifier is IVerifier { function _loadVerificationKey() internal pure virtual { assembly { // gate setup commitments - mstore(VK_GATE_SETUP_0_X_SLOT, 0x236c54d6ae3745765605abfdd3d1533aaf27c583bbac66c43f5555e2b087db42) - mstore(VK_GATE_SETUP_0_Y_SLOT, 0x0b2b13c749c19a0be311c0eec76abddbc0848e2454cc7323605a714256ef101a) - mstore(VK_GATE_SETUP_1_X_SLOT, 0x04659caf7b05471ba5ba85b1ab62267aa6c456836e625f169f7119d55b9462d2) - mstore(VK_GATE_SETUP_1_Y_SLOT, 0x0ea63403692148d2ad22189a1e5420076312f4d46e62036a043a6b0b84d5b410) - mstore(VK_GATE_SETUP_2_X_SLOT, 0x0e6696d09d65fce1e42805be03fca1f14aea247281f688981f925e77d4ce2291) - mstore(VK_GATE_SETUP_2_Y_SLOT, 0x0228f6cf8fe20c1e07e5b78bf8c41d50e55975a126d22a198d1e56acd4bbb3dd) - mstore(VK_GATE_SETUP_3_X_SLOT, 0x14685dafe340b1dec5eafcd5e7faddaf24f3781ddc53309cc25d0b42c00541dd) - mstore(VK_GATE_SETUP_3_Y_SLOT, 0x0e651cff9447cb360198899b80fa23e89ec13bc94ff161729aa841d2b55ea5be) - mstore(VK_GATE_SETUP_4_X_SLOT, 0x16e9ef76cb68f2750eb0ee72382dd9911a982308d0ab10ef94dada13c382ae73) - mstore(VK_GATE_SETUP_4_Y_SLOT, 0x22e404bc91350f3bc7daad1d1025113742436983c85eac5ab7b42221a181b81e) - mstore(VK_GATE_SETUP_5_X_SLOT, 0x0d9b29613037a5025655c82b143d2b7449c98f3aea358307c8529249cc54f3b9) - mstore(VK_GATE_SETUP_5_Y_SLOT, 0x15b3c4c946ad1babfc4c03ff7c2423fd354af3a9305c499b7fb3aaebe2fee746) - mstore(VK_GATE_SETUP_6_X_SLOT, 0x08aa077804a60caf18621f96c63d7d1b532f44b13c273956f81b4c41f1f8f076) - mstore(VK_GATE_SETUP_6_Y_SLOT, 0x01fcb7c6e22aab56eb8b61bae6f457411bd41bcc5f1e8311421a98ccee23b72e) - mstore(VK_GATE_SETUP_7_X_SLOT, 0x283344a1ab3e55ecfd904d0b8e9f4faea338df5a4ead2fa9a42f0e103da40abc) - mstore(VK_GATE_SETUP_7_Y_SLOT, 0x223b37b83b9687512d322993edd70e508dd80adb10bcf7321a3cc8a44c269521) + mstore(VK_GATE_SETUP_0_X_SLOT, 0x054b0ed7dd15637829a8311ff09e912292bb5009fa5293632b7f590f63fbb8e4) + mstore(VK_GATE_SETUP_0_Y_SLOT, 0x0c1b49eba175d4b85903f6021a2592945fb414ef82e57d8e8b18e769b79913a0) + mstore(VK_GATE_SETUP_1_X_SLOT, 0x165a927da6a4645835e465eeba4c60dca3aa2ca56b49e0a1b6170e3150fbef81) + mstore(VK_GATE_SETUP_1_Y_SLOT, 0x0aacc3d0830be4bf9bbca3b0329f9519e3127d13a126a4021f884c322f96e223) + mstore(VK_GATE_SETUP_2_X_SLOT, 0x1591549a8e5376ef07b216264bf5916f608fb49777750ba7f61406616da2c444) + mstore(VK_GATE_SETUP_2_Y_SLOT, 0x12d22c1cd67d82f57f14dc13e2d8923039d06300ff49df7d999bcaf64fdfd5d7) + mstore(VK_GATE_SETUP_3_X_SLOT, 0x215ff6c049d73d5b8bb1a02ce540d68490ef1fb52891e57d6f4b365bdf5729ed) + mstore(VK_GATE_SETUP_3_Y_SLOT, 0x264337a5471c7627dc3e46b655a2db5350bf3f48be739d61a54643116442be93) + mstore(VK_GATE_SETUP_4_X_SLOT, 0x072a1da16e0ccdc16e238b951e4179168d498336070d927a86f08192322012c9) + mstore(VK_GATE_SETUP_4_Y_SLOT, 0x2a7e401a43d51eb4fbbef6b3b9e1b3d13bc2fc670e1f8f3307e1dc3dbe97ed4c) + mstore(VK_GATE_SETUP_5_X_SLOT, 0x09b71be2e8a45dcbe7654cf369c4f1f2e7eab4b97869a469fb7a149d989f7226) + mstore(VK_GATE_SETUP_5_Y_SLOT, 0x197e1e2cefbd4f99558b89ca875e01fec0f14f05e5128bd869c87d6bf2f307fa) + mstore(VK_GATE_SETUP_6_X_SLOT, 0x21708e89d408cd584078ff0aa9132fc8d5c1635502beb267db870e86a07a08e2) + mstore(VK_GATE_SETUP_6_Y_SLOT, 0x2a9b239cf563fdc1bd61485d50183672304d0a72e2bf82298de6e36255705ba9) + mstore(VK_GATE_SETUP_7_X_SLOT, 0x28f1fb0891ede6b5ee5754b3ff4ed95ff69712a8af36b344d86681f8299a41ac) + mstore(VK_GATE_SETUP_7_Y_SLOT, 0x191376f72d21d1f307d30a856e015f1635a5684cec2f5bba906954e26551e9cb) // gate selectors commitments - mstore(VK_GATE_SELECTORS_0_X_SLOT, 0x1f67f0ba5f7e837bc680acb4e612ebd938ad35211aa6e05b96cad19e66b82d2d) - mstore(VK_GATE_SELECTORS_0_Y_SLOT, 0x2820641a84d2e8298ac2ac42bd4b912c0c37f768ecc83d3a29e7c720763d15a1) - mstore(VK_GATE_SELECTORS_1_X_SLOT, 0x0353257957562270292a17860ca8e8827703f828f440ee004848b1e23fdf9de2) - mstore(VK_GATE_SELECTORS_1_Y_SLOT, 0x305f4137fee253dff8b2bfe579038e8f25d5bd217865072af5d89fc8800ada24) + mstore(VK_GATE_SELECTORS_0_X_SLOT, 0x116738c4b76005b372f69974b9102c1a93135b691ac998984a5080e849e3f027) + mstore(VK_GATE_SELECTORS_0_Y_SLOT, 0x1875c1058b050df9f30326c0c946151e67f88ecf47edec3df9abc72445707dcf) + mstore(VK_GATE_SELECTORS_1_X_SLOT, 0x2d5c06d0c8aa6a3520b8351f82341affcbb1a0bf27bceb9bab175e3e1d38cf47) + mstore(VK_GATE_SELECTORS_1_Y_SLOT, 0x0ff8d923a0374308147f6dd4fc513f6d0640f5df699f4836825ef460df3f8d6a) // permutation commitments - mstore(VK_PERMUTATION_0_X_SLOT, 0x13a600154b369ff3237706d00948e465ee1c32c7a6d3e18bccd9c4a15910f2e5) - mstore(VK_PERMUTATION_0_Y_SLOT, 0x138aa24fbf4cdddc75114811b3d59040394c218ecef3eb46ef9bd646f7e53776) - mstore(VK_PERMUTATION_1_X_SLOT, 0x277fff1f80c409357e2d251d79f6e3fd2164b755ce69cfd72de5c690289df662) - mstore(VK_PERMUTATION_1_Y_SLOT, 0x25235588e28c70eea3e35531c80deac25cd9b53ea3f98993f120108bc7abf670) - mstore(VK_PERMUTATION_2_X_SLOT, 0x0990e07a9b001048b947d0e5bd6157214c7359b771f01bf52bd771ba563a900e) - mstore(VK_PERMUTATION_2_Y_SLOT, 0x05e5fb090dd40914c8606d875e301167ae3047d684a02b44d9d36f1eaf43d0b4) - mstore(VK_PERMUTATION_3_X_SLOT, 0x1d4656690b33299db5631401a282afab3e16c78ee2c9ad9efea628171dcbc6bc) - mstore(VK_PERMUTATION_3_Y_SLOT, 0x0ebda2ebe582f601f813ec1e3970d13ef1500c742a85cce9b7f190f333de03b0) + mstore(VK_PERMUTATION_0_X_SLOT, 0x05b56e128c5c961e289905f3e311d44bf3768e7ecbc34cb299ab512d95a67072) + mstore(VK_PERMUTATION_0_Y_SLOT, 0x0033321debc3d87f48ffe67bd408c0078b50586003904bc440529c6d635aeef7) + mstore(VK_PERMUTATION_1_X_SLOT, 0x264be88fe8356e4bc0b37ea534d1956630c6976410a38c703e8702d5d98584be) + mstore(VK_PERMUTATION_1_Y_SLOT, 0x1ce1186bd2681359c38a1fc70fd14e522f762692f8f9ed14ccebd95c5fdaf9de) + mstore(VK_PERMUTATION_2_X_SLOT, 0x18cb10d4373dc6eff5507b9572728fc7c1b0dc38b021eaad8b429d710ea419e5) + mstore(VK_PERMUTATION_2_Y_SLOT, 0x0d58bb86064f7f28e7e9f632f0dcfd630f792fa3939682b4e14db6a1ee198432) + mstore(VK_PERMUTATION_3_X_SLOT, 0x1f724cfe2fc22cdeb8cc323338759ac083d2a94631d5f48db74988862a404ee3) + mstore(VK_PERMUTATION_3_Y_SLOT, 0x2e0d1978ef73d1446d6d47269b57fe29842154788c18f90e7e052e5625ca7bf6) // lookup tables commitments mstore(VK_LOOKUP_TABLE_0_X_SLOT, 0x2c513ed74d9d57a5ec901e074032741036353a2c4513422e96e7b53b302d765b) @@ -328,12 +328,12 @@ contract Verifier is IVerifier { mstore(VK_LOOKUP_TABLE_3_Y_SLOT, 0x09d004fe08dc4d19c382df36fad22ef676185663543703e6a4b40203e50fd8a6) // lookup selector commitment - mstore(VK_LOOKUP_SELECTOR_X_SLOT, 0x2f4d347c7fb61daaadfff881e24f4b5dcfdc0d70a95bcb148168b90ef93e0007) - mstore(VK_LOOKUP_SELECTOR_Y_SLOT, 0x2322632465ba8e28cd0a4befd813ea85a972f4f6fa8e8603cf5d062dbcb14065) + mstore(VK_LOOKUP_SELECTOR_X_SLOT, 0x1641f5d312e6f62720b1e6cd1d1be5bc0e69d10d20a12dc97ff04e2107e10ccc) + mstore(VK_LOOKUP_SELECTOR_Y_SLOT, 0x277f435d376acc3261ef9d5748e6705086214daf46d04edc80fbd657f8d9e73d) // table type commitment - mstore(VK_LOOKUP_TABLE_TYPE_X_SLOT, 0x1e3c9fc98c118e4bc34f1f93d214a5d86898e980c40d8e2c180c6ada377a7467) - mstore(VK_LOOKUP_TABLE_TYPE_Y_SLOT, 0x2260a13535c35a15c173f5e5797d4b675b55d164a9995bfb7624971324bd84a8) + mstore(VK_LOOKUP_TABLE_TYPE_X_SLOT, 0x1b5f1cfddd6713cf25d9e6850a1b3fe80d6ef7fe2c67248f25362d5f9b31893c) + mstore(VK_LOOKUP_TABLE_TYPE_Y_SLOT, 0x0945076de03a0d240067e5f02b8fc11eaa589df3343542576eb59fdb3ecb57e0) // flag for using recursive part mstore(VK_RECURSIVE_FLAG_SLOT, 0) diff --git a/ethereum/contracts/zksync/facets/Executor.sol b/ethereum/contracts/zksync/facets/Executor.sol index e9cbb5e72..9e1205bf8 100644 --- a/ethereum/contracts/zksync/facets/Executor.sol +++ b/ethereum/contracts/zksync/facets/Executor.sol @@ -119,7 +119,7 @@ contract ExecutorFacet is Base, IExecutor { // See SystemLogKey enum in Constants.sol for ordering. uint256 processedLogs; - bytes32 providedL2ToL1PubdataHash = keccak256(_newBatch.totalL2ToL1Pubdata); + //bytes32 providedL2ToL1PubdataHash = keccak256(_newBatch.totalL2ToL1Pubdata); // linear traversal of the logs for (uint256 i = 0; i < emittedL2Logs.length; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) { @@ -137,8 +137,8 @@ contract ExecutorFacet is Base, IExecutor { require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lm"); l2LogsTreeRoot = logValue; } else if (logKey == uint256(SystemLogKey.TOTAL_L2_TO_L1_PUBDATA_KEY)) { - require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln"); - require(providedL2ToL1PubdataHash == logValue, "wp"); + // require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln"); + // require(providedL2ToL1PubdataHash == logValue, "wp"); } else if (logKey == uint256(SystemLogKey.STATE_DIFF_HASH_KEY)) { require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lb"); stateDiffHash = logValue; @@ -364,7 +364,7 @@ contract ExecutorFacet is Base, IExecutor { function _verifyProof(uint256[] memory proofPublicInput, ProofInput calldata _proof) internal view { // We can only process 1 batch proof at a time. - require(proofPublicInput.length == 1, "t4"); + require(_proof.serializedProof.length == 1, "t4"); bool successVerifyProof = s.verifier.verify( proofPublicInput, diff --git a/ethereum/contracts/zksync/facets/validium/Executor.sol b/ethereum/contracts/zksync/facets/validium/Executor.sol new file mode 100644 index 000000000..5fd7568b9 --- /dev/null +++ b/ethereum/contracts/zksync/facets/validium/Executor.sol @@ -0,0 +1,480 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {Base} from "../Base.sol"; +import {COMMIT_TIMESTAMP_NOT_OLDER, COMMIT_TIMESTAMP_APPROXIMATION_DELTA, EMPTY_STRING_KECCAK, L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_INITIAL_STORAGE_CHANGES_COMMITMENT_BYTES, MAX_REPEATED_STORAGE_CHANGES_COMMITMENT_BYTES, MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, PACKED_L2_BLOCK_TIMESTAMP_MASK, PUBLIC_INPUT_SHIFT} from "../../Config.sol"; +import {IExecutor, L2_LOG_ADDRESS_OFFSET, L2_LOG_KEY_OFFSET, L2_LOG_VALUE_OFFSET, SystemLogKey} from "../../interfaces/IExecutor.sol"; +import {PriorityQueue, PriorityOperation} from "../../libraries/PriorityQueue.sol"; +import {UncheckedMath} from "../../../common/libraries/UncheckedMath.sol"; +import {UnsafeBytes} from "../../../common/libraries/UnsafeBytes.sol"; +import {VerifierParams} from "../../Storage.sol"; +import {L2_BOOTLOADER_ADDRESS, L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, L2_KNOWN_CODE_STORAGE_SYSTEM_CONTRACT_ADDR} from "../../../common/L2ContractAddresses.sol"; + +/// @title zkSync Executor contract capable of processing events emitted in the zkSync protocol. +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +contract ValidiumExecutorFacet is Base, IExecutor { + using UncheckedMath for uint256; + using PriorityQueue for PriorityQueue.Queue; + + string public constant override getName = "ValidiumExecutorFacet"; + + /// @dev Process one batch commit using the previous batch StoredBatchInfo + /// @dev returns new batch StoredBatchInfo + /// @notice Does not change storage + function _commitOneBatch( + StoredBatchInfo memory _previousBatch, + CommitBatchInfo calldata _newBatch, + bytes32 _expectedSystemContractUpgradeTxHash + ) internal view returns (StoredBatchInfo memory) { + require(_newBatch.batchNumber == _previousBatch.batchNumber + 1, "f"); // only commit next batch + + // Check that batch contain all meta information for L2 logs. + // Get the chained hash of priority transaction hashes. + ( + uint256 expectedNumberOfLayer1Txs, + bytes32 expectedPriorityOperationsHash, + bytes32 previousBatchHash, + bytes32 stateDiffHash, + bytes32 l2LogsTreeRoot, + uint256 packedBatchAndL2BlockTimestamp + ) = _processL2Logs(_newBatch, _expectedSystemContractUpgradeTxHash); + + require(_previousBatch.batchHash == previousBatchHash, "l"); + // Check that the priority operation hash in the L2 logs is as expected + require(expectedPriorityOperationsHash == _newBatch.priorityOperationsHash, "t"); + // Check that the number of processed priority operations is as expected + require(expectedNumberOfLayer1Txs == _newBatch.numberOfLayer1Txs, "ta"); + + // Check the timestamp of the new batch + _verifyBatchTimestamp(packedBatchAndL2BlockTimestamp, _newBatch.timestamp, _previousBatch.timestamp); + + // Create batch commitment for the proof verification + bytes32 commitment = _createBatchCommitment(_newBatch, stateDiffHash); + + return + StoredBatchInfo( + _newBatch.batchNumber, + _newBatch.newStateRoot, + _newBatch.indexRepeatedStorageChanges, + _newBatch.numberOfLayer1Txs, + _newBatch.priorityOperationsHash, + l2LogsTreeRoot, + _newBatch.timestamp, + commitment + ); + } + + /// @notice checks that the timestamps of both the new batch and the new L2 block are correct. + /// @param _packedBatchAndL2BlockTimestamp - packed batch and L2 block timestamp in a format of batchTimestamp * 2**128 + l2BatchTimestamp + /// @param _expectedBatchTimestamp - expected batch timestamp + /// @param _previousBatchTimestamp - the timestamp of the previous batch + function _verifyBatchTimestamp( + uint256 _packedBatchAndL2BlockTimestamp, + uint256 _expectedBatchTimestamp, + uint256 _previousBatchTimestamp + ) internal view { + // Check that the timestamp that came from the system context is expected + uint256 batchTimestamp = _packedBatchAndL2BlockTimestamp >> 128; + require(batchTimestamp == _expectedBatchTimestamp, "tb"); + + // While the fact that _previousBatchTimestamp < batchTimestamp is already checked on L2, + // we double check it here for clarity + require(_previousBatchTimestamp < batchTimestamp, "h3"); + + uint256 lastL2BlockTimestamp = _packedBatchAndL2BlockTimestamp & PACKED_L2_BLOCK_TIMESTAMP_MASK; + + // All L2 blocks have timestamps within the range of [batchTimestamp, lastL2BlockTimestamp]. + // So here we need to only double check that: + // - The timestamp of the batch is not too small. + // - The timestamp of the last L2 block is not too big. + require(block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER <= batchTimestamp, "h1"); // New batch timestamp is too small + require(lastL2BlockTimestamp <= block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA, "h2"); // The last L2 block timestamp is too big + } + + /// @dev Check that L2 logs are proper and batch contain all meta information for them + /// @dev The logs processed here should line up such that only one log for each key from the + /// SystemLogKey enum in Constants.sol is processed per new batch. + /// @dev Data returned from here will be used to form the batch commitment. + function _processL2Logs( + CommitBatchInfo calldata _newBatch, + bytes32 _expectedSystemContractUpgradeTxHash + ) + internal + pure + returns ( + uint256 numberOfLayer1Txs, + bytes32 chainedPriorityTxsHash, + bytes32 previousBatchHash, + bytes32 stateDiffHash, + bytes32 l2LogsTreeRoot, + uint256 packedBatchAndL2BlockTimestamp + ) + { + // Copy L2 to L1 logs into memory. + bytes memory emittedL2Logs = _newBatch.systemLogs; + + // Used as bitmap to set/check log processing happens exactly once. + // See SystemLogKey enum in Constants.sol for ordering. + uint256 processedLogs; + + //bytes32 providedL2ToL1PubdataHash = keccak256(_newBatch.totalL2ToL1Pubdata); + + // linear traversal of the logs + for (uint256 i = 0; i < emittedL2Logs.length; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) { + // Extract the values to be compared to/used such as the log sender, key, and value + (address logSender, ) = UnsafeBytes.readAddress(emittedL2Logs, i + L2_LOG_ADDRESS_OFFSET); + (uint256 logKey, ) = UnsafeBytes.readUint256(emittedL2Logs, i + L2_LOG_KEY_OFFSET); + (bytes32 logValue, ) = UnsafeBytes.readBytes32(emittedL2Logs, i + L2_LOG_VALUE_OFFSET); + + // Ensure that the log hasn't been processed already + require(!_checkBit(processedLogs, uint8(logKey)), "kp"); + processedLogs = _setBit(processedLogs, uint8(logKey)); + + // Need to check that each log was sent by the correct address. + if (logKey == uint256(SystemLogKey.L2_TO_L1_LOGS_TREE_ROOT_KEY)) { + require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lm"); + l2LogsTreeRoot = logValue; + } else if (logKey == uint256(SystemLogKey.TOTAL_L2_TO_L1_PUBDATA_KEY)) { + // require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln"); + // require(providedL2ToL1PubdataHash == logValue, "wp"); + } else if (logKey == uint256(SystemLogKey.STATE_DIFF_HASH_KEY)) { + require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lb"); + stateDiffHash = logValue; + } else if (logKey == uint256(SystemLogKey.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY)) { + require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sc"); + packedBatchAndL2BlockTimestamp = uint256(logValue); + } else if (logKey == uint256(SystemLogKey.PREV_BATCH_HASH_KEY)) { + require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sv"); + previousBatchHash = logValue; + } else if (logKey == uint256(SystemLogKey.CHAINED_PRIORITY_TXN_HASH_KEY)) { + require(logSender == L2_BOOTLOADER_ADDRESS, "bl"); + chainedPriorityTxsHash = logValue; + } else if (logKey == uint256(SystemLogKey.NUMBER_OF_LAYER_1_TXS_KEY)) { + require(logSender == L2_BOOTLOADER_ADDRESS, "bk"); + numberOfLayer1Txs = uint256(logValue); + } else if (logKey == uint256(SystemLogKey.EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY)) { + require(logSender == L2_BOOTLOADER_ADDRESS, "bu"); + require(_expectedSystemContractUpgradeTxHash == logValue, "ut"); + } else { + revert("ul"); + } + } + + // We only require 7 logs to be checked, the 8th is if we are expecting a protocol upgrade + // Without the protocol upgrade we expect 7 logs: 2^7 - 1 = 127 + // With the protocol upgrade we expect 8 logs: 2^8 - 1 = 255 + if (_expectedSystemContractUpgradeTxHash == bytes32(0)) { + require(processedLogs == 127, "b7"); + } else { + require(processedLogs == 255, "b8"); + } + } + + /// @notice Commit batch + /// @notice 1. Checks timestamp. + /// @notice 2. Process L2 logs. + /// @notice 3. Store batch commitments. + function commitBatches( + StoredBatchInfo memory _lastCommittedBatchData, + CommitBatchInfo[] calldata _newBatchesData + ) external override nonReentrant onlyValidator { + // Check that we commit batches after last committed batch + require(s.storedBatchHashes[s.totalBatchesCommitted] == _hashStoredBatchInfo(_lastCommittedBatchData), "i"); // incorrect previous batch data + require(_newBatchesData.length > 0, "No batches to commit"); + + bytes32 systemContractsUpgradeTxHash = s.l2SystemContractsUpgradeTxHash; + // Upgrades are rarely done so we optimize a case with no active system contracts upgrade. + if (systemContractsUpgradeTxHash == bytes32(0) || s.l2SystemContractsUpgradeBatchNumber != 0) { + _commitBatchesWithoutSystemContractsUpgrade(_lastCommittedBatchData, _newBatchesData); + } else { + _commitBatchesWithSystemContractsUpgrade( + _lastCommittedBatchData, + _newBatchesData, + systemContractsUpgradeTxHash + ); + } + + s.totalBatchesCommitted = s.totalBatchesCommitted + _newBatchesData.length; + } + + /// @dev Commits new batches without any system contracts upgrade. + /// @param _lastCommittedBatchData The data of the last committed batch. + /// @param _newBatchesData An array of batch data that needs to be committed. + function _commitBatchesWithoutSystemContractsUpgrade( + StoredBatchInfo memory _lastCommittedBatchData, + CommitBatchInfo[] calldata _newBatchesData + ) internal { + for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { + _lastCommittedBatchData = _commitOneBatch(_lastCommittedBatchData, _newBatchesData[i], bytes32(0)); + + s.storedBatchHashes[_lastCommittedBatchData.batchNumber] = _hashStoredBatchInfo(_lastCommittedBatchData); + emit BlockCommit( + _lastCommittedBatchData.batchNumber, + _lastCommittedBatchData.batchHash, + _lastCommittedBatchData.commitment + ); + } + } + + /// @dev Commits new batches with a system contracts upgrade transaction. + /// @param _lastCommittedBatchData The data of the last committed batch. + /// @param _newBatchesData An array of batch data that needs to be committed. + /// @param _systemContractUpgradeTxHash The transaction hash of the system contract upgrade. + function _commitBatchesWithSystemContractsUpgrade( + StoredBatchInfo memory _lastCommittedBatchData, + CommitBatchInfo[] calldata _newBatchesData, + bytes32 _systemContractUpgradeTxHash + ) internal { + // The system contract upgrade is designed to be executed atomically with the new bootloader, a default account, + // ZKP verifier, and other system parameters. Hence, we ensure that the upgrade transaction is + // carried out within the first batch committed after the upgrade. + + // While the logic of the contract ensures that the s.l2SystemContractsUpgradeBatchNumber is 0 when this function is called, + // this check is added just in case. Since it is a hot read, it does not encure noticable gas cost. + require(s.l2SystemContractsUpgradeBatchNumber == 0, "ik"); + + // Save the batch number where the upgrade transaction was executed. + s.l2SystemContractsUpgradeBatchNumber = _newBatchesData[0].batchNumber; + + for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { + // The upgrade transaction must only be included in the first batch. + bytes32 expectedUpgradeTxHash = i == 0 ? _systemContractUpgradeTxHash : bytes32(0); + _lastCommittedBatchData = _commitOneBatch( + _lastCommittedBatchData, + _newBatchesData[i], + expectedUpgradeTxHash + ); + + s.storedBatchHashes[_lastCommittedBatchData.batchNumber] = _hashStoredBatchInfo(_lastCommittedBatchData); + emit BlockCommit( + _lastCommittedBatchData.batchNumber, + _lastCommittedBatchData.batchHash, + _lastCommittedBatchData.commitment + ); + } + } + + /// @dev Pops the priority operations from the priority queue and returns a rolling hash of operations + function _collectOperationsFromPriorityQueue(uint256 _nPriorityOps) internal returns (bytes32 concatHash) { + concatHash = EMPTY_STRING_KECCAK; + + for (uint256 i = 0; i < _nPriorityOps; i = i.uncheckedInc()) { + PriorityOperation memory priorityOp = s.priorityQueue.popFront(); + concatHash = keccak256(abi.encode(concatHash, priorityOp.canonicalTxHash)); + } + } + + /// @dev Executes one batch + /// @dev 1. Processes all pending operations (Complete priority requests) + /// @dev 2. Finalizes batch on Ethereum + /// @dev _executedBatchIdx is an index in the array of the batches that we want to execute together + function _executeOneBatch(StoredBatchInfo memory _storedBatch, uint256 _executedBatchIdx) internal { + uint256 currentBatchNumber = _storedBatch.batchNumber; + require(currentBatchNumber == s.totalBatchesExecuted + _executedBatchIdx + 1, "k"); // Execute batches in order + require( + _hashStoredBatchInfo(_storedBatch) == s.storedBatchHashes[currentBatchNumber], + "exe10" // executing batch should be committed + ); + + bytes32 priorityOperationsHash = _collectOperationsFromPriorityQueue(_storedBatch.numberOfLayer1Txs); + require(priorityOperationsHash == _storedBatch.priorityOperationsHash, "x"); // priority operations hash does not match to expected + + // Save root hash of L2 -> L1 logs tree + s.l2LogsRootHashes[currentBatchNumber] = _storedBatch.l2LogsTreeRoot; + } + + /// @notice Execute batches, complete priority operations and process withdrawals. + /// @notice 1. Processes all pending operations (Complete priority requests) + /// @notice 2. Finalizes batch on Ethereum + function executeBatches(StoredBatchInfo[] calldata _batchesData) external nonReentrant onlyValidator { + uint256 nBatches = _batchesData.length; + for (uint256 i = 0; i < nBatches; i = i.uncheckedInc()) { + _executeOneBatch(_batchesData[i], i); + emit BlockExecution(_batchesData[i].batchNumber, _batchesData[i].batchHash, _batchesData[i].commitment); + } + + uint256 newTotalBatchesExecuted = s.totalBatchesExecuted + nBatches; + s.totalBatchesExecuted = newTotalBatchesExecuted; + require(newTotalBatchesExecuted <= s.totalBatchesVerified, "n"); // Can't execute batches more than committed and proven currently. + + uint256 batchWhenUpgradeHappened = s.l2SystemContractsUpgradeBatchNumber; + if (batchWhenUpgradeHappened != 0 && batchWhenUpgradeHappened <= newTotalBatchesExecuted) { + delete s.l2SystemContractsUpgradeTxHash; + delete s.l2SystemContractsUpgradeBatchNumber; + } + } + + /// @notice Batches commitment verification. + /// @notice Only verifies batch commitments without any other processing + function proveBatches( + StoredBatchInfo calldata _prevBatch, + StoredBatchInfo[] calldata _committedBatches, + ProofInput calldata _proof + ) external nonReentrant onlyValidator { + // Save the variables into the stack to save gas on reading them later + uint256 currentTotalBatchesVerified = s.totalBatchesVerified; + uint256 committedBatchesLength = _committedBatches.length; + + // Save the variable from the storage to memory to save gas + VerifierParams memory verifierParams = s.verifierParams; + + // Initialize the array, that will be used as public input to the ZKP + uint256[] memory proofPublicInput = new uint256[](committedBatchesLength); + + // Check that the batch passed by the validator is indeed the first unverified batch + require(_hashStoredBatchInfo(_prevBatch) == s.storedBatchHashes[currentTotalBatchesVerified], "t1"); + + bytes32 prevBatchCommitment = _prevBatch.commitment; + for (uint256 i = 0; i < committedBatchesLength; i = i.uncheckedInc()) { + currentTotalBatchesVerified = currentTotalBatchesVerified.uncheckedInc(); + require( + _hashStoredBatchInfo(_committedBatches[i]) == s.storedBatchHashes[currentTotalBatchesVerified], + "o1" + ); + + bytes32 currentBatchCommitment = _committedBatches[i].commitment; + proofPublicInput[i] = _getBatchProofPublicInput( + prevBatchCommitment, + currentBatchCommitment, + verifierParams + ); + + prevBatchCommitment = currentBatchCommitment; + } + require(currentTotalBatchesVerified <= s.totalBatchesCommitted, "q"); + + // #if DUMMY_VERIFIER + + // Additional level of protection for the mainnet + assert(block.chainid != 1); + // We allow skipping the zkp verification for the test(net) environment + // If the proof is not empty, verify it, otherwise, skip the verification + if (_proof.serializedProof.length > 0) { + _verifyProof(proofPublicInput, _proof); + } + // #else + _verifyProof(proofPublicInput, _proof); + // #endif + + emit BlocksVerification(s.totalBatchesVerified, currentTotalBatchesVerified); + s.totalBatchesVerified = currentTotalBatchesVerified; + } + + function _verifyProof(uint256[] memory proofPublicInput, ProofInput calldata _proof) internal view { + // We can only process 1 batch proof at a time. + require(_proof.serializedProof.length == 1, "t4"); + + bool successVerifyProof = s.verifier.verify( + proofPublicInput, + _proof.serializedProof, + _proof.recursiveAggregationInput + ); + require(successVerifyProof, "p"); // Proof verification fail + } + + /// @dev Gets zk proof public input + function _getBatchProofPublicInput( + bytes32 _prevBatchCommitment, + bytes32 _currentBatchCommitment, + VerifierParams memory _verifierParams + ) internal pure returns (uint256) { + return + uint256( + keccak256( + abi.encodePacked( + _prevBatchCommitment, + _currentBatchCommitment, + _verifierParams.recursionNodeLevelVkHash, + _verifierParams.recursionLeafLevelVkHash + ) + ) + ) >> PUBLIC_INPUT_SHIFT; + } + + /// @notice Reverts unexecuted batches + /// @param _newLastBatch batch number after which batches should be reverted + /// NOTE: Doesn't delete the stored data about batches, but only decreases + /// counters that are responsible for the number of batches + function revertBatches(uint256 _newLastBatch) external nonReentrant onlyValidator { + require(s.totalBatchesCommitted > _newLastBatch, "v1"); // The last committed batch is less than new last batch + require(_newLastBatch >= s.totalBatchesExecuted, "v2"); // Already executed batches cannot be reverted + + if (_newLastBatch < s.totalBatchesVerified) { + s.totalBatchesVerified = _newLastBatch; + } + s.totalBatchesCommitted = _newLastBatch; + + // Reset the batch number of the executed system contracts upgrade transaction if the batch + // where the system contracts upgrade was committed is among the reverted batches. + if (s.l2SystemContractsUpgradeBatchNumber > _newLastBatch) { + delete s.l2SystemContractsUpgradeBatchNumber; + } + + emit BlocksRevert(s.totalBatchesCommitted, s.totalBatchesVerified, s.totalBatchesExecuted); + } + + /// @notice Returns larger of two values + function _maxU256(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? b : a; + } + + /// @dev Creates batch commitment from its data + function _createBatchCommitment( + CommitBatchInfo calldata _newBatchData, + bytes32 _stateDiffHash + ) internal view returns (bytes32) { + bytes32 passThroughDataHash = keccak256(_batchPassThroughData(_newBatchData)); + bytes32 metadataHash = keccak256(_batchMetaParameters()); + bytes32 auxiliaryOutputHash = keccak256(_batchAuxiliaryOutput(_newBatchData, _stateDiffHash)); + + return keccak256(abi.encode(passThroughDataHash, metadataHash, auxiliaryOutputHash)); + } + + function _batchPassThroughData(CommitBatchInfo calldata _batch) internal pure returns (bytes memory) { + return + abi.encodePacked( + _batch.indexRepeatedStorageChanges, + _batch.newStateRoot, + uint64(0), // index repeated storage changes in zkPorter + bytes32(0) // zkPorter batch hash + ); + } + + function _batchMetaParameters() internal view returns (bytes memory) { + return abi.encodePacked(s.zkPorterIsAvailable, s.l2BootloaderBytecodeHash, s.l2DefaultAccountBytecodeHash); + } + + function _batchAuxiliaryOutput( + CommitBatchInfo calldata _batch, + bytes32 _stateDiffHash + ) internal pure returns (bytes memory) { + require(_batch.systemLogs.length <= MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, "pu"); + + bytes32 l2ToL1LogsHash = keccak256(_batch.systemLogs); + + return + abi.encode( + l2ToL1LogsHash, + _stateDiffHash, + _batch.bootloaderHeapInitialContentsHash, + _batch.eventsQueueStateHash + ); + } + + /// @notice Returns the keccak hash of the ABI-encoded StoredBatchInfo + function _hashStoredBatchInfo(StoredBatchInfo memory _storedBatchInfo) internal pure returns (bytes32) { + return keccak256(abi.encode(_storedBatchInfo)); + } + + /// @notice Returns true if the bit at index {_index} is 1 + function _checkBit(uint256 _bitMap, uint8 _index) internal pure returns (bool) { + return (_bitMap & (1 << _index)) > 0; + } + + /// @notice Sets the given bit in {_num} at index {_index} to 1. + function _setBit(uint256 _bitMap, uint8 _index) internal pure returns (uint256) { + return _bitMap | (1 << _index); + } +} diff --git a/ethereum/scripts/deploy.ts b/ethereum/scripts/deploy.ts index afd0335f2..a41e3cc61 100644 --- a/ethereum/scripts/deploy.ts +++ b/ethereum/scripts/deploy.ts @@ -23,6 +23,7 @@ async function main() { .option("--create2-salt ") .option("--diamond-upgrade-init ") .option("--only-verifier") + .option("--validium") .action(async (cmd) => { const deployWallet = cmd.privateKey ? new Wallet(cmd.privateKey, provider) @@ -81,7 +82,7 @@ async function main() { await deployer.deployGovernance(create2Salt, { gasPrice, nonce }); await deployer.deployAllowList(create2Salt, { gasPrice, nonce: nonce + 1 }); - await deployer.deployZkSyncContract(create2Salt, gasPrice, nonce + 2); + await deployer.deployZkSyncContract(create2Salt, gasPrice, nonce + 2, cmd.validium); await deployer.deployBridgeContracts(create2Salt, gasPrice); // Do not pass nonce, since it was increment after deploying zkSync contracts await deployer.deployWethBridgeContracts(create2Salt, gasPrice); await deployer.deployValidatorTimelock(create2Salt, { gasPrice }); diff --git a/ethereum/src.ts/deploy.ts b/ethereum/src.ts/deploy.ts index a00c16b1e..ee4dee7ad 100644 --- a/ethereum/src.ts/deploy.ts +++ b/ethereum/src.ts/deploy.ts @@ -244,6 +244,19 @@ export class Deployer { const contractAddress = await this.deployViaCreate2("ExecutorFacet", [], create2Salt, ethTxOptions); if (this.verbose) { + console.log(`VALIDIUM=false`); + console.log(`CONTRACTS_EXECUTOR_FACET_ADDR=${contractAddress}`); + } + + this.addresses.ZkSync.ExecutorFacet = contractAddress; + } + + public async deployValidiumExecutorFacet(create2Salt: string, ethTxOptions: ethers.providers.TransactionRequest) { + ethTxOptions.gasLimit ??= 10_000_000; + const contractAddress = await this.deployViaCreate2("ValidiumExecutorFacet", [], create2Salt, ethTxOptions); + + if (this.verbose) { + console.log(`VALIDIUM=true`); console.log(`CONTRACTS_EXECUTOR_FACET_ADDR=${contractAddress}`); } @@ -409,13 +422,17 @@ export class Deployer { this.addresses.ZkSync.DiamondProxy = contractAddress; } - public async deployZkSyncContract(create2Salt: string, gasPrice?: BigNumberish, nonce?) { + public async deployZkSyncContract(create2Salt: string, gasPrice?: BigNumberish, nonce?, validium?: boolean) { nonce = nonce ? parseInt(nonce) : await this.deployWallet.getTransactionCount(); + const executorFacetPromise = validium + ? this.deployValidiumExecutorFacet(create2Salt, { gasPrice, nonce: nonce + 1 }) + : this.deployExecutorFacet(create2Salt, { gasPrice, nonce: nonce + 1 }); + // deploy zkSync contract const independentZkSyncDeployPromises = [ this.deployMailboxFacet(create2Salt, { gasPrice, nonce }), - this.deployExecutorFacet(create2Salt, { gasPrice, nonce: nonce + 1 }), + executorFacetPromise, this.deployAdminFacet(create2Salt, { gasPrice, nonce: nonce + 2 }), this.deployGettersFacet(create2Salt, { gasPrice, nonce: nonce + 3 }), this.deployDiamondInit(create2Salt, { gasPrice, nonce: nonce + 4 }), @@ -425,7 +442,6 @@ export class Deployer { await this.deployDiamondProxy(create2Salt, { gasPrice, nonce }); } - public async deployBridgeContracts(create2Salt: string, gasPrice?: BigNumberish, nonce?) { nonce = nonce ? parseInt(nonce) : await this.deployWallet.getTransactionCount(); diff --git a/tools/data/scheduler_key.json b/tools/data/scheduler_key.json index 01e0deb97..d792b2731 100644 --- a/tools/data/scheduler_key.json +++ b/tools/data/scheduler_key.json @@ -6,121 +6,121 @@ "gate_setup_commitments": [ { "x": [ - 4563648229522529090, - 12621273650309129924, - 6198549568814142266, - 2552508369834820982 + 3134321788309977316, + 10573132553967014755, + 3001703164893106466, + 381414913732862840 ], "y": [ - 6942986305285328922, - 13872369038900622115, - 16362071052994133467, - 804758705072609803 + 10023015411950883744, + 6896159948336889230, + 6414240783194755732, + 872372229201319096 ], "infinity": false }, { "x": [ - 11488992528554025682, - 12016824828223971094, - 11942004360057333370, - 316831626296641307 + 13120971644342103937, + 11793287663204294817, + 3883340854702399708, + 1610760885102732376 ], "y": [ - 304673622018339856, - 7139037552557818730, - 12475560967982555143, - 1055588351918295250 + 2272149790438908451, + 16362277919451948034, + 11222024348659324185, + 769204936692720831 ], "infinity": false }, { "x": [ - 2274984630539920017, - 5398167177582250136, - 16440396753384808945, - 1037682586893548769 + 17731804648385463364, + 6957978511947926439, + 554530057858945391, + 1554116369209063151 ], "y": [ - 10168660308952593373, - 16526369642614237721, - 569062739734175056, - 155645558476901406 + 11068663668443960791, + 4165938511251890045, + 9157185920319394352, + 1356194940161196789 ], "infinity": false }, { "x": [ - 14005362797509427677, - 2662603874351919260, - 14261489165672308143, - 1470528288349794782 + 8019563329680255469, + 10443600923825661309, + 10066002756835006084, + 2404912031772130651 ], "y": [ - 11144229651170108862, - 11439490264313454962, - 114993091474760680, - 1037267173208738614 + 11909280006603456147, + 5818438825251413345, + 15870199885834935123, + 2757108579883054631 ], "infinity": false }, { "x": [ - 10726125240955612787, - 1916320162213728495, - 1058608086768277905, - 1651114031905829493 + 9723414060399071945, + 10180812700717519482, + 7936340440930941206, + 516257686460616129 ], "y": [ - 13237242732587628574, - 4774776044666137690, - 14401013098807103799, - 2514139699916115771 + 567977185774136652, + 4306281713268395827, + 18140207600873092049, + 3061955278209883828 ], "infinity": false }, { "x": [ - 14434760601334248377, - 5316938318287831815, - 6221098547630910324, - 980422841280734466 + 18120818717781619238, + 16711368075993785449, + 16673817803744408050, + 700058928459046347 ], "y": [ - 9201886393750447942, - 3840149540273146267, - 18179910191622136829, - 1563809864380914603 + 7622480271915550714, + 13902980411406060504, + 6164172017934139902, + 1836938876363296665 ], "infinity": false }, { "x": [ - 17877966991893524598, - 5994085157062523222, - 1757001537059388699, - 624319710399696047 + 15818628187542915298, + 15402701417353228903, + 4645743436884029384, + 2409582523262225752 ], "y": [ - 4763287561833789230, - 2005258298669826833, - 16972767076042430273, - 143191352994868054 + 10225110015471016873, + 3480449575574012457, + 13646267911522236018, + 3070086728021966273 ], "infinity": false }, { "x": [ - 11830690209042008764, - 11761396005838073769, - 18271188400274886574, - 2896734446482773484 + 15593293662666768812, + 17768691370516984644, + 17174288836059912543, + 2950415245130983093 ], "y": [ - 1890606551566554401, - 10220931290312275762, - 3256711195869515344, - 2466626485328709457 + 10405941745355450827, + 3865610534756768698, + 563805946543955734, + 1806918679491891699 ], "infinity": false } @@ -128,31 +128,31 @@ "gate_selectors_commitments": [ { "x": [ - 10865727529243127085, - 4083978853392244827, - 14303622309482785753, - 2263042021033673595 + 5354921692103962663, + 10597914855112022168, + 8283977291194706970, + 1254033438787241395 ], "y": [ - 3019601017411802529, - 880444282195426618, - 9998743525359587628, - 2891421025832200233 + 17990692095059328463, + 7491895001046969405, + 17510882385599010078, + 1762527058736778745 ], "infinity": false }, { "x": [ - 5208608554346323426, - 8575970970223832576, - 2966209169082345602, - 239576408267301488 + 12328426125821267783, + 14677689403443047323, + 2357692814373165823, + 3268494923353713205 ], "y": [ - 17715084817752316452, - 2726293100894160682, - 17920596859559317135, - 3485576345363305439 + 9394214569640955242, + 450630302635608118, + 1477019964334489453, + 1150908451828220680 ], "infinity": false } @@ -160,78 +160,78 @@ "permutation_commitments": [ { "x": [ - 14761045450946573029, - 17157644513453531531, - 2555518804134782053, - 1415819224310783987 + 11073033365046587506, + 17543366073703943346, + 2925375977998636107, + 411355966917613086 ], "y": [ - 17265629196749977462, - 4128711855633066822, - 8435602817910411328, - 1408116296902303196 + 4634938960149933815, + 10038620738808728516, + 5260176309304737799, + 14410327903164543 ], "infinity": false }, { "x": [ - 3307267823832528482, - 2406249680085831639, - 9091964031261402109, - 2846274000290842933 + 4505573069708166334, + 3514663015240928368, + 13885581324134225254, + 2759554901468343883 ], "y": [ - 17374905554931807856, - 6690578002079222163, - 11809376320193686210, - 2676076649992974574 + 14766134794032708062, + 3419963379718679828, + 14090109324006346322, + 2080971354192483161 ], "infinity": false }, { "x": [ - 3159118708748226574, - 5508845413629697013, - 13350869305506486049, - 689297560178790472 + 10034756028637387237, + 13956897381252459181, + 17676764419229650887, + 1786540180828440303 ], "y": [ - 15696011303896469684, - 12551611148155235140, - 14438660833518031207, - 425021756161657108 + 16234833038341145650, + 1114974762353197748, + 16711158590984748387, + 961724704749485864 ], "infinity": false }, { "x": [ - 18349397811516917436, - 4473982696343317918, - 13070312540813307819, - 2109468484629113245 + 13207237492056542947, + 9498840683026707597, + 13316073393799666368, + 2265958217127439582 ], "y": [ - 13254534552549721008, - 17388411854346636521, - 17875890960520499518, - 1062184221180884481 + 9080715171198565366, + 9520983963961194766, + 7885036753736171049, + 3318336507646038340 ], "infinity": false } ], - "total_lookup_entries_length": 1787472, + "total_lookup_entries_length": 1786644, "lookup_selector_commitment": { "x": [ - 9324906502432882695, - 14977861238256290580, - 12538013124354067293, - 3408438202312564138 + 9218954341000481996, + 1038591043397823945, + 2355917848722531772, + 1603833229224637991 ], "y": [ - 14942105932194201701, - 12210090881357612547, - 14774705021036784261, - 2531694948512337448 + 9294257929334679357, + 9665091690516467420, + 7057032139323633744, + 2846067557162208306 ], "infinity": false }, @@ -299,16 +299,16 @@ ], "lookup_table_type_commitment": { "x": [ - 1732877442096985191, - 7537030715658833452, - 14073502080301311448, - 2178792007727681099 + 2681380516794566972, + 967983640969946255, + 2727464508424142824, + 1972327038478390223 ], "y": [ - 8513095304113652904, - 6581396660744182779, - 13939755637576387431, - 2477157044961106453 + 7977458078956869600, + 12274734452276806231, + 29244742286950686, + 667948288229117220 ], "infinity": false }, @@ -396,4 +396,4 @@ "infinity": false } ] -} +} \ No newline at end of file