2020-04-23 22:16:21 +00:00
|
|
|
package storiface
|
|
|
|
|
2020-07-21 18:01:25 +00:00
|
|
|
import (
|
2020-09-06 16:47:16 +00:00
|
|
|
"context"
|
2020-11-17 15:28:41 +00:00
|
|
|
"errors"
|
2020-09-14 07:44:55 +00:00
|
|
|
"fmt"
|
2020-07-21 18:01:25 +00:00
|
|
|
"time"
|
|
|
|
|
2020-09-06 16:47:16 +00:00
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/ipfs/go-cid"
|
|
|
|
|
2020-09-07 03:49:10 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
2022-06-14 15:00:51 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/proof"
|
2022-06-14 18:03:38 +00:00
|
|
|
"github.com/filecoin-project/lotus/storage/sealer/sealtasks"
|
2020-07-21 18:01:25 +00:00
|
|
|
)
|
|
|
|
|
2021-11-29 13:42:20 +00:00
|
|
|
type WorkerID uuid.UUID // worker session UUID
|
|
|
|
|
|
|
|
func (w WorkerID) String() string {
|
|
|
|
return uuid.UUID(w).String()
|
|
|
|
}
|
|
|
|
|
2020-04-23 22:16:21 +00:00
|
|
|
type WorkerInfo struct {
|
|
|
|
Hostname string
|
|
|
|
|
2021-06-21 18:35:47 +00:00
|
|
|
// IgnoreResources indicates whether the worker's available resources should
|
|
|
|
// be used ignored (true) or used (false) for the purposes of scheduling and
|
|
|
|
// task assignment. Only supported on local workers. Used for testing.
|
|
|
|
// Default should be false (zero value, i.e. resources taken into account).
|
|
|
|
IgnoreResources bool
|
|
|
|
Resources WorkerResources
|
2020-04-23 22:16:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type WorkerResources struct {
|
|
|
|
MemPhysical uint64
|
2021-09-09 21:41:59 +00:00
|
|
|
MemUsed uint64
|
2020-04-23 22:16:21 +00:00
|
|
|
MemSwap uint64
|
2021-09-09 21:41:59 +00:00
|
|
|
MemSwapUsed uint64
|
2020-04-23 22:16:21 +00:00
|
|
|
|
2020-04-27 12:38:24 +00:00
|
|
|
CPUs uint64 // Logical cores
|
2020-04-23 22:16:21 +00:00
|
|
|
GPUs []string
|
2021-11-29 13:42:20 +00:00
|
|
|
|
|
|
|
// if nil use the default resource table
|
|
|
|
Resources map[sealtasks.TaskType]map[abi.RegisteredSealProof]Resources
|
|
|
|
}
|
|
|
|
|
|
|
|
func (wr WorkerResources) ResourceSpec(spt abi.RegisteredSealProof, tt sealtasks.TaskType) Resources {
|
|
|
|
res := ResourceTable[tt][spt]
|
|
|
|
|
|
|
|
// if the worker specifies custom resource table, prefer that
|
|
|
|
if wr.Resources != nil {
|
|
|
|
tr, ok := wr.Resources[tt]
|
|
|
|
if !ok {
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok := tr[spt]
|
|
|
|
if ok {
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// otherwise, use the default resource table
|
|
|
|
return res
|
2020-04-23 22:16:21 +00:00
|
|
|
}
|
|
|
|
|
2023-02-28 09:33:15 +00:00
|
|
|
// PrepResourceSpec is like ResourceSpec, but meant for use limiting parallel preparing
|
|
|
|
// tasks.
|
|
|
|
func (wr WorkerResources) PrepResourceSpec(spt abi.RegisteredSealProof, tt, prepTT sealtasks.TaskType) Resources {
|
|
|
|
res := wr.ResourceSpec(spt, tt)
|
|
|
|
|
|
|
|
if prepTT != tt && prepTT != sealtasks.TTNoop {
|
|
|
|
prepRes := wr.ResourceSpec(spt, prepTT)
|
|
|
|
res.MaxConcurrent = prepRes.MaxConcurrent
|
|
|
|
}
|
|
|
|
|
|
|
|
// otherwise, use the default resource table
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2020-04-23 22:16:21 +00:00
|
|
|
type WorkerStats struct {
|
2020-10-18 10:35:44 +00:00
|
|
|
Info WorkerInfo
|
2022-03-18 20:31:15 +00:00
|
|
|
Tasks []sealtasks.TaskType
|
2020-10-18 10:35:44 +00:00
|
|
|
Enabled bool
|
2020-04-23 22:16:21 +00:00
|
|
|
|
|
|
|
MemUsedMin uint64
|
|
|
|
MemUsedMax uint64
|
2021-09-01 01:59:25 +00:00
|
|
|
GpuUsed float64 // nolint
|
|
|
|
CpuUse uint64 // nolint
|
2022-05-25 12:44:11 +00:00
|
|
|
|
|
|
|
TaskCounts map[string]int
|
2020-04-23 22:16:21 +00:00
|
|
|
}
|
2020-07-21 18:01:25 +00:00
|
|
|
|
2020-11-09 22:38:20 +00:00
|
|
|
const (
|
2021-10-15 19:26:35 +00:00
|
|
|
RWPrepared = 1
|
|
|
|
RWRunning = 0
|
2020-11-09 22:38:20 +00:00
|
|
|
RWRetWait = -1
|
|
|
|
RWReturned = -2
|
|
|
|
RWRetDone = -3
|
|
|
|
)
|
|
|
|
|
2020-07-21 18:01:25 +00:00
|
|
|
type WorkerJob struct {
|
2020-09-07 14:12:46 +00:00
|
|
|
ID CallID
|
2020-07-21 18:01:25 +00:00
|
|
|
Sector abi.SectorID
|
|
|
|
Task sealtasks.TaskType
|
|
|
|
|
2021-10-15 19:26:35 +00:00
|
|
|
// 2+ - assigned
|
|
|
|
// 1 - prepared
|
2020-11-09 22:38:20 +00:00
|
|
|
// 0 - running
|
|
|
|
// -1 - ret-wait
|
|
|
|
// -2 - returned
|
|
|
|
// -3 - ret-done
|
|
|
|
RunWait int
|
2020-08-27 21:14:33 +00:00
|
|
|
Start time.Time
|
2020-11-09 22:09:04 +00:00
|
|
|
|
|
|
|
Hostname string `json:",omitempty"` // optional, set for ret-wait jobs
|
2020-07-21 18:01:25 +00:00
|
|
|
}
|
2020-09-06 16:47:16 +00:00
|
|
|
|
|
|
|
type CallID struct {
|
|
|
|
Sector abi.SectorID
|
|
|
|
ID uuid.UUID
|
|
|
|
}
|
|
|
|
|
2020-09-14 07:44:55 +00:00
|
|
|
func (c CallID) String() string {
|
|
|
|
return fmt.Sprintf("%d-%d-%s", c.Sector.Miner, c.Sector.Number, c.ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ fmt.Stringer = &CallID{}
|
|
|
|
|
2020-09-06 16:47:16 +00:00
|
|
|
var UndefCall CallID
|
|
|
|
|
|
|
|
type WorkerCalls interface {
|
2022-01-14 13:11:04 +00:00
|
|
|
// async
|
2022-06-17 11:31:05 +00:00
|
|
|
DataCid(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData Data) (CallID, error)
|
|
|
|
AddPiece(ctx context.Context, sector SectorRef, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData Data) (CallID, error)
|
|
|
|
SealPreCommit1(ctx context.Context, sector SectorRef, ticket abi.SealRandomness, pieces []abi.PieceInfo) (CallID, error)
|
|
|
|
SealPreCommit2(ctx context.Context, sector SectorRef, pc1o PreCommit1Out) (CallID, error)
|
|
|
|
SealCommit1(ctx context.Context, sector SectorRef, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids SectorCids) (CallID, error)
|
|
|
|
SealCommit2(ctx context.Context, sector SectorRef, c1o Commit1Out) (CallID, error)
|
2022-11-16 16:07:42 +00:00
|
|
|
FinalizeSector(ctx context.Context, sector SectorRef) (CallID, error)
|
|
|
|
FinalizeReplicaUpdate(ctx context.Context, sector SectorRef) (CallID, error)
|
2022-06-17 11:31:05 +00:00
|
|
|
ReleaseUnsealed(ctx context.Context, sector SectorRef, safeToFree []Range) (CallID, error)
|
|
|
|
ReplicaUpdate(ctx context.Context, sector SectorRef, pieces []abi.PieceInfo) (CallID, error)
|
|
|
|
ProveReplicaUpdate1(ctx context.Context, sector SectorRef, sectorKey, newSealed, newUnsealed cid.Cid) (CallID, error)
|
|
|
|
ProveReplicaUpdate2(ctx context.Context, sector SectorRef, sectorKey, newSealed, newUnsealed cid.Cid, vanillaProofs ReplicaVanillaProofs) (CallID, error)
|
|
|
|
GenerateSectorKeyFromData(ctx context.Context, sector SectorRef, commD cid.Cid) (CallID, error)
|
|
|
|
MoveStorage(ctx context.Context, sector SectorRef, types SectorFileType) (CallID, error)
|
|
|
|
UnsealPiece(context.Context, SectorRef, UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (CallID, error)
|
|
|
|
Fetch(context.Context, SectorRef, SectorFileType, PathType, AcquireMode) (CallID, error)
|
2022-09-16 21:45:23 +00:00
|
|
|
DownloadSectorData(ctx context.Context, sector SectorRef, finalized bool, src map[SectorFileType]SectorLocation) (CallID, error)
|
2022-01-14 13:11:04 +00:00
|
|
|
|
|
|
|
// sync
|
|
|
|
GenerateWinningPoSt(ctx context.Context, ppt abi.RegisteredPoStProof, mid abi.ActorID, sectors []PostSectorChallenge, randomness abi.PoStRandomness) ([]proof.PoStProof, error)
|
|
|
|
GenerateWindowPoSt(ctx context.Context, ppt abi.RegisteredPoStProof, mid abi.ActorID, sectors []PostSectorChallenge, partitionIdx int, randomness abi.PoStRandomness) (WindowPoStResult, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
type WindowPoStResult struct {
|
|
|
|
PoStProofs proof.PoStProof
|
|
|
|
Skipped []abi.SectorID
|
|
|
|
}
|
|
|
|
|
|
|
|
type PostSectorChallenge struct {
|
|
|
|
SealProof abi.RegisteredSealProof
|
|
|
|
SectorNumber abi.SectorNumber
|
|
|
|
SealedCID cid.Cid
|
|
|
|
Challenge []uint64
|
2022-01-18 10:25:04 +00:00
|
|
|
Update bool
|
2022-01-14 13:11:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type FallbackChallenges struct {
|
|
|
|
Sectors []abi.SectorNumber
|
|
|
|
Challenges map[abi.SectorNumber][]uint64
|
2020-09-06 16:47:16 +00:00
|
|
|
}
|
|
|
|
|
2020-11-17 15:17:45 +00:00
|
|
|
type ErrorCode int
|
|
|
|
|
|
|
|
const (
|
|
|
|
ErrUnknown ErrorCode = iota
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// Temp Errors
|
|
|
|
ErrTempUnknown ErrorCode = iota + 100
|
|
|
|
ErrTempWorkerRestart
|
|
|
|
ErrTempAllocateSpace
|
|
|
|
)
|
|
|
|
|
2023-09-21 15:37:02 +00:00
|
|
|
type WorkError interface {
|
|
|
|
ErrCode() ErrorCode
|
|
|
|
}
|
|
|
|
|
2020-11-17 15:17:45 +00:00
|
|
|
type CallError struct {
|
2020-11-17 15:28:41 +00:00
|
|
|
Code ErrorCode
|
|
|
|
Message string
|
|
|
|
sub error
|
2020-11-17 15:17:45 +00:00
|
|
|
}
|
|
|
|
|
2023-09-21 15:37:02 +00:00
|
|
|
func (c *CallError) ErrCode() ErrorCode {
|
|
|
|
return c.Code
|
|
|
|
}
|
|
|
|
|
2020-11-17 15:17:45 +00:00
|
|
|
func (c *CallError) Error() string {
|
2020-11-17 15:28:41 +00:00
|
|
|
return fmt.Sprintf("storage call error %d: %s", c.Code, c.Message)
|
2020-11-17 15:17:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CallError) Unwrap() error {
|
2020-11-17 15:28:41 +00:00
|
|
|
if c.sub != nil {
|
|
|
|
return c.sub
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors.New(c.Message)
|
2020-11-17 15:17:45 +00:00
|
|
|
}
|
|
|
|
|
2023-09-21 15:37:02 +00:00
|
|
|
var _ WorkError = &CallError{}
|
|
|
|
|
2020-11-17 15:17:45 +00:00
|
|
|
func Err(code ErrorCode, sub error) *CallError {
|
|
|
|
return &CallError{
|
2020-11-17 15:28:41 +00:00
|
|
|
Code: code,
|
|
|
|
Message: sub.Error(),
|
|
|
|
|
|
|
|
sub: sub,
|
2020-11-17 15:17:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-06 16:47:16 +00:00
|
|
|
type WorkerReturn interface {
|
2022-04-26 16:22:52 +00:00
|
|
|
ReturnDataCid(ctx context.Context, callID CallID, pi abi.PieceInfo, err *CallError) error
|
2020-11-17 15:17:45 +00:00
|
|
|
ReturnAddPiece(ctx context.Context, callID CallID, pi abi.PieceInfo, err *CallError) error
|
2022-06-17 11:31:05 +00:00
|
|
|
ReturnSealPreCommit1(ctx context.Context, callID CallID, p1o PreCommit1Out, err *CallError) error
|
|
|
|
ReturnSealPreCommit2(ctx context.Context, callID CallID, sealed SectorCids, err *CallError) error
|
|
|
|
ReturnSealCommit1(ctx context.Context, callID CallID, out Commit1Out, err *CallError) error
|
|
|
|
ReturnSealCommit2(ctx context.Context, callID CallID, proof Proof, err *CallError) error
|
2020-11-17 15:17:45 +00:00
|
|
|
ReturnFinalizeSector(ctx context.Context, callID CallID, err *CallError) error
|
|
|
|
ReturnReleaseUnsealed(ctx context.Context, callID CallID, err *CallError) error
|
2022-06-17 11:31:05 +00:00
|
|
|
ReturnReplicaUpdate(ctx context.Context, callID CallID, out ReplicaUpdateOut, err *CallError) error
|
|
|
|
ReturnProveReplicaUpdate1(ctx context.Context, callID CallID, proofs ReplicaVanillaProofs, err *CallError) error
|
|
|
|
ReturnProveReplicaUpdate2(ctx context.Context, callID CallID, proof ReplicaUpdateProof, err *CallError) error
|
2021-12-01 19:01:55 +00:00
|
|
|
ReturnGenerateSectorKeyFromData(ctx context.Context, callID CallID, err *CallError) error
|
2022-02-08 14:06:42 +00:00
|
|
|
ReturnFinalizeReplicaUpdate(ctx context.Context, callID CallID, err *CallError) error
|
2020-11-17 15:17:45 +00:00
|
|
|
ReturnMoveStorage(ctx context.Context, callID CallID, err *CallError) error
|
|
|
|
ReturnUnsealPiece(ctx context.Context, callID CallID, err *CallError) error
|
|
|
|
ReturnReadPiece(ctx context.Context, callID CallID, ok bool, err *CallError) error
|
2022-08-31 11:56:25 +00:00
|
|
|
ReturnDownloadSector(ctx context.Context, callID CallID, err *CallError) error
|
2020-11-17 15:17:45 +00:00
|
|
|
ReturnFetch(ctx context.Context, callID CallID, err *CallError) error
|
2020-09-06 16:47:16 +00:00
|
|
|
}
|