-
Notifications
You must be signed in to change notification settings - Fork 177
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
FIP-0045 updates removing opt-in migration #455
Changes from all commits
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 | ||||
---|---|---|---|---|---|---|
|
@@ -11,13 +11,9 @@ requires: FIP-0034 | |||||
--- | ||||||
|
||||||
TODO: | ||||||
- Re-spec ExtendClaimTerms as a token receiver hook value rather than explicit method | ||||||
- Spec methods for sector migration on miner, market, and verifreg actors | ||||||
- Spec change to SectorOnChainInfo to distinguish migrated sectors | ||||||
- Figure out best migration plan for pending deals, pre-committed sectors | ||||||
- Confirm policy for built-in market actor's default term maximum | ||||||
- Spec token receiver hook payload schema for allocation requests | ||||||
- Spec token receiver hook payload for extending allocations with new datacap | ||||||
- Market method for fetching allocation/claim ids for deals (needed?) | ||||||
- Spec hook/method for a different client extending the claim by spending DataCap (needed?). | ||||||
|
||||||
|
||||||
## Simple Summary | ||||||
|
@@ -83,7 +79,7 @@ and is much simpler than the Filecoin Plus premium proposal that also attempted | |||||
- *Claim*: a provider's assertion they are storing all or part of an allocation | ||||||
- *Term*: period of time for which a DataCap allocation or claim is valid or active. | ||||||
|
||||||
### Data cap allocations | ||||||
### Verified Registry DataCap allocations | ||||||
|
||||||
The Filecoin Plus verified registry actor is extended to record allocations of DataCap to specific | ||||||
pieces of data to be stored by a provider. An allocation is independent of any deal with the | ||||||
|
@@ -114,14 +110,18 @@ struct Allocation { | |||||
``` | ||||||
|
||||||
An allocation specifies a range of terms for which the provider may commit the data, between some | ||||||
minimum and maximum. An allocation's maximum term must be at least as large as its minimum term. | ||||||
|
||||||
minimum and maximum. | ||||||
An allocation's maximum term must be at least as large as its minimum term. | ||||||
Due to the implementation of term enforcement (details below), clients should leave a large buffer | ||||||
between the minimum and maximum term to make the allocation practical for a provider. | ||||||
|
||||||
Network policy limits the maximum value for an allocation's expiration, | ||||||
so that an allocation cannot occupy non-useful DataCap indefinitely. | ||||||
|
||||||
**Parameters** | ||||||
- The minimum allowed value for `TermMinimum` is 6 months. | ||||||
- The maximum allowed value for `TermMaximum` is 5 years (can be increased by a future FIP). | ||||||
- `MinimumVerifiedAllocationTerm`: The minimum allowed value for `TermMinimum` is 6 months. | ||||||
- `MaximumVerifiedAllocationTerm`: The maximum allowed value for `TermMaximum` is 5 years (can be increased by a future FIP). | ||||||
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
|
||||||
- `MaximumVerifiedAllocationExpiration`: The maximum difference between `Expiration` and the epoch at which an allocation is created is 60 days. | ||||||
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. Why 60 days? Is this the current expiration term for DataCap? 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. I chose 60 days as a reasonable balance between flexibility for providers scheduling deal-making, and the value being effective at reducing squatting. I'm very open to adjusting this value – please make a comment in the discussion thread if you would propose an alternative. There's no current expiration, but it's worth introducing here because the changes make it practically a bit easier to squat on datacap (possible today, but more involved). 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. I don't have any specific value in mind. I was trying to understand the reasoning for the 60 days. It sounds reasonable to me as well. |
||||||
|
||||||
Allocations are stored in the verified registry actor's state, grouped by client address. | ||||||
Nesting by client promotes more efficient lookups at scale, | ||||||
|
@@ -135,18 +135,19 @@ struct State { | |||||
Allocations: HAMT[Address]HAMT[AllocationID]Allocation | ||||||
|
||||||
// Sequence number for allocation IDs. | ||||||
// The value `0` is reserved for "no allocation" | ||||||
NextAllocationId: AllocationID // uint64 | ||||||
} | ||||||
``` | ||||||
|
||||||
#### Operations | ||||||
|
||||||
#### Creation of allocations | ||||||
An allocation is created by a verified client by transferring DataCap tokens (see below) | ||||||
to the verified registry. | ||||||
The `Allocation` metadata must be provided as transfer metadata. | ||||||
The verified registry checks the same preconditions as the existing `UseBytes` method. | ||||||
The size of the allocation must match the number of tokens received. | ||||||
|
||||||
#### Removal of expired allocations | ||||||
An allocation may be removed after its expiration epoch has passed (by anyone). | ||||||
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. Why are we allowing expired allocations to be removed "by anyone"? What is the expected behavior here? Should clients remove them or are we supposed to have an automated process doing it? 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. There is no reason to restrict it to the client address specifically, so this gives flexibility to users. E.g. if a client is a multisig or DAO or other complex entity, they don't need to go to the cost and trouble of multisigning this inconsequential message – one of the parties/delegates/employees can just do it. There's no "should" or automation. Clients can clean up when the gas savings associated with a smaller collection justify it. 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. Got it. This makes sense. |
||||||
When removed, the DataCap tokens are transferred back to the client. | ||||||
The verified registry provides a new method to process removals, replacing `RestoreBytes`. | ||||||
|
@@ -165,12 +166,12 @@ fn RemoveExpiredAllocations(params: RemoveExpiredAllocationsParams) | |||||
|
||||||
Allocations are also removed when claimed by a provider (see below). | ||||||
|
||||||
The `RemoveVerifiedClientDataCap` method invokes a privileged method of the DataCap token actor | ||||||
to burn DataCap tokens held on a client's balance. | ||||||
#### Revocation of un-allocated data cap | ||||||
The existing `RemoveVerifiedClientDataCap` method is changed to invoke a | ||||||
privileged method of the DataCap token actor to burn DataCap tokens held on a client's balance. | ||||||
Only the verified registry actor is permitted to invoke this method. | ||||||
|
||||||
### Data cap claims | ||||||
|
||||||
### Verified Registry DataCap claims | ||||||
The verified registry actor is further extended to record each storage provider's commitment to a | ||||||
DataCap allocation, called a claim. A claim represents a provider's obligation to store a piece of | ||||||
data, and corresponding benefit of incentivized storage power. | ||||||
|
@@ -208,7 +209,7 @@ struct State { | |||||
} | ||||||
``` | ||||||
|
||||||
#### Operations | ||||||
#### Creation of claims from allocations | ||||||
An allocation is claimed when a storage miner actor proves the corresponding piece of data | ||||||
is committed to a sector. | ||||||
Upon converting an allocation to a claim, the verified registry actor burns the associated | ||||||
|
@@ -245,7 +246,8 @@ struct SectorClaimResult { | |||||
fn ClaimAllocations(params: ClaimAllocationsParams) -> ClaimAllocationsResult | ||||||
``` | ||||||
|
||||||
The record of a claim may be removed by the provider after the term maximum has elapsed. | ||||||
#### Removal of expired claims | ||||||
The record of a claim may be removed after the term maximum has elapsed. | ||||||
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. Who can remove expired claims? Is this an automated process? 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. Iiuc, Anyone can remove the expired claims and it’s triggered by an onchain message. 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. Similar to above, anyone can. In practise this will probably be some ancillary or operations account associated with a provider. There's no automation. |
||||||
|
||||||
``` | ||||||
struct RemoveExpiredClaimsParams { | ||||||
|
@@ -258,24 +260,14 @@ struct RemoveExpiredClaimsParams { | |||||
fn RemoveExpiredClaims(params: RemoveExpiredClaimsParams) | ||||||
``` | ||||||
|
||||||
|
||||||
The maximum term for a claim may be increased by the client which originally made the allocation, | ||||||
up to the network policy maximum. | ||||||
|
||||||
A verified client can extend the term for a claim _beyond_ the initial maximum term by | ||||||
spending new DataCap. | ||||||
The term maximum can be extended up to the network policy maximum beyond the current epoch. | ||||||
The client extending the claim need not be the one that made the original allocation. | ||||||
This is similar to issuing a new allocation/claim for the same data, | ||||||
but avoids overheads of re-sealing. | ||||||
|
||||||
TODO: rework this to be a token receiver hook rather than explicit method | ||||||
#### Extension of claim term by client | ||||||
A client of a claim may increase its maximum term up to `MaximumVerifiedAllocationTerm`. | ||||||
|
||||||
``` | ||||||
struct ClaimTerm { | ||||||
Provider: Address // needed to find claim in state | ||||||
ClaimID: ClaimID | ||||||
TermMaximum: int64 // duration in epochs | ||||||
TermMaximum: int64 // new duration in epochs from TermStart | ||||||
} | ||||||
struct ExtendClaimTermsParams{ | ||||||
Claims: []ClaimTerm | ||||||
|
@@ -290,10 +282,21 @@ struct ExtendClaimTermsResult { | |||||
// Called by allocation client to extend the maximum term of their allocations, | ||||||
// without consuming DataCap. | ||||||
// The new TermMaximum must be no less than the current one, | ||||||
// and no greater than the maximum initial term. | ||||||
// and no greater than MaximumVerifiedAllocationTerm. | ||||||
fn ExtendClaimTerms(params: ExtendClaimTermsParams) -> ExtendClaimTermsResult | ||||||
jennijuju marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
``` | ||||||
|
||||||
#### Renewal of claim term by spending datacap | ||||||
A verified client can extend the term for a claim _beyond_ the initial maximum term by | ||||||
jennijuju marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
spending new DataCap. | ||||||
The claim's term maximum can be extended up to `MaximumVerifiedAllocationTerm` beyond the current epoch. | ||||||
The client extending the claim need not be the one that made the original allocation. | ||||||
jennijuju marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
This is similar to issuing a new allocation/claim for the same data, | ||||||
but avoids overheads of re-sealing. | ||||||
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 mechanism makes a lot of sense. There is no reason to re-seal the same data just because one needs to spend new DataCap. |
||||||
|
||||||
TODO: spec token receiver hook for extending | ||||||
|
||||||
|
||||||
### Data cap token | ||||||
The `VerifiedClients` map of addreses to balances is removed from the verified registry state. | ||||||
The balances of DataCap tokens held by verified clients are extracted to a DataCap token actor. | ||||||
|
@@ -324,42 +327,45 @@ Parties will continue to interact with the built-in market actor and verified re | |||||
The built-in account and multisig actors are changed to implement a receiver hook method, as specified by FRC-0046. | ||||||
This hook always succeeds, without inspecting the payload. | ||||||
|
||||||
#### Operations | ||||||
The `AddVerifiedClient` method is changed to invoke the DataCap token actor to | ||||||
#### Changes to datacap operations | ||||||
The verified registry's `AddVerifiedClient` method is changed to invoke the DataCap token actor to | ||||||
mint new tokens to the client's balance. | ||||||
|
||||||
The `UseBytes` method is removed. | ||||||
The verified registry's `UseBytes` method is removed. | ||||||
To create an allocation, a verified client transfers DataCap tokens to the verified registry actor. | ||||||
The transfer must be accompanied by one or more `Allocation` records which specify | ||||||
the allocation(s) to create. | ||||||
The registry may reject the transfer if the allocations are invalid. | ||||||
|
||||||
The `RestoreBytes` method is also removed. | ||||||
The verified registry's `RestoreBytes` method is also removed. | ||||||
Instead, the `RevokeAllocations` method on the verified registry actor transfers any released | ||||||
DataCap tokens back to the client's balance for re-use. | ||||||
|
||||||
### Simplified quality-adjusted power | ||||||
A DataCap allocation/claim is valid for a range of commitment terms, between a client-specified | ||||||
minimum and maximum, so long as the allocation is claimed before the allocation expires. | ||||||
|
||||||
The actual term for a claim begins at the epoch the data is committed into a sector, | ||||||
proven either with proof-of-replication or replica-update. | ||||||
There is no distinct "deal start epoch". | ||||||
A sector containing a DataCap claim is immediately eligible for a power multiplier of 10 | ||||||
for that fraction of the sector's capacity occupied by the incentivized data | ||||||
The actual term for a claim ends the epoch that the sector containing the data expires, | ||||||
or that data is replaced. | ||||||
|
||||||
A sector's `DealWeight` and `VerifiedDealWeight` are calculated as simple sums of the sizes | ||||||
of the deals, with no multiplication by duration. | ||||||
The miner actor computes a sector’s power as `SectorSize + (9 * VerifedDealWeight)`. | ||||||
|
||||||
A sector containing a DataCap claim is thus immediately eligible for a power multiplier of 10 | ||||||
for that fraction of the sector's capacity occupied by `VerifiedDealWeight` | ||||||
(subject to the existing requirement to initially prove the sector in Window PoSt). | ||||||
|
||||||
The actual term for a claim ends the epoch that the sector containing the data expires, | ||||||
or that data is replaced. | ||||||
The term cannot end during a sector's lifetime, except by explicit replacement of data. | ||||||
If data is replaced, the sector immediately loses the power multiplier for that fraction | ||||||
of the sector's capacity. | ||||||
A claim term cannot end during a sector's lifetime, except by explicit replacement of data. | ||||||
If data is replaced, the sector's verified deal weight is reduced and it immediately | ||||||
loses the power multiplier for that fraction of the sector's capacity. | ||||||
(Replacing non-zero data in a sector is not possible today). | ||||||
|
||||||
Aligning the claim's term with the sector's expiration exactly in this way removes the | ||||||
"spreading-out" of QA power over a sector's life in the current method of computation. | ||||||
Providers gain 10x power for each byte of verified data exactly while that data is proven. | ||||||
The miner actor computes a sector’s power as `SectorSize + (9 * VerifiedSize)`. | ||||||
|
||||||
#### Pledge | ||||||
A sector's pledge requirement is proportional to its share of power, but never decreases, just as today. | ||||||
|
@@ -375,7 +381,28 @@ The pledge requirement for the old sector is not decreased, | |||||
but any subsequent penalty is calculated using its current (i.e. reduced) power. | ||||||
|
||||||
### Storage miner actor | ||||||
The built-in miner actor is trusted to enforce the verified and the continual storage of the data. | ||||||
#### Differentiated sectors | ||||||
A new field `SimpleQAPower: bool` is added to `SectorOnChainInfo`. | ||||||
During the migration activating this proposal, `SimpleQAPower` is set for each sector: | ||||||
- `true` if the sector has `VerifiedDealWeight = 0` and `DealWeight = 0`, | ||||||
- `false` otherwise | ||||||
|
||||||
All sectors committed after this proposal is activated take `SimpleQAPower = true`. | ||||||
The value of `SimpleQAPower` never changes for an individual sector. | ||||||
|
||||||
A sector with `SimpleQAPower = true` has its deal weights calculated as simple sums of deal size, | ||||||
and QA power calculated according to the simple method described above, with no spreading out effect. | ||||||
|
||||||
A sector with `SimpleQAPower = false` continues to use the existing QA-power calculation. | ||||||
Such a sector cannot claim any allocations. | ||||||
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 likely to result in increased expirations, with "old" sectors being replaced by new sectors that can take allocations. In addition, CC sectors can take advantage of this new way to package deals, while sectors with data have to wait for their deals to end. Could we have a mechanism to turn sectors with 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. It is impossible to change the data in a non-CC sector today anyway (there is no "re-snap"), so there are no sectors to which this would apply. It will be easier to implement re-snapping after this change, though, but by the time we do this will be an even smaller issue. There are reasons not to do this. Perhaps for a narrow case of sectors where all the deals have already expired there would be fewer unwanted effects, but still this would cause a slight power loss for the SP, so is unlikely a major flow. I agree that, for a capacity-constrained SP, a CC sector is more valuable than a sector with expired deals at the end of its life, due to the option of taking deals into it. But that's already the case today. |
||||||
Such a sector may be extended, but, as today, this will result in its power being diluted | ||||||
to "spread out" the verified reward over the sector's new commitment duration. | ||||||
|
||||||
The `SimpleQAPower` field will become redundant and may be removed by a network upgrade once | ||||||
all sectors with the value `false` have expired. | ||||||
|
||||||
#### Term enforcement | ||||||
The built-in miner actor enforces the term and the continual storage of the data. | ||||||
|
||||||
The miner actor requires that the sector into which a claimed piece is committed must have a | ||||||
**remaining lifespan that is sufficient to fulfil the minimum term**. | ||||||
|
@@ -395,16 +422,9 @@ There is **no change to termination penalty** calculations. | |||||
If a sector is terminated early (continual faults, or manual termination), | ||||||
the provider will pay a penalty related to the expected reward earned by the sector (up to some limit). | ||||||
|
||||||
The verified registry can support re-commitment of the same data in a new sector | ||||||
(even though the built-in storage market actor does not support resumption of a terminated deal). | ||||||
If a claim’s maximum term has not been reached when a sector terminates, | ||||||
the provider may commit the same piece into a new sector and regain the quality-adjusted power. | ||||||
The new sector’s committed lifespan is still constrained to fit within the claim’s term. | ||||||
The miner actor must ensure that the old sector is no longer alive. | ||||||
|
||||||
#### Sector extension | ||||||
A sector's scheduled commitment term cannot be extended beyond the maximum term of any | ||||||
verified claim attributed to it. | ||||||
claim attributed to it. | ||||||
Thus, to extend a sector, a provider must simultaneously drop any verified claims with | ||||||
terms that would be exceeded by the extended commitment. | ||||||
Dropping a verified claim reduces the sector's power accordingly, as well as | ||||||
|
@@ -480,7 +500,7 @@ The built-in market specifies an allocation's minimum term to be equal to the de | |||||
and maximum term to be some amount greater than the deal duration. | ||||||
|
||||||
**Parameters** | ||||||
- The built-in market calculates a term maximum of 1 year greater than a deal's specified duration. | ||||||
- `MarketDefaultMaximumAllocationTerm`: The built-in market calculates a term maximum of 90 days greater than a deal's specified duration. | ||||||
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. Why 90 days? 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. Why not? This value was chosen as a compromise between flexibility for SP deal packing, and reasonably requesting the client's nominated term. The discussion thread for this is #313 (comment) 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. Trying to understand the reasoning. I don't have any arguments against the 90 days. |
||||||
|
||||||
``` | ||||||
let dealAllocation = Allocation { | ||||||
|
@@ -489,12 +509,16 @@ let dealAllocation = Allocation { | |||||
Data: deal.PieceCID | ||||||
Size: deal.PieceSize | ||||||
TermMinimum: deal.EndEpoch - deal.StartEpoch | ||||||
TermMaximum: deal.EndEpoch - deal.StartEpoch + EPOCHS_IN_YEAR | ||||||
Expiration: deal.StartEpoch | ||||||
TermMaximum: deal.EndEpoch - deal.StartEpoch + MarketDefaultMaximumAllocationTerm | ||||||
Expiration: min(deal.StartEpoch, CURRENT_EPOCH + MaximumVerifiedAllocationExpiration) | ||||||
AllowRanges: false | ||||||
} | ||||||
``` | ||||||
|
||||||
The market will accept verified deals with a `StartEpoch` beyond the maximum allowed allocation `Expiration`. | ||||||
anorth marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
If such a deal is not activated before the allocation expires, it will not confer QA power. | ||||||
However, the deal may still be activated and sector commitment should proceed (without QA power). | ||||||
|
||||||
The market stores allocation IDs for not-yet-activated deals in a new mapping, | ||||||
and the claim ID for activated deals in deal state. | ||||||
|
||||||
|
@@ -526,43 +550,20 @@ The miner actor then invokes `ClaimAllocations` and, if successful, | |||||
computes quality adjusted power for the sector according to the piece size and QA power multiplier. | ||||||
|
||||||
### Migration | ||||||
#### Network upgrade | ||||||
A network state migration is required to implement this proposal. | ||||||
|
||||||
That migration must: | ||||||
- Implement the new verified registry state schema for allocations and claims. | ||||||
- Implement the new verified registry state schema for allocations and claims, | ||||||
and set `NextAllocationId = 1`. | ||||||
jennijuju marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
- Migrate the verified registry client balances map to DataCap token balances, | ||||||
with appropriate unit conversion. | ||||||
- Add a new field to SectorOnChainInfo identifying whether its quality-adjusted power is calculated | ||||||
according to the old spread-out method, or the new direct method | ||||||
- TODO: handle pending deals: either create allocations or keep not-yet-proven sectors in the old world. | ||||||
|
||||||
#### Opt-in per-sector | ||||||
The power for existing sectors is not changed by this proposal. | ||||||
|
||||||
A provider may opt in to migrate a sector to the new QA power calculation method by invoking a new method. | ||||||
Each active deal is converted to a claim as if an allocation had been created when the deal was made. | ||||||
The claim's minimum term is the deal's duration, and maximum term is the greater of either | ||||||
the sector's current expiration epoch, or 540 days beyond the current epoch | ||||||
(since the provider could extend the sector to such lifetime prior to migrating). | ||||||
|
||||||
Expired deals cannot be migrated, even though the old QA power calculation method has spread out | ||||||
their power and reward over the sector's full lifetime. | ||||||
This will generally result in an increase in power for a sector, | ||||||
but may result in a decrease in case of expired deals. | ||||||
This is why the migration is opt-in. | ||||||
|
||||||
A new method on the storage miner actor: | ||||||
- Fetches information about each not-yet-expired verified deal from the market | ||||||
- Calls the verified registry to create a claim for each such deal. | ||||||
- Re-calculates power according to the amount of space committed to active claims. | ||||||
- Re-caclulates pledge requirement according to the new power and network conditions (but never decreases) | ||||||
|
||||||
After migration, the client can extend the migrated claims' terms up to the network policy maximum. | ||||||
After claims are extended, the provider can extend the sector commitment duration to match. | ||||||
Note that a migrated sector cannot be extended unless the claim terms are extended, | ||||||
lest it violate a claim's maximum term. | ||||||
|
||||||
TODO: specify migration method and changes to SectorOnChainInfo | ||||||
- Add a new field `SimpleQAPower` to each `SectorOnChainInfo`, | ||||||
taking the value `DealWeight == 0 && VerifiedDealWeight == 0` | ||||||
- Add the pending allocation mapping to market state, and claim ID field to deal states (all `0`) | ||||||
- For each pending (not yet activated) deal with `Verified = true`, create an Allocation | ||||||
- The maximum term for such allocations is 540 days, in order to support any possible sector duration | ||||||
- The expiration for such allocations is set to `MaximumVerifiedAllocationExpiration` after the migration epoch, | ||||||
which may be before the deal's start date. | ||||||
|
||||||
## Design Rationale | ||||||
The design rationale is mostly provided by the proposal's motivation. | ||||||
|
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.
What's the potential use case here?