lotus/storage/pipeline/receive.go

325 lines
9.6 KiB
Go
Raw Normal View History

2022-08-24 19:27:27 +00:00
package sealing
import (
"bytes"
2022-08-24 19:27:27 +00:00
"context"
2022-09-09 10:54:48 +00:00
"net/url"
"github.com/ipfs/go-cid"
2022-08-24 19:27:27 +00:00
"github.com/ipfs/go-datastore"
"github.com/multiformats/go-multihash"
2022-08-24 19:27:27 +00:00
"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/crypto"
"github.com/filecoin-project/go-state-types/proof"
"github.com/filecoin-project/go-statemachine"
2022-08-24 19:27:27 +00:00
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/storage/sealer/storiface"
2022-08-24 19:27:27 +00:00
)
func (m *Sealing) Receive(ctx context.Context, meta api.RemoteSectorMeta) error {
m.inputLk.Lock()
defer m.inputLk.Unlock()
si, err := m.checkSectorMeta(ctx, meta)
if err != nil {
2022-08-24 19:27:27 +00:00
return err
}
exists, err := m.sectors.Has(uint64(meta.Sector.Number))
if err != nil {
2022-08-30 19:45:36 +00:00
return xerrors.Errorf("checking if sector exists: %w", err)
}
if exists {
2022-08-30 19:45:36 +00:00
return xerrors.Errorf("sector %d state already exists", meta.Sector.Number)
}
err = m.sectors.Send(uint64(meta.Sector.Number), SectorReceive{
State: si,
})
if err != nil {
return xerrors.Errorf("receiving sector: %w", err)
}
return nil
2022-08-24 19:27:27 +00:00
}
func (m *Sealing) checkSectorMeta(ctx context.Context, meta api.RemoteSectorMeta) (SectorInfo, error) {
2022-08-24 19:27:27 +00:00
{
mid, err := address.IDFromAddress(m.maddr)
if err != nil {
panic(err)
}
if meta.Sector.Miner != abi.ActorID(mid) {
return SectorInfo{}, xerrors.Errorf("sector for wrong actor - expected actor id %d, sector was for actor %d", mid, meta.Sector.Miner)
2022-08-24 19:27:27 +00:00
}
}
{
// initial sanity check, doesn't prevent races
_, err := m.GetSectorInfo(meta.Sector.Number)
if err != nil && !xerrors.Is(err, datastore.ErrNotFound) {
return SectorInfo{}, err
2022-08-24 19:27:27 +00:00
}
if err == nil {
return SectorInfo{}, xerrors.Errorf("sector with ID %d already exists in the sealing pipeline", meta.Sector.Number)
2022-08-24 19:27:27 +00:00
}
}
{
spt, err := m.currentSealProof(ctx)
if err != nil {
return SectorInfo{}, err
2022-08-24 19:27:27 +00:00
}
if meta.Type != spt {
return SectorInfo{}, xerrors.Errorf("sector seal proof type doesn't match current seal proof type (%d!=%d)", meta.Type, spt)
2022-08-24 19:27:27 +00:00
}
}
ts, err := m.Api.ChainHead(ctx)
if err != nil {
return SectorInfo{}, xerrors.Errorf("getting chain head: %w", err)
}
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
nv, err := m.Api.StateNetworkVersion(ctx, ts.Key())
if err != nil {
return SectorInfo{}, xerrors.Errorf("getting network version: %w", err)
}
2022-08-30 19:45:36 +00:00
var info SectorInfo
var validatePoRep bool
2022-08-30 19:45:36 +00:00
2022-08-24 19:27:27 +00:00
switch SectorState(meta.State) {
2022-08-30 19:45:36 +00:00
case Proving, Available:
2022-09-16 21:45:23 +00:00
if meta.CommitMessage != nil {
if err := checkMessagePrefix(*meta.CommitMessage); err != nil {
return SectorInfo{}, xerrors.Errorf("commit message prefix: %w", err)
}
info.CommitMessage = meta.CommitMessage
}
2022-08-24 19:27:27 +00:00
fallthrough
2022-08-30 19:45:36 +00:00
case SubmitCommit:
if meta.PreCommitDeposit == nil {
return SectorInfo{}, xerrors.Errorf("sector PreCommitDeposit was null")
}
info.PreCommitDeposit = *meta.PreCommitDeposit
2022-08-30 19:45:36 +00:00
info.PreCommitTipSet = meta.PreCommitTipSet
2022-09-16 21:45:23 +00:00
if info.PreCommitMessage != nil {
if err := checkMessagePrefix(*meta.PreCommitMessage); err != nil {
return SectorInfo{}, xerrors.Errorf("commit message prefix: %w", err)
}
info.PreCommitMessage = meta.PreCommitMessage
}
2022-08-30 19:45:36 +00:00
// check provided seed
if len(meta.SeedValue) != abi.RandomnessLength {
return SectorInfo{}, xerrors.Errorf("seed randomness had wrong length %d", len(meta.SeedValue))
}
maddrBuf := new(bytes.Buffer)
if err := m.maddr.MarshalCBOR(maddrBuf); err != nil {
return SectorInfo{}, xerrors.Errorf("marshal miner address for seed check: %w", err)
}
rand, err := m.Api.StateGetRandomnessFromBeacon(ctx, crypto.DomainSeparationTag_InteractiveSealChallengeSeed, meta.SeedEpoch, maddrBuf.Bytes(), ts.Key())
if err != nil {
return SectorInfo{}, xerrors.Errorf("generating check seed: %w", err)
}
if !bytes.Equal(rand, meta.SeedValue) {
return SectorInfo{}, xerrors.Errorf("provided(%x) and generated(%x) seeds differ", meta.SeedValue, rand)
}
2022-08-30 19:45:36 +00:00
info.SeedValue = meta.SeedValue
info.SeedEpoch = meta.SeedEpoch
info.Proof = meta.CommitProof
validatePoRep = true
2022-08-24 19:27:27 +00:00
fallthrough
case PreCommitting:
// check provided ticket
if len(meta.TicketValue) != abi.RandomnessLength {
return SectorInfo{}, xerrors.Errorf("ticket randomness had wrong length %d", len(meta.TicketValue))
}
maddrBuf := new(bytes.Buffer)
if err := m.maddr.MarshalCBOR(maddrBuf); err != nil {
return SectorInfo{}, xerrors.Errorf("marshal miner address for ticket check: %w", err)
}
rand, err := m.Api.StateGetRandomnessFromTickets(ctx, crypto.DomainSeparationTag_SealRandomness, meta.TicketEpoch, maddrBuf.Bytes(), ts.Key())
if err != nil {
return SectorInfo{}, xerrors.Errorf("generating check ticket: %w", err)
}
if !bytes.Equal(rand, meta.TicketValue) {
return SectorInfo{}, xerrors.Errorf("provided(%x) and generated(%x) tickets differ", meta.TicketValue, rand)
}
2022-08-30 19:45:36 +00:00
info.TicketValue = meta.TicketValue
info.TicketEpoch = meta.TicketEpoch
2022-08-24 19:27:27 +00:00
2022-08-30 19:45:36 +00:00
info.PreCommit1Out = meta.PreCommit1Out
// check CommD/R
if meta.CommD == nil || meta.CommR == nil {
return SectorInfo{}, xerrors.Errorf("both CommR/CommD cids need to be set for sectors in PreCommitting and later states")
}
dp := meta.CommD.Prefix()
if dp.Version != 1 || dp.Codec != cid.FilCommitmentUnsealed || dp.MhType != multihash.SHA2_256_TRUNC254_PADDED || dp.MhLength != 32 {
return SectorInfo{}, xerrors.Errorf("CommD cid has wrong prefix")
}
rp := meta.CommR.Prefix()
if rp.Version != 1 || rp.Codec != cid.FilCommitmentSealed || rp.MhType != multihash.POSEIDON_BLS12_381_A1_FC1 || rp.MhLength != 32 {
return SectorInfo{}, xerrors.Errorf("CommR cid has wrong prefix")
}
info.CommD = meta.CommD
2022-08-30 19:45:36 +00:00
info.CommR = meta.CommR
2022-08-24 19:27:27 +00:00
if meta.DataSealed == nil {
return SectorInfo{}, xerrors.Errorf("expected DataSealed to be set")
}
if meta.DataCache == nil {
return SectorInfo{}, xerrors.Errorf("expected DataCache to be set")
}
2022-09-09 08:32:27 +00:00
info.RemoteDataSealed = meta.DataSealed // todo make head requests to check?
info.RemoteDataCache = meta.DataCache
2022-09-09 10:54:48 +00:00
if meta.RemoteCommit1Endpoint != "" {
// validate the url
if _, err := url.Parse(meta.RemoteCommit1Endpoint); err != nil {
return SectorInfo{}, xerrors.Errorf("parsing remote c1 endpoint url: %w", err)
}
info.RemoteCommit1Endpoint = meta.RemoteCommit1Endpoint
}
if meta.RemoteCommit2Endpoint != "" {
// validate the url
if _, err := url.Parse(meta.RemoteCommit2Endpoint); err != nil {
return SectorInfo{}, xerrors.Errorf("parsing remote c2 endpoint url: %w", err)
}
info.RemoteCommit2Endpoint = meta.RemoteCommit2Endpoint
}
// If we get a sector after PC2, and remote C1 endpoint is set, assume that we're getting finalized sector data
if info.RemoteCommit1Endpoint != "" {
info.RemoteDataFinalized = true
}
2022-08-24 19:27:27 +00:00
fallthrough
case GetTicket, Packing:
info.Return = ReturnState(meta.State)
info.State = ReceiveSector
2022-08-30 19:45:36 +00:00
info.SectorNumber = meta.Sector.Number
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
info.Pieces = make([]SafeSectorPiece, len(meta.Pieces))
2022-08-30 19:45:36 +00:00
info.SectorType = meta.Type
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
for i, piece := range meta.Pieces {
info.Pieces[i] = SafeSectorPiece{
real: piece,
}
if !info.Pieces[i].HasDealInfo() {
continue // cc
}
err := info.Pieces[i].DealInfo().Valid(nv)
if err != nil {
return SectorInfo{}, xerrors.Errorf("piece %d deal info invalid: %w", i, err)
}
}
if meta.RemoteSealingDoneEndpoint != "" {
// validate the url
if _, err := url.Parse(meta.RemoteSealingDoneEndpoint); err != nil {
return SectorInfo{}, xerrors.Errorf("parsing remote sealing-done endpoint url: %w", err)
}
info.RemoteSealingDoneEndpoint = meta.RemoteSealingDoneEndpoint
}
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
if err := checkPieces(ctx, m.maddr, meta.Sector.Number, info.Pieces, m.Api, false); err != nil {
return SectorInfo{}, xerrors.Errorf("checking pieces: %w", err)
2022-08-30 19:45:36 +00:00
}
2022-08-24 19:27:27 +00:00
if meta.DataUnsealed == nil {
return SectorInfo{}, xerrors.Errorf("expected DataUnsealed to be set")
}
info.RemoteDataUnsealed = meta.DataUnsealed
// some late checks which require previous checks
if validatePoRep {
ok, err := m.verif.VerifySeal(proof.SealVerifyInfo{
SealProof: meta.Type,
SectorID: meta.Sector,
DealIDs: nil,
Randomness: meta.TicketValue,
InteractiveRandomness: meta.SeedValue,
Proof: meta.CommitProof,
SealedCID: *meta.CommR,
UnsealedCID: *meta.CommD,
})
if err != nil {
return SectorInfo{}, xerrors.Errorf("validating seal proof: %w", err)
}
if !ok {
return SectorInfo{}, xerrors.Errorf("seal proof invalid")
}
}
return info, nil
2022-08-24 19:27:27 +00:00
default:
return SectorInfo{}, xerrors.Errorf("imported sector State in not supported")
2022-08-24 19:27:27 +00:00
}
}
func (m *Sealing) handleReceiveSector(ctx statemachine.Context, sector SectorInfo) error {
2022-09-16 21:45:23 +00:00
toFetch := map[storiface.SectorFileType]storiface.SectorLocation{}
2022-09-16 21:45:23 +00:00
for fileType, data := range map[storiface.SectorFileType]*storiface.SectorLocation{
storiface.FTUnsealed: sector.RemoteDataUnsealed,
storiface.FTSealed: sector.RemoteDataSealed,
storiface.FTCache: sector.RemoteDataCache,
} {
if data == nil {
continue
}
if data.Local {
// todo check exists
continue
}
toFetch[fileType] = *data
}
if len(toFetch) > 0 {
if err := m.sealer.DownloadSectorData(ctx.Context(), m.minerSector(sector.SectorType, sector.SectorNumber), sector.RemoteDataFinalized, toFetch); err != nil {
return xerrors.Errorf("downloading sector data: %w", err) // todo send err event
}
}
// todo data checks?
return ctx.Send(SectorReceived{})
}
2022-09-16 21:45:23 +00:00
func checkMessagePrefix(c cid.Cid) error {
p := c.Prefix()
if p.Version != 1 || p.MhLength != 32 || p.MhType != multihash.BLAKE2B_MIN+31 || p.Codec != cid.DagCBOR {
return xerrors.New("invalid message prefix")
}
return nil
}