- 
                Notifications
    
You must be signed in to change notification settings  - Fork 17
 
feat(IValidator): Allow Forward Progress Despite Missing Proofs #321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b7b54ea
              29cf3b2
              c448c41
              91f66ec
              a14e411
              4c75bb6
              93b682d
              a62e6a7
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| 
          
            
          
           | 
    @@ -860,7 +860,6 @@ contract FilecoinWarmStorageService is | |||||
| revert Errors.InvalidChallengeEpoch(dataSetId, minWindow, maxWindow, challengeEpoch); | ||||||
| } | ||||||
| provingDeadlines[dataSetId] = firstDeadline; | ||||||
| provenThisPeriod[dataSetId] = false; | ||||||
| 
     | 
||||||
| // Initialize the activation epoch when proving first starts | ||||||
| // This marks when the data set became active for proving | ||||||
| 
          
            
          
           | 
    @@ -910,15 +909,6 @@ contract FilecoinWarmStorageService is | |||||
| emit FaultRecord(dataSetId, faultPeriods, provingDeadlines[dataSetId]); | ||||||
| } | ||||||
| 
     | 
||||||
| // Record the status of the current/previous proving period that's ending | ||||||
| if (provingDeadlines[dataSetId] != NO_PROVING_DEADLINE && provenThisPeriod[dataSetId]) { | ||||||
| // Determine the period ID that just completed | ||||||
| uint256 completedPeriodId = getProvingPeriodForEpoch(dataSetId, provingDeadlines[dataSetId] - 1); | ||||||
| 
     | 
||||||
| // Record whether this period was proven | ||||||
| provenPeriods[dataSetId][completedPeriodId >> 8] |= 1 << (completedPeriodId & 255); | ||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is already set by possessionProven There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hah, odd, any idea why it's in here too? hopefully just an oversight and not some functionality I'm not seeing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code has changed over time. Before it was a bitmap, this could set both true and false. Since I also see things initialized to false elsewhere, perhaps the original author did not know that false was the default.  | 
||||||
| } | ||||||
| 
     | 
||||||
| provingDeadlines[dataSetId] = nextDeadline; | ||||||
| provenThisPeriod[dataSetId] = false; | ||||||
| 
     | 
||||||
| 
          
            
          
           | 
    @@ -1126,8 +1116,10 @@ contract FilecoinWarmStorageService is | |||||
| * @return The period ID this epoch belongs to, or type(uint256).max if before activation | ||||||
| */ | ||||||
| function getProvingPeriodForEpoch(uint256 dataSetId, uint256 epoch) public view returns (uint256) { | ||||||
| uint256 activationEpoch = provingActivationEpoch[dataSetId]; | ||||||
| return _provingPeriodForEpoch(provingActivationEpoch[dataSetId], epoch); | ||||||
| } | ||||||
| 
     | 
||||||
| function _provingPeriodForEpoch(uint256 activationEpoch, uint256 epoch) internal view returns (uint256) { | ||||||
| // If proving wasn't activated or epoch is before activation | ||||||
| if (activationEpoch == 0 || epoch < activationEpoch) { | ||||||
| return type(uint256).max; // Invalid period | ||||||
| 
          
            
          
           | 
    @@ -1442,78 +1434,71 @@ contract FilecoinWarmStorageService is | |||||
| }); | ||||||
| } | ||||||
| 
     | 
||||||
| // Count proven epochs and find the last proven epoch | ||||||
| (uint256 provenEpochCount, uint256 lastProvenEpoch) = | ||||||
| // Count proven epochs up to toEpoch, possibly stopping earlier if unresolved | ||||||
| (uint256 provenEpochCount, uint256 settleUpTo) = | ||||||
| _findProvenEpochs(dataSetId, fromEpoch, toEpoch, activationEpoch); | ||||||
| 
     | 
||||||
| // If no epochs are proven, we can't settle anything | ||||||
| if (provenEpochCount == 0) { | ||||||
| return ValidationResult({ | ||||||
| modifiedAmount: 0, | ||||||
| settleUpto: fromEpoch, | ||||||
| settleUpto: settleUpTo, | ||||||
                
      
                  wjmelements marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||||||
| note: "No proven epochs in the requested range" | ||||||
| }); | ||||||
| } | ||||||
| 
     | 
||||||
| // Calculate the modified amount based on proven epochs | ||||||
| uint256 modifiedAmount = (proposedAmount * provenEpochCount) / totalEpochsRequested; | ||||||
| 
     | 
||||||
| return ValidationResult({ | ||||||
| modifiedAmount: modifiedAmount, | ||||||
| settleUpto: lastProvenEpoch, // Settle up to the last proven epoch | ||||||
| note: "" | ||||||
| }); | ||||||
| return ValidationResult({modifiedAmount: modifiedAmount, settleUpto: settleUpTo, note: ""}); | ||||||
| } | ||||||
| 
     | 
