1717// SPDX-License-Identifier: GPL-3.0-or-later
1818pragma solidity ^ 0.8.21 ;
1919
20+ import {Math} from "@openzeppelin/contracts/utils/math/Math.sol " ;
21+
2022import {DatasetType} from "src/v0.8/types/DatasetType.sol " ;
2123import {IMerkleUtils} from "src/v0.8/interfaces/utils/IMerkleUtils.sol " ;
2224import {DatasetProofLIB} from "src/v0.8/module/dataset/library/proof/DatasetProofLIB.sol " ;
@@ -39,6 +41,7 @@ library DatasetChallengeProofLIB {
3941 bytes32 [][] memory _siblings ,
4042 uint32 [] memory _paths ,
4143 bytes32 [] memory _roots ,
44+ uint64 [] memory _leafChallengeCount ,
4245 IMerkleUtils _merkle
4346 ) internal {
4447 //For each challenge proofs submitted by an auditor, the random seed must be different.
@@ -54,6 +57,7 @@ library DatasetChallengeProofLIB {
5457 _siblings,
5558 _paths,
5659 _roots,
60+ _leafChallengeCount,
5761 _merkle
5862 ),
5963 "Invalid challenge proofs "
@@ -81,34 +85,29 @@ library DatasetChallengeProofLIB {
8185 bytes32 [] memory _leaves ,
8286 bytes32 [][] memory _siblings ,
8387 uint32 [] memory _paths ,
84- bytes32 [] memory roots ,
88+ bytes32 [] memory _roots ,
89+ uint64 [] memory _leafChallengeCount ,
8590 IMerkleUtils _merkle
8691 ) private view returns (bool ) {
87- require (
88- roots.length == _leaves.length ,
89- "roots.length != _leaves.length "
90- );
91- require (
92- roots.length == _siblings.length ,
93- "roots.length != _siblings.length "
94- );
95- require (roots.length == _paths.length , "roots.length != _paths.length " );
96-
97- for (uint32 i = 0 ; i < roots.length ; i++ ) {
98- require (
99- _leaves[i] !=
100- 0x0000000000000000000000000000000000000000000000000000000000000000 ,
101- "invalid leaf "
102- );
103- if (
104- ! _merkle.isValidMerkleProof (
105- roots[i],
106- _leaves[i],
107- _siblings[i],
108- _paths[i]
109- )
110- ) {
111- return false ;
92+ uint32 index = 0 ;
93+ for (uint32 i = 0 ; i < _roots.length ; i++ ) {
94+ for (uint32 j = 0 ; j < _leafChallengeCount[i]; j++ ) {
95+ require (
96+ _leaves[index] !=
97+ 0x0000000000000000000000000000000000000000000000000000000000000000 ,
98+ "invalid leaf "
99+ );
100+ if (
101+ ! _merkle.isValidMerkleProof (
102+ _roots[i],
103+ _leaves[index],
104+ _siblings[index],
105+ _paths[index]
106+ )
107+ ) {
108+ return false ;
109+ }
110+ index++ ;
112111 }
113112 }
114113 return true ;
@@ -182,11 +181,11 @@ library DatasetChallengeProofLIB {
182181 /// @dev This function returns a car Challenge information for a specific dataset.
183182 /// @param _randomSeed The cars challenge random seed.
184183 /// @param _index The car index of challenge.
185- /// @param _proofsCount the cars Challenge count for specific dataset.
186- function generateChallengeIndex (
184+ /// @param _carNum the cars Challenge count for specific dataset.
185+ function genCarChallengeIndex (
187186 uint64 _randomSeed ,
188187 uint64 _index ,
189- uint64 _proofsCount
188+ uint64 _carNum
190189 ) internal pure returns (uint64 ) {
191190 // Convert randomness and index to bytes
192191 bytes memory input = new bytes (16 );
@@ -208,6 +207,44 @@ library DatasetChallengeProofLIB {
208207 carChallenge |= uint64 (uint8 (hash[i])) << uint64 (i * 8 );
209208 }
210209
211- return carChallenge % _proofsCount;
210+ return carChallenge % _carNum;
211+ }
212+
213+ /**
214+ * @dev Calculates the number of challenges per leaf for each car.
215+ * @param _carChallengesCount The number of cars participating in challenges.
216+ * @param _leavesChallengesCount The total number of challenges across all leaves.
217+ * @return An array containing the number of challenges per leaf for each car.
218+ */
219+ function leafChallengeCount (
220+ uint64 _carChallengesCount ,
221+ uint64 _leavesChallengesCount
222+ ) internal pure returns (uint64 [] memory ) {
223+ uint64 [] memory count = new uint64 [](_carChallengesCount);
224+ uint64 equalDistribution = _leavesChallengesCount / _carChallengesCount;
225+ uint64 remainder = _leavesChallengesCount % _carChallengesCount;
226+
227+ for (uint64 i = 0 ; i < _carChallengesCount; i++ ) {
228+ count[i] = equalDistribution;
229+ }
230+
231+ for (uint64 i = 0 ; i < remainder; i++ ) {
232+ count[i]++ ;
233+ }
234+
235+ return count;
236+ }
237+
238+ /**
239+ * @dev Calculates the number of challenges for each car based on the number of cars and total challenges.
240+ * @param _carNum The number of cars participating in challenges.
241+ * @param _leavesChallengesCount The total number of challenges across all leaves.
242+ * @return The number of challenges per car.
243+ */
244+ function carChallengeCount (
245+ uint64 _carNum ,
246+ uint64 _leavesChallengesCount
247+ ) internal pure returns (uint64 ) {
248+ return uint64 (Math.min (_carNum, _leavesChallengesCount));
212249 }
213250}
0 commit comments