2024-05-02 09:17:33 +00:00
|
|
|
package seal
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/ipfs/go-cid"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/curiosrc/ffi"
|
|
|
|
"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/storage/paths"
|
|
|
|
"github.com/filecoin-project/lotus/storage/sealer/storiface"
|
|
|
|
)
|
|
|
|
|
|
|
|
type TreeRCTask struct {
|
|
|
|
sp *SealPoller
|
|
|
|
db *harmonydb.DB
|
|
|
|
sc *ffi.SealCalls
|
|
|
|
|
|
|
|
max int
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTreeRCTask(sp *SealPoller, db *harmonydb.DB, sc *ffi.SealCalls, maxTrees int) *TreeRCTask {
|
|
|
|
return &TreeRCTask{
|
|
|
|
sp: sp,
|
|
|
|
db: db,
|
|
|
|
sc: sc,
|
|
|
|
|
|
|
|
max: maxTrees,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TreeRCTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done bool, err error) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
var sectorParamsArr []struct {
|
|
|
|
SpID int64 `db:"sp_id"`
|
|
|
|
SectorNumber int64 `db:"sector_number"`
|
|
|
|
RegSealProof abi.RegisteredSealProof `db:"reg_seal_proof"`
|
|
|
|
CommD string `db:"tree_d_cid"`
|
|
|
|
}
|
|
|
|
|
|
|
|
err = t.db.Select(ctx, §orParamsArr, `
|
|
|
|
SELECT sp_id, sector_number, reg_seal_proof, tree_d_cid
|
|
|
|
FROM sectors_sdr_pipeline
|
|
|
|
WHERE task_id_tree_c = $1 AND task_id_tree_r = $1`, taskID)
|
|
|
|
if err != nil {
|
|
|
|
return false, xerrors.Errorf("getting sector params: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(sectorParamsArr) != 1 {
|
|
|
|
return false, xerrors.Errorf("expected 1 sector params, got %d", len(sectorParamsArr))
|
|
|
|
}
|
|
|
|
sectorParams := sectorParamsArr[0]
|
|
|
|
|
|
|
|
commd, err := cid.Parse(sectorParams.CommD)
|
|
|
|
if err != nil {
|
|
|
|
return false, xerrors.Errorf("parsing unsealed CID: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sref := storiface.SectorRef{
|
|
|
|
ID: abi.SectorID{
|
|
|
|
Miner: abi.ActorID(sectorParams.SpID),
|
|
|
|
Number: abi.SectorNumber(sectorParams.SectorNumber),
|
|
|
|
},
|
|
|
|
ProofType: sectorParams.RegSealProof,
|
|
|
|
}
|
|
|
|
|
|
|
|
// R / C
|
2024-05-22 08:08:32 +00:00
|
|
|
sealed, unsealed, err := t.sc.TreeRC(ctx, &taskID, sref, commd)
|
2024-05-02 09:17:33 +00:00
|
|
|
if err != nil {
|
|
|
|
return false, xerrors.Errorf("computing tree r and c: %w", err)
|
|
|
|
}
|
|
|
|
|
2024-05-22 08:08:32 +00:00
|
|
|
if unsealed != commd {
|
|
|
|
return false, xerrors.Errorf("commd %s does match unsealed %s", commd.String(), unsealed.String())
|
|
|
|
}
|
|
|
|
|
2024-05-02 09:17:33 +00:00
|
|
|
// todo synth porep
|
|
|
|
|
|
|
|
// todo porep challenge check
|
|
|
|
|
|
|
|
n, err := t.db.Exec(ctx, `UPDATE sectors_sdr_pipeline
|
2024-05-15 15:40:40 +00:00
|
|
|
SET after_tree_r = true, after_tree_c = true, tree_r_cid = $3, task_id_tree_r = NULL, task_id_tree_c = NULL
|
2024-05-02 09:17:33 +00:00
|
|
|
WHERE sp_id = $1 AND sector_number = $2`,
|
|
|
|
sectorParams.SpID, sectorParams.SectorNumber, sealed)
|
|
|
|
if err != nil {
|
|
|
|
return false, xerrors.Errorf("store sdr-trees success: updating pipeline: %w", err)
|
|
|
|
}
|
|
|
|
if n != 1 {
|
|
|
|
return false, xerrors.Errorf("store sdr-trees success: updated %d rows", n)
|
|
|
|
}
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TreeRCTask) CanAccept(ids []harmonytask.TaskID, engine *harmonytask.TaskEngine) (*harmonytask.TaskID, error) {
|
|
|
|
var tasks []struct {
|
|
|
|
TaskID harmonytask.TaskID `db:"task_id_tree_c"`
|
|
|
|
SpID int64 `db:"sp_id"`
|
|
|
|
SectorNumber int64 `db:"sector_number"`
|
|
|
|
StorageID string `db:"storage_id"`
|
|
|
|
}
|
|
|
|
|
|
|
|
if storiface.FTCache != 4 {
|
|
|
|
panic("storiface.FTCache != 4")
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
indIDs := make([]int64, len(ids))
|
|
|
|
for i, id := range ids {
|
|
|
|
indIDs[i] = int64(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
err := t.db.Select(ctx, &tasks, `
|
|
|
|
SELECT p.task_id_tree_c, 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_tree_r = ANY ($1) AND l.sector_filetype = 4
|
|
|
|
`, indIDs)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("getting tasks: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ls, err := t.sc.LocalStorage(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("getting local storage: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
acceptables := map[harmonytask.TaskID]bool{}
|
|
|
|
|
|
|
|
for _, t := range ids {
|
|
|
|
acceptables[t] = true
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, t := range tasks {
|
|
|
|
if _, ok := acceptables[t.TaskID]; !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, l := range ls {
|
|
|
|
if string(l.ID) == t.StorageID {
|
|
|
|
return &t.TaskID, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TreeRCTask) TypeDetails() harmonytask.TaskTypeDetails {
|
|
|
|
ssize := abi.SectorSize(32 << 30) // todo task details needs taskID to get correct sector size
|
|
|
|
if isDevnet {
|
|
|
|
ssize = abi.SectorSize(2 << 20)
|
|
|
|
}
|
2024-05-07 15:20:00 +00:00
|
|
|
gpu := 1.0
|
|
|
|
if isDevnet {
|
|
|
|
gpu = 0
|
|
|
|
}
|
2024-05-02 09:17:33 +00:00
|
|
|
|
|
|
|
return harmonytask.TaskTypeDetails{
|
|
|
|
Max: t.max,
|
|
|
|
Name: "TreeRC",
|
|
|
|
Cost: resources.Resources{
|
|
|
|
Cpu: 1,
|
2024-05-07 15:20:00 +00:00
|
|
|
Gpu: gpu,
|
2024-05-02 09:17:33 +00:00
|
|
|
Ram: 8 << 30,
|
|
|
|
Storage: t.sc.Storage(t.taskToSector, storiface.FTSealed, storiface.FTCache, ssize, storiface.PathSealing, paths.MinFreeStoragePercentage),
|
|
|
|
},
|
|
|
|
MaxFailures: 3,
|
|
|
|
Follows: nil,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TreeRCTask) Adder(taskFunc harmonytask.AddTaskFunc) {
|
|
|
|
t.sp.pollers[pollerTreeRC].Set(taskFunc)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TreeRCTask) taskToSector(id harmonytask.TaskID) (ffi.SectorRef, error) {
|
|
|
|
var refs []ffi.SectorRef
|
|
|
|
|
|
|
|
err := t.db.Select(context.Background(), &refs, `SELECT sp_id, sector_number, reg_seal_proof FROM sectors_sdr_pipeline WHERE task_id_tree_r = $1`, id)
|
|
|
|
if err != nil {
|
|
|
|
return ffi.SectorRef{}, xerrors.Errorf("getting sector ref: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(refs) != 1 {
|
|
|
|
return ffi.SectorRef{}, xerrors.Errorf("expected 1 sector ref, got %d", len(refs))
|
|
|
|
}
|
|
|
|
|
|
|
|
return refs[0], nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ harmonytask.TaskInterface = &TreeRCTask{}
|