-
Notifications
You must be signed in to change notification settings - Fork 187
Description
Problem
Currently Filecoin sectors can only store deal data referenced by on-chain deals. CC sectors and non-deal areas of sectors must store null (\0) bytes to be verifiable on-chain. This limitation is caused by how the UnsealedCID (CommD) is computed in the miner actor.
Unfortunately publishing deals is a very expensive on-chain operation, especially for smaller pieces where this cost it can be the main part of the storage fee. Off-chain deal support / alternative markets (e.g. more scalable storage market on ETH2.0 with data stored on Filecoin) seem to be good solutions to this problem, at least for non-FIL+ deals.
This proposal is only the first, but major, part of what needs to be done to support off-chain deals. It's likely that some off-chain deal protocols will require additional actor methods to be implemented (for example a method to check if a sector wasn't terminated early for settling payment channels)
Current state
Currently, when precommitting sectors, a number of DealIDs can be specified with SectorPreCommitInfo:
// Information provided by a miner when pre-committing a sector.
type SectorPreCommitInfo struct {
SealProof abi.RegisteredSealProof
SectorNumber abi.SectorNumber
SealedCID cid.Cid `checked:"true"`
SealRandEpoch abi.ChainEpoch
DealIDs []abi.DealID // ****
Expiration abi.ChainEpoch
ReplaceCapacity bool
ReplaceSectorDeadline uint64
ReplaceSectorPartition uint64
ReplaceSectorNumber abi.SectorNumber
}This information is then stored in miner actor state, and used to compute UnsealedCID when verifying PoRep by turning specified DealIDs into []abi.PieceInfos, and calling the ComputeUnsealedSectorCID syscall through the storage market actor.
type abi.PieceInfo struct {
Size abi.PaddedPieceSize
PieceCID cid.Cid
}ComputeUnsealedSectorCID(reg abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error)Proposed solution
We can change or create a new version of the SectorPreCommitInfo miner actor struct, changing the DealIDs array to a new array which allows specifying non-deal PieceCIDs:
+type SectorPieceInfo struct{
+ PieceCID *cid.Cid `checked:"true"` // CommP
+ PieceSize abi.PaddedPieceSize
+
+ DealID abi.DealID
+}
// Information provided by a miner when pre-committing a sector.
type SectorPreCommitInfo struct {
SealProof abi.RegisteredSealProof
SectorNumber abi.SectorNumber
SealedCID cid.Cid `checked:"true"` // CommR
SealRandEpoch abi.ChainEpoch
- DealIDs []abi.DealID
+ Pieces []SectorPieceInfo
Expiration abi.ChainEpoch
ReplaceCapacity bool // Whether to replace a "committed capacity" no-deal sector (requires non-empty DealIDs)
// The committed capacity sector to replace, and it's deadline/partition location
ReplaceSectorDeadline uint64
ReplaceSectorPartition uint64
ReplaceSectorNumber abi.SectorNumber
}When computing UnsealedCID for PoRep verification, []SectorPieceInfo would be turned into []abi.PieceInfo for the ComputeUnsealedSectorCID actor syscall as follows:
- If
PieceCIDisnull, assert thatPieceSize==0, then getabi.PieceInfofor the referencedDealIDfrom the market actor - If
PieceCIDis not null, assert thatDealID==0, check the multicodec/multihash the same way it's checked in the storage market actor, then createabi.PieceInfousing specified PieceCID/PieceSize - Process all entries in sequence, keeping order when creating
[]abi.PieceInfoto allow interleaving non-deal and deal data
(it's possible to save 1 byte per entry by changing PieceSize/DealID to a single uint64 value (DealIdOrPieceSize), and processing it based on whether PieceCID is null or not)
Discussion
State migration
Depending on implementation details, this proposal may involve a relatively major state migration. We should look into ways of limiting that.
Added overhead for deal data
Publishing storage on-chain deals already has multiple kilobytes of read/write overhead. Each abi.DealID entry is 5B (1B cbor header, 4B for integer data). Depending on implementation, a dealID SectorPieceInfo entry will be 7 or 8 bytes, which is a negligible difference
Related FIPs
- FIP-0008 (Add miner batched sector pre-commit method) is proposing creation of a new precommit method. It could be used to also introduce changes to
SectorPreCommitInfowithout breaking the old method - FIP-0007 (h/amt-v3) requires a migration of all HAMT data. Since this proposal also likely requires migration of at least miner PreCommittedSectors HAMTs, it may be a good idea to bundle those migrations into a single state upgrade