||||||
| function _findProvenEpochs(uint256 dataSetId, uint256 fromEpoch, uint256 toEpoch, uint256 activationEpoch) | ||||||
| internal | ||||||
| view | ||||||
| returns (uint256 provenEpochCount, uint256 settledUpTo) | ||||||
| returns (uint256 provenEpochCount, uint256 settleUpTo) | ||||||
| { | ||||||
| require(toEpoch >= activationEpoch && toEpoch <= block.number, Errors.InvalidEpochRange(fromEpoch, toEpoch)); | ||||||
| uint256 currentPeriod = getProvingPeriodForEpoch(dataSetId, block.number); | ||||||
| 
     | 
||||||
| if (fromEpoch < activationEpoch - 1) { | ||||||
| fromEpoch = activationEpoch - 1; | ||||||
| } | ||||||
| 
     | 
||||||
| uint256 startingPeriod = getProvingPeriodForEpoch(dataSetId, fromEpoch + 1); | ||||||
| uint256 startingPeriod = _provingPeriodForEpoch(activationEpoch, fromEpoch + 1); | ||||||
| 
     | 
||||||
| // handle first period separately | ||||||
| // handle first period separately; it may be partially settled already | ||||||
| uint256 startingPeriodDeadline = _calcPeriodDeadline(activationEpoch, startingPeriod); | ||||||
| 
     | 
||||||
| if (toEpoch < startingPeriodDeadline) { | ||||||
| if (_isPeriodProven(dataSetId, startingPeriod, currentPeriod)) { | ||||||
| if (_isPeriodProven(dataSetId, startingPeriod)) { | ||||||
| provenEpochCount = toEpoch - fromEpoch; | ||||||
| settledUpTo = toEpoch; | ||||||
| settleUpTo = toEpoch; | ||||||
| } else { | ||||||
| settleUpTo = fromEpoch; | ||||||
                
      
                  wjmelements marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||||||
| } | ||||||
| } else { | ||||||
| if (_isPeriodProven(dataSetId, startingPeriod, currentPeriod)) { | ||||||
| if (_isPeriodProven(dataSetId, startingPeriod)) { | ||||||
| provenEpochCount += (startingPeriodDeadline - fromEpoch); | ||||||
| } | ||||||
| 
     | 
||||||
| uint256 endingPeriod = getProvingPeriodForEpoch(dataSetId, toEpoch); | ||||||
| uint256 endingPeriod = _provingPeriodForEpoch(activationEpoch, toEpoch); | ||||||
| // loop through the proving periods between startingPeriod and endingPeriod | ||||||
| for (uint256 period = startingPeriod + 1; period < endingPeriod; period++) { | ||||||
| if (_isPeriodProven(dataSetId, period, currentPeriod)) { | ||||||
| if (_isPeriodProven(dataSetId, period)) { | ||||||
| provenEpochCount += maxProvingPeriod; | ||||||
| } | ||||||
| } | ||||||
| settledUpTo = _calcPeriodDeadline(activationEpoch, endingPeriod - 1); | ||||||
| settleUpTo = _calcPeriodDeadline(activationEpoch, endingPeriod - 1); | ||||||
| 
     | 
||||||
| // handle the last period separately | ||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
        Suggested change
       
    
  | 
||||||
| if (_isPeriodProven(dataSetId, endingPeriod, currentPeriod)) { | ||||||
| provenEpochCount += (toEpoch - settledUpTo); | ||||||
| settledUpTo = toEpoch; | ||||||
| if (_isPeriodProven(dataSetId, endingPeriod)) { | ||||||
| provenEpochCount += (toEpoch - settleUpTo); | ||||||
| settleUpTo = toEpoch; | ||||||
| } | ||||||
| } | ||||||
| return (provenEpochCount, settledUpTo); | ||||||
| return (provenEpochCount, settleUpTo); | ||||||
| } | ||||||
| 
     | 
||||||
| function _isPeriodProven(uint256 dataSetId, uint256 periodId, uint256 currentPeriod) private view returns (bool) { | ||||||
| if (periodId == currentPeriod) { | ||||||
| return provenThisPeriod[dataSetId]; | ||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because this is set by   | 
||||||
| } | ||||||
| function _isPeriodProven(uint256 dataSetId, uint256 periodId) private view returns (bool) { | ||||||
| uint256 isProven = provenPeriods[dataSetId][periodId >> 8] & (1 << (periodId & 255)); | ||||||
| return isProven != 0; | ||||||
| } | ||||||
| 
          
            
          
           | 
    ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can expect this to already be false when this data set's proving deadline is not initialized