lotus/provider/lpseal/task_finalize.go

153 lines
3.8 KiB
Go
Raw Normal View History

2024-01-30 11:43:57 +00:00
package lpseal
import (
"context"
2024-01-30 22:43:27 +00:00
"golang.org/x/xerrors"
2024-01-30 11:43:57 +00:00
"github.com/filecoin-project/go-state-types/abi"
2024-01-30 22:43:27 +00:00
2024-01-30 11:43:57 +00:00
"github.com/filecoin-project/lotus/lib/harmony/harmonydb"
"github.com/filecoin-project/lotus/lib/harmony/harmonytask"
"github.com/filecoin-project/lotus/lib/harmony/resources"
"github.com/filecoin-project/lotus/provider/lpffi"
"github.com/filecoin-project/lotus/storage/sealer/storiface"
)
type FinalizeTask struct {
max int
sp *SealPoller
sc *lpffi.SealCalls
db *harmonydb.DB
}
func NewFinalizeTask(max int, sp *SealPoller, sc *lpffi.SealCalls, db *harmonydb.DB) *FinalizeTask {
return &FinalizeTask{
max: max,
sp: sp,
sc: sc,
db: db,
}
}
func (f *FinalizeTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done bool, err error) {
2024-02-08 21:29:43 +00:00
var tasks []struct {
2024-01-30 11:43:57 +00:00
SpID int64 `db:"sp_id"`
SectorNumber int64 `db:"sector_number"`
RegSealProof int64 `db:"reg_seal_proof"`
}
ctx := context.Background()
2024-02-08 21:29:43 +00:00
err = f.db.Select(ctx, &tasks, `
2024-02-21 13:19:48 +00:00
SELECT sp_id, sector_number, reg_seal_proof FROM sectors_sdr_pipeline WHERE task_id_finalize = $1`, taskID)
2024-01-30 11:43:57 +00:00
if err != nil {
return false, xerrors.Errorf("getting task: %w", err)
}
2024-02-08 21:29:43 +00:00
if len(tasks) != 1 {
return false, xerrors.Errorf("expected one task")
}
task := tasks[0]
2024-02-10 18:14:31 +00:00
var keepUnsealed bool
2024-02-21 13:19:48 +00:00
if err := f.db.QueryRow(ctx, `SELECT COALESCE(BOOL_OR(NOT data_delete_on_finalize), FALSE) FROM sectors_sdr_initial_pieces WHERE sp_id = $1 AND sector_number = $2`, task.SpID, task.SectorNumber).Scan(&keepUnsealed); err != nil {
2024-02-10 18:14:31 +00:00
return false, err
}
2024-01-30 11:43:57 +00:00
sector := storiface.SectorRef{
ID: abi.SectorID{
Miner: abi.ActorID(task.SpID),
Number: abi.SectorNumber(task.SectorNumber),
},
ProofType: abi.RegisteredSealProof(task.RegSealProof),
}
2024-02-10 18:14:31 +00:00
err = f.sc.FinalizeSector(ctx, sector, keepUnsealed)
2024-01-30 11:43:57 +00:00
if err != nil {
return false, xerrors.Errorf("finalizing sector: %w", err)
}
// set after_finalize
_, err = f.db.Exec(ctx, `update sectors_sdr_pipeline set after_finalize=true where task_id_finalize=$1`, taskID)
if err != nil {
return false, xerrors.Errorf("updating task: %w", err)
}
return true, nil
}
func (f *FinalizeTask) CanAccept(ids []harmonytask.TaskID, engine *harmonytask.TaskEngine) (*harmonytask.TaskID, error) {
var tasks []struct {
TaskID harmonytask.TaskID `db:"task_id_finalize"`
SpID int64 `db:"sp_id"`
SectorNumber int64 `db:"sector_number"`
StorageID string `db:"storage_id"`
}
if 4 != storiface.FTCache {
panic("storiface.FTCache != 4")
}
ctx := context.Background()
2024-02-08 21:29:43 +00:00
indIDs := make([]int64, len(ids))
for i, id := range ids {
indIDs[i] = int64(id)
}
2024-01-30 11:43:57 +00:00
err := f.db.Select(ctx, &tasks, `
2024-02-21 13:19:48 +00:00
SELECT p.task_id_finalize, p.sp_id, p.sector_number, l.storage_id FROM sectors_sdr_pipeline p
INNER JOIN sector_location l ON p.sp_id = l.miner_id AND p.sector_number = l.sector_num
WHERE task_id_finalize = ANY ($1) AND l.sector_filetype = 4
`, indIDs)
2024-01-30 11:43:57 +00:00
if err != nil {
return nil, xerrors.Errorf("getting tasks: %w", err)
}
ls, err := f.sc.LocalStorage(ctx)
if err != nil {
return nil, xerrors.Errorf("getting local storage: %w", err)
}
2024-01-30 19:05:47 +00:00
acceptables := map[harmonytask.TaskID]bool{}
for _, t := range ids {
acceptables[t] = true
}
2024-01-30 11:43:57 +00:00
for _, t := range tasks {
2024-01-30 19:05:47 +00:00
if _, ok := acceptables[t.TaskID]; !ok {
continue
}
2024-01-30 11:43:57 +00:00
for _, l := range ls {
if string(l.ID) == t.StorageID {
return &t.TaskID, nil
}
}
}
return nil, nil
}
func (f *FinalizeTask) TypeDetails() harmonytask.TaskTypeDetails {
return harmonytask.TaskTypeDetails{
Max: f.max,
Name: "Finalize",
Cost: resources.Resources{
Cpu: 1,
Gpu: 0,
Ram: 100 << 20,
},
MaxFailures: 10,
}
}
func (f *FinalizeTask) Adder(taskFunc harmonytask.AddTaskFunc) {
f.sp.pollers[pollerFinalize].Set(taskFunc)
}
var _ harmonytask.TaskInterface = &FinalizeTask{}