Add network proportion to homepage and /vspinfo (and revoked proportion) (#264)
* Add network proportion to homepage and /vspinfo. Proportion is calculated using the number of tickets currently registered with the VSP, divided by the total size of the network ticket pool as reported by `getblockheader`. The value will only ever be an estimate because: - it's possible for a single ticket to be added to multiple VSPs. - vspd does not distinguish between immature and live tickets, whereas `getblockheader` only reports live tickets. - `getblockheader` is reporting the size of the ticket pool as of the previous block, not the current block. * xaur suggestions * Show missed ticket %, not just the raw number.
This commit is contained in:
parent
978b78e745
commit
9867f78385
@ -54,7 +54,8 @@ when a VSP is closed will result in an error.
|
||||
"voting":10,
|
||||
"voted":25,
|
||||
"revoked":3,
|
||||
"blockheight":623212
|
||||
"blockheight":623212,
|
||||
"estimatednetworkproportion":0.048478414
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
11
rpc/dcrd.go
11
rpc/dcrd.go
@ -224,17 +224,6 @@ func (c *DcrdRPC) CanTicketVote(rawTx *dcrdtypes.TxRawResult, ticketHash string,
|
||||
return live, nil
|
||||
}
|
||||
|
||||
// GetBestBlockHeight uses getblockcount RPC to query the height of the best
|
||||
// block known by the dcrd instance.
|
||||
func (c *DcrdRPC) GetBestBlockHeight() (int64, error) {
|
||||
var height int64
|
||||
err := c.Call(c.ctx, "getblockcount", &height)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return height, nil
|
||||
}
|
||||
|
||||
// ParseBlockConnectedNotification extracts the block header from a
|
||||
// blockconnected JSON-RPC notification.
|
||||
func ParseBlockConnectedNotification(params json.RawMessage) (*wire.BlockHeader, error) {
|
||||
|
||||
@ -53,3 +53,7 @@ func indentJSON(input string) template.HTML {
|
||||
func atomsToDCR(atoms int64) string {
|
||||
return dcrutil.Amount(atoms).String()
|
||||
}
|
||||
|
||||
func float32ToPercent(input float32) string {
|
||||
return fmt.Sprintf("%.2f%%", input*100)
|
||||
}
|
||||
|
||||
@ -32,7 +32,9 @@ type vspStats struct {
|
||||
VspClosed bool
|
||||
Debug bool
|
||||
Designation string
|
||||
BlockHeight int64
|
||||
BlockHeight uint32
|
||||
NetworkProportion float32
|
||||
RevokedProportion float32
|
||||
}
|
||||
|
||||
var statsMtx sync.RWMutex
|
||||
@ -80,7 +82,7 @@ func updateVSPStats(ctx context.Context, db *database.VspDatabase,
|
||||
return err
|
||||
}
|
||||
|
||||
blockHeight, err := dcrdClient.GetBestBlockHeight()
|
||||
bestBlock, err := dcrdClient.GetBestBlockHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -92,7 +94,9 @@ func updateVSPStats(ctx context.Context, db *database.VspDatabase,
|
||||
stats.Voting = voting
|
||||
stats.Voted = voted
|
||||
stats.Revoked = revoked
|
||||
stats.BlockHeight = blockHeight
|
||||
stats.BlockHeight = bestBlock.Height
|
||||
stats.NetworkProportion = float32(voting) / float32(bestBlock.PoolSize)
|
||||
stats.RevokedProportion = float32(revoked) / float32(voted)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -53,6 +53,11 @@ body {
|
||||
color: #091440;
|
||||
}
|
||||
|
||||
.vsp-stats .stat-value .text-muted{
|
||||
font-size: 18px;
|
||||
color: #8997A5;
|
||||
}
|
||||
|
||||
footer {
|
||||
flex-shrink: 0;
|
||||
font-size: 0.8rem;
|
||||
|
||||
@ -14,7 +14,10 @@
|
||||
|
||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||
<div class="stat-title">Revoked tickets</div>
|
||||
<div class="stat-value">{{ .Revoked }}</div>
|
||||
<div class="stat-value">
|
||||
{{ .Revoked }}
|
||||
<span class="text-muted">({{ float32ToPercent .RevokedProportion }})</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||
@ -27,6 +30,11 @@
|
||||
<div class="stat-value">{{ .Network }}</div>
|
||||
</div>
|
||||
|
||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||
<div class="stat-title">Network Proportion</div>
|
||||
<div class="stat-value">{{ float32ToPercent .NetworkProportion }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
|
||||
@ -15,7 +15,8 @@ type vspInfoResponse struct {
|
||||
Voting int64 `json:"voting"`
|
||||
Voted int64 `json:"voted"`
|
||||
Revoked int64 `json:"revoked"`
|
||||
BlockHeight int64 `json:"blockheight"`
|
||||
BlockHeight uint32 `json:"blockheight"`
|
||||
NetworkProportion float32 `json:"estimatednetworkproportion"`
|
||||
}
|
||||
|
||||
type feeAddressRequest struct {
|
||||
|
||||
@ -26,5 +26,6 @@ func vspInfo(c *gin.Context) {
|
||||
Voted: cachedStats.Voted,
|
||||
Revoked: cachedStats.Revoked,
|
||||
BlockHeight: cachedStats.BlockHeight,
|
||||
NetworkProportion: cachedStats.NetworkProportion,
|
||||
}, c)
|
||||
}
|
||||
|
||||
@ -184,6 +184,7 @@ func router(debugMode bool, cookieSecret []byte, dcrd rpc.DcrdConnect, wallets r
|
||||
"stripWss": stripWss,
|
||||
"indentJSON": indentJSON,
|
||||
"atomsToDCR": atomsToDCR,
|
||||
"float32ToPercent": float32ToPercent,
|
||||
})
|
||||
|
||||
router.LoadHTMLGlob("webapi/templates/*.html")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user