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 @@
1day: {{.Win1}} |
7day: {{.Win7}} |
30day: {{.Win30}} |