diff --git a/provider/lpweb/hapi/routes.go b/provider/lpweb/hapi/routes.go index 47f924fab..2e752935d 100644 --- a/provider/lpweb/hapi/routes.go +++ b/provider/lpweb/hapi/routes.go @@ -33,6 +33,9 @@ func Routes(r *mux.Router, deps *deps.Deps) error { r.HandleFunc("/simpleinfo/tasks", a.indexTasks) r.HandleFunc("/simpleinfo/taskhistory", a.indexTasksHistory) r.HandleFunc("/simpleinfo/pipeline-porep", a.indexPipelinePorep) + + // pipeline-porep page + r.HandleFunc("/simpleinfo/pipeline-porep/sectors", a.pipelinePorepSectors) return nil } diff --git a/provider/lpweb/hapi/simpleinfo_pipeline_porep.go b/provider/lpweb/hapi/simpleinfo_pipeline_porep.go new file mode 100644 index 000000000..36bd3221b --- /dev/null +++ b/provider/lpweb/hapi/simpleinfo_pipeline_porep.go @@ -0,0 +1,195 @@ +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) +} diff --git a/provider/lpweb/hapi/web/pipeline_porep_sectors.gohtml b/provider/lpweb/hapi/web/pipeline_porep_sectors.gohtml new file mode 100644 index 000000000..f5069fe6d --- /dev/null +++ b/provider/lpweb/hapi/web/pipeline_porep_sectors.gohtml @@ -0,0 +1,138 @@ +{{define "pipeline_porep_sectors"}} + {{range .}} +
+ SDR
+
+ {{if .AfterSDR}}done{{else}}
+ {{if ne .TaskSDR nil}}T:{{.TaskSDR}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ TreeC
+
+ {{if .AfterTreeC}}done{{else}}
+ {{if ne .TaskTreeC nil}}T:{{.TaskTreeC}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ PComm Msg
+
+ {{if .AfterPrecommitMsg}}done{{else}}
+ {{if ne .TaskPrecommitMsg nil}}T:{{.TaskPrecommitMsg}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ PComm Wait
+
+ {{if .AfterPrecommitMsgSuccess}}done{{else}}
+ --
+ {{end}}
+
+ |
+
+ Wait Seed
+
+ {{if .AfterSeed}}done{{else}}
+ {{if ne .SeedEpoch nil}}@{{.SeedEpoch}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ PoRep
+
+ {{if .AfterPoRep}}done{{else}}
+ {{if ne .TaskPoRep nil}}T:{{.TaskPoRep}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ Clear Cache
+
+ {{if .AfterFinalize}}done{{else}}
+ {{if ne .TaskFinalize nil}}T:{{.TaskFinalize}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ Move Storage
+
+ {{if .AfterMoveStorage}}done{{else}}
+ {{if ne .TaskMoveStorage nil}}T:{{.TaskMoveStorage}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ On Chain
+ {{if .ChainSector}}yes{{else}}{{if .ChainAlloc}}allocated{{else}}no{{end}}{{end}}
+ |
+
+ TreeD
+
+ {{if .AfterTreeD}}done{{else}}
+ {{if ne .TaskTreeD nil}}T:{{.TaskTreeD}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ TreeR
+
+ {{if .AfterTreeR}}done{{else}}
+ {{if ne .TaskTreeR nil}}T:{{.TaskTreeR}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+
+
+
+
+ Commit Msg
+
+ {{if .AfterCommitMsg}}done{{else}}
+ {{if ne .TaskCommitMsg nil}}T:{{.TaskCommitMsg}}{{else}}--{{end}}
+ {{end}}
+
+ |
+
+ Commit Wait
+
+ {{if .AfterCommitMsgSuccess}}done{{else}}
+ --
+ {{end}}
+
+ |
+
+ Active
+ {{if .ChainActive}}yes{{else}}
+ {{if .ChainUnproven}}unproven{{else}}
+ {{if .ChainFaulty}}faulty{{else}}no{{end}}
+ {{end}}
+ {{end}}
+
+ |
+
Sector ID | +Create Time | +State | +
---|