sealmgr: Interfaces; simple initial impl
This commit is contained in:
parent
98dbb2f70f
commit
3abb59a550
@ -1,12 +1,14 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
"github.com/filecoin-project/lotus/storage/sealmgr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// alias because cbor-gen doesn't like non-alias types
|
// alias because cbor-gen doesn't like non-alias types
|
||||||
@ -103,30 +105,14 @@ type StorageMiner interface {
|
|||||||
|
|
||||||
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error
|
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error
|
||||||
|
|
||||||
WorkerStats(context.Context) (WorkerStats, error)
|
/*WorkerStats(context.Context) (sealsched.WorkerStats, error)*/
|
||||||
|
|
||||||
// WorkerQueue registers a remote worker
|
/*// WorkerQueue registers a remote worker
|
||||||
WorkerQueue(context.Context, WorkerCfg) (<-chan WorkerTask, error)
|
WorkerQueue(context.Context, WorkerCfg) (<-chan WorkerTask, error)
|
||||||
|
|
||||||
WorkerDone(ctx context.Context, task uint64, res SealRes) error
|
WorkerDone(ctx context.Context, task uint64, res SealRes) error*/
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorkerStats struct {
|
|
||||||
Total int
|
|
||||||
Free int
|
|
||||||
|
|
||||||
AddPieceWait int
|
|
||||||
PreCommitWait int
|
|
||||||
CommitWait int
|
|
||||||
UnsealWait int
|
|
||||||
}
|
|
||||||
|
|
||||||
type WorkerTask struct {
|
|
||||||
}
|
|
||||||
type WorkerCfg struct {
|
|
||||||
NoPreCommit bool
|
|
||||||
NoCommit bool
|
|
||||||
}
|
|
||||||
type SealRes struct {
|
type SealRes struct {
|
||||||
Err string
|
Err string
|
||||||
GoErr error `json:"-"`
|
GoErr error `json:"-"`
|
||||||
@ -150,8 +136,8 @@ type SectorInfo struct {
|
|||||||
CommR *cid.Cid
|
CommR *cid.Cid
|
||||||
Proof []byte
|
Proof []byte
|
||||||
Deals []abi.DealID
|
Deals []abi.DealID
|
||||||
Ticket SealTicket
|
Ticket sealmgr.SealTicket
|
||||||
Seed SealSeed
|
Seed sealmgr.SealSeed
|
||||||
Retries uint64
|
Retries uint64
|
||||||
|
|
||||||
LastErr string
|
LastErr string
|
||||||
@ -168,21 +154,3 @@ type SealedRef struct {
|
|||||||
type SealedRefs struct {
|
type SealedRefs struct {
|
||||||
Refs []SealedRef
|
Refs []SealedRef
|
||||||
}
|
}
|
||||||
|
|
||||||
type SealTicket struct {
|
|
||||||
Value abi.SealRandomness
|
|
||||||
Epoch abi.ChainEpoch
|
|
||||||
}
|
|
||||||
|
|
||||||
type SealSeed struct {
|
|
||||||
Value abi.InteractiveSealRandomness
|
|
||||||
Epoch abi.ChainEpoch
|
|
||||||
}
|
|
||||||
|
|
||||||
func (st *SealTicket) Equals(ost *SealTicket) bool {
|
|
||||||
return bytes.Equal(st.Value, ost.Value) && st.Epoch == ost.Epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
func (st *SealSeed) Equals(ost *SealSeed) bool {
|
|
||||||
return bytes.Equal(st.Value, ost.Value) && st.Epoch == ost.Epoch
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
@ -168,10 +167,10 @@ type StorageMinerStruct struct {
|
|||||||
SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"`
|
SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"`
|
||||||
SectorsUpdate func(context.Context, abi.SectorNumber, api.SectorState) error `perm:"write"`
|
SectorsUpdate func(context.Context, abi.SectorNumber, api.SectorState) error `perm:"write"`
|
||||||
|
|
||||||
WorkerStats func(context.Context) (sectorbuilder.WorkerStats, error) `perm:"read"`
|
/* WorkerStats func(context.Context) (sealsched.WorkerStats, error) `perm:"read"`
|
||||||
|
*/
|
||||||
WorkerQueue func(ctx context.Context, cfg sectorbuilder.WorkerCfg) (<-chan sectorbuilder.WorkerTask, error) `perm:"admin"` // TODO: worker perm
|
/* WorkerQueue func(ctx context.Context, cfg sealsched.WorkerCfg) (<-chan sealsched.WorkerTask, error) `perm:"admin"` // TODO: worker perm
|
||||||
WorkerDone func(ctx context.Context, task uint64, res sectorbuilder.SealRes) error `perm:"admin"`
|
WorkerDone func(ctx context.Context, task uint64, res sealsched.SealRes) error `perm:"admin"`*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,17 +600,17 @@ func (c *StorageMinerStruct) SectorsUpdate(ctx context.Context, id abi.SectorNum
|
|||||||
return c.Internal.SectorsUpdate(ctx, id, state)
|
return c.Internal.SectorsUpdate(ctx, id, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (sectorbuilder.WorkerStats, error) {
|
/*func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (sealsched.WorkerStats, error) {
|
||||||
return c.Internal.WorkerStats(ctx)
|
return c.Internal.WorkerStats(ctx)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
func (c *StorageMinerStruct) WorkerQueue(ctx context.Context, cfg sectorbuilder.WorkerCfg) (<-chan sectorbuilder.WorkerTask, error) {
|
/*func (c *StorageMinerStruct) WorkerQueue(ctx context.Context, cfg sectorbuilder.WorkerCfg) (<-chan sectorbuilder.WorkerTask, error) {
|
||||||
return c.Internal.WorkerQueue(ctx, cfg)
|
return c.Internal.WorkerQueue(ctx, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StorageMinerStruct) WorkerDone(ctx context.Context, task uint64, res sectorbuilder.SealRes) error {
|
func (c *StorageMinerStruct) WorkerDone(ctx context.Context, task uint64, res sectorbuilder.SealRes) error {
|
||||||
return c.Internal.WorkerDone(ctx, task, res)
|
return c.Internal.WorkerDone(ctx, task, res)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
var _ api.Common = &CommonStruct{}
|
var _ api.Common = &CommonStruct{}
|
||||||
var _ api.FullNode = &FullNodeStruct{}
|
var _ api.FullNode = &FullNodeStruct{}
|
||||||
|
92
storage/sealmgr/simple.go
Normal file
92
storage/sealmgr/simple.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package sealmgr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-fil-markets/storedcounter"
|
||||||
|
"github.com/filecoin-project/go-sectorbuilder"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
|
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Simple implements a very basic storage manager which has one local worker,
|
||||||
|
// running one thing locally
|
||||||
|
type Simple struct {
|
||||||
|
sc *storedcounter.StoredCounter
|
||||||
|
maddr address.Address
|
||||||
|
|
||||||
|
rateLimiter sync.Mutex
|
||||||
|
worker Worker
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSimpleManager(sc *storedcounter.StoredCounter, maddr address.Address, sb sectorbuilder.Basic) (*Simple, error) {
|
||||||
|
mid, err := address.IDFromAddress(maddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("get miner id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w := &LocalWorker{
|
||||||
|
sealer: sb,
|
||||||
|
mid: abi.ActorID(mid),
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Simple{
|
||||||
|
sc: sc,
|
||||||
|
maddr: maddr,
|
||||||
|
worker: w,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simple) NewSector() (SectorInfo, error) {
|
||||||
|
n, err := s.sc.Next()
|
||||||
|
if err != nil {
|
||||||
|
return SectorInfo{}, xerrors.Errorf("acquire sector number: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mid, err := address.IDFromAddress(s.maddr)
|
||||||
|
if err != nil {
|
||||||
|
return SectorInfo{}, xerrors.Errorf("get miner id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return SectorInfo{
|
||||||
|
ID: abi.SectorID{
|
||||||
|
Miner: abi.ActorID(mid),
|
||||||
|
Number: abi.SectorNumber(n),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simple) AddPiece(ctx context.Context, si SectorInfo, sz abi.UnpaddedPieceSize, r io.Reader) (cid.Cid, SectorInfo, error) {
|
||||||
|
s.rateLimiter.Lock()
|
||||||
|
defer s.rateLimiter.Unlock()
|
||||||
|
|
||||||
|
return s.worker.AddPiece(ctx, si, sz, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simple) RunSeal(ctx context.Context, task TaskType, si SectorInfo) (SectorInfo, error) {
|
||||||
|
s.rateLimiter.Lock()
|
||||||
|
defer s.rateLimiter.Unlock()
|
||||||
|
|
||||||
|
return s.worker.Run(ctx, task, si)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simple) GenerateEPostCandidates(sectorInfo []abi.SectorInfo, challengeSeed abi.PoStRandomness, faults []abi.SectorNumber) ([]ffi.PoStCandidateWithTicket, error) {
|
||||||
|
return s.worker.(*LocalWorker).sealer.GenerateEPostCandidates(sectorInfo, challengeSeed, faults)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simple) GenerateFallbackPoSt(sectorInfo []abi.SectorInfo, challengeSeed abi.PoStRandomness, faults []abi.SectorNumber) ([]ffi.PoStCandidateWithTicket, []abi.PoStProof, error) {
|
||||||
|
return s.worker.(*LocalWorker).sealer.GenerateFallbackPoSt(sectorInfo, challengeSeed, faults)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Simple) ComputeElectionPoSt(sectorInfo []abi.SectorInfo, challengeSeed abi.PoStRandomness, winners []abi.PoStCandidate) ([]abi.PoStProof, error) {
|
||||||
|
return s.worker.(*LocalWorker).sealer.ComputeElectionPoSt(sectorInfo, challengeSeed, winners)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Manager = &Simple{}
|
9
storage/sealmgr/task.go
Normal file
9
storage/sealmgr/task.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package sealmgr
|
||||||
|
|
||||||
|
type TaskType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TTPreCommit1 TaskType = "seal/v0/precommit/1"
|
||||||
|
TTPreCommit2 TaskType = "seal/v0/precommit/2" // Commit1 is called here too
|
||||||
|
TTCommit2 TaskType = "seal/v0/commit/2"
|
||||||
|
)
|
80
storage/sealmgr/types.go
Normal file
80
storage/sealmgr/types.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package sealmgr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-sectorbuilder"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type SealTicket struct {
|
||||||
|
Value abi.SealRandomness
|
||||||
|
Epoch abi.ChainEpoch
|
||||||
|
}
|
||||||
|
|
||||||
|
type SealSeed struct {
|
||||||
|
Value abi.InteractiveSealRandomness
|
||||||
|
Epoch abi.ChainEpoch
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *SealTicket) Equals(ost *SealTicket) bool {
|
||||||
|
return bytes.Equal(st.Value, ost.Value) && st.Epoch == ost.Epoch
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *SealSeed) Equals(ost *SealSeed) bool {
|
||||||
|
return bytes.Equal(st.Value, ost.Value) && st.Epoch == ost.Epoch
|
||||||
|
}
|
||||||
|
|
||||||
|
// SectorInfo holds all sector-related metadata
|
||||||
|
type SectorInfo struct {
|
||||||
|
ID abi.SectorID
|
||||||
|
|
||||||
|
Pieces []abi.PieceInfo
|
||||||
|
|
||||||
|
Ticket SealTicket
|
||||||
|
Seed SealSeed
|
||||||
|
|
||||||
|
PreCommit1Out []byte
|
||||||
|
|
||||||
|
Sealed *cid.Cid
|
||||||
|
Unsealed *cid.Cid
|
||||||
|
|
||||||
|
CommitInput []byte
|
||||||
|
Proof []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (si SectorInfo) PieceSizes() []abi.UnpaddedPieceSize {
|
||||||
|
out := make([]abi.UnpaddedPieceSize, len(si.Pieces))
|
||||||
|
for i := range out {
|
||||||
|
out[i] = si.Pieces[i].Size.Unpadded()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Worker interface {
|
||||||
|
AddPiece(context.Context, SectorInfo, abi.UnpaddedPieceSize, io.Reader) (cid.Cid, SectorInfo, error)
|
||||||
|
Run(context.Context, TaskType, SectorInfo) (SectorInfo, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Manager interface {
|
||||||
|
// NewSector allocates staging area for data
|
||||||
|
NewSector() (SectorInfo, error)
|
||||||
|
|
||||||
|
// AddPiece appends the piece to the specified sector. Returns PieceCID, and
|
||||||
|
// mutated sector info
|
||||||
|
//
|
||||||
|
// Note: The passed reader can support other transfer mechanisms, making
|
||||||
|
// it possible to move the data between data transfer module and workers
|
||||||
|
AddPiece(context.Context, SectorInfo, abi.UnpaddedPieceSize, io.Reader) (cid.Cid, SectorInfo, error)
|
||||||
|
|
||||||
|
RunSeal(ctx context.Context, task TaskType, si SectorInfo) (SectorInfo, error)
|
||||||
|
|
||||||
|
// Storage manager forwards proving calls
|
||||||
|
sectorbuilder.Prover
|
||||||
|
}
|
74
storage/sealmgr/worker_local.go
Normal file
74
storage/sealmgr/worker_local.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package sealmgr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-sectorbuilder"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LocalWorker struct {
|
||||||
|
sealer sectorbuilder.Basic
|
||||||
|
mid abi.ActorID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *LocalWorker) Run(ctx context.Context, task TaskType, si SectorInfo) (SectorInfo, error) {
|
||||||
|
if si.ID.Miner != w.mid {
|
||||||
|
return si, xerrors.Errorf("received a task with wrong actor id; worker for %d, task for %d", w.mid, si.ID.Miner)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch task {
|
||||||
|
case TTPreCommit1:
|
||||||
|
pco, err := w.sealer.SealPreCommit1(ctx, si.ID.Number, si.Ticket.Value, si.Pieces)
|
||||||
|
if err != nil {
|
||||||
|
return si, xerrors.Errorf("calling sealer: %w", err)
|
||||||
|
}
|
||||||
|
si.PreCommit1Out = pco
|
||||||
|
case TTPreCommit2:
|
||||||
|
sealed, unsealed, err := w.sealer.SealPreCommit2(ctx, si.ID.Number, si.PreCommit1Out)
|
||||||
|
if err != nil {
|
||||||
|
return si, xerrors.Errorf("calling sealer (precommit2): %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
si.Sealed = &sealed
|
||||||
|
si.Unsealed = &unsealed
|
||||||
|
|
||||||
|
// We also call Commit1 here as it only grabs some inputs for the snark,
|
||||||
|
// which is very fast (<1s), and it doesn't really make sense to have a separate
|
||||||
|
// task type for it
|
||||||
|
|
||||||
|
c2in, err := w.sealer.SealCommit1(ctx, si.ID.Number, si.Ticket.Value, si.Seed.Value, si.Pieces, *si.Sealed, *si.Unsealed)
|
||||||
|
if err != nil {
|
||||||
|
return si, xerrors.Errorf("calling sealer (commit1): %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
si.CommitInput = c2in
|
||||||
|
case TTCommit2:
|
||||||
|
proof, err := w.sealer.SealCommit2(ctx, si.ID.Number, si.CommitInput)
|
||||||
|
if err != nil {
|
||||||
|
return SectorInfo{}, xerrors.Errorf("calling sealer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
si.Proof = proof
|
||||||
|
default:
|
||||||
|
return si, xerrors.Errorf("unknown task type '%s'", task)
|
||||||
|
}
|
||||||
|
|
||||||
|
return si, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *LocalWorker) AddPiece(ctx context.Context, si SectorInfo, sz abi.UnpaddedPieceSize, r io.Reader) (cid.Cid, SectorInfo, error) {
|
||||||
|
pi, err := w.sealer.AddPiece(ctx, sz, si.ID.Number, r, si.PieceSizes())
|
||||||
|
if err != nil {
|
||||||
|
return cid.Cid{}, SectorInfo{}, xerrors.Errorf("addPiece on local worker: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
si.Pieces = append(si.Pieces, pi)
|
||||||
|
return pi.PieceCID, si, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Worker = &LocalWorker{}
|
Loading…
Reference in New Issue
Block a user