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,
|
"voting":10,
|
||||||
"voted":25,
|
"voted":25,
|
||||||
"revoked":3,
|
"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
|
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
|
// ParseBlockConnectedNotification extracts the block header from a
|
||||||
// blockconnected JSON-RPC notification.
|
// blockconnected JSON-RPC notification.
|
||||||
func ParseBlockConnectedNotification(params json.RawMessage) (*wire.BlockHeader, error) {
|
func ParseBlockConnectedNotification(params json.RawMessage) (*wire.BlockHeader, error) {
|
||||||
|
|||||||
@ -53,3 +53,7 @@ func indentJSON(input string) template.HTML {
|
|||||||
func atomsToDCR(atoms int64) string {
|
func atomsToDCR(atoms int64) string {
|
||||||
return dcrutil.Amount(atoms).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
|
VspClosed bool
|
||||||
Debug bool
|
Debug bool
|
||||||
Designation string
|
Designation string
|
||||||
BlockHeight int64
|
BlockHeight uint32
|
||||||
|
NetworkProportion float32
|
||||||
|
RevokedProportion float32
|
||||||
}
|
}
|
||||||
|
|
||||||
var statsMtx sync.RWMutex
|
var statsMtx sync.RWMutex
|
||||||
@ -80,7 +82,7 @@ func updateVSPStats(ctx context.Context, db *database.VspDatabase,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
blockHeight, err := dcrdClient.GetBestBlockHeight()
|
bestBlock, err := dcrdClient.GetBestBlockHeader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -92,7 +94,9 @@ func updateVSPStats(ctx context.Context, db *database.VspDatabase,
|
|||||||
stats.Voting = voting
|
stats.Voting = voting
|
||||||
stats.Voted = voted
|
stats.Voted = voted
|
||||||
stats.Revoked = revoked
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,11 @@ body {
|
|||||||
color: #091440;
|
color: #091440;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vsp-stats .stat-value .text-muted{
|
||||||
|
font-size: 18px;
|
||||||
|
color: #8997A5;
|
||||||
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
|||||||
@ -14,7 +14,10 @@
|
|||||||
|
|
||||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||||
<div class="stat-title">Revoked tickets</div>
|
<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>
|
||||||
|
|
||||||
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
<div class="col-6 col-sm-4 col-lg-2 py-3">
|
||||||
@ -27,6 +30,11 @@
|
|||||||
<div class="stat-value">{{ .Network }}</div>
|
<div class="stat-value">{{ .Network }}</div>
|
||||||
</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>
|
</div>
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@ -15,7 +15,8 @@ type vspInfoResponse struct {
|
|||||||
Voting int64 `json:"voting"`
|
Voting int64 `json:"voting"`
|
||||||
Voted int64 `json:"voted"`
|
Voted int64 `json:"voted"`
|
||||||
Revoked int64 `json:"revoked"`
|
Revoked int64 `json:"revoked"`
|
||||||
BlockHeight int64 `json:"blockheight"`
|
BlockHeight uint32 `json:"blockheight"`
|
||||||
|
NetworkProportion float32 `json:"estimatednetworkproportion"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type feeAddressRequest struct {
|
type feeAddressRequest struct {
|
||||||
|
|||||||
@ -26,5 +26,6 @@ func vspInfo(c *gin.Context) {
|
|||||||
Voted: cachedStats.Voted,
|
Voted: cachedStats.Voted,
|
||||||
Revoked: cachedStats.Revoked,
|
Revoked: cachedStats.Revoked,
|
||||||
BlockHeight: cachedStats.BlockHeight,
|
BlockHeight: cachedStats.BlockHeight,
|
||||||
|
NetworkProportion: cachedStats.NetworkProportion,
|
||||||
}, c)
|
}, c)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -184,6 +184,7 @@ func router(debugMode bool, cookieSecret []byte, dcrd rpc.DcrdConnect, wallets r
|
|||||||
"stripWss": stripWss,
|
"stripWss": stripWss,
|
||||||
"indentJSON": indentJSON,
|
"indentJSON": indentJSON,
|
||||||
"atomsToDCR": atomsToDCR,
|
"atomsToDCR": atomsToDCR,
|
||||||
|
"float32ToPercent": float32ToPercent,
|
||||||
})
|
})
|
||||||
|
|
||||||
router.LoadHTMLGlob("webapi/templates/*.html")
|
router.LoadHTMLGlob("webapi/templates/*.html")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user