vspd/webapi/homepage.go
Jamie Holdstock d1a838bf7f Add vspclosedmsg config.
If vspclosed is set to true, the provided message will be displayed on the webpage and returned by the status API endpoint.
2021-06-10 09:45:22 +08:00

113 lines
2.6 KiB
Go

// Copyright (c) 2020 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package webapi
import (
"context"
"encoding/base64"
"net/http"
"sync"
"time"
"github.com/decred/dcrd/chaincfg/v3"
"github.com/decred/vspd/database"
"github.com/decred/vspd/rpc"
"github.com/gin-gonic/gin"
)
// vspStats is used to cache values which are commonly used by the API, so
// repeated web requests don't repeatedly trigger DB or RPC calls.
type vspStats struct {
PubKey string
Voting int64
Voted int64
Revoked int64
VSPFee float64
Network string
UpdateTime string
SupportEmail string
VspClosed bool
VspClosedMsg string
Debug bool
Designation string
BlockHeight uint32
NetworkProportion float32
RevokedProportion float32
VspdVersion string
}
var statsMtx sync.RWMutex
var stats *vspStats
func getVSPStats() *vspStats {
statsMtx.RLock()
defer statsMtx.RUnlock()
return stats
}
// initVSPStats creates the struct which holds the cached VSP stats, and
// initializes it with static values.
func initVSPStats() {
statsMtx.Lock()
defer statsMtx.Unlock()
stats = &vspStats{
PubKey: base64.StdEncoding.EncodeToString(signPubKey),
VSPFee: cfg.VSPFee,
Network: cfg.NetParams.Name,
SupportEmail: cfg.SupportEmail,
VspClosed: cfg.VspClosed,
VspClosedMsg: cfg.VspClosedMsg,
Debug: cfg.Debug,
Designation: cfg.Designation,
VspdVersion: cfg.VspdVersion,
}
}
// updateVSPStats updates the dynamic values in the cached VSP stats (ticket
// counts and best block height).
func updateVSPStats(ctx context.Context, db *database.VspDatabase,
dcrd rpc.DcrdConnect, netParams *chaincfg.Params) error {
// Update counts of voting, voted and revoked tickets.
voting, voted, revoked, err := db.CountTickets()
if err != nil {
return err
}
// Update best block height.
dcrdClient, err := dcrd.Client(ctx, netParams)
if err != nil {
return err
}
bestBlock, err := dcrdClient.GetBestBlockHeader()
if err != nil {
return err
}
statsMtx.Lock()
defer statsMtx.Unlock()
stats.UpdateTime = dateTime(time.Now().Unix())
stats.Voting = voting
stats.Voted = voted
stats.Revoked = revoked
stats.BlockHeight = bestBlock.Height
stats.NetworkProportion = float32(voting) / float32(bestBlock.PoolSize)
stats.RevokedProportion = float32(revoked) / float32(voted)
return nil
}
func homepage(c *gin.Context) {
c.HTML(http.StatusOK, "homepage.html", gin.H{
"VspStats": getVSPStats(),
})
}