From 9b62333d39e4ed5558285a8d0bdb55fd03d6da2c Mon Sep 17 00:00:00 2001 From: QUAQ Date: Wed, 28 Feb 2024 17:20:48 -0600 Subject: [PATCH] simplify blob verificaiton interface --- .../src/core/EigenDAServiceManagerStorage.sol | 6 +-- .../src/interfaces/IEigenDAServiceManager.sol | 13 ++---- .../src/libraries/EigenDARollupUtils.sol | 16 ++++++++ contracts/test/unit/EigenDABlobUtils.t.sol | 40 +++++++------------ contracts/test/unit/MockRollup.t.sol | 21 +++++----- 5 files changed, 44 insertions(+), 52 deletions(-) diff --git a/contracts/src/core/EigenDAServiceManagerStorage.sol b/contracts/src/core/EigenDAServiceManagerStorage.sol index 4d2531c665..84cbef1dd0 100644 --- a/contracts/src/core/EigenDAServiceManagerStorage.sol +++ b/contracts/src/core/EigenDAServiceManagerStorage.sol @@ -16,10 +16,6 @@ abstract contract EigenDAServiceManagerStorage is IEigenDAServiceManager { /// @notice Unit of measure (in blocks) for which data will be stored for after confirmation. uint32 public constant STORE_DURATION_BLOCKS = 2 weeks / 12 seconds; - /// @notice Minimum Batch size, in bytes. - uint32 internal constant MIN_STORE_SIZE = 32; - /// @notice Maximum Batch size, in bytes. - uint32 internal constant MAX_STORE_SIZE = 4e9; /** * @notice The maximum amount of blocks in the past that the service will consider stake amounts to still be 'valid'. * @dev To clarify edge cases, the middleware can look `BLOCK_STALE_MEASURE` blocks into the past, i.e. it may trust stakes from the interval @@ -29,6 +25,8 @@ abstract contract EigenDAServiceManagerStorage is IEigenDAServiceManager { * have to serve after they've deregistered. */ uint32 public constant BLOCK_STALE_MEASURE = 150; + + bytes public constant quorumAdversaryThresholdPercentages = hex"3232"; /// @notice The current batchId uint32 public batchId; diff --git a/contracts/src/interfaces/IEigenDAServiceManager.sol b/contracts/src/interfaces/IEigenDAServiceManager.sol index bcaddd9dc2..b2e8d4729b 100644 --- a/contracts/src/interfaces/IEigenDAServiceManager.sol +++ b/contracts/src/interfaces/IEigenDAServiceManager.sol @@ -54,19 +54,9 @@ interface IEigenDAServiceManager is IServiceManager { struct BatchMetadata { BatchHeader batchHeader; // the header of the data store bytes32 signatoryRecordHash; // the hash of the signatory record - uint96 fee; // the amount of paymentToken paid for the datastore uint32 confirmationBlockNumber; // the block number at which the batch was confirmed } - // Relevant metadata for a given datastore - struct BatchMetadataWithSignatoryRecord { - bytes32 batchHeaderHash; // the header hash of the data store - uint32 referenceBlockNumber; // the block number at which stakes - bytes32[] nonSignerPubkeyHashes; // the pubkeyHashes of all of the nonSigners - uint96 fee; // the amount of paymentToken paid for the datastore - uint32 blockNumber; // the block number at which the datastore was confirmed - } - // FUNCTIONS /// @notice mapping between the batchId to the hash of the metadata of the corresponding Batch @@ -94,4 +84,7 @@ interface IEigenDAServiceManager is IServiceManager { /// @notice The maximum amount of blocks in the past that the service will consider stake amounts to still be 'valid'. function BLOCK_STALE_MEASURE() external view returns (uint32); + + /// @notice Returns the bytes array of quotaAdversaryThresholdPercentages + function quorumAdversaryThresholdPercentages() external view returns (bytes memory); } diff --git a/contracts/src/libraries/EigenDARollupUtils.sol b/contracts/src/libraries/EigenDARollupUtils.sol index a342a0566d..1880023f4c 100644 --- a/contracts/src/libraries/EigenDARollupUtils.sol +++ b/contracts/src/libraries/EigenDARollupUtils.sol @@ -63,6 +63,13 @@ library EigenDARollupUtils { "EigenDARollupUtils.verifyBlob: adversaryThresholdPercentage is not valid" ); + uint8 _adversaryThresholdPercentage = getQuorumAdversaryThreshold(eigenDAServiceManager, blobHeader.quorumBlobParams[i].quorumNumber); + if(_adversaryThresholdPercentage > 0){ + require(blobHeader.quorumBlobParams[i].adversaryThresholdPercentage >= _adversaryThresholdPercentage, + "EigenDARollupUtils.verifyBlob: adversaryThresholdPercentage is not met" + ); + } + // make sure that the stake signed for is greater than the given quorumThresholdPercentage require(uint8(blobVerificationProof.batchMetadata.batchHeader.quorumThresholdPercentages[uint8(blobVerificationProof.quorumThresholdIndexes[i])]) >= blobHeader.quorumBlobParams[i].quorumThresholdPercentage, @@ -72,6 +79,15 @@ library EigenDARollupUtils { } } + function getQuorumAdversaryThreshold( + IEigenDAServiceManager eigenDAServiceManager, + uint256 quorumNumber + ) public view returns(uint8 adversaryThresholdPercentage) { + if(eigenDAServiceManager.quorumAdversaryThresholdPercentages().length > quorumNumber){ + adversaryThresholdPercentage = uint8(eigenDAServiceManager.quorumAdversaryThresholdPercentages()[quorumNumber]); + } + } + /** * @notice opens the KZG commitment at a point * @param point the point to evaluate the polynomial at diff --git a/contracts/test/unit/EigenDABlobUtils.t.sol b/contracts/test/unit/EigenDABlobUtils.t.sol index 021ed36970..11d1071d3f 100644 --- a/contracts/test/unit/EigenDABlobUtils.t.sol +++ b/contracts/test/unit/EigenDABlobUtils.t.sol @@ -26,14 +26,12 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { address confirmer = address(uint160(uint256(keccak256(abi.encodePacked("confirmer"))))); address notConfirmer = address(uint160(uint256(keccak256(abi.encodePacked("notConfirmer"))))); - address newFeeSetter = address(uint160(uint256(keccak256(abi.encodePacked("newFeeSetter"))))); EigenDABlobUtilsHarness eigenDABlobUtilsHarness; EigenDAServiceManager eigenDAServiceManager; EigenDAServiceManager eigenDAServiceManagerImplementation; - uint256 feePerBytePerTime = 0; uint8 defaultCodingRatioPercentage = 10; uint32 defaultReferenceBlockNumber = 100; uint32 defaultConfirmationBlockNumber = 1000; @@ -73,9 +71,9 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { function testVerifyBlob_TwoQuorums(uint256 pseudoRandomNumber) public { uint256 numQuorumBlobParams = 2; IEigenDAServiceManager.BlobHeader[] memory blobHeader = new IEigenDAServiceManager.BlobHeader[](2); - blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams); uint256 anotherPseudoRandomNumber = uint256(keccak256(abi.encodePacked(pseudoRandomNumber))); - blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams); IEigenDAServiceManager.BatchHeader memory batchHeader; bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); @@ -92,7 +90,6 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { IEigenDAServiceManager.BatchMetadata memory batchMetadata; batchMetadata.batchHeader = batchHeader; batchMetadata.signatoryRecordHash = keccak256(abi.encodePacked("signatoryRecordHash")); - batchMetadata.fee = 100; batchMetadata.confirmationBlockNumber = defaultConfirmationBlockNumber; stdstore @@ -120,9 +117,9 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { function testVerifyBlob_InvalidMetadataHash(uint256 pseudoRandomNumber) public { uint256 numQuorumBlobParams = pseudoRandomNumber % 192; IEigenDAServiceManager.BlobHeader[] memory blobHeader = new IEigenDAServiceManager.BlobHeader[](2); - blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams); uint256 anotherPseudoRandomNumber = uint256(keccak256(abi.encodePacked(pseudoRandomNumber))); - blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams); EigenDARollupUtils.BlobVerificationProof memory blobVerificationProof; blobVerificationProof.batchId = defaultBatchId; @@ -134,9 +131,9 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { function testVerifyBlob_InvalidMerkleProof(uint256 pseudoRandomNumber) public { uint256 numQuorumBlobParams = pseudoRandomNumber % 192; IEigenDAServiceManager.BlobHeader[] memory blobHeader = new IEigenDAServiceManager.BlobHeader[](2); - blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams); uint256 anotherPseudoRandomNumber = uint256(keccak256(abi.encodePacked(pseudoRandomNumber))); - blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams); // add dummy batch metadata IEigenDAServiceManager.BatchMetadata memory batchMetadata; @@ -160,9 +157,9 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { function testVerifyBlob_RandomNumberOfQuorums(uint256 pseudoRandomNumber) public { uint256 numQuorumBlobParams = pseudoRandomNumber % 192; IEigenDAServiceManager.BlobHeader[] memory blobHeader = new IEigenDAServiceManager.BlobHeader[](2); - blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams); uint256 anotherPseudoRandomNumber = uint256(keccak256(abi.encodePacked(pseudoRandomNumber))); - blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams); IEigenDAServiceManager.BatchHeader memory batchHeader; bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); @@ -179,7 +176,6 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { IEigenDAServiceManager.BatchMetadata memory batchMetadata; batchMetadata.batchHeader = batchHeader; batchMetadata.signatoryRecordHash = keccak256(abi.encodePacked("signatoryRecordHash")); - batchMetadata.fee = 100; batchMetadata.confirmationBlockNumber = defaultConfirmationBlockNumber; stdstore @@ -207,9 +203,9 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { function testVerifyBlob_QuorumNumberMismatch(uint256 pseudoRandomNumber) public { uint256 numQuorumBlobParams = 2; IEigenDAServiceManager.BlobHeader[] memory blobHeader = new IEigenDAServiceManager.BlobHeader[](2); - blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams); uint256 anotherPseudoRandomNumber = uint256(keccak256(abi.encodePacked(pseudoRandomNumber))); - blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams); IEigenDAServiceManager.BatchHeader memory batchHeader; bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); @@ -226,7 +222,6 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { IEigenDAServiceManager.BatchMetadata memory batchMetadata; batchMetadata.batchHeader = batchHeader; batchMetadata.signatoryRecordHash = keccak256(abi.encodePacked("signatoryRecordHash")); - batchMetadata.fee = 100; batchMetadata.confirmationBlockNumber = defaultConfirmationBlockNumber; stdstore @@ -253,9 +248,9 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { function testVerifyBlob_QuorumThresholdNotMet(uint256 pseudoRandomNumber) public { uint256 numQuorumBlobParams = 2; IEigenDAServiceManager.BlobHeader[] memory blobHeader = new IEigenDAServiceManager.BlobHeader[](2); - blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[0] = _generateRandomBlobHeader(pseudoRandomNumber, numQuorumBlobParams); uint256 anotherPseudoRandomNumber = uint256(keccak256(abi.encodePacked(pseudoRandomNumber))); - blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[1] = _generateRandomBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams); IEigenDAServiceManager.BatchHeader memory batchHeader; bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); @@ -272,7 +267,6 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { IEigenDAServiceManager.BatchMetadata memory batchMetadata; batchMetadata.batchHeader = batchHeader; batchMetadata.signatoryRecordHash = keccak256(abi.encodePacked("signatoryRecordHash")); - batchMetadata.fee = 100; batchMetadata.confirmationBlockNumber = defaultConfirmationBlockNumber; stdstore @@ -297,7 +291,7 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { } // generates a random blob header with the given coding ratio percentage as the ratio of original data to encoded data - function _generateRandomBlobHeader(uint256 pseudoRandomNumber, uint256 numQuorumsBlobParams, uint8 codingRatioPercentage) internal returns (IEigenDAServiceManager.BlobHeader memory) { + function _generateRandomBlobHeader(uint256 pseudoRandomNumber, uint256 numQuorumsBlobParams) internal returns (IEigenDAServiceManager.BlobHeader memory) { if(pseudoRandomNumber == 0) { pseudoRandomNumber = 1; } @@ -317,13 +311,7 @@ contract EigenDABlobUtilsUnit is BLSMockAVSDeployer { blobHeader.quorumBlobParams[i].quorumNumber = uint8(uint256(blobHeader.quorumBlobParams[i].quorumNumber) + 1) % 192; } quorumNumbersUsed[blobHeader.quorumBlobParams[i].quorumNumber] = true; - blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = uint8(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].adversaryThresholdPercentage", i)))) % 100; - // make the adversaryRatioPercentage at most 100 - codingRatioPercentage - uint256 j = uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].adversaryThresholdPercentage nonce", i))); - while(blobHeader.quorumBlobParams[i].adversaryThresholdPercentage > 100 - codingRatioPercentage) { - blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = uint8(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].adversaryThresholdPercentage", j)))) % 100; - j++; - } + blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, blobHeader.quorumBlobParams[i].quorumNumber); blobHeader.quorumBlobParams[i].chunkLength = uint32(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].chunkLength", i)))); blobHeader.quorumBlobParams[i].quorumThresholdPercentage = blobHeader.quorumBlobParams[i].adversaryThresholdPercentage + 1; } diff --git a/contracts/test/unit/MockRollup.t.sol b/contracts/test/unit/MockRollup.t.sol index ac6f65d77f..cf3f13f275 100644 --- a/contracts/test/unit/MockRollup.t.sol +++ b/contracts/test/unit/MockRollup.t.sol @@ -25,7 +25,6 @@ contract MockRollupTest is BLSMockAVSDeployer { EigenDAServiceManager eigenDAServiceManager; EigenDAServiceManager eigenDAServiceManagerImplementation; - uint256 feePerBytePerTime = 0; uint8 defaultCodingRatioPercentage = 10; uint32 defaultReferenceBlockNumber = 100; uint32 defaultConfirmationBlockNumber = 1000; @@ -115,9 +114,9 @@ contract MockRollupTest is BLSMockAVSDeployer { function _getCommitment(uint256 pseudoRandomNumber) internal returns (IEigenDAServiceManager.BlobHeader memory, EigenDARollupUtils.BlobVerificationProof memory){ uint256 numQuorumBlobParams = 2; IEigenDAServiceManager.BlobHeader[] memory blobHeader = new IEigenDAServiceManager.BlobHeader[](2); - blobHeader[0] = _generateBlobHeader(pseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[0] = _generateBlobHeader(pseudoRandomNumber, numQuorumBlobParams); uint256 anotherPseudoRandomNumber = uint256(keccak256(abi.encodePacked(pseudoRandomNumber))); - blobHeader[1] = _generateBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams, defaultCodingRatioPercentage); + blobHeader[1] = _generateBlobHeader(anotherPseudoRandomNumber, numQuorumBlobParams); IEigenDAServiceManager.BatchHeader memory batchHeader; bytes memory firstBlobHash = abi.encodePacked(blobHeader[0].hashBlobHeader()); @@ -134,7 +133,6 @@ contract MockRollupTest is BLSMockAVSDeployer { IEigenDAServiceManager.BatchMetadata memory batchMetadata; batchMetadata.batchHeader = batchHeader; batchMetadata.signatoryRecordHash = keccak256(abi.encodePacked("signatoryRecordHash")); - batchMetadata.fee = 100; batchMetadata.confirmationBlockNumber = defaultConfirmationBlockNumber; stdstore @@ -156,7 +154,7 @@ contract MockRollupTest is BLSMockAVSDeployer { return (blobHeader[1], blobVerificationProof); } - function _generateBlobHeader(uint256 pseudoRandomNumber, uint256 numQuorumsBlobParams, uint8 codingRatioPercentage) internal returns (IEigenDAServiceManager.BlobHeader memory) { + function _generateBlobHeader(uint256 pseudoRandomNumber, uint256 numQuorumsBlobParams) internal returns (IEigenDAServiceManager.BlobHeader memory) { if(pseudoRandomNumber == 0) { pseudoRandomNumber = 1; } @@ -174,13 +172,7 @@ contract MockRollupTest is BLSMockAVSDeployer { blobHeader.quorumBlobParams[i].quorumNumber = uint8(uint256(blobHeader.quorumBlobParams[i].quorumNumber) + 1) % 192; } quorumNumbersUsed[blobHeader.quorumBlobParams[i].quorumNumber] = true; - blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = uint8(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].adversaryThresholdPercentage", i)))) % 100; - // make the adversaryRatioPercentage at most 100 - codingRatioPercentage - uint256 j = uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].adversaryThresholdPercentage nonce", i))); - while(blobHeader.quorumBlobParams[i].adversaryThresholdPercentage > 100 - codingRatioPercentage) { - blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = uint8(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].adversaryThresholdPercentage", j)))) % 100; - j++; - } + blobHeader.quorumBlobParams[i].adversaryThresholdPercentage = EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, blobHeader.quorumBlobParams[i].quorumNumber); blobHeader.quorumBlobParams[i].chunkLength = uint32(uint256(keccak256(abi.encodePacked(pseudoRandomNumber, "blobHeader.quorumBlobParams[i].chunkLength", i)))); blobHeader.quorumBlobParams[i].quorumThresholdPercentage = blobHeader.quorumBlobParams[i].adversaryThresholdPercentage + 1; } @@ -192,4 +184,9 @@ contract MockRollupTest is BLSMockAVSDeployer { return blobHeader; } + function testGetQuorumAdversaryThreshold () public { + require(EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, 0) == 50, "getQuorumAdversaryThreshold failed"); + require(EigenDARollupUtils.getQuorumAdversaryThreshold(eigenDAServiceManager, 1) == 50, "getQuorumAdversaryThreshold failed"); + } + } \ No newline at end of file