diff --git a/curiosrc/web/hapi/simpleinfo.go b/curiosrc/web/hapi/simpleinfo.go index e78c1dffb..fd6635059 100644 --- a/curiosrc/web/hapi/simpleinfo.go +++ b/curiosrc/web/hapi/simpleinfo.go @@ -35,6 +35,8 @@ type actorInfo struct { ActorBalance, ActorAvailable, WorkerBalance string + Win1, Win7, Win30 int64 + Deadlines []actorDeadline } diff --git a/curiosrc/web/hapi/watch_actor.go b/curiosrc/web/hapi/watch_actor.go index f7fb73d3f..a65608f14 100644 --- a/curiosrc/web/hapi/watch_actor.go +++ b/curiosrc/web/hapi/watch_actor.go @@ -70,6 +70,11 @@ func (a *app) updateActor(ctx context.Context) error { return err } + wins, err := a.spWins(ctx) + if err != nil { + return xerrors.Errorf("getting sp wins: %w", err) + } + for addr, cnames := range confNameToAddr { p, err := api.StateMinerPower(ctx, addr, types.EmptyTSK) if err != nil { @@ -167,6 +172,10 @@ func (a *app) updateActor(ctx context.Context) error { ActorBalance: types.FIL(mact.Balance).Short(), ActorAvailable: types.FIL(avail).Short(), WorkerBalance: types.FIL(wbal).Short(), + + Win1: wins[addr].Win1, // note: zero values are fine here + Win7: wins[addr].Win7, + Win30: wins[addr].Win30, }) } @@ -199,6 +208,57 @@ func (a *app) loadConfigs(ctx context.Context) (map[string]string, error) { return configs, nil } +type wins struct { + SpID int64 `db:"sp_id"` + Win1 int64 `db:"win1"` + Win7 int64 `db:"win7"` + Win30 int64 `db:"win30"` +} + +func (a *app) spWins(ctx context.Context) (map[address.Address]wins, error) { + var w []wins + + // note: this query uses mining_tasks_won_sp_id_base_compute_time_index + err := a.db.Select(ctx, &w, `WITH wins AS ( + SELECT + sp_id, + base_compute_time, + won + FROM + mining_tasks + WHERE + won = true + AND base_compute_time > NOW() - INTERVAL '30 days' + ) + + SELECT + sp_id, + COUNT(*) FILTER (WHERE base_compute_time > NOW() - INTERVAL '1 day') AS "win1", + COUNT(*) FILTER (WHERE base_compute_time > NOW() - INTERVAL '7 days') AS "win7", + COUNT(*) FILTER (WHERE base_compute_time > NOW() - INTERVAL '30 days') AS "win30" + FROM + wins + GROUP BY + sp_id + ORDER BY + sp_id`) + if err != nil { + return nil, xerrors.Errorf("query win counts: %w", err) + } + + wm := make(map[address.Address]wins) + for _, wi := range w { + ma, err := address.NewIDAddress(uint64(wi.SpID)) + if err != nil { + return nil, xerrors.Errorf("parsing miner address: %w", err) + } + + wm[ma] = wi + } + + return wm, nil +} + func forEachConfig[T any](a *app, cb func(name string, v T) error) error { confs, err := a.loadConfigs(context.Background()) if err != nil { diff --git a/curiosrc/web/hapi/web/actor_summary.gohtml b/curiosrc/web/hapi/web/actor_summary.gohtml index 92f1139ce..bf577d802 100644 --- a/curiosrc/web/hapi/web/actor_summary.gohtml +++ b/curiosrc/web/hapi/web/actor_summary.gohtml @@ -18,6 +18,13 @@ {{.ActorBalance}} {{.ActorAvailable}} {{.WorkerBalance}} + + + + + +
1day:  {{.Win1}}
7day:  {{.Win7}}
30day: {{.Win30}}
+ {{end}} {{end}} \ No newline at end of file diff --git a/curiosrc/web/static/index.html b/curiosrc/web/static/index.html index eaabe0173..674b4a88e 100644 --- a/curiosrc/web/static/index.html +++ b/curiosrc/web/static/index.html @@ -60,6 +60,7 @@ Host ID Last Contact + Tasks (24h) @@ -100,6 +101,7 @@ Balance Available Worker + Wins diff --git a/lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql b/lib/harmony/harmonydb/sql/20240317-web-summary-index.sql similarity index 52% rename from lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql rename to lib/harmony/harmonydb/sql/20240317-web-summary-index.sql index a5f907778..b34707d52 100644 --- a/lib/harmony/harmonydb/sql/20240317-tasksummary-index.sql +++ b/lib/harmony/harmonydb/sql/20240317-web-summary-index.sql @@ -1,3 +1,7 @@ /* Used for webui clusterMachineSummary */ CREATE INDEX harmony_task_history_work_index ON harmony_task_history (completed_by_host_and_port ASC, name ASC, result ASC, work_end DESC); + +/* Used for webui actorSummary sp wins */ +create index mining_tasks_won_sp_id_base_compute_time_index + on mining_tasks (won asc, sp_id asc, base_compute_time desc);