Skip to content

Commit

Permalink
integrate with other homepage changes and incorporate code suggestions.
Browse files Browse the repository at this point in the history
Works in changes to master from decred#921, which included a full rework
of the left info column. Switches the column order based on feedback
from slack and matrix. Adds a little approved/rejected message when
the necessary votes have been received.

Switches the semantics of the vote tallying a little so that a
consensus result is indicated when available. Also changed the enum
from 0,1,2 for no, yes, missing to -1, 1, 0, which seemed
appropriate for what they represent. Added contructor for
`explorertypes.VotingInfo`.

Switched the color scheme to a simpler two-tone grey for now. Change
the `text-success` boostrap class elements to a custom `text-green`,
because the former had poor contrast on lighter backgrounds.
  • Loading branch information
buck54321 committed Jan 30, 2019
1 parent f702354 commit 223a5f9
Show file tree
Hide file tree
Showing 26 changed files with 496 additions and 444 deletions.
7 changes: 4 additions & 3 deletions db/dcrsqlite/apisource.go
Expand Up @@ -1181,7 +1181,7 @@ func (db *WiredDB) GetAddressTransactionsRawWithSkip(addr string, count int, ski
return txarray
}

func sumTxRawResult(txs []dcrjson.TxRawResult) (sum float64) {
func sumOutsTxRawResult(txs []dcrjson.TxRawResult) (sum float64) {
for _, tx := range txs {
for _, vout := range tx.Vout {
sum += vout.Value
Expand All @@ -1193,8 +1193,7 @@ func sumTxRawResult(txs []dcrjson.TxRawResult) (sum float64) {
func makeExplorerBlockBasic(data *dcrjson.GetBlockVerboseResult, params *chaincfg.Params) *exptypes.BlockBasic {
index := dbtypes.CalculateWindowIndex(data.Height, params.StakeDiffWindowSize)

total := sumTxRawResult(data.RawTx)
total += sumTxRawResult(data.RawSTx)
total := sumOutsTxRawResult(data.RawTx) + sumOutsTxRawResult(data.RawSTx)

block := &exptypes.BlockBasic{
IndexVal: index,
Expand Down Expand Up @@ -1288,6 +1287,8 @@ func makeExplorerAddressTx(data *dcrjson.SearchRawTransactionsResult, address st
return tx
}

// GetExplorerBlocks creates an slice of exptypes.BlockBasic beginning at start
// and decreasing in block height to end, not including end.
func (db *WiredDB) GetExplorerBlocks(start int, end int) []*exptypes.BlockBasic {
if start < end {
return nil
Expand Down
3 changes: 2 additions & 1 deletion explorer/explorer_test.go
@@ -1,11 +1,12 @@
package explorer

import (
// Imports for TestFormatNumber
// Imports for TestThreeSigFigs
// "fmt"
// "math"
// "math/rand"
// "time"

"testing"

"github.com/decred/dcrd/chaincfg"
Expand Down
13 changes: 11 additions & 2 deletions explorer/explorerroutes.go
Expand Up @@ -123,26 +123,35 @@ func (exp *explorerUI) Home(w http.ResponseWriter, r *http.Request) {
}

blocks := exp.blockData.GetExplorerBlocks(int(height), int(height)-5)
bestBlock := blocks[0]
var bestBlock *types.BlockBasic
if blocks == nil {
bestBlock = new(types.BlockBasic)
} else {
bestBlock = blocks[0]
}

// Lock for both MempoolData and pageData.HomeInfo
exp.MempoolData.RLock()
exp.pageData.RLock()

tallys, consensus := exp.MempoolData.VotingInfo.BlockStatus(bestBlock.Hash)

str, err := exp.templates.execTemplateToString("home", struct {
*CommonPageData
Info *types.HomeInfo
Mempool *types.MempoolInfo
BestBlock *types.BlockBasic
BlockTally []int
Consensus int
Blocks []*types.BlockBasic
NetName string
}{
CommonPageData: exp.commonData(),
Info: exp.pageData.HomeInfo,
Mempool: exp.MempoolData,
BestBlock: bestBlock,
BlockTally: exp.MempoolData.VotingInfo.Tallys(bestBlock.Hash),
BlockTally: tallys,
Consensus: consensus,
Blocks: blocks,
NetName: exp.NetName,
})
Expand Down
6 changes: 3 additions & 3 deletions explorer/mempool.go
Expand Up @@ -112,7 +112,7 @@ func (exp *explorerUI) mempoolMonitor(txChan chan *types.NewMempoolTx) {

// Maintain a separate total that excludes votes for sidechain blocks and
// multiple votes that spend the same ticket.
likely := true
likelyMineable := true

// Add the tx to the appropriate tx slice in MempoolData and update the
// count for the transaction type.
Expand Down Expand Up @@ -149,7 +149,7 @@ func (exp *explorerUI) mempoolMonitor(txChan chan *types.NewMempoolTx) {
exp.MempoolData.VoteTotal += tx.TotalOut
exp.MempoolData.VotingInfo.Tally(tx.VoteInfo)
} else {
likely = false
likelyMineable = false
}
case "Regular":
exp.MempoolData.InvRegular[tx.Hash] = struct{}{}
Expand All @@ -176,7 +176,7 @@ func (exp *explorerUI) mempoolMonitor(txChan chan *types.NewMempoolTx) {

// Store totals
exp.MempoolData.NumAll++
if likely {
if likelyMineable {
exp.MempoolData.LikelyTotal += tx.TotalOut
}
exp.MempoolData.TotalOut += tx.TotalOut
Expand Down
44 changes: 32 additions & 12 deletions explorer/types/explorertypes.go
Expand Up @@ -21,9 +21,9 @@ import (

// Types of vote
const (
VoteReject = iota
VoteAffirm
VoteMissing
VoteReject = -1
VoteAffirm = 1
VoteMissing = 0
)

// TimeDef is time.Time wrapper that formats time by default as a string without
Expand Down Expand Up @@ -554,31 +554,42 @@ type VotingInfo struct {
VoteTallys map[string]*VoteTally `json:"vote_tally"`
}

// NewVotingInfo initializes a VotingInfo.
func NewVotingInfo(votesPerBlock uint16) VotingInfo {
return VotingInfo{
MaxVotesPerBlock: votesPerBlock,
VotedTickets: make(map[string]bool),
VoteTallys: make(map[string]*VoteTally),
}
}

// Tally adds the VoteInfo to the VotingInfo.VoteTally
func (vi *VotingInfo) Tally(vinfo *VoteInfo) {
_, ok := vi.VoteTallys[vinfo.Validation.Hash]
if ok {
vi.VoteTallys[vinfo.Validation.Hash].Mark(vinfo.Validation.Validity)
return
}
marks := make([]bool, 1, vi.MaxVotesPerBlock)
marks[0] = vinfo.Validation.Validity
vi.VoteTallys[vinfo.Validation.Hash] = &VoteTally{
TicketsPerBlock: int(vi.MaxVotesPerBlock),
Marks: []bool{vinfo.Validation.Validity},
Marks: marks,
}
}

// Tallys fetches the mempool VoteTally.VoteList if found, else a list of
// VoteMissing.
func (vi *VotingInfo) Tallys(hash string) []int {
func (vi *VotingInfo) BlockStatus(hash string) ([]int, int) {
tally, ok := vi.VoteTallys[hash]
if ok {
return tally.VoteList()
return tally.Status()
}
marks := make([]int, int(vi.MaxVotesPerBlock))
for i := range marks {
marks[i] = VoteMissing
}
return marks
return marks, VoteMissing
}

// VoteTally manages a list of bools representing the votes for a block.
Expand All @@ -592,22 +603,31 @@ func (tally *VoteTally) Mark(vote bool) {
tally.Marks = append(tally.Marks, vote)
}

// VoteList is a list of ints representing votes both received and not yet
// received for a block.
// Status is a list of ints representing votes both received and not yet
// received for a block, and a single int representing consensus.
// 0: rejected, 1: affirmed, 2: vote not yet received
func (tally *VoteTally) VoteList() []int {
func (tally *VoteTally) Status() ([]int, int) {
votes := []int{}
var up, down, consensus int
for _, affirmed := range tally.Marks {
if affirmed {
up++
votes = append(votes, VoteAffirm)
} else {
down++
votes = append(votes, VoteReject)
}
}
for i := len(votes); i < tally.TicketsPerBlock; i++ {
votes = append(votes, VoteMissing)
}
return votes
threshold := tally.TicketsPerBlock / 2
if up > threshold {
consensus = VoteAffirm
} else if down > threshold {
consensus = VoteReject
}
return votes, consensus
}

// Affirmations counts the number of selected ticket holders who have voted
Expand All @@ -622,7 +642,7 @@ func (tally *VoteTally) Affirmations() (c int) {
}

// VoteCount is the number of votes received.
func (tally *VoteTally) VoteCount() (c int) {
func (tally *VoteTally) VoteCount() int {
return len(tally.Marks)
}

Expand Down
14 changes: 5 additions & 9 deletions mempool/collector.go
Expand Up @@ -301,15 +301,11 @@ func ParseTxns(txs []exptypes.MempoolTx, params *chaincfg.Params, lastBlock *Blo
regular := make([]exptypes.MempoolTx, 0)

var regularTotal, ticketTotal, voteTotal, revTotal float64
var likely bool
var likelyMineable bool

var totalOut, likelyTotal float64
var totalSize int32
votingInfo := exptypes.VotingInfo{
MaxVotesPerBlock: params.TicketsPerBlock,
VotedTickets: make(map[string]bool),
VoteTallys: make(map[string]*exptypes.VoteTally),
}
votingInfo := exptypes.NewVotingInfo(params.TicketsPerBlock)
invRegular := make(map[string]struct{})
invStake := make(map[string]struct{})

Expand All @@ -319,7 +315,7 @@ func ParseTxns(txs []exptypes.MempoolTx, params *chaincfg.Params, lastBlock *Blo
var latestTime int64
ticketSpendInds := make(exptypes.BlockValidatorIndex)
for _, tx := range txs {
likely = true
likelyMineable = true
switch tx.Type {
case "Ticket":
if _, found := invStake[tx.Hash]; found {
Expand Down Expand Up @@ -348,7 +344,7 @@ func ParseTxns(txs []exptypes.MempoolTx, params *chaincfg.Params, lastBlock *Blo
voteTotal += tx.TotalOut
votingInfo.Tally(tx.VoteInfo)
} else {
likely = false
likelyMineable = false
}
case "Revocation":
if _, found := invStake[tx.Hash]; found {
Expand All @@ -367,7 +363,7 @@ func ParseTxns(txs []exptypes.MempoolTx, params *chaincfg.Params, lastBlock *Blo
}

// Update mempool totals
if likely {
if likelyMineable {
likelyTotal += tx.TotalOut
}
totalOut += tx.TotalOut
Expand Down
Binary file modified public/fonts/icomoon.eot
Binary file not shown.
3 changes: 3 additions & 0 deletions public/fonts/icomoon.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/fonts/icomoon.ttf
Binary file not shown.
Binary file modified public/fonts/icomoon.woff
Binary file not shown.
14 changes: 0 additions & 14 deletions public/images/general.svg

This file was deleted.

7 changes: 0 additions & 7 deletions public/images/mining.svg

This file was deleted.

5 changes: 0 additions & 5 deletions public/images/staking.svg

This file was deleted.

2 changes: 1 addition & 1 deletion public/js/controllers/charts_controller.js
Expand Up @@ -190,7 +190,7 @@ export default class extends Controller {
this.settings = TurboQuery.nullTemplate(['chart', 'zoom', 'roll'])
this.query.update(this.settings)
if (this.settings.zoom) {
this.setSelectedZoom(null)
this.setSelectedZoom(this.settings.zoom)
}
if (this.settings.roll) {
this.setRollPeriod(this.settings.roll)
Expand Down
28 changes: 19 additions & 9 deletions public/js/controllers/homepage_controller.js
Expand Up @@ -55,16 +55,12 @@ export default class extends Controller {
'bsubsidyTotal', 'bsubsidyPow', 'bsubsidyPos', 'bsubsidyDev',
'coinSupply', 'blocksdiff', 'devFund', 'windowIndex', 'posBar',
'rewardIdx', 'powBar', 'poolSize', 'poolValue', 'ticketReward',
<<<<<<< df338e482277d26437e4ac6fcc5c82911678ec8a
'targetPct', 'poolSizePct', 'hashrate', 'hashrateDelta',
'nextExpectedSdiff', 'nextExpectedMin', 'nextExpectedMax'
=======
'targetPct', 'poolSizePct', 'mempool', 'mpRegTotal', 'mpRegCount',
'mpTicketTotal', 'mpTicketCount', 'mpVoteTotal', 'mpVoteCount',
'nextExpectedSdiff', 'nextExpectedMin', 'nextExpectedMax', 'mempool',
'mpRegTotal', 'mpRegCount', 'mpTicketTotal', 'mpTicketCount', 'mpVoteTotal', 'mpVoteCount',
'mpRevTotal', 'mpRevCount', 'mpRegBar', 'mpVoteBar', 'mpTicketBar',
'mpRevBar', 'voteTally', 'blockVotes', 'blockHeight', 'blockSize',
'blockTotal'
>>>>>>> add live data summaries to the homepage
'blockTotal', 'consensusMsg'
]
}

Expand Down Expand Up @@ -137,16 +133,30 @@ export default class extends Controller {

setVotes () {
var hash = this.blockVotesTarget.dataset.hash
var votes = this.mempool.votes(hash)
this.blockVotesTarget.querySelectorAll('span').forEach((span, i) => {
var votes = this.mempool.blockVoteTally(hash)
this.blockVotesTarget.querySelectorAll('div').forEach((div, i) => {
let span = div.firstChild
if (i < votes.affirm) {
span.className = 'd-inline-block dcricon-affirm'
div.dataset.tooltip = 'the stakeholder has voted to accept this block'
} else if (i < votes.affirm + votes.reject) {
span.className = 'd-inline-block dcricon-reject'
div.dataset.tooltip = 'the stakeholder has voted to reject this block'
} else {
span.className = 'd-inline-block dcricon-missing'
div.dataset.tooltip = 'this vote has not been received yet'
}
})
var threshold = this.ticketsPerBlock / 2
if (votes.affirm > threshold) {
this.consensusMsgTarget.textContent = 'approved'
this.consensusMsgTarget.className = 'small text-green'
} else if (votes.reject > threshold) {
this.consensusMsgTarget.textContent = 'rejected'
this.consensusMsgTarget.className = 'small text-danger'
} else {
this.consensusMsgTarget.textContent = ''
}
}

renderLatestTransactions (txs, incremental) {
Expand Down
2 changes: 1 addition & 1 deletion public/js/helpers/humanize_helper.js
Expand Up @@ -20,7 +20,7 @@ function hashParts (hash) {
var humanize = {
fmtPercentage: function (val) {
var sign = '+'
var cssClass = 'text-success'
var cssClass = 'text-green'
if (val < 1) {
sign = ''
cssClass = 'text-danger'
Expand Down
4 changes: 2 additions & 2 deletions public/js/helpers/mempool_helper.js
Expand Up @@ -117,7 +117,7 @@ export default class Mempool {
}
}

votes (hash) {
blockVoteTally (hash) {
return this.mempool.reduce((votes, tx) => {
if (tx.type !== 'Vote') return votes
let validation = tx.voteInfo.block_validation
Expand All @@ -140,7 +140,7 @@ export default class Mempool {
if (tx.type === 'Vote') {
let validation = tx.voteInfo.block_validation
if (!d.vote[validation.hash]) {
d.vote[validation.hash] = this.votes(validation.hash)
d.vote[validation.hash] = this.blockVoteTally(validation.hash)
}
} else {
d[mpKeys[tx.type]] += 1
Expand Down
2 changes: 1 addition & 1 deletion public/scss/_variables_reference.scss
Expand Up @@ -1098,4 +1098,4 @@ $positions: static, relative, absolute, fixed, sticky !default;
// Printing

$print-page-size: a3 !default;
$print-body-min-width: map-get($grid-breakpoints, "lg") !default;
$print-body-min-width: map-get($grid-breakpoints, "lg") !default;
2 changes: 1 addition & 1 deletion public/scss/global.scss
Expand Up @@ -10,7 +10,7 @@ html {

body {
padding-bottom: 2.1rem;
padding-top: 1em;
padding-top: 0.8em;
}

.container.main {
Expand Down

0 comments on commit 223a5f9

Please sign in to comment.