lotus/storage/pipeline/piece/piece_info.go
Łukasz Magiera 6a0f16b084 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-03-22 07:00:28 +01:00

187 lines
5.8 KiB
Go

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
}