The StorageDurationMultiplier FIP proposes increasing the maximum sector commitment length from 1.5 to 5 years. The naive way to achieve this goal is to increase the MaxSectorDuration
parameter from 1.5 to 5 years. This parameter tweak seems very simple, but it has an unaccounted externality of causing mitigation of possible PoRep bug to be much more difficult.
What follows is an implementation proposal allowing for a significant reduction in the effort required for future mitigation, while causing only a slight increase in complexity.
The core of the proposal is to separate the period of validity of a proof from the period of commitment for a sector. This leaves the 1.5-year sector extension process in place to maintain proof validity, but allows SPs to commit to longer periods.
The existing sector Expiration
property would be renamed to CommitmentExpiration
with a duration range from MinSectorLifetime
to MaxSectorLifetime
.
A new sector property is introduced called ProofExpiration
. The initial value of ProofExpiration
always falls into the range of (CurrentEpoch + MaxProofDuration - ProofRefereshWindow, CurrentEpoch + MaximumProofDuration]
or CommitmentExpiration
whichever is smaller.
MaxProofDuration
: maximum period from last commitment or refresh for which a PoRep is valid, set to 1.5y to match current behaviourProofRefreshWindow
: a window of time before ProofExpiration when the proof can be extended, set to 0.5yThe proof refresh window creates a trade-off: the larger the window, the more refreshes can happen in a singular batch, but more frequently each proof must be refreshed.
For example with MaxProofDuration
of 1.5y and ProofRefreshWindow
of 0.5y, each extension will be at least 1y and at most 1.5y. SPs will have to refresh sectors every MaxProofDuration - ProofRefereshWindow
epochs.
The proof expiration is not freely chosen by the SP, but takes a value that is derived and quantised from the sector’s activation epoch. It is calculated as:
$$ \begin{align*} \Delta E =\ & \mathrm{MaxProofDuration} - \mathrm{ProofRefereshWindow} \\ \text{ProofExpiration} =\ & \text{SectorActivation} + \Delta E \cdot \left\lceil \frac{\text{CurrentEpoch - SectorActivation} + 1}{\Delta E}\right \rceil + \mathrm{ProofRefereshWindow} \end{align*} $$
Current Epoch | Current Proof Expiration | New Proof Expiration | New Proof Duration |
---|---|---|---|
0 - Sector Activation | NaN | 1.5y | 1.5y |
1.0000y - Refresh | 1.5y | 2.5y | 1.5y |
1.4999y - Refresh | 1.5y | 2.5y | 1y |
1.6y - Refresh does nothing | 2.5y | 2.5y | 0.9y |
2.0000y - Refresh | 2.5y | 3.5y | 1.5y |
2.4999y - Refresh | 2.5y | 3.5y | 1y |
At initial commitment, it should calculate MaxProofDuration
, then the refresh has to be made every year. We can play with longer durations or shorter refresh windows, but shorter refresh window doesn’t buy us much.
Storage Provider can at any point call RefreshProofEpiration(SectorSelector)
requesting a refreshed proof expiration. This call only results in an actual refresh of the ProofExpiration
if called within ProofRefereshWindow
of the ProofExpiration
.
This call will refresh the ProofExpiration
of each of the requested sectors to fall into (CurrentEpoch + MaxProofDuration - ProofRefereshWindow, CurrentEpoch + MaximumProofDuration]
according to the above formula or CommitmentExpiration
whichever is smaller.