lotus/storage/pipeline/piece/piece_info.go

187 lines
5.8 KiB
Go
Raw Normal View History

feat: sealing: Support nv22 DDO features in the sealing pipeline (#11226) * Initial work supporting DDO pieces in lotus-miner * sealing: Update pipeline input to operate on UniversalPiece * sealing: Update pipeline checks/sealing states to operate on UniversalPiece * sealing: Make pipeline build with UniversalPiece * move PieceDealInfo out of api * make gen * make sealing pipeline unit tests pass * fix itest ensemble build * don't panic in SectorsStatus with deals * stop linter from complaining about checkPieces * fix sector import tests * mod tidy * sealing: Add logic for (pre)committing DDO sectors * sealing: state-types with method defs * DDO non-snap pipeline works(?), DDO Itests * DDO support in snapdeals pipeline * make gen * update actor bundles * update the gst market fix * fix: chain: use PreCommitSectorsBatch2 when setting up genesis * some bug fixes * integration working changes * update actor bundles * Make TestOnboardRawPieceSnap pass * Appease the linter * Make deadlines test pass with v12 actors * Update go-state-types, abstract market DealState * make gen * mod tidy, lint fixes * Fix some more tests * Bump version in master Bump version in master * Make gen Make gen * fix sender * fix: lotus-provider: Fix winning PoSt * fix: sql Scan cannot write to an object * Actually show miner-addrs in info-log Actually show miner-addrs in lotus-provider info-log * [WIP] feat: Add nv22 skeleton Addition of Network Version 22 skeleton * update FFI * ddo is now nv22 * make gen * temp actor bundle with ddo * use working go-state-types * gst with v13 market migration * update bundle, builtin.MethodsMiner.ProveCommitSectors2 -> 3 * actually working v13 migration, v13 migration itest * Address review * sealing: Correct DDO snap pledge math * itests: Mixed ddo itest * pipeline: Fix sectorWeight * sealing: convert market deals into PAMs in mixed sectors * sealing: make market to ddo conversion work * fix lint * update gst * Update actors and GST to lastest integ branch * commit batcher: Update ProveCommitSectors3Params builder logic * make gen * use builtin-actors master * ddo: address review * itests: Add commd assertions to ddo tests * make gen * gst with fixed types * config knobs for RequireActivationSuccess * storage: Drop obsolete flaky tasts --------- Co-authored-by: Jennifer Wang <jiayingw703@gmail.com> Co-authored-by: Aayush <arajasek94@gmail.com> Co-authored-by: Shrenuj Bansal <shrenuj.bansal@protocol.ai> Co-authored-by: Phi <orjan.roren@gmail.com> Co-authored-by: Andrew Jackson (Ajax) <snadrus@gmail.com> Co-authored-by: TippyFlits <james.bluett@protocol.ai>
2024-01-25 14:15:55 +00:00
package piece
import (
"context"
"fmt"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/types"
)
// DealInfo is a tuple of deal identity and its schedule
type PieceDealInfo struct {
// "Old" builtin-market deal info
PublishCid *cid.Cid
DealID abi.DealID
DealProposal *market.DealProposal
// Common deal info, required for all pieces
// TODO: https://github.com/filecoin-project/lotus/issues/11237
DealSchedule DealSchedule
// Direct Data Onboarding
// When PieceActivationManifest is set, builtin-market deal info must not be set
PieceActivationManifest *miner.PieceActivationManifest
// Best-effort deal asks
KeepUnsealed bool
}
// DealSchedule communicates the time interval of a storage deal. The deal must
// appear in a sealed (proven) sector no later than StartEpoch, otherwise it
// is invalid.
type DealSchedule struct {
StartEpoch abi.ChainEpoch
EndEpoch abi.ChainEpoch
}
func (ds *PieceDealInfo) isBuiltinMarketDeal() bool {
return ds.PublishCid != nil
}
// Valid validates the deal info after being accepted through RPC, checks that
// the deal metadata is well-formed.
func (ds *PieceDealInfo) Valid(nv network.Version) error {
hasLegacyDealInfo := ds.PublishCid != nil && ds.DealID != 0 && ds.DealProposal != nil
hasPieceActivationManifest := ds.PieceActivationManifest != nil
if hasLegacyDealInfo && hasPieceActivationManifest {
return xerrors.Errorf("piece deal info has both legacy deal info and piece activation manifest")
}
if !hasLegacyDealInfo && !hasPieceActivationManifest {
return xerrors.Errorf("piece deal info has neither legacy deal info nor piece activation manifest")
}
if hasLegacyDealInfo {
if _, err := ds.DealProposal.Cid(); err != nil {
return xerrors.Errorf("checking proposal CID: %w", err)
}
}
if ds.DealSchedule.StartEpoch <= 0 {
return xerrors.Errorf("invalid deal start epoch %d", ds.DealSchedule.StartEpoch)
}
if ds.DealSchedule.EndEpoch <= 0 {
return xerrors.Errorf("invalid deal end epoch %d", ds.DealSchedule.EndEpoch)
}
if ds.DealSchedule.EndEpoch <= ds.DealSchedule.StartEpoch {
return xerrors.Errorf("invalid deal end epoch %d (start %d)", ds.DealSchedule.EndEpoch, ds.DealSchedule.StartEpoch)
}
if hasPieceActivationManifest {
if nv < network.Version22 {
return xerrors.Errorf("direct-data-onboarding pieces aren't accepted before network version 22")
}
// todo any more checks seem reasonable to put here?
}
return nil
}
type AllocationAPI interface {
StateGetAllocationForPendingDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*verifregtypes.Allocation, error)
StateGetAllocation(ctx context.Context, clientAddr address.Address, allocationId verifregtypes.AllocationId, tsk types.TipSetKey) (*verifregtypes.Allocation, error)
}
func (ds *PieceDealInfo) GetAllocation(ctx context.Context, aapi AllocationAPI, tsk types.TipSetKey) (*verifregtypes.Allocation, error) {
switch {
case ds.isBuiltinMarketDeal():
return aapi.StateGetAllocationForPendingDeal(ctx, ds.DealID, tsk)
default:
if ds.PieceActivationManifest.VerifiedAllocationKey == nil {
return nil, nil
}
caddr, err := address.NewIDAddress(uint64(ds.PieceActivationManifest.VerifiedAllocationKey.Client))
if err != nil {
return nil, err
}
all, err := aapi.StateGetAllocation(ctx, caddr, verifregtypes.AllocationId(ds.PieceActivationManifest.VerifiedAllocationKey.ID), tsk)
if err != nil {
return nil, err
}
if all == nil {
return nil, nil
}
if all.Client != ds.PieceActivationManifest.VerifiedAllocationKey.Client {
return nil, xerrors.Errorf("allocation client mismatch: %d != %d", all.Client, ds.PieceActivationManifest.VerifiedAllocationKey.Client)
}
return all, nil
}
}
// StartEpoch returns the last epoch in which the sector containing this deal
// must be sealed (committed) in order for the deal to be valid.
func (ds *PieceDealInfo) StartEpoch() (abi.ChainEpoch, error) {
switch {
case ds.isBuiltinMarketDeal():
return ds.DealSchedule.StartEpoch, nil
default:
// note - when implementing make sure to cache any dynamically computed values
// todo do we want a smarter mechanism here
return ds.DealSchedule.StartEpoch, nil
}
}
// EndEpoch returns the minimum epoch until which the sector containing this
// deal must be committed until.
func (ds *PieceDealInfo) EndEpoch() (abi.ChainEpoch, error) {
switch {
case ds.isBuiltinMarketDeal():
return ds.DealSchedule.EndEpoch, nil
default:
// note - when implementing make sure to cache any dynamically computed values
// todo do we want a smarter mechanism here
return ds.DealSchedule.StartEpoch, nil
}
}
func (ds *PieceDealInfo) PieceCID() cid.Cid {
switch {
case ds.isBuiltinMarketDeal():
return ds.DealProposal.PieceCID
default:
return ds.PieceActivationManifest.CID
}
}
func (ds *PieceDealInfo) String() string {
switch {
case ds.isBuiltinMarketDeal():
return fmt.Sprintf("BuiltinMarket{DealID: %d, PieceCID: %s, PublishCid: %s}", ds.DealID, ds.DealProposal.PieceCID, ds.PublishCid)
default:
// todo check that VAlloc doesn't print as a pointer
return fmt.Sprintf("DirectDataOnboarding{PieceCID: %s, VAllloc: %x}", ds.PieceActivationManifest.CID, ds.PieceActivationManifest.VerifiedAllocationKey)
}
}
func (ds *PieceDealInfo) KeepUnsealedRequested() bool {
return ds.KeepUnsealed
}
type PieceKey string
// Key returns a unique identifier for this deal info, for use in maps.
func (ds *PieceDealInfo) Key() PieceKey {
return PieceKey(ds.String())
}
func (ds *PieceDealInfo) Impl() PieceDealInfo {
return *ds
}