You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.0 KiB
116 lines
3.0 KiB
8 years ago
|
package stratum
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"net/http"
|
||
|
"sync/atomic"
|
||
|
"time"
|
||
|
|
||
|
"../util"
|
||
|
)
|
||
|
|
||
|
func (s *StratumServer) StatsIndex(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||
|
w.WriteHeader(http.StatusOK)
|
||
|
|
||
|
hashrate, hashrate24h, totalOnline, miners := s.collectMinersStats()
|
||
|
stats := map[string]interface{}{
|
||
|
"miners": miners,
|
||
|
"hashrate": hashrate,
|
||
|
"hashrate24h": hashrate24h,
|
||
|
"totalMiners": len(miners),
|
||
|
"totalOnline": totalOnline,
|
||
|
"timedOut": len(miners) - totalOnline,
|
||
|
"now": util.MakeTimestamp(),
|
||
|
}
|
||
|
|
||
|
stats["luck"] = s.getLuckStats()
|
||
|
|
||
|
if t := s.currentBlockTemplate(); t != nil {
|
||
|
stats["height"] = t.Height
|
||
|
stats["diff"] = t.Difficulty
|
||
|
roundShares := atomic.LoadInt64(&s.roundShares)
|
||
|
stats["variance"] = roundShares / t.Difficulty
|
||
|
stats["template"] = true
|
||
|
}
|
||
|
json.NewEncoder(w).Encode(stats)
|
||
|
}
|
||
|
|
||
|
func (s *StratumServer) collectMinersStats() (float64, float64, int, []interface{}) {
|
||
|
now := util.MakeTimestamp()
|
||
|
var result []interface{}
|
||
|
totalhashrate := float64(0)
|
||
|
totalhashrate24h := float64(0)
|
||
|
totalOnline := 0
|
||
|
window24h := 24 * time.Hour
|
||
|
|
||
|
for m := range s.miners.Iter() {
|
||
|
stats := make(map[string]interface{})
|
||
|
lastBeat := m.Val.getLastBeat()
|
||
|
hashrate := m.Val.hashrate(s.estimationWindow)
|
||
|
hashrate24h := m.Val.hashrate(window24h)
|
||
|
totalhashrate += hashrate
|
||
|
totalhashrate24h += hashrate24h
|
||
|
stats["name"] = m.Key
|
||
|
stats["hashrate"] = hashrate
|
||
|
stats["hashrate24h"] = hashrate24h
|
||
|
stats["lastBeat"] = lastBeat
|
||
|
stats["validShares"] = atomic.LoadUint64(&m.Val.validShares)
|
||
|
stats["invalidShares"] = atomic.LoadUint64(&m.Val.invalidShares)
|
||
|
stats["accepts"] = atomic.LoadUint64(&m.Val.accepts)
|
||
|
stats["rejects"] = atomic.LoadUint64(&m.Val.rejects)
|
||
|
if !s.config.Frontend.HideIP {
|
||
|
stats["ip"] = m.Val.IP
|
||
|
}
|
||
|
|
||
|
if now-lastBeat > (int64(s.timeout/2) / 1000000) {
|
||
|
stats["warning"] = true
|
||
|
}
|
||
|
if now-lastBeat > (int64(s.timeout) / 1000000) {
|
||
|
stats["timeout"] = true
|
||
|
} else {
|
||
|
totalOnline++
|
||
|
}
|
||
|
result = append(result, stats)
|
||
|
}
|
||
|
return totalhashrate, totalhashrate24h, totalOnline, result
|
||
|
}
|
||
|
|
||
|
func (s *StratumServer) getLuckStats() map[string]interface{} {
|
||
|
now := util.MakeTimestamp()
|
||
|
var variance float64
|
||
|
var totalVariance float64
|
||
|
var blocksCount int
|
||
|
var totalBlocksCount int
|
||
|
|
||
|
s.blocksMu.Lock()
|
||
|
defer s.blocksMu.Unlock()
|
||
|
|
||
|
for k, v := range s.blockStats {
|
||
|
if k >= now-int64(s.luckWindow) {
|
||
|
blocksCount++
|
||
|
variance += v
|
||
|
}
|
||
|
if k >= now-int64(s.luckLargeWindow) {
|
||
|
totalBlocksCount++
|
||
|
totalVariance += v
|
||
|
} else {
|
||
|
delete(s.blockStats, k)
|
||
|
}
|
||
|
}
|
||
|
if blocksCount != 0 {
|
||
|
variance = variance / float64(blocksCount)
|
||
|
}
|
||
|
if totalBlocksCount != 0 {
|
||
|
totalVariance = totalVariance / float64(totalBlocksCount)
|
||
|
}
|
||
|
result := make(map[string]interface{})
|
||
|
result["variance"] = variance
|
||
|
result["blocksCount"] = blocksCount
|
||
|
result["window"] = s.config.LuckWindow
|
||
|
result["totalVariance"] = totalVariance
|
||
|
result["totalBlocksCount"] = totalBlocksCount
|
||
|
result["largeWindow"] = s.config.LargeLuckWindow
|
||
|
return result
|
||
|
}
|