lotus/storage/sectorblocks/blocks.go
Łukasz Magiera 9e03fcab83
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 15:15:55 +01:00

178 lines
4.4 KiB
Go

package sectorblocks
import (
"bytes"
"context"
"encoding/binary"
"errors"
"io"
"sync"
dshelp "github.com/ipfs/boxo/datastore/dshelp"
"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
"github.com/ipfs/go-datastore/query"
"golang.org/x/xerrors"
cborutil "github.com/filecoin-project/go-cbor-util"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/storage/pipeline/piece"
"github.com/filecoin-project/lotus/storage/sealer/storiface"
)
type SealSerialization uint8
const (
SerializationUnixfs0 SealSerialization = 'u'
)
var dsPrefix = datastore.NewKey("/sealedblocks")
var ErrNotFound = errors.New("not found")
func DealIDToDsKey(dealID abi.DealID) datastore.Key {
buf := make([]byte, binary.MaxVarintLen64)
size := binary.PutUvarint(buf, uint64(dealID))
return dshelp.NewKeyFromBinary(buf[:size])
}
func DsKeyToDealID(key datastore.Key) (uint64, error) {
buf, err := dshelp.BinaryFromDsKey(key)
if err != nil {
return 0, err
}
dealID, _ := binary.Uvarint(buf)
return dealID, nil
}
type SectorBuilder interface {
SectorAddPieceToAny(ctx context.Context, size abi.UnpaddedPieceSize, r storiface.Data, d piece.PieceDealInfo) (api.SectorOffset, error)
SectorsStatus(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (api.SectorInfo, error)
}
type SectorBlocks struct {
SectorBuilder
keys datastore.Batching
keyLk sync.Mutex
}
func NewSectorBlocks(sb SectorBuilder, ds dtypes.MetadataDS) *SectorBlocks {
sbc := &SectorBlocks{
SectorBuilder: sb,
keys: namespace.Wrap(ds, dsPrefix),
}
return sbc
}
func (st *SectorBlocks) writeRef(ctx context.Context, dealID abi.DealID, sectorID abi.SectorNumber, offset abi.PaddedPieceSize, size abi.UnpaddedPieceSize) error {
st.keyLk.Lock() // TODO: make this multithreaded
defer st.keyLk.Unlock()
v, err := st.keys.Get(ctx, DealIDToDsKey(dealID))
if err == datastore.ErrNotFound {
err = nil
}
if err != nil {
return xerrors.Errorf("getting existing refs: %w", err)
}
var refs api.SealedRefs
if len(v) > 0 {
if err := cborutil.ReadCborRPC(bytes.NewReader(v), &refs); err != nil {
return xerrors.Errorf("decoding existing refs: %w", err)
}
}
refs.Refs = append(refs.Refs, api.SealedRef{
SectorID: sectorID,
Offset: offset,
Size: size,
})
newRef, err := cborutil.Dump(&refs)
if err != nil {
return xerrors.Errorf("serializing refs: %w", err)
}
return st.keys.Put(ctx, DealIDToDsKey(dealID), newRef) // TODO: batch somehow
}
func (st *SectorBlocks) AddPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, d piece.PieceDealInfo) (abi.SectorNumber, abi.PaddedPieceSize, error) {
so, err := st.SectorBuilder.SectorAddPieceToAny(ctx, size, r, d)
if err != nil {
return 0, 0, err
}
// TODO: DealID has very low finality here
err = st.writeRef(ctx, d.DealID, so.Sector, so.Offset, size)
if err != nil {
return 0, 0, xerrors.Errorf("writeRef: %w", err)
}
return so.Sector, so.Offset, nil
}
func (st *SectorBlocks) List(ctx context.Context) (map[uint64][]api.SealedRef, error) {
res, err := st.keys.Query(ctx, query.Query{})
if err != nil {
return nil, err
}
ents, err := res.Rest()
if err != nil {
return nil, err
}
out := map[uint64][]api.SealedRef{}
for _, ent := range ents {
dealID, err := DsKeyToDealID(datastore.RawKey(ent.Key))
if err != nil {
return nil, err
}
var refs api.SealedRefs
if err := cborutil.ReadCborRPC(bytes.NewReader(ent.Value), &refs); err != nil {
return nil, err
}
out[dealID] = refs.Refs
}
return out, nil
}
func (st *SectorBlocks) GetRefs(ctx context.Context, dealID abi.DealID) ([]api.SealedRef, error) { // TODO: track local sectors
ent, err := st.keys.Get(ctx, DealIDToDsKey(dealID))
if err == datastore.ErrNotFound {
err = ErrNotFound
}
if err != nil {
return nil, err
}
var refs api.SealedRefs
if err := cborutil.ReadCborRPC(bytes.NewReader(ent), &refs); err != nil {
return nil, err
}
return refs.Refs, nil
}
func (st *SectorBlocks) GetSize(ctx context.Context, dealID abi.DealID) (uint64, error) {
refs, err := st.GetRefs(ctx, dealID)
if err != nil {
return 0, err
}
return uint64(refs[0].Size), nil
}
func (st *SectorBlocks) Has(ctx context.Context, dealID abi.DealID) (bool, error) {
// TODO: ensure sector is still there
return st.keys.Has(ctx, DealIDToDsKey(dealID))
}