diff --git a/config/common/smart-contract-errors.toml b/config/common/smart-contract-errors.toml index 36015605a..eaa68c18b 100644 --- a/config/common/smart-contract-errors.toml +++ b/config/common/smart-contract-errors.toml @@ -28,7 +28,7 @@ "b1504a5f" = "BlobSubmissionDataIsMissing" "c0e41e1d" = "EmptyBlobDataAtIndex" "fb4cd6ef" = "FinalBlockDoesNotMatchShnarfFinalBlock" -"2526F108 " = "ShnarfAndFinalBlockNumberLengthsMismatched" +"2526F108" = "ShnarfAndFinalBlockNumberLengthsMismatched" "d3664fb3" = "FinalShnarfWrong" "4e686675" = "L2MerkleRootDoesNotExist" "e5d14425" = "L2MerkleRootAlreadyAnchored" @@ -46,3 +46,4 @@ "d39e75f9" = "L1MessageNumberSynchronizationWrong" "7557a60a" = "L1RollingHashSynchronizationWrong" "36a4bb94" = "FinalRollingHashIsZero" +"42ab979d" = "ParentBlobNotSubmitted" diff --git a/contracts/abi/LineaRollupV6.0.abi b/contracts/abi/LineaRollupV6.0.abi index 5f8cd5442..b9ee6255a 100644 --- a/contracts/abi/LineaRollupV6.0.abi +++ b/contracts/abi/LineaRollupV6.0.abi @@ -52,27 +52,6 @@ "name": "DataAlreadySubmitted", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - } - ], - "name": "DataStartingBlockDoesNotMatch", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyBlobData", - "type": "error" - }, { "inputs": [ { @@ -174,38 +153,6 @@ "name": "FinalizationStateIncorrect", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "firstBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - } - ], - "name": "FirstBlockGreaterThanFinalBlock", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "firstBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lastFinalizedBlock", - "type": "uint256" - } - ], - "name": "FirstBlockLessThanOrEqualToLastFinalizedBlock", - "type": "error" - }, { "inputs": [], "name": "FirstByteIsNotZero", @@ -296,22 +243,6 @@ "name": "LastFinalizationTimeNotLapsed", "type": "error" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "actual", - "type": "bytes32" - } - ], - "name": "LastFinalizedShnarfWrong", - "type": "error" - }, { "inputs": [ { @@ -388,6 +319,17 @@ "name": "MissingRollingHashForMessageNumber", "type": "error" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "shnarf", + "type": "bytes32" + } + ], + "name": "ParentBlobNotSubmitted", + "type": "error" + }, { "inputs": [], "name": "PeriodIsZero", @@ -461,27 +403,6 @@ "name": "ReentrantCall", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "shnarfsLength", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockNumbers", - "type": "uint256" - } - ], - "name": "ShnarfAndFinalBlockNumberLengthsMismatched", - "type": "error" - }, - { - "inputs": [], - "name": "SnarkHashIsZeroHash", - "type": "error" - }, { "inputs": [], "name": "StartingRootHashDoesNotMatch", @@ -555,18 +476,6 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "startBlock", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "endBlock", - "type": "uint256" - }, { "indexed": false, "internalType": "bytes32", @@ -1315,6 +1224,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "shnarf", + "type": "bytes32" + } + ], + "name": "blobShnarfExists", + "outputs": [ + { + "internalType": "uint256", + "name": "exists", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1656,7 +1584,7 @@ }, { "internalType": "uint256", - "name": "finalBlockInData", + "name": "endBlockNumber", "type": "uint256" }, { @@ -2296,25 +2224,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "shnarf", - "type": "bytes32" - } - ], - "name": "shnarfFinalBlockNumbers", - "outputs": [ - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -2338,33 +2247,6 @@ "inputs": [ { "components": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "firstBlockInData", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - } - ], - "internalType": "struct ILineaRollup.SupportingSubmissionDataV2", - "name": "submissionData", - "type": "tuple" - }, { "internalType": "uint256", "name": "dataEvaluationClaim", @@ -2379,10 +2261,20 @@ "internalType": "bytes", "name": "kzgProof", "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "finalStateRootHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "snarkHash", + "type": "bytes32" } ], - "internalType": "struct ILineaRollup.BlobSubmissionData[]", - "name": "_blobSubmissionData", + "internalType": "struct ILineaRollup.BlobSubmission[]", + "name": "_blobSubmissions", "type": "tuple[]" }, { @@ -2410,16 +2302,6 @@ "name": "finalStateRootHash", "type": "bytes32" }, - { - "internalType": "uint256", - "name": "firstBlockInData", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, { "internalType": "bytes32", "name": "snarkHash", @@ -2431,8 +2313,8 @@ "type": "bytes" } ], - "internalType": "struct ILineaRollup.SubmissionDataV2", - "name": "_submissionData", + "internalType": "struct ILineaRollup.CompressedCalldataSubmission", + "name": "_submission", "type": "tuple" }, { diff --git a/contracts/contracts/LineaRollup.sol b/contracts/contracts/LineaRollup.sol index 4fdaae747..5d55b52bb 100644 --- a/contracts/contracts/LineaRollup.sol +++ b/contracts/contracts/LineaRollup.sol @@ -40,6 +40,7 @@ contract LineaRollup is ) ); + uint256 internal constant SHNARF_EXISTS_DEFAULT_VALUE = 1; bytes32 internal constant EMPTY_HASH = 0x0; uint256 internal constant BLS_CURVE_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513; @@ -49,15 +50,15 @@ contract LineaRollup is uint256 internal constant SIX_MONTHS_IN_SECONDS = (365 / 2) * 24 * 60 * 60; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. + /// @dev DEPRECATED in favor of the single blobShnarfExists mapping. mapping(bytes32 dataHash => bytes32 finalStateRootHash) public dataFinalStateRootHashes; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. + /// @dev DEPRECATED in favor of the single blobShnarfExists mapping. mapping(bytes32 dataHash => bytes32 parentHash) public dataParents; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. + /// @dev DEPRECATED in favor of the single blobShnarfExists mapping. mapping(bytes32 dataHash => bytes32 shnarfHash) public dataShnarfHashes; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. + /// @dev DEPRECATED in favor of the single blobShnarfExists mapping. mapping(bytes32 dataHash => uint256 startingBlock) public dataStartingBlock; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. + /// @dev DEPRECATED in favor of the single blobShnarfExists mapping. mapping(bytes32 dataHash => uint256 endingBlock) public dataEndingBlock; /// @dev DEPRECATED in favor of currentFinalizedState hash. @@ -69,8 +70,9 @@ contract LineaRollup is /** * @dev NB: THIS IS THE ONLY MAPPING BEING USED FOR DATA SUBMISSION TRACKING. + * @dev NB: NB: This was shnarfFinalBlockNumbers and is replaced to indicate only that a shnarf exists with a value of 1. */ - mapping(bytes32 shnarf => uint256 finalBlockNumber) public shnarfFinalBlockNumbers; + mapping(bytes32 shnarf => uint256 exists) public blobShnarfExists; /// @dev Hash of the L2 computed L1 message number, rolling hash and finalized timestamp. bytes32 public currentFinalizedState; @@ -118,7 +120,7 @@ contract LineaRollup is currentL2BlockNumber = _initializationData.initialL2BlockNumber; stateRootHashes[_initializationData.initialL2BlockNumber] = _initializationData.initialStateRootHash; - shnarfFinalBlockNumbers[GENESIS_SHNARF] = _initializationData.initialL2BlockNumber; + blobShnarfExists[GENESIS_SHNARF] = SHNARF_EXISTS_DEFAULT_VALUE; currentFinalizedShnarf = GENESIS_SHNARF; currentFinalizedState = _computeLastFinalizedState(0, EMPTY_HASH, _initializationData.genesisTimestamp); @@ -203,16 +205,16 @@ contract LineaRollup is * @notice Submit one or more EIP-4844 blobs. * @dev OPERATOR_ROLE is required to execute. * @dev This should be a blob carrying transaction. - * @param _blobSubmissionData The data for blob submission including proofs and required polynomials. + * @param _blobSubmissions The data for blob submission including proofs and required polynomials. * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. * @param _finalBlobShnarf The expected final shnarf post computation of all the blob shnarfs. */ function submitBlobs( - BlobSubmissionData[] calldata _blobSubmissionData, + BlobSubmission[] calldata _blobSubmissions, bytes32 _parentShnarf, bytes32 _finalBlobShnarf ) external whenTypeAndGeneralNotPaused(PauseType.BLOB_SUBMISSION) onlyRole(OPERATOR_ROLE) { - uint256 blobSubmissionLength = _blobSubmissionData.length; + uint256 blobSubmissionLength = _blobSubmissions.length; if (blobSubmissionLength == 0) { revert BlobSubmissionDataIsMissing(); @@ -224,17 +226,18 @@ contract LineaRollup is bytes32 currentDataEvaluationPoint; bytes32 currentDataHash; - uint256 lastFinalizedBlockNumber = currentL2BlockNumber; /// @dev Assigning in memory saves a lot of gas vs. calldata reading. - BlobSubmissionData memory blobSubmissionData; + BlobSubmission memory blobSubmission; - bytes32 computedShnarf = _parentShnarf; + if (blobShnarfExists[_parentShnarf] == 0) { + revert ParentBlobNotSubmitted(_parentShnarf); + } - uint256 blobFinalBlockNumber = shnarfFinalBlockNumbers[computedShnarf]; + bytes32 computedShnarf = _parentShnarf; for (uint256 i; i < blobSubmissionLength; i++) { - blobSubmissionData = _blobSubmissionData[i]; + blobSubmission = _blobSubmissions[i]; currentDataHash = blobhash(i); @@ -242,27 +245,25 @@ contract LineaRollup is revert EmptyBlobDataAtIndex(i); } - _validateSubmissionData(blobSubmissionData.submissionData, blobFinalBlockNumber, lastFinalizedBlockNumber); + bytes32 snarkHash = blobSubmission.snarkHash; - currentDataEvaluationPoint = Utils._efficientKeccak(blobSubmissionData.submissionData.snarkHash, currentDataHash); + currentDataEvaluationPoint = Utils._efficientKeccak(snarkHash, currentDataHash); _verifyPointEvaluation( currentDataHash, uint256(currentDataEvaluationPoint), - blobSubmissionData.dataEvaluationClaim, - blobSubmissionData.kzgCommitment, - blobSubmissionData.kzgProof + blobSubmission.dataEvaluationClaim, + blobSubmission.kzgCommitment, + blobSubmission.kzgProof ); computedShnarf = _computeShnarf( computedShnarf, - blobSubmissionData.submissionData.snarkHash, - blobSubmissionData.submissionData.finalStateRootHash, + snarkHash, + blobSubmission.finalStateRootHash, currentDataEvaluationPoint, - bytes32(blobSubmissionData.dataEvaluationClaim) + bytes32(blobSubmission.dataEvaluationClaim) ); - - blobFinalBlockNumber = blobSubmissionData.submissionData.finalBlockInData; } if (_finalBlobShnarf != computedShnarf) { @@ -274,110 +275,55 @@ contract LineaRollup is * Note: As only the last shnarf is stored, we don't need to validate shnarfs, * computed for any previous blobs in the submission (if multiple are submitted). */ - if (shnarfFinalBlockNumbers[computedShnarf] != 0) { + if (blobShnarfExists[computedShnarf] != 0) { revert DataAlreadySubmitted(computedShnarf); } /// @dev use the last shnarf as the submission to store as technically it becomes the next parent shnarf. - shnarfFinalBlockNumbers[computedShnarf] = blobFinalBlockNumber; + blobShnarfExists[computedShnarf] = SHNARF_EXISTS_DEFAULT_VALUE; - emit DataSubmittedV3( - _blobSubmissionData[0].submissionData.firstBlockInData, - blobFinalBlockNumber, - _parentShnarf, - computedShnarf, - blobSubmissionData.submissionData.finalStateRootHash - ); + emit DataSubmittedV3(_parentShnarf, computedShnarf, blobSubmission.finalStateRootHash); } /** * @notice Submit blobs using compressed data via calldata. * @dev OPERATOR_ROLE is required to execute. - * @param _submissionData The supporting data for compressed data submission including compressed data. + * @param _submission The supporting data for compressed data submission including compressed data. * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. * @param _expectedShnarf The expected shnarf post computation of all the submission. */ function submitDataAsCalldata( - SubmissionDataV2 calldata _submissionData, + CompressedCalldataSubmission calldata _submission, bytes32 _parentShnarf, bytes32 _expectedShnarf ) external whenTypeAndGeneralNotPaused(PauseType.CALLDATA_SUBMISSION) onlyRole(OPERATOR_ROLE) { - if (_submissionData.compressedData.length == 0) { + if (_submission.compressedData.length == 0) { revert EmptySubmissionData(); } - SupportingSubmissionDataV2 memory submissionData = SupportingSubmissionDataV2({ - finalStateRootHash: _submissionData.finalStateRootHash, - firstBlockInData: _submissionData.firstBlockInData, - finalBlockInData: _submissionData.finalBlockInData, - snarkHash: _submissionData.snarkHash - }); + bytes32 currentDataHash = keccak256(_submission.compressedData); - bytes32 currentDataHash = keccak256(_submissionData.compressedData); + bytes32 dataEvaluationPoint = Utils._efficientKeccak(_submission.snarkHash, currentDataHash); - _validateSubmissionData(submissionData, shnarfFinalBlockNumbers[_parentShnarf], currentL2BlockNumber); - - bytes32 dataEvaluationPoint = Utils._efficientKeccak(_submissionData.snarkHash, currentDataHash); bytes32 computedShnarf = _computeShnarf( _parentShnarf, - _submissionData.snarkHash, - _submissionData.finalStateRootHash, + _submission.snarkHash, + _submission.finalStateRootHash, dataEvaluationPoint, - _calculateY(_submissionData.compressedData, dataEvaluationPoint) + _calculateY(_submission.compressedData, dataEvaluationPoint) ); if (_expectedShnarf != computedShnarf) { revert FinalShnarfWrong(_expectedShnarf, computedShnarf); } - if (shnarfFinalBlockNumbers[computedShnarf] != 0) { + if (blobShnarfExists[computedShnarf] != 0) { revert DataAlreadySubmitted(computedShnarf); } - shnarfFinalBlockNumbers[computedShnarf] = _submissionData.finalBlockInData; + blobShnarfExists[computedShnarf] = SHNARF_EXISTS_DEFAULT_VALUE; - emit DataSubmittedV3( - _submissionData.firstBlockInData, - _submissionData.finalBlockInData, - _parentShnarf, - computedShnarf, - _submissionData.finalStateRootHash - ); - } - - /** - * @notice Internal function to validate submission data. - * @param _submissionData The supporting data for compressed data submission excluding compressed data. - * @param _parentFinalBlockNumber The final block number for the parent blob. - * @param _lastFinalizedBlockNumber The last finalized block number. - */ - function _validateSubmissionData( - SupportingSubmissionDataV2 memory _submissionData, - uint256 _parentFinalBlockNumber, - uint256 _lastFinalizedBlockNumber - ) internal pure { - if (_submissionData.finalStateRootHash == EMPTY_HASH) { - revert FinalBlockStateEqualsZeroHash(); - } - - if (_submissionData.snarkHash == EMPTY_HASH) { - revert SnarkHashIsZeroHash(); - } - - // for it to be equal the number would have to wrap round twice in overflow.. - unchecked { - if (_parentFinalBlockNumber + 1 != _submissionData.firstBlockInData) { - revert DataStartingBlockDoesNotMatch(_parentFinalBlockNumber + 1, _submissionData.firstBlockInData); - } - } - - if (_submissionData.firstBlockInData <= _lastFinalizedBlockNumber) { - revert FirstBlockLessThanOrEqualToLastFinalizedBlock(_submissionData.firstBlockInData, _lastFinalizedBlockNumber); - } - - if (_submissionData.firstBlockInData > _submissionData.finalBlockInData) { - revert FirstBlockGreaterThanFinalBlock(_submissionData.firstBlockInData, _submissionData.finalBlockInData); - } + emit DataSubmittedV3(_parentShnarf, computedShnarf, _submission.finalStateRootHash); } /** @@ -502,7 +448,7 @@ contract LineaRollup is lastFinalizedShnarf, finalShnarf, lastFinalizedBlockNumber, - shnarfFinalBlockNumbers[finalShnarf] + _finalizationData.endBlockNumber ); _verifyProof(publicInput, _proofType, _aggregatedProof); @@ -518,11 +464,8 @@ contract LineaRollup is FinalizationDataV3 calldata _finalizationData, uint256 _lastFinalizedBlock ) internal returns (bytes32 finalShnarf) { - if (_finalizationData.finalBlockInData <= _lastFinalizedBlock) { - revert FinalBlockNumberLessThanOrEqualToLastFinalizedBlock( - _finalizationData.finalBlockInData, - _lastFinalizedBlock - ); + if (_finalizationData.endBlockNumber <= _lastFinalizedBlock) { + revert FinalBlockNumberLessThanOrEqualToLastFinalizedBlock(_finalizationData.endBlockNumber, _lastFinalizedBlock); } _validateL2ComputedRollingHash(_finalizationData.l1RollingHashMessageNumber, _finalizationData.l1RollingHash); @@ -563,9 +506,9 @@ contract LineaRollup is _addL2MerkleRoots(_finalizationData.l2MerkleRoots, _finalizationData.l2MerkleTreesDepth); _anchorL2MessagingBlocks(_finalizationData.l2MessagingBlocksOffsets, _lastFinalizedBlock); - stateRootHashes[_finalizationData.finalBlockInData] = _finalizationData.shnarfData.finalStateRootHash; + stateRootHashes[_finalizationData.endBlockNumber] = _finalizationData.shnarfData.finalStateRootHash; - currentL2BlockNumber = _finalizationData.finalBlockInData; + currentL2BlockNumber = _finalizationData.endBlockNumber; currentFinalizedShnarf = finalShnarf; @@ -576,9 +519,8 @@ contract LineaRollup is ); emit DataFinalizedV3( - /// @dev incremented to cover the starting block of data being finalized ++_lastFinalizedBlock, - _finalizationData.finalBlockInData, + _finalizationData.endBlockNumber, finalShnarf, _finalizationData.parentStateRootHash, _finalizationData.shnarfData.finalStateRootHash @@ -657,7 +599,7 @@ contract LineaRollup is * _finalizationData.lastFinalizedTimestamp, * _finalizationData.finalTimestamp, * _lastFinalizedBlockNumber, - * _finalizationData.finalBlockInData, + * _finalizationData.endBlockNumber, * _finalizationData.lastFinalizedL1RollingHash, * _finalizationData.l1RollingHash, * _finalizationData.lastFinalizedL1RollingHashMessageNumber, @@ -670,7 +612,7 @@ contract LineaRollup is * ) * Data is found at the following offsets: * 0x00 parentStateRootHash - * 0x20 finalBlockInData + * 0x20 endBlockNumber * 0x40 shnarfData.parentShnarf * 0x60 shnarfData.snarkHash * 0x80 shnarfData.finalStateRootHash @@ -692,14 +634,14 @@ contract LineaRollup is * @param _finalizationData The full finalization data. * @param _finalShnarf The final shnarf in the finalization. * @param _lastFinalizedBlockNumber The last finalized block number. - * @param _finalBlockNumber Final block number being finalized. + * @param _endBlockNumber End block number being finalized. */ function _computePublicInput( FinalizationDataV3 calldata _finalizationData, bytes32 _lastFinalizedShnarf, bytes32 _finalShnarf, uint256 _lastFinalizedBlockNumber, - uint256 _finalBlockNumber + uint256 _endBlockNumber ) private pure returns (uint256 publicInput) { assembly { let mPtr := mload(0x40) @@ -714,8 +656,8 @@ contract LineaRollup is mstore(add(mPtr, 0x80), _lastFinalizedBlockNumber) - // shnarfFinalBlockNumbers[finalShnarf] - mstore(add(mPtr, 0xA0), _finalBlockNumber) + // _finalizationData.endBlockNumber + mstore(add(mPtr, 0xA0), _endBlockNumber) /** * _finalizationData.lastFinalizedL1RollingHash diff --git a/contracts/contracts/interfaces/l1/ILineaRollup.sol b/contracts/contracts/interfaces/l1/ILineaRollup.sol index 9f93133bd..c93f16a9c 100644 --- a/contracts/contracts/interfaces/l1/ILineaRollup.sol +++ b/contracts/contracts/interfaces/l1/ILineaRollup.sol @@ -40,34 +40,16 @@ interface ILineaRollup { /** * @notice Supporting data for compressed calldata submission including compressed data. - * @dev finalStateRootHash is used to set state root hash at the end of the data. - * @dev firstBlockInData is the first block that is included in the data submitted. - * @dev finalBlockInData is the last block that is included in the data submitted. + * @dev finalStateRootHash is used to set state root at the end of the data. * @dev snarkHash is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. * @dev compressedData is the compressed transaction data. It contains ordered data for each L2 block - l2Timestamps, the encoded transaction data. */ - struct SubmissionDataV2 { + struct CompressedCalldataSubmission { bytes32 finalStateRootHash; - uint256 firstBlockInData; - uint256 finalBlockInData; bytes32 snarkHash; bytes compressedData; } - /** - * @notice Supporting data for compressed blob data submission. - * @dev finalStateRootHash is used to set state root at the end of the data. - * @dev firstBlockInData is the first block that is included in the data submitted. - * @dev finalBlockInData is the last block that is included in the data submitted. - * @dev snarkHash is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. - */ - struct SupportingSubmissionDataV2 { - bytes32 finalStateRootHash; - uint256 firstBlockInData; - uint256 finalBlockInData; - bytes32 snarkHash; - } - /** * @notice Shnarf data for validating a shnarf. * @dev parentShnarf is the parent computed shnarf. @@ -91,18 +73,19 @@ interface ILineaRollup { * @dev kzgCommitment The blob KZG commitment. * @dev kzgProof The blob KZG point proof. */ - struct BlobSubmissionData { - SupportingSubmissionDataV2 submissionData; + struct BlobSubmission { uint256 dataEvaluationClaim; bytes kzgCommitment; bytes kzgProof; + bytes32 finalStateRootHash; + bytes32 snarkHash; } /** * @notice Supporting data for finalization with proof. * @dev NB: the dynamic sized fields are placed last on purpose for efficient keccaking on public input. * @dev parentStateRootHash is the expected last state root hash finalized. - * @dev finalBlockInData is the final block finalizing until. + * @dev endBlockNumber is the end block finalizing until. * @dev shnarfData contains data about the last data submission's shnarf used in finalization. * @dev lastFinalizedTimestamp is the expected last finalized block's timestamp. * @dev finalTimestamp is the timestamp of the last block being finalized. @@ -113,12 +96,12 @@ interface ILineaRollup { * @dev l1RollingHashMessageNumber is the calculated message number on L2 that is expected to match the existing L1 rolling hash. * This value will be used along with the stored last finalized L2 calculated message number in the public input. * @dev l2MerkleTreesDepth is the depth of all l2MerkleRoots. - * @dev l2MerkleRoots is an array of L2 message Merkle roots of depth l2MerkleTreesDepth between last finalized block and finalSubmissionData.finalBlockInData. + * @dev l2MerkleRoots is an array of L2 message Merkle roots of depth l2MerkleTreesDepth between last finalized block and finalSubmissionData.finalBlockNumber. * @dev l2MessagingBlocksOffsets indicates by offset from currentL2BlockNumber which L2 blocks contain MessageSent events. */ struct FinalizationDataV3 { bytes32 parentStateRootHash; - uint256 finalBlockInData; + uint256 endBlockNumber; ShnarfData shnarfData; uint256 lastFinalizedTimestamp; uint256 finalTimestamp; @@ -172,19 +155,11 @@ interface ILineaRollup { /** * @notice Emitted when compressed data is being submitted and verified succesfully on L1. * @dev The block range is indexed and parent shnarf included for state reconstruction simplicity. - * @param startBlock The indexed L2 block number indicating which block the data starts from. - * @param endBlock The indexed L2 block number indicating which block the data ends on. * @param parentShnarf The parent shnarf for the data being submitted. * @param shnarf The indexed shnarf for the data being submitted. * @param finalStateRootHash The L2 state root hash that the current blob submission ends on. NB: The last blob in the collection. */ - event DataSubmittedV3( - uint256 indexed startBlock, - uint256 indexed endBlock, - bytes32 parentShnarf, - bytes32 indexed shnarf, - bytes32 finalStateRootHash - ); + event DataSubmittedV3(bytes32 parentShnarf, bytes32 indexed shnarf, bytes32 finalStateRootHash); /** * @notice Emitted when L2 blocks have been finalized on L1. @@ -222,11 +197,6 @@ interface ILineaRollup { */ error PointEvaluationFailed(); - /** - * @dev Thrown when the blobhash equals the zero hash. - */ - error EmptyBlobData(); - /** * @dev Thrown when the blobhash at an index equals to the zero hash. */ @@ -242,21 +212,11 @@ interface ILineaRollup { */ error BlobSubmissionDataEmpty(uint256 emptyBlobIndex); - /** - * @dev Thrown when the starting block in the data item is out of sequence with the last block number. - */ - error DataStartingBlockDoesNotMatch(uint256 expected, uint256 actual); - /** * @dev Thrown when the current data was already submitted. */ error DataAlreadySubmitted(bytes32 currentDataHash); - /** - * @dev Thrown when the last finalized shnarf does not match the parent finalizing from. - */ - error LastFinalizedShnarfWrong(bytes32 expected, bytes32 actual); - /** * @dev Thrown when submissionData is empty. */ @@ -272,16 +232,6 @@ interface ILineaRollup { */ error FinalizationStateIncorrect(bytes32 expected, bytes32 value); - /** - * @dev Thrown when the first block is greater than final block in submission data. - */ - error FirstBlockGreaterThanFinalBlock(uint256 firstBlockNumber, uint256 finalBlockNumber); - - /** - * @dev Thrown when the first block in data is less than or equal to the last finalized block during data submission. - */ - error FirstBlockLessThanOrEqualToLastFinalizedBlock(uint256 firstBlockNumber, uint256 lastFinalizedBlock); - /** * @dev Thrown when the final block number in finalization data is less than or equal to the last finalized block during finalization. */ @@ -319,14 +269,14 @@ interface ILineaRollup { error BytesLengthNotMultipleOf32(); /** - * @dev Thrown when the snarkhash is the zero hash. + * @dev Thrown when the computed shnarf does not match what is expected. */ - error SnarkHashIsZeroHash(); + error FinalShnarfWrong(bytes32 expected, bytes32 value); /** - * @dev Thrown when the computed shnarf does not match what is expected. + * @dev Thrown when a shnarf does not exist for a parent blob. */ - error FinalShnarfWrong(bytes32 expected, bytes32 value); + error ParentBlobNotSubmitted(bytes32 shnarf); /** * @notice Adds or updates the verifier contract address for a proof type. @@ -356,12 +306,12 @@ interface ILineaRollup { * @notice Submit one or more EIP-4844 blobs. * @dev OPERATOR_ROLE is required to execute. * @dev This should be a blob carrying transaction. - * @param _blobSubmissionData The data for blob submission including proofs and required polynomials. + * @param _blobSubmissions The data for blob submission including proofs and required polynomials. * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. * @param _finalBlobShnarf The expected final shnarf post computation of all the blob shnarfs. */ function submitBlobs( - BlobSubmissionData[] calldata _blobSubmissionData, + BlobSubmission[] calldata _blobSubmissions, bytes32 _parentShnarf, bytes32 _finalBlobShnarf ) external; @@ -369,12 +319,12 @@ interface ILineaRollup { /** * @notice Submit blobs using compressed data via calldata. * @dev OPERATOR_ROLE is required to execute. - * @param _submissionData The supporting data for compressed data submission including compressed data. + * @param _submission The supporting data for compressed data submission including compressed data. * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. * @param _expectedShnarf The expected shnarf post computation of all the submission. */ function submitDataAsCalldata( - SubmissionDataV2 calldata _submissionData, + CompressedCalldataSubmission calldata _submission, bytes32 _parentShnarf, bytes32 _expectedShnarf ) external; diff --git a/contracts/contracts/test-contracts/TestLineaRollup.sol b/contracts/contracts/test-contracts/TestLineaRollup.sol index 013ca09ca..17083ba45 100644 --- a/contracts/contracts/test-contracts/TestLineaRollup.sol +++ b/contracts/contracts/test-contracts/TestLineaRollup.sol @@ -24,8 +24,8 @@ contract TestLineaRollup is LineaRollup { return _calculateY(_data, _x); } - function setupParentShnarf(bytes32 _shnarf, uint256 _finalBlockNumber) external { - shnarfFinalBlockNumbers[_shnarf] = _finalBlockNumber; + function setupParentShnarf(bytes32 _shnarf) external { + blobShnarfExists[_shnarf] = 1; } function setupParentDataShnarf(bytes32 _parentDataHash, bytes32 _shnarf) external { @@ -49,6 +49,6 @@ contract TestLineaRollup is LineaRollup { } function setShnarfFinalBlockNumber(bytes32 _shnarf, uint256 _finalBlockNumber) external { - shnarfFinalBlockNumbers[_shnarf] = _finalBlockNumber; + blobShnarfExists[_shnarf] = _finalBlockNumber; } } diff --git a/contracts/scripts/testEIP4844/SixInOne/sendBlobTransaction.ts b/contracts/scripts/testEIP4844/SixInOne/sendBlobTransaction.ts index 2ed8bfcee..4ccdfbe02 100644 --- a/contracts/scripts/testEIP4844/SixInOne/sendBlobTransaction.ts +++ b/contracts/scripts/testEIP4844/SixInOne/sendBlobTransaction.ts @@ -209,23 +209,21 @@ async function main() { // eslint-disable-next-line @typescript-eslint/no-explicit-any function mapToTuple(blobSubmissionDataItems: BlobSubmissionData[]): any { return blobSubmissionDataItems.map((blobSubmissionData) => [ - [ - blobSubmissionData.submissionData.finalStateRootHash, - blobSubmissionData.submissionData.firstBlockInData, - blobSubmissionData.submissionData.finalBlockInData, - blobSubmissionData.submissionData.snarkHash, - ], blobSubmissionData.dataEvaluationClaim, blobSubmissionData.kzgCommitment, blobSubmissionData.kzgProof, + blobSubmissionData.submissionData.finalStateRootHash, + blobSubmissionData.submissionData.snarkHash, ]); } function encodeCall(submissionData: BlobSubmissionData[]): DataHexString { + //submitBlobs((uint256,bytes,bytes,bytes32,bytes32)[],bytes32,bytes32)": "99467a35" + const encodedCall = ethers.concat([ - "0x42fbe842", + "0x99467a35", ethers.AbiCoder.defaultAbiCoder().encode( - ["tuple(tuple(bytes32,uint256,uint256,bytes32),uint256,bytes,bytes)[]", "bytes32", "bytes32"], + ["tuple(uint256,bytes,bytes,bytes32,bytes32)[]", "bytes32", "bytes32"], [ mapToTuple(submissionData), submissionData[0].parentSubmissionData.shnarf, @@ -354,9 +352,10 @@ async function sendProof( ]; console.log(proofData); - + //finalizeBlocks(bytes,uint256,(bytes32,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32),uint256,uint256,bytes32,bytes32,uint256,uint256,uint256,bytes32[],bytes))": "5603c65f" + //finalizeBlocks(bytes,uint256,(bytes32,uint256,(bytes32,bytes32,bytes32,bytes32,bytes32),uint256,uint256,bytes32,bytes32,uint256,uint256,uint256,bytes32[],bytes))": "5603c65f" const encodedCall = ethers.concat([ - "0x227be0dc", + "0x5603c65f", ethers.AbiCoder.defaultAbiCoder().encode( [ "bytes", diff --git a/contracts/test/LineaRollup.ts b/contracts/test/LineaRollup.ts index be6600db8..6edd28b3d 100644 --- a/contracts/test/LineaRollup.ts +++ b/contracts/test/LineaRollup.ts @@ -400,8 +400,8 @@ describe("Linea Rollup contract", () => { .submitDataAsCalldata(submissionData, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }), ).to.not.be.reverted; - const finalBlockNumber = await lineaRollup.shnarfFinalBlockNumbers(expectedShnarf); - expect(finalBlockNumber).to.equal(submissionData.finalBlockInData); + const blobShnarfExists = await lineaRollup.blobShnarfExists(expectedShnarf); + expect(blobShnarfExists).to.equal(1n); }); it("Should successfully submit 2 compressed data chunks in two transactions", async () => { @@ -419,9 +419,8 @@ describe("Linea Rollup contract", () => { }), ).to.not.be.reverted; - const finalBlockNumber = await lineaRollup.shnarfFinalBlockNumbers(secondExpectedShnarf); - - expect(finalBlockNumber).to.equal(secondSubmissionData.finalBlockInData); + const blobShnarfExists = await lineaRollup.blobShnarfExists(expectedShnarf); + expect(blobShnarfExists).to.equal(1n); }); it("Should emit an event while submitting 1 compressed data chunk", async () => { @@ -430,30 +429,11 @@ describe("Linea Rollup contract", () => { const submitDataCall = lineaRollup .connect(operator) .submitDataAsCalldata(submissionData, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }); - const eventArgs = [ - submissionData.firstBlockInData, - submissionData.finalBlockInData, - prevShnarf, - expectedShnarf, - submissionData.finalStateRootHash, - ]; + const eventArgs = [prevShnarf, expectedShnarf, submissionData.finalStateRootHash]; await expectEvent(lineaRollup, submitDataCall, "DataSubmittedV3", eventArgs); }); - it("Should fail if the stored shnarf block number + 1 does not match the starting submission number", async () => { - const [submissionData] = generateCallDataSubmission(0, 1); - - await lineaRollup.setShnarfFinalBlockNumber(prevShnarf, 99n); - - const submitDataCall = lineaRollup - .connect(operator) - .submitDataAsCalldata(submissionData, prevShnarf, secondExpectedShnarf, { gasLimit: 30_000_000 }); - const eventArgs = [100n, 1n]; - - await expectRevertWithCustomError(lineaRollup, submitDataCall, "DataStartingBlockDoesNotMatch", eventArgs); - }); - it("Should fail if the final state root hash is empty", async () => { const [submissionData] = generateCallDataSubmission(0, 1); @@ -463,27 +443,11 @@ describe("Linea Rollup contract", () => { .connect(operator) .submitDataAsCalldata(submissionData, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }); - await expectRevertWithCustomError(lineaRollup, submitDataCall, "FinalBlockStateEqualsZeroHash"); - }); - - it("Should fail if the block numbers are out of sequence", async () => { - const [firstSubmissionData, secondSubmissionData] = generateCallDataSubmission(0, 2); - - await expect( - lineaRollup - .connect(operator) - .submitDataAsCalldata(firstSubmissionData, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }), - ).to.not.be.reverted; - - const expectedFirstBlock = secondSubmissionData.firstBlockInData; - secondSubmissionData.firstBlockInData = secondSubmissionData.firstBlockInData + 1n; - - const submitDataCall = lineaRollup - .connect(operator) - .submitDataAsCalldata(secondSubmissionData, expectedShnarf, secondExpectedShnarf, { gasLimit: 30_000_000 }); - const eventArgs = [expectedFirstBlock, secondSubmissionData.firstBlockInData]; - - await expectRevertWithCustomError(lineaRollup, submitDataCall, "DataStartingBlockDoesNotMatch", eventArgs); + // TODO: Make the failure shnarf dynamic and computed + await expectRevertWithCustomError(lineaRollup, submitDataCall, "FinalShnarfWrong", [ + expectedShnarf, + "0xf53c28b2287f506b4df1b9de48cf3601392d54a73afe400a6f8f4ded2e0929ad", + ]); }); it("Should fail to submit where expected shnarf is wrong", async () => { @@ -534,36 +498,6 @@ describe("Linea Rollup contract", () => { await expectRevertWithCustomError(lineaRollup, submitDataCall, "IsPaused", [CALLDATA_SUBMISSION_PAUSE_TYPE]); }); - it("Should revert with FirstBlockLessThanOrEqualToLastFinalizedBlock when submitting data with firstBlockInData less than currentL2BlockNumber", async () => { - await lineaRollup.setLastFinalizedBlock(1_000_000); - - const submitDataCall = lineaRollup - .connect(operator) - .submitDataAsCalldata(DATA_ONE, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }); - - await expectRevertWithCustomError(lineaRollup, submitDataCall, "FirstBlockLessThanOrEqualToLastFinalizedBlock", [ - DATA_ONE.firstBlockInData, - 1000000, - ]); - }); - - it("Should revert with FirstBlockGreaterThanFinalBlock when submitting data with firstBlockInData greater than finalBlockInData", async () => { - const submissionData: CalldataSubmissionData = { - ...DATA_ONE, - firstBlockInData: DATA_ONE.firstBlockInData, - finalBlockInData: DATA_ONE.firstBlockInData - 1n, - }; - - const submitDataCall = lineaRollup - .connect(operator) - .submitDataAsCalldata(submissionData, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }); - - await expectRevertWithCustomError(lineaRollup, submitDataCall, "FirstBlockGreaterThanFinalBlock", [ - submissionData.firstBlockInData, - submissionData.finalBlockInData, - ]); - }); - it("Should revert with DataAlreadySubmitted when submitting same compressed data twice in 2 separate transactions", async () => { await lineaRollup .connect(operator) @@ -582,7 +516,7 @@ describe("Linea Rollup contract", () => { .submitDataAsCalldata(DATA_ONE, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }); const [dataOneCopy] = generateCallDataSubmission(0, 1); - dataOneCopy.finalBlockInData = 234253242n; + dataOneCopy.endBlockNumber = 234253242n; const submitDataCall = lineaRollup .connect(operator) @@ -601,14 +535,18 @@ describe("Linea Rollup contract", () => { .connect(operator) .submitDataAsCalldata(submissionData, prevShnarf, expectedShnarf, { gasLimit: 30_000_000 }); - await expectRevertWithCustomError(lineaRollup, submitDataCall, "SnarkHashIsZeroHash"); + // TODO: Make the failure shnarf dynamic and computed + await expectRevertWithCustomError(lineaRollup, submitDataCall, "FinalShnarfWrong", [ + expectedShnarf, + "0xa6b52564082728b51bb81a4fa92cfb4ec3af8de3f18b5d68ec27b89eead93293", + ]); }); }); describe("EIP-4844 Blob submission tests", () => { beforeEach(async () => { await lineaRollup.setLastFinalizedBlock(0); - await lineaRollup.setupParentShnarf(prevShnarf, 0); + await lineaRollup.setupParentShnarf(prevShnarf); await lineaRollup.setupParentDataShnarf(parentDataHash, prevShnarf); await lineaRollup.setupParentFinalizedStateRoot(parentDataHash, parentStateRootHash); }); @@ -649,17 +587,56 @@ describe("Linea Rollup contract", () => { expect(receipt).is.not.null; const expectedEventArgs = [ - blobDataSubmission[0].submissionData.firstBlockInData, - blobDataSubmission[0].submissionData.finalBlockInData, parentShnarf, finalShnarf, - blobDataSubmission[blobDataSubmission.length - 1].submissionData.finalStateRootHash, + blobDataSubmission[blobDataSubmission.length - 1].finalStateRootHash, ]; expectEventDirectFromReceiptData(lineaRollup as BaseContract, receipt!, "DataSubmittedV3", expectedEventArgs); - const finalBlockNumber = await lineaRollup.shnarfFinalBlockNumbers(finalShnarf); - expect(finalBlockNumber).to.equal(blobDataSubmission[0].submissionData.finalBlockInData); + const blobShnarfExists = await lineaRollup.blobShnarfExists(finalShnarf); + expect(blobShnarfExists).to.equal(1n); + }); + + it("Fails the blob submission when the parent shnarf is missing", async () => { + const operatorHDSigner = getWalletForIndex(2); + + const lineaRollupAddress = await lineaRollup.getAddress(); + const { blobDataSubmission, compressedBlobs, finalShnarf } = generateBlobDataSubmission(0, 1); + const nonExistingParentShnarf = generateRandomBytes(32); + + const encodedCall = lineaRollup.interface.encodeFunctionData("submitBlobs", [ + blobDataSubmission, + nonExistingParentShnarf, + finalShnarf, + ]); + + const { maxFeePerGas, maxPriorityFeePerGas } = await ethers.provider.getFeeData(); + const nonce = await operatorHDSigner.getNonce(); + + const transaction = Transaction.from({ + data: encodedCall, + maxPriorityFeePerGas: maxPriorityFeePerGas!, + maxFeePerGas: maxFeePerGas!, + to: lineaRollupAddress, + chainId: (await ethers.provider.getNetwork()).chainId, + type: 3, + nonce, + value: 0, + gasLimit: 5_000_000, + kzg, + maxFeePerBlobGas: 1n, + blobs: compressedBlobs, + }); + + const signedTx = await operatorHDSigner.signTransaction(transaction); + + await expectRevertWithCustomError( + lineaRollup, + ethers.provider.broadcastTransaction(signedTx), + "ParentBlobNotSubmitted", + [nonExistingParentShnarf], + ); }); it("Fails when the blob submission data is missing", async () => { @@ -776,7 +753,7 @@ describe("Linea Rollup contract", () => { const lineaRollupAddress = await lineaRollup.getAddress(); const { blobDataSubmission, compressedBlobs, parentShnarf, finalShnarf } = generateBlobDataSubmission(0, 1); - blobDataSubmission[0].submissionData.finalStateRootHash = HASH_ZERO; + blobDataSubmission[0].finalStateRootHash = HASH_ZERO; const encodedCall = lineaRollup.interface.encodeFunctionData("submitBlobs", [ blobDataSubmission, @@ -804,10 +781,12 @@ describe("Linea Rollup contract", () => { const signedTx = await operatorHDSigner.signTransaction(transaction); + // TODO: Make the failure shnarf dynamic and computed await expectRevertWithCustomError( lineaRollup, ethers.provider.broadcastTransaction(signedTx), - "FinalBlockStateEqualsZeroHash", + "FinalShnarfWrong", + [finalShnarf, "0x22f8fb954df8328627fe9c48b60192f4d970a92891417aaadea39300ca244d36"], ); }); @@ -819,96 +798,7 @@ describe("Linea Rollup contract", () => { // Set the snarkHash to HASH_ZERO for a specific index const emptyDataIndex = 0; - blobDataSubmission[emptyDataIndex].submissionData.snarkHash = HASH_ZERO; - - const encodedCall = lineaRollup.interface.encodeFunctionData("submitBlobs", [ - blobDataSubmission, - parentShnarf, - finalShnarf, - ]); - - const { maxFeePerGas, maxPriorityFeePerGas } = await ethers.provider.getFeeData(); - const nonce = await operatorHDSigner.getNonce(); - - const transaction = Transaction.from({ - data: encodedCall, - maxPriorityFeePerGas: maxPriorityFeePerGas!, - maxFeePerGas: maxFeePerGas!, - to: lineaRollupAddress, - chainId: (await ethers.provider.getNetwork()).chainId, - type: 3, - nonce, - value: 0, - gasLimit: 5_000_000, - kzg, - maxFeePerBlobGas: 1n, - blobs: compressedBlobs, - }); - - const signedTx = await operatorHDSigner.signTransaction(transaction); - - await expectRevertWithCustomError( - lineaRollup, - ethers.provider.broadcastTransaction(signedTx), - "SnarkHashIsZeroHash", - ); - }); - - it("Should fail if the block numbers are out of sequence", async () => { - const operatorHDSigner = getWalletForIndex(2); - - const lineaRollupAddress = await lineaRollup.getAddress(); - const { blobDataSubmission, compressedBlobs, parentShnarf, finalShnarf } = generateBlobDataSubmission(0, 2); - - blobDataSubmission[1].submissionData.firstBlockInData = - blobDataSubmission[1].submissionData.finalBlockInData + 1n; - - const encodedCall = lineaRollup.interface.encodeFunctionData("submitBlobs", [ - blobDataSubmission, - parentShnarf, - finalShnarf, - ]); - - const { maxFeePerGas, maxPriorityFeePerGas } = await ethers.provider.getFeeData(); - const nonce = await operatorHDSigner.getNonce(); - - const transaction = Transaction.from({ - data: encodedCall, - maxPriorityFeePerGas: maxPriorityFeePerGas!, - maxFeePerGas: maxFeePerGas!, - to: lineaRollupAddress, - chainId: (await ethers.provider.getNetwork()).chainId, - type: 3, - nonce, - value: 0, - gasLimit: 5_000_000, - kzg, - maxFeePerBlobGas: 1n, - blobs: compressedBlobs, - }); - - const signedTx = await operatorHDSigner.signTransaction(transaction); - - await expectRevertWithCustomError( - lineaRollup, - ethers.provider.broadcastTransaction(signedTx), - "DataStartingBlockDoesNotMatch", - [ - blobDataSubmission[0].submissionData.finalBlockInData + 1n, - blobDataSubmission[1].submissionData.firstBlockInData, - ], - ); - }); - - it("Should revert with FirstBlockLessThanOrEqualToLastFinalizedBlock when submitting data with firstBlockInData less than currentL2BlockNumber", async () => { - const operatorHDSigner = getWalletForIndex(2); - - const lineaRollupAddress = await lineaRollup.getAddress(); - const { blobDataSubmission, compressedBlobs, parentShnarf, finalShnarf } = generateBlobDataSubmission(0, 1); - - // Set the currentL2BlockNumber to a value greater than the firstBlockInData - const currentL2BlockNumber = 1_000_000n; - await lineaRollup.setLastFinalizedBlock(currentL2BlockNumber); + blobDataSubmission[emptyDataIndex].snarkHash = generateRandomBytes(32); const encodedCall = lineaRollup.interface.encodeFunctionData("submitBlobs", [ blobDataSubmission, @@ -939,52 +829,7 @@ describe("Linea Rollup contract", () => { await expectRevertWithCustomError( lineaRollup, ethers.provider.broadcastTransaction(signedTx), - "FirstBlockLessThanOrEqualToLastFinalizedBlock", - [blobDataSubmission[0].submissionData.firstBlockInData, currentL2BlockNumber], - ); - }); - - it("Should revert with FirstBlockGreaterThanFinalBlock when submitting data with firstBlockInData greater than finalBlockInData", async () => { - const operatorHDSigner = getWalletForIndex(2); - - const lineaRollupAddress = await lineaRollup.getAddress(); - const { blobDataSubmission, compressedBlobs, parentShnarf, finalShnarf } = generateBlobDataSubmission(0, 1); - - // Set the firstBlockInData to be greater than the finalBlockInData - blobDataSubmission[0].submissionData.finalBlockInData = - blobDataSubmission[0].submissionData.firstBlockInData - 1n; - - const encodedCall = lineaRollup.interface.encodeFunctionData("submitBlobs", [ - blobDataSubmission, - parentShnarf, - finalShnarf, - ]); - - const { maxFeePerGas, maxPriorityFeePerGas } = await ethers.provider.getFeeData(); - const nonce = await operatorHDSigner.getNonce(); - - const transaction = Transaction.from({ - data: encodedCall, - maxPriorityFeePerGas: maxPriorityFeePerGas!, - maxFeePerGas: maxFeePerGas!, - to: lineaRollupAddress, - chainId: (await ethers.provider.getNetwork()).chainId, - type: 3, - nonce, - value: 0, - gasLimit: 5_000_000, - kzg, - maxFeePerBlobGas: 1n, - blobs: compressedBlobs, - }); - - const signedTx = await operatorHDSigner.signTransaction(transaction); - - await expectRevertWithCustomError( - lineaRollup, - ethers.provider.broadcastTransaction(signedTx), - "FirstBlockGreaterThanFinalBlock", - [blobDataSubmission[0].submissionData.firstBlockInData, blobDataSubmission[0].submissionData.finalBlockInData], + "PointEvaluationFailed", ); }); @@ -1183,7 +1028,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: blobAggregatedProof1To155.l1RollingHash, l1RollingHashMessageNumber: BigInt(blobAggregatedProof1To155.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(blobAggregatedProof1To155.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(blobAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(blobAggregatedProof1To155.finalBlockNumber), parentStateRootHash: blobAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(blobAggregatedProof1To155.finalTimestamp), l2MerkleRoots: blobAggregatedProof1To155.l2MerkleRoots, @@ -1221,7 +1066,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: blobAggregatedProof1To155.l1RollingHash, l1RollingHashMessageNumber: BigInt(blobAggregatedProof1To155.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(blobAggregatedProof1To155.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(blobAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(blobAggregatedProof1To155.finalBlockNumber), parentStateRootHash: blobAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(blobAggregatedProof1To155.finalTimestamp), l2MerkleRoots: blobAggregatedProof1To155.l2MerkleRoots, @@ -1272,7 +1117,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: blobAggregatedProof1To155.l1RollingHash, l1RollingHashMessageNumber: BigInt(blobAggregatedProof1To155.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(blobAggregatedProof1To155.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(blobAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(blobAggregatedProof1To155.finalBlockNumber), parentStateRootHash: blobAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(blobAggregatedProof1To155.finalTimestamp), l2MerkleRoots: blobAggregatedProof1To155.l2MerkleRoots, @@ -1339,7 +1184,7 @@ describe("Linea Rollup contract", () => { }); describe("With and without submission data", () => { - it("Should revert if _finalizationData.finalBlockNumber is less than or equal to currentL2BlockNumber", async () => { + it("Should revert if _finalizationData.endBlockNumber is less than or equal to currentL2BlockNumber", async () => { await lineaRollup.setLastFinalizedBlock(10_000_000); const finalizationData = await generateFinalizationData(); @@ -1358,7 +1203,7 @@ describe("Linea Rollup contract", () => { lineaRollup, finalizeCall, "FinalBlockNumberLessThanOrEqualToLastFinalizedBlock", - [finalizationData.finalBlockInData, 10_000_000], + [finalizationData.endBlockNumber, 10_000_000], ); }); @@ -1393,9 +1238,6 @@ describe("Linea Rollup contract", () => { const parentStateRootHash = await lineaRollup.stateRootHashes(lastFinalizedBlockNumber); finalizationData.parentStateRootHash = parentStateRootHash; - const currentFinalizedShnarf = await lineaRollup.currentFinalizedShnarf(); - finalizationData.lastFinalizedShnarf = currentFinalizedShnarf; - const proof = calldataAggregatedProof1To155.aggregatedProof; const finalizeCall = lineaRollup @@ -1446,7 +1288,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: calculateRollingHash(HASH_ZERO, messageHash), l1RollingHashMessageNumber: 10n, lastFinalizedTimestamp: DEFAULT_LAST_FINALIZED_TIMESTAMP, - finalBlockInData: BigInt(calldataAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber), parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp), l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots, @@ -1507,7 +1349,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: calculateRollingHash(HASH_ZERO, messageHash), l1RollingHashMessageNumber: 10n, lastFinalizedTimestamp: DEFAULT_LAST_FINALIZED_TIMESTAMP, - finalBlockInData: BigInt(calldataAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber), parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(new Date(new Date().setHours(new Date().getHours() + 2)).getTime()), // Set to 2 hours in the future l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots, @@ -1551,7 +1393,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: calculateRollingHash(HASH_ZERO, messageHash), l1RollingHashMessageNumber: 10n, lastFinalizedTimestamp: DEFAULT_LAST_FINALIZED_TIMESTAMP, - finalBlockInData: BigInt(calldataAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber), parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp), l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots, @@ -1691,7 +1533,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: calldataAggregatedProof1To155.l1RollingHash, l1RollingHashMessageNumber: BigInt(calldataAggregatedProof1To155.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(calldataAggregatedProof1To155.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(calldataAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber), parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp), l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots, @@ -1729,7 +1571,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: calldataAggregatedProof1To155.l1RollingHash, l1RollingHashMessageNumber: BigInt(calldataAggregatedProof1To155.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(calldataAggregatedProof1To155.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(calldataAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber), parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp), l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots, @@ -1770,7 +1612,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: calldataAggregatedProof1To155.l1RollingHash, l1RollingHashMessageNumber: BigInt(calldataAggregatedProof1To155.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(calldataAggregatedProof1To155.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(calldataAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber), parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp), l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots, @@ -1809,7 +1651,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: calldataAggregatedProof1To155.l1RollingHash, l1RollingHashMessageNumber: BigInt(calldataAggregatedProof1To155.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(calldataAggregatedProof1To155.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(calldataAggregatedProof1To155.finalBlockNumber), + endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber), parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash, finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp), l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots, @@ -2055,13 +1897,7 @@ describe("Linea Rollup contract", () => { const receipt = await ethers.provider.getTransactionReceipt(txResponse.hash); - const expectedEventArgs = [ - blobSubmission[0].submissionData.firstBlockInData, - blobSubmission[blobSubmission.length - 1].submissionData.finalBlockInData, - parentShnarf, - finalShnarf, - blobSubmission[blobSubmission.length - 1].submissionData.finalStateRootHash, - ]; + const expectedEventArgs = [parentShnarf, finalShnarf, blobSubmission[blobSubmission.length - 1].finalStateRootHash]; expectEventDirectFromReceiptData(lineaRollup as BaseContract, receipt!, "DataSubmittedV3", expectedEventArgs); } @@ -2080,7 +1916,7 @@ describe("Linea Rollup contract", () => { l1RollingHash: proofData.l1RollingHash, l1RollingHashMessageNumber: BigInt(proofData.l1RollingHashMessageNumber), lastFinalizedTimestamp: BigInt(proofData.parentAggregationLastBlockTimestamp), - finalBlockInData: BigInt(proofData.finalBlockNumber), + endBlockNumber: BigInt(proofData.finalBlockNumber), parentStateRootHash: proofData.parentStateRootHash, finalTimestamp: BigInt(proofData.finalTimestamp), l2MerkleRoots: proofData.l2MerkleRoots, @@ -2100,7 +1936,7 @@ describe("Linea Rollup contract", () => { const eventArgs = [ BigInt(proofData.lastFinalizedBlockNumber) + 1n, - finalizationData.finalBlockInData, + finalizationData.endBlockNumber, proofData.finalShnarf, finalizationData.parentStateRootHash, finalStateRootHash, @@ -2109,13 +1945,13 @@ describe("Linea Rollup contract", () => { await expectEvent(lineaRollup, finalizeCompressedCall, "DataFinalizedV3", eventArgs); const [expectedFinalStateRootHash, lastFinalizedBlockNumber, lastFinalizedState] = await Promise.all([ - lineaRollup.stateRootHashes(finalizationData.finalBlockInData), + lineaRollup.stateRootHashes(finalizationData.endBlockNumber), lineaRollup.currentL2BlockNumber(), lineaRollup.currentFinalizedState(), ]); expect(expectedFinalStateRootHash).to.equal(finalizationData.shnarfData.finalStateRootHash); - expect(lastFinalizedBlockNumber).to.equal(finalizationData.finalBlockInData); + expect(lastFinalizedBlockNumber).to.equal(finalizationData.endBlockNumber); expect(lastFinalizedState).to.equal( generateKeccak256( ["uint256", "bytes32", "uint256"], @@ -2183,7 +2019,9 @@ describe("Linea Rollup contract", () => { // Deploy new implementation const newLineaRollupFactory = await ethers.getContractFactory("contracts/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory); + const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { + unsafeAllowRenames: true, + }); const upgradedContract = await newLineaRollup.waitForDeployment(); const upgradeCall = upgradedContract.reinitializeLineaRollupV6( @@ -2207,7 +2045,9 @@ describe("Linea Rollup contract", () => { // Deploy new implementation const newLineaRollupFactory = await ethers.getContractFactory("contracts/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory); + const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { + unsafeAllowRenames: true, + }); const upgradedContract = await newLineaRollup.waitForDeployment(); const upgradeCall = upgradedContract.reinitializeLineaRollupV6( newRoleAddresses, @@ -2224,7 +2064,9 @@ describe("Linea Rollup contract", () => { // Deploy new implementation const newLineaRollupFactory = await ethers.getContractFactory("contracts/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory); + const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { + unsafeAllowRenames: true, + }); const upgradedContract = await newLineaRollup.waitForDeployment(); await upgradedContract.reinitializeLineaRollupV6( newRoleAddresses, @@ -2246,7 +2088,9 @@ describe("Linea Rollup contract", () => { it("Should revert with ZeroAddressNotAllowed when addressWithRole is zero address in reinitializeLineaRollupV6", async () => { // Deploy new implementation const newLineaRollupFactory = await ethers.getContractFactory("contracts/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory); + const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { + unsafeAllowRenames: true, + }); const upgradedContract = await newLineaRollup.waitForDeployment(); const roleAddresses = [{ addressWithRole: ZeroAddress, role: DEFAULT_ADMIN_ROLE }, ...newRoleAddresses.slice(1)]; @@ -2265,7 +2109,9 @@ describe("Linea Rollup contract", () => { it("Should set all permissions", async () => { // Deploy new implementation const newLineaRollupFactory = await ethers.getContractFactory("contracts/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory); + const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { + unsafeAllowRenames: true, + }); const upgradedContract = await newLineaRollup.waitForDeployment(); await upgradedContract.reinitializeLineaRollupV6( @@ -2283,7 +2129,9 @@ describe("Linea Rollup contract", () => { it("Should set all pause types and unpause types in mappings and emit events", async () => { // Deploy new implementation const newLineaRollupFactory = await ethers.getContractFactory("contracts/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory); + const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { + unsafeAllowRenames: true, + }); const upgradedContract = await newLineaRollup.waitForDeployment(); const reinitializePromise = upgradedContract.reinitializeLineaRollupV6( diff --git a/contracts/test/common/helpers/dataGeneration.ts b/contracts/test/common/helpers/dataGeneration.ts index 47414a19c..7462ec841 100644 --- a/contracts/test/common/helpers/dataGeneration.ts +++ b/contracts/test/common/helpers/dataGeneration.ts @@ -10,12 +10,10 @@ import { import { FinalizationData, CalldataSubmissionData, - SubmissionAndCompressedData, - BlobSubmissionData, ShnarfData, ParentSubmissionData, ParentAndExpectedShnarf, - SubmissionData, + BlobSubmission, } from "../types"; import { generateRandomBytes, range } from "./general"; import { generateKeccak256 } from "./hashing"; @@ -28,7 +26,7 @@ export const generateL2MessagingBlocksOffsets = (start: number, end: number) => export async function generateFinalizationData(overrides?: Partial): Promise { return { aggregatedProof: generateRandomBytes(928), - finalBlockInData: 99n, + endBlockNumber: 99n, shnarfData: generateParentShnarfData(1), parentStateRootHash: generateRandomBytes(32), lastFinalizedTimestamp: BigInt((await networkTime.latest()) - 2), @@ -48,8 +46,6 @@ export function generateCallDataSubmission(startDataIndex: number, finalDataInde return COMPRESSED_SUBMISSION_DATA.slice(startDataIndex, finalDataIndex).map((data) => { const returnData = { finalStateRootHash: data.finalStateRootHash, - firstBlockInData: BigInt(data.conflationOrder.startingBlockNumber), - finalBlockInData: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), snarkHash: data.snarkHash, compressedData: ethers.hexlify(ethers.decodeBase64(data.compressedData)), }; @@ -61,23 +57,25 @@ export function generateBlobDataSubmission( startDataIndex: number, finalDataIndex: number, isMultiple: boolean = false, -): { blobDataSubmission: BlobSubmissionData[]; compressedBlobs: string[]; parentShnarf: string; finalShnarf: string } { +): { + blobDataSubmission: BlobSubmission[]; + compressedBlobs: string[]; + parentShnarf: string; + finalShnarf: string; +} { const dataSet = isMultiple ? BLOB_SUBMISSION_DATA_MULTIPLE_PROOF : BLOB_SUBMISSION_DATA; const compressedBlobs: string[] = []; const parentShnarf = dataSet[startDataIndex].prevShnarf; const finalShnarf = dataSet[finalDataIndex - 1].expectedShnarf; + const blobDataSubmission = dataSet.slice(startDataIndex, finalDataIndex).map((data) => { compressedBlobs.push(ethers.hexlify(ethers.decodeBase64(data.compressedData))); - const returnData: BlobSubmissionData = { - submissionData: { - finalStateRootHash: data.finalStateRootHash, - firstBlockInData: BigInt(data.conflationOrder.startingBlockNumber), - finalBlockInData: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), - snarkHash: data.snarkHash, - }, + const returnData: BlobSubmission = { dataEvaluationClaim: data.expectedY, kzgCommitment: data.commitment, kzgProof: data.kzgProofContract, + finalStateRootHash: data.finalStateRootHash, + snarkHash: data.snarkHash, }; return returnData; }); @@ -140,15 +138,15 @@ export function generateBlobParentShnarfData(index: number, multiple?: boolean): } export function generateExpectedParentSubmissionHash( - firstBlockInData: bigint, - finalBlockInData: bigint, + firstBlockNumber: bigint, + endBlockNumber: bigint, finalStateRootHash: string, shnarf: string, dataParentHash: string, ): string { return generateKeccak256( ["uint256", "uint256", "bytes32", "bytes32", "bytes32"], - [firstBlockInData, finalBlockInData, finalStateRootHash, shnarf, dataParentHash], + [firstBlockNumber, endBlockNumber, finalStateRootHash, shnarf, dataParentHash], ); } @@ -156,8 +154,8 @@ export function generateParentSubmissionDataForIndex(index: number): ParentSubmi if (index === 0) { return { finalStateRootHash: COMPRESSED_SUBMISSION_DATA[0].parentStateRootHash, - firstBlockInData: 0n, - finalBlockInData: 0n, + firstBlockNumber: 0n, + endBlockNumber: 0n, shnarf: generateKeccak256( ["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"], [HASH_ZERO, HASH_ZERO, COMPRESSED_SUBMISSION_DATA[0].parentStateRootHash, HASH_ZERO, HASH_ZERO], @@ -167,8 +165,8 @@ export function generateParentSubmissionDataForIndex(index: number): ParentSubmi return { finalStateRootHash: COMPRESSED_SUBMISSION_DATA[index - 1].finalStateRootHash, - firstBlockInData: BigInt(COMPRESSED_SUBMISSION_DATA[index - 1].conflationOrder.startingBlockNumber), - finalBlockInData: BigInt(COMPRESSED_SUBMISSION_DATA[index - 1].conflationOrder.upperBoundaries.slice(-1)[0]), + firstBlockNumber: BigInt(COMPRESSED_SUBMISSION_DATA[index - 1].conflationOrder.startingBlockNumber), + endBlockNumber: BigInt(COMPRESSED_SUBMISSION_DATA[index - 1].conflationOrder.upperBoundaries.slice(-1)[0]), shnarf: COMPRESSED_SUBMISSION_DATA[index - 1].expectedShnarf, }; } @@ -191,8 +189,8 @@ export function generateParentSubmissionDataForIndexForMultiple(index: number): if (index === 0) { return { finalStateRootHash: COMPRESSED_SUBMISSION_DATA_MULTIPLE_PROOF[0].parentStateRootHash, - firstBlockInData: 0n, - finalBlockInData: 0n, + firstBlockNumber: 0n, + endBlockNumber: 0n, shnarf: generateKeccak256( ["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"], [HASH_ZERO, HASH_ZERO, COMPRESSED_SUBMISSION_DATA_MULTIPLE_PROOF[0].parentStateRootHash, HASH_ZERO, HASH_ZERO], @@ -201,8 +199,8 @@ export function generateParentSubmissionDataForIndexForMultiple(index: number): } return { finalStateRootHash: COMPRESSED_SUBMISSION_DATA_MULTIPLE_PROOF[index - 1].finalStateRootHash, - firstBlockInData: BigInt(COMPRESSED_SUBMISSION_DATA_MULTIPLE_PROOF[index - 1].conflationOrder.startingBlockNumber), - finalBlockInData: BigInt( + firstBlockNumber: BigInt(COMPRESSED_SUBMISSION_DATA_MULTIPLE_PROOF[index - 1].conflationOrder.startingBlockNumber), + endBlockNumber: BigInt( COMPRESSED_SUBMISSION_DATA_MULTIPLE_PROOF[index - 1].conflationOrder.upperBoundaries.slice(-1)[0], ), shnarf: COMPRESSED_SUBMISSION_DATA_MULTIPLE_PROOF[index - 1].expectedShnarf, @@ -216,8 +214,8 @@ export function generateSubmissionData(startDataIndex: number, finalDataIndex: n parentStateRootHash: data.parentStateRootHash, dataParentHash: data.parentDataHash, finalStateRootHash: data.finalStateRootHash, - firstBlockInData: BigInt(data.conflationOrder.startingBlockNumber), - finalBlockInData: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), + firstBlockNumber: BigInt(data.conflationOrder.startingBlockNumber), + endBlockNumber: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), snarkHash: data.snarkHash, }, compressedData: ethers.hexlify(ethers.decodeBase64(data.compressedData)), @@ -236,8 +234,8 @@ export function generateSubmissionDataMultipleProofs( parentStateRootHash: data.parentStateRootHash, dataParentHash: data.parentDataHash, finalStateRootHash: data.finalStateRootHash, - firstBlockInData: BigInt(data.conflationOrder.startingBlockNumber), - finalBlockInData: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), + firstBlockNumber: BigInt(data.conflationOrder.startingBlockNumber), + endBlockNumber: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), snarkHash: data.snarkHash, }, compressedData: ethers.hexlify(ethers.decodeBase64(data.compressedData)), @@ -254,8 +252,8 @@ export function generateCallDataSubmissionMultipleProofs( parentStateRootHash: data.parentStateRootHash, dataParentHash: data.parentDataHash, finalStateRootHash: data.finalStateRootHash, - firstBlockInData: BigInt(data.conflationOrder.startingBlockNumber), - finalBlockInData: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), + firstBlockNumber: BigInt(data.conflationOrder.startingBlockNumber), + endBlockNumber: BigInt(data.conflationOrder.upperBoundaries.slice(-1)[0]), snarkHash: data.snarkHash, compressedData: ethers.hexlify(ethers.decodeBase64(data.compressedData)), parentShnarf: data.prevShnarf, @@ -274,8 +272,8 @@ export function generateSubmissionDataFromJSON( parentStateRootHash: parsedJSONData.parentStateRootHash, dataParentHash: parsedJSONData.parentDataHash, finalStateRootHash: parsedJSONData.finalStateRootHash, - firstBlockInData: BigInt(startingBlockNumber), - finalBlockInData: BigInt(endingBlockNumber), + firstBlockNumber: BigInt(startingBlockNumber), + endBlockNumber: BigInt(endingBlockNumber), snarkHash: parsedJSONData.snarkHash, compressedData: ethers.hexlify(ethers.decodeBase64(parsedJSONData.compressedData)), }; @@ -289,7 +287,7 @@ export function generateFinalizationDataFromJSON(parsedJSONData: any): Finalizat const { aggregatedProverVersion, aggregatedVerifierIndex, aggregatedProofPublicInput, ...data } = parsedJSONData; return { ...data, - finalBlockNumber: BigInt(data.finalBlockNumber), + endBlockNumber: BigInt(data.endBlockNumber), l1RollingHashMessageNumber: BigInt(data.l1RollingHashMessageNumber), l2MerkleTreesDepth: BigInt(data.l2MerkleTreesDepth), l2MessagingBlocksOffsets: data.l2MessagingBlocksOffsets, diff --git a/contracts/test/common/types.ts b/contracts/test/common/types.ts index 2bd08eb78..a33a30abd 100644 --- a/contracts/test/common/types.ts +++ b/contracts/test/common/types.ts @@ -33,24 +33,18 @@ export type DebugData = { finalHash: string; }; -export type SubmissionData = { - finalStateRootHash: string; - firstBlockInData: bigint; - finalBlockInData: bigint; - snarkHash: string; -}; - -export type BlobSubmissionData = { - submissionData: SubmissionData; +export type BlobSubmission = { dataEvaluationClaim: string; kzgCommitment: string; kzgProof: string; + finalStateRootHash: string; + snarkHash: string; }; export type ParentSubmissionData = { finalStateRootHash: string; - firstBlockInData: bigint; - finalBlockInData: bigint; + firstBlockNumber: bigint; + endBlockNumber: bigint; shnarf: string; }; @@ -67,18 +61,15 @@ export type ShnarfData = { dataEvaluationClaim: string; }; -export type CalldataSubmissionData = SubmissionData & { - compressedData: string; -}; - -export type SubmissionAndCompressedData = { - submissionData: SubmissionData; +export type CalldataSubmissionData = { + finalStateRootHash: string; + snarkHash: string; compressedData: string; }; export type FinalizationData = { aggregatedProof: string; - finalBlockInData: bigint; + endBlockNumber: bigint; shnarfData: ShnarfData; parentStateRootHash: string; lastFinalizedTimestamp: bigint; diff --git a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt index 56e43b539..b6d09b729 100644 --- a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt +++ b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt @@ -167,7 +167,7 @@ class CoordinatorConfigTest { "b1504a5f" to "BlobSubmissionDataIsMissing", "c0e41e1d" to "EmptyBlobDataAtIndex", "fb4cd6ef" to "FinalBlockDoesNotMatchShnarfFinalBlock", - "2526F108 " to "ShnarfAndFinalBlockNumberLengthsMismatched", + "2526F108" to "ShnarfAndFinalBlockNumberLengthsMismatched", "d3664fb3" to "FinalShnarfWrong", "4e686675" to "L2MerkleRootDoesNotExist", "e5d14425" to "L2MerkleRootAlreadyAnchored", @@ -180,6 +180,7 @@ class CoordinatorConfigTest { "b015579f" to "IsNotPaused", "3b174434" to "MessageHashesListLengthHigherThanOneHundred", "ca389c44" to "InvalidProofOrProofVerificationRanOutOfGas", + "42ab979d" to "ParentBlobNotSubmitted", // L2 Message Service "6446cc9c" to "MessageHashesListLengthIsZero", "d39e75f9" to "L1MessageNumberSynchronizationWrong",