lotus/provider/lpweb/hapi/simpleinfo_pipeline_porep.go
2024-02-16 21:22:38 +01:00

196 lines
5.9 KiB
Go

package hapi
import (
"net/http"
"time"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/must"
)
func (a *app) pipelinePorepSectors(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
type PipelineTask struct {
SpID int64 `db:"sp_id"`
SectorNumber int64 `db:"sector_number"`
CreateTime time.Time `db:"create_time"`
TaskSDR *int64 `db:"task_id_sdr"`
AfterSDR bool `db:"after_sdr"`
TaskTreeD *int64 `db:"task_id_tree_d"`
AfterTreeD bool `db:"after_tree_d"`
TaskTreeC *int64 `db:"task_id_tree_c"`
AfterTreeC bool `db:"after_tree_c"`
TaskTreeR *int64 `db:"task_id_tree_r"`
AfterTreeR bool `db:"after_tree_r"`
TaskPrecommitMsg *int64 `db:"task_id_precommit_msg"`
AfterPrecommitMsg bool `db:"after_precommit_msg"`
AfterPrecommitMsgSuccess bool `db:"after_precommit_msg_success"`
SeedEpoch *int64 `db:"seed_epoch"`
TaskPoRep *int64 `db:"task_id_porep"`
PoRepProof []byte `db:"porep_proof"`
AfterPoRep bool `db:"after_porep"`
TaskFinalize *int64 `db:"task_id_finalize"`
AfterFinalize bool `db:"after_finalize"`
TaskMoveStorage *int64 `db:"task_id_move_storage"`
AfterMoveStorage bool `db:"after_move_storage"`
TaskCommitMsg *int64 `db:"task_id_commit_msg"`
AfterCommitMsg bool `db:"after_commit_msg"`
AfterCommitMsgSuccess bool `db:"after_commit_msg_success"`
Failed bool `db:"failed"`
FailedReason string `db:"failed_reason"`
}
var tasks []PipelineTask
err := a.db.Select(ctx, &tasks, `SELECT
sp_id, sector_number,
create_time,
task_id_sdr, after_sdr,
task_id_tree_d, after_tree_d,
task_id_tree_c, after_tree_c,
task_id_tree_r, after_tree_r,
task_id_precommit_msg, after_precommit_msg,
after_precommit_msg_success, seed_epoch,
task_id_porep, porep_proof, after_porep,
task_id_finalize, after_finalize,
task_id_move_storage, after_move_storage,
task_id_commit_msg, after_commit_msg,
after_commit_msg_success,
failed, failed_reason
FROM sectors_sdr_pipeline order by sp_id, sector_number`) // todo where constrain list
if err != nil {
http.Error(w, xerrors.Errorf("failed to fetch pipeline tasks: %w", err).Error(), http.StatusInternalServerError)
return
}
type sectorListEntry struct {
PipelineTask
Address address.Address
CreateTime string
AfterSeed bool
ChainAlloc, ChainSector, ChainActive, ChainUnproven, ChainFaulty bool
}
head, err := a.workingApi.ChainHead(ctx)
if err != nil {
http.Error(w, xerrors.Errorf("failed to fetch chain head: %w", err).Error(), http.StatusInternalServerError)
return
}
epoch := head.Height()
stor := store.ActorStore(ctx, blockstore.NewAPIBlockstore(a.workingApi))
type minerBitfields struct {
alloc, sectorSet, active, unproven, faulty bitfield.BitField
}
minerBitfieldCache := map[address.Address]minerBitfields{}
sectorList := make([]sectorListEntry, 0, len(tasks))
for _, task := range tasks {
task := task
task.CreateTime = task.CreateTime.Local()
addr, err := address.NewIDAddress(uint64(task.SpID))
if err != nil {
http.Error(w, xerrors.Errorf("failed to create actor address: %w", err).Error(), http.StatusInternalServerError)
return
}
mbf, ok := minerBitfieldCache[addr]
if !ok {
act, err := a.workingApi.StateGetActor(ctx, addr, types.EmptyTSK)
if err != nil {
http.Error(w, xerrors.Errorf("failed to load actor: %w", err).Error(), http.StatusInternalServerError)
return
}
mas, err := miner.Load(stor, act)
if err != nil {
http.Error(w, xerrors.Errorf("failed to load miner actor: %w", err).Error(), http.StatusInternalServerError)
return
}
activeSectors, err := miner.AllPartSectors(mas, miner.Partition.ActiveSectors)
if err != nil {
http.Error(w, xerrors.Errorf("failed to load active sectors: %w", err).Error(), http.StatusInternalServerError)
return
}
allSectors, err := miner.AllPartSectors(mas, miner.Partition.AllSectors)
if err != nil {
http.Error(w, xerrors.Errorf("failed to load all sectors: %w", err).Error(), http.StatusInternalServerError)
return
}
unproved, err := miner.AllPartSectors(mas, miner.Partition.UnprovenSectors)
if err != nil {
http.Error(w, xerrors.Errorf("failed to load unproven sectors: %w", err).Error(), http.StatusInternalServerError)
return
}
faulty, err := miner.AllPartSectors(mas, miner.Partition.FaultySectors)
if err != nil {
http.Error(w, xerrors.Errorf("failed to load faulty sectors: %w", err).Error(), http.StatusInternalServerError)
return
}
alloc, err := mas.GetAllocatedSectors()
if err != nil {
http.Error(w, xerrors.Errorf("failed to load allocated sectors: %w", err).Error(), http.StatusInternalServerError)
return
}
mbf = minerBitfields{
alloc: *alloc,
sectorSet: allSectors,
active: activeSectors,
unproven: unproved,
faulty: faulty,
}
minerBitfieldCache[addr] = mbf
}
afterSeed := task.SeedEpoch != nil && *task.SeedEpoch <= int64(epoch)
sectorList = append(sectorList, sectorListEntry{
PipelineTask: task,
Address: addr,
CreateTime: task.CreateTime.Format(time.DateTime),
AfterSeed: afterSeed,
ChainAlloc: must.One(mbf.alloc.IsSet(uint64(task.SectorNumber))),
ChainSector: must.One(mbf.sectorSet.IsSet(uint64(task.SectorNumber))),
ChainActive: must.One(mbf.active.IsSet(uint64(task.SectorNumber))),
ChainUnproven: must.One(mbf.unproven.IsSet(uint64(task.SectorNumber))),
ChainFaulty: must.One(mbf.faulty.IsSet(uint64(task.SectorNumber))),
})
}
a.executeTemplate(w, "pipeline_porep_sectors", sectorList)
}