Skip to content

Commit 8dfb15c

Browse files
committed
cmd/dcrdata: dynamically scale hashrate units
1 parent 9c02e71 commit 8dfb15c

5 files changed

Lines changed: 80 additions & 9 deletions

File tree

cmd/dcrdata/internal/explorer/templates.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ type templates struct {
3535
exec func(string, interface{}) (string, error)
3636
}
3737

38+
type hashrateDisplay struct {
39+
Parts []string
40+
Unit string
41+
}
42+
3843
func newTemplates(folder string, reload bool, common []string, helpers template.FuncMap) templates {
3944
com := make([]string, 0, len(common))
4045
for _, file := range common {
@@ -210,6 +215,34 @@ func amountAsDecimalPartsTrimmed(v, numPlaces int64, useCommas bool) []string {
210215
return []string{left, right, tail}
211216
}
212217

218+
func hashRateFormatting(phRate float64) hashrateDisplay {
219+
units := []struct {
220+
label string
221+
multiplier float64
222+
}{
223+
{label: "Th/s", multiplier: 1},
224+
{label: "Ph/s", multiplier: 1e-3},
225+
{label: "Eh/s", multiplier: 1e-6},
226+
}
227+
228+
thRate := phRate * 1e3
229+
unitIndex := 0
230+
if thRate > 0 {
231+
unitIndex = int(math.Floor(math.Log10(thRate) / 3))
232+
if unitIndex < 0 {
233+
unitIndex = 0
234+
} else if unitIndex >= len(units) {
235+
unitIndex = len(units) - 1
236+
}
237+
}
238+
239+
value := thRate * units[unitIndex].multiplier
240+
return hashrateDisplay{
241+
Parts: float64Formatting(value, 8, true, 2),
242+
Unit: units[unitIndex].label,
243+
}
244+
}
245+
213246
// threeSigFigs returns a representation of the float formatted to three
214247
// significant figures, with an appropriate magnitude prefix (k, M, B).
215248
// For (k, M, G) prefixes for file/memory sizes, use humanize.Bytes.
@@ -406,6 +439,7 @@ func makeTemplateFuncMap(params *chaincfg.Params) template.FuncMap {
406439
return p
407440
},
408441
"float64AsDecimalParts": float64Formatting,
442+
"hashRateFormatting": hashRateFormatting,
409443
"amountAsDecimalParts": func(v int64, useCommas bool) []string {
410444
return float64Formatting(dcrutil.Amount(v).ToCoin(), 8, useCommas)
411445
},

cmd/dcrdata/public/js/controllers/charts_controller.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ const multiYAxisChart = ['ticket-price', 'coin-supply', 'privacy-participation']
2525
// index 0 represents y1 and 1 represents y2 axes.
2626
const yValueRanges = { 'ticket-price': [1] }
2727
const chainworkUnits = ['exahash', 'zettahash', 'yottahash']
28-
const hashrateUnits = ['Th/s', 'Ph/s', 'Eh/s']
2928
let ticketPoolSizeTarget, premine, stakeValHeight, stakeShare
3029
let baseSubsidy, subsidyInterval, subsidyExponent, windowSize, avgBlockTime
3130
let rawCoinSupply, rawPoolValue
@@ -626,10 +625,13 @@ export default class extends Controller {
626625
break
627626

628627
case 'hashrate': // Total chainwork over time
629-
d = zip2D(data, data.rate, 1e-3, data.offset)
630-
assign(gOptions, mapDygraphOptions(d, [xlabel, 'Network Hashrate (petahash/s)'],
631-
false, 'Network Hashrate (petahash/s)', true, false))
632-
yFormatter = customYFormatter(y => withBigUnits(y * 1e3, hashrateUnits))
628+
{
629+
const unit = humanize.hashrateUnit(data.rate, 'Th/s')
630+
d = zip2D(data, data.rate, unit.multiplier, data.offset)
631+
assign(gOptions, mapDygraphOptions(d, [xlabel, `Network Hashrate (${unit.label})`],
632+
false, `Network Hashrate (${unit.description})`, true, false))
633+
yFormatter = customYFormatter(y => `${y.toFixed(3)} ${unit.label}`)
634+
}
633635
break
634636

635637
case 'missed-votes':

cmd/dcrdata/public/js/controllers/homepage_controller.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default class extends Controller {
3939
'bsubsidyTotal', 'bsubsidyPow', 'bsubsidyPos', 'bsubsidyDev',
4040
'coinSupply', 'blocksdiff', 'devFund', 'windowIndex', 'posBar',
4141
'rewardIdx', 'powBar', 'poolSize', 'poolValue', 'ticketReward',
42-
'targetPct', 'poolSizePct', 'hashrate', 'hashrateDelta',
42+
'targetPct', 'poolSizePct', 'hashrate', 'hashrateUnit', 'hashrateDelta',
4343
'nextExpectedSdiff', 'nextExpectedMin', 'nextExpectedMax', 'mempool',
4444
'mpRegTotal', 'mpRegCount', 'mpTicketTotal', 'mpTicketCount', 'mpVoteTotal', 'mpVoteCount',
4545
'mpRevTotal', 'mpRevCount', 'mpRegBar', 'mpVoteBar', 'mpTicketBar',
@@ -188,7 +188,9 @@ export default class extends Controller {
188188
this.poolSizePctTarget.textContent = parseFloat(ex.pool_info.percent).toFixed(2)
189189
const treasuryTotal = ex.dev_fund + ex.treasury_bal.balance
190190
this.devFundTarget.innerHTML = humanize.decimalParts(treasuryTotal / 100000000, true, 0)
191-
this.hashrateTarget.innerHTML = humanize.decimalParts(ex.hash_rate, false, 8, 2)
191+
const hashrate = humanize.hashrate(ex.hash_rate, 'Ph/s')
192+
this.hashrateTarget.innerHTML = humanize.decimalParts(hashrate.value, false, 8, 2)
193+
this.hashrateUnitTarget.textContent = hashrate.unit
192194
this.hashrateDeltaTarget.innerHTML = humanize.fmtPercentage(ex.hash_rate_change_month)
193195
this.blockVotesTarget.dataset.hash = blockData.block.hash
194196
this.setVotes()

cmd/dcrdata/public/js/helpers/humanize_helper.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ function round (value, precision) {
88
return Math.round(value * multiplier) / multiplier
99
}
1010

11+
const hashrateUnits = [
12+
{ label: 'Th/s', description: 'terahash/s', multiplier: 1 },
13+
{ label: 'Ph/s', description: 'petahash/s', multiplier: 1e-3 },
14+
{ label: 'Eh/s', description: 'exahash/s', multiplier: 1e-6 }
15+
]
16+
1117
function hashParts (hash) {
1218
const clipLen = 6
1319
const hashLen = hash.length - clipLen
@@ -73,6 +79,32 @@ const humanize = {
7379

7480
return htmlString
7581
},
82+
hashrateUnit: function (rates, sourceUnit) {
83+
let maxRate = 0
84+
const sourceMultiplier = sourceUnit === 'Ph/s' ? 1e3 : sourceUnit === 'Eh/s' ? 1e6 : 1
85+
if (!Array.isArray(rates)) rates = [rates]
86+
for (const rate of rates) {
87+
const thRate = rate * sourceMultiplier
88+
if (thRate > maxRate) maxRate = thRate
89+
}
90+
if (!Number.isFinite(maxRate) || maxRate === 0) return hashrateUnits[0]
91+
92+
const unitIndex = Math.min(
93+
Math.max(Math.floor(Math.log10(maxRate) / 3), 0),
94+
hashrateUnits.length - 1
95+
)
96+
return hashrateUnits[unitIndex]
97+
},
98+
hashrate: function (rate, sourceUnit) {
99+
const sourceMultiplier = sourceUnit === 'Ph/s' ? 1e3 : sourceUnit === 'Eh/s' ? 1e6 : 1
100+
const thRate = rate * sourceMultiplier
101+
const unit = this.hashrateUnit(rate, sourceUnit)
102+
return {
103+
value: thRate * unit.multiplier,
104+
unit: unit.label,
105+
description: unit.description
106+
}
107+
},
76108
threeSigFigs: function (v) {
77109
const sign = v >= 0 ? '' : '-'
78110
v = Math.abs(v)

cmd/dcrdata/views/home.tmpl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,10 @@
314314
</div>
315315
<div class="col-12 mb-3 mb-sm-2 mb-md-3 mb-lg-3">
316316
<div class="fs13 text-secondary"><a href="/charts?chart=hashrate">Hashrate</a></div>
317+
{{ $hashrate := hashRateFormatting .HashRate }}
317318
<div class="mono lh1rem pt-1 pb-1 fs14-decimal fs24 d-flex align-items-baseline">
318-
<span data-homepage-target="hashrate">{{template "decimalParts" (float64AsDecimalParts .HashRate 8 true 2)}}</span>
319-
<span class="ps-1 unit lh15rem">Ph/s</span>
319+
<span data-homepage-target="hashrate">{{template "decimalParts" $hashrate.Parts}}</span>
320+
<span class="ps-1 unit lh15rem" data-homepage-target="hashrateUnit">{{ $hashrate.Unit }}</span>
320321
</div>
321322
<div class="fs12 text-black-50 lh1rem text-black-50">
322323
<span data-homepage-target="hashrateDelta">{{template "fmtPercentage" .HashRateChangeMonth}}</span> in past 30 days

0 commit comments

Comments
 (0)