Skip to content

Commit 7aa730c

Browse files
lovel8siriusyim
authored andcommitted
fix: πŸ› Fixed _getChallengeRoots function
βœ… Closes: #383
1 parent 74ae672 commit 7aa730c

File tree

2 files changed

+104
-51
lines changed

2 files changed

+104
-51
lines changed

β€Žsrc/v0.8/module/dataset/DatasetsChallenge.solβ€Ž

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,22 @@ contract DatasetsChallenge is
158158
"Not an election winner"
159159
);
160160

161-
bytes32[] memory roots = _getChallengeRoots(
162-
_datasetId,
163-
_randomSeed,
164-
roles.filplus().datasetRuleChallengePointsPerAuditor()
165-
);
161+
(
162+
bytes32[] memory roots,
163+
uint64[] memory leafChallengeCount
164+
) = _getChallengeRoots(
165+
_datasetId,
166+
_randomSeed,
167+
roles.filplus().datasetRuleChallengePointsPerAuditor()
168+
);
166169

167170
datasetChallengeProof._submitDatasetChallengeProofs(
168171
_randomSeed,
169172
_leaves,
170173
_siblings,
171174
_paths,
172175
roots,
176+
leafChallengeCount,
173177
roles.merkleUtils()
174178
);
175179

@@ -331,22 +335,36 @@ contract DatasetsChallenge is
331335
/// @dev This function returns the cars Challenge information for a specific dataset.
332336
/// @param _datasetId The ID of the dataset for which proof is submitted.
333337
/// @param _randomSeed The cars challenge random seed.
334-
/// @param _carChallengesCount the cars Challenge count for specific dataset.
338+
/// @param _challengesCount the Challenge count for specific dataset.
335339
function _getChallengeRoots(
336340
uint64 _datasetId,
337341
uint64 _randomSeed,
338-
uint64 _carChallengesCount
339-
) internal view returns (bytes32[] memory) {
340-
bytes32[] memory carChallenges = new bytes32[](_carChallengesCount);
341-
for (uint64 i = 0; i < _carChallengesCount; i++) {
342-
carChallenges[i] = _getChallengeRoot(
342+
uint64 _challengesCount
343+
) internal view returns (bytes32[] memory, uint64[] memory) {
344+
uint64 carNum = roles.datasetsProof().getDatasetProofCount(
345+
_datasetId,
346+
DatasetType.DataType.Source
347+
);
348+
349+
uint64 carChallengesCount = DatasetChallengeProofLIB.carChallengeCount(
350+
carNum,
351+
_challengesCount
352+
);
353+
uint64[] memory leafChallengeCount = DatasetChallengeProofLIB
354+
.leafChallengeCount(carChallengesCount, _challengesCount);
355+
bytes32[] memory roots = new bytes32[](carChallengesCount);
356+
357+
for (uint64 i = 0; i < carChallengesCount; i++) {
358+
roots[i] = _getChallengeRoot(
343359
_datasetId,
344360
_randomSeed,
345361
i,
346-
_carChallengesCount
362+
carChallengesCount,
363+
carNum
347364
);
348365
}
349-
return carChallenges;
366+
367+
return (roots, leafChallengeCount);
350368
}
351369

352370
/// @notice generate a car challenge.
@@ -355,24 +373,22 @@ contract DatasetsChallenge is
355373
/// @param _randomSeed The cars challenge random seed.
356374
/// @param _index The car index of challenge.
357375
/// @param _carChallengesCount the cars Challenge count for specific dataset.
376+
/// @param _carNum the cars count for specific dataset.
358377
function _getChallengeRoot(
359378
uint64 _datasetId,
360379
uint64 _randomSeed,
361380
uint64 _index,
362-
uint64 _carChallengesCount
381+
uint64 _carChallengesCount,
382+
uint64 _carNum
363383
) internal view returns (bytes32) {
364384
uint64 index = 0;
365-
uint64 proofsCount = roles.datasetsProof().getDatasetProofCount(
366-
_datasetId,
367-
DatasetType.DataType.Source
368-
);
369-
if (_carChallengesCount == proofsCount) {
385+
if (_carChallengesCount == _carNum) {
370386
index = _index;
371387
} else {
372-
index = DatasetChallengeProofLIB.generateChallengeIndex(
388+
index = DatasetChallengeProofLIB.genCarChallengeIndex(
373389
_randomSeed,
374390
_index,
375-
proofsCount
391+
_carNum
376392
);
377393
}
378394

β€Žsrc/v0.8/module/dataset/library/challenge/DatasetChallengeProofLIB.solβ€Ž

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
// SPDX-License-Identifier: GPL-3.0-or-later
1818
pragma solidity ^0.8.21;
1919

20+
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
21+
2022
import {DatasetType} from "src/v0.8/types/DatasetType.sol";
2123
import {IMerkleUtils} from "src/v0.8/interfaces/utils/IMerkleUtils.sol";
2224
import {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

Comments
Β (0)