Browse Source

Valid / Stale / Invalid 24h

master
yuriy0803 5 years ago
parent
commit
af6bc92ede
  1. 5
      proxy/miner.go
  2. 1
      proxy/stratum.go
  3. 197
      storage/redis.go
  4. 6
      www/app/templates/account/index.hbs

5
proxy/miner.go

@ -6,8 +6,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/yuriy0803/go-etchash"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/yuriy0803/go-etchash"
) )
var ecip1099FBlockClassic uint64 = 11700000 // classic mainnet var ecip1099FBlockClassic uint64 = 11700000 // classic mainnet
@ -36,6 +36,7 @@ func (s *ProxyServer) processShare(login, id, ip string, t *BlockTemplate, param
h, ok := t.headers[hashNoNonce] h, ok := t.headers[hashNoNonce]
if !ok { if !ok {
log.Printf("Stale share from %v@%v", login, ip) log.Printf("Stale share from %v@%v", login, ip)
s.backend.WriteWorkerShareStatus(login, id, false, true, false)
return false, false return false, false
} }
@ -56,6 +57,7 @@ func (s *ProxyServer) processShare(login, id, ip string, t *BlockTemplate, param
} }
if !hasher.Verify(share) { if !hasher.Verify(share) {
s.backend.WriteWorkerShareStatus(login, id, false, false, true)
return false, false return false, false
} }
@ -88,5 +90,6 @@ func (s *ProxyServer) processShare(login, id, ip string, t *BlockTemplate, param
log.Println("Failed to insert share data into backend:", err) log.Println("Failed to insert share data into backend:", err)
} }
} }
s.backend.WriteWorkerShareStatus(login, id, true, false, false)
return false, true return false, true
} }

1
proxy/stratum.go

@ -197,6 +197,7 @@ func (s *ProxyServer) broadcastNewJobs() {
count := len(s.sessions) count := len(s.sessions)
log.Printf("Broadcasting new job to %v stratum miners", count) log.Printf("Broadcasting new job to %v stratum miners", count)
s.backend.NumberStratumWorker(count)
start := time.Now() start := time.Now()
bcast := make(chan int, 1024) bcast := make(chan int, 1024)
n := 0 n := 0

197
storage/redis.go

@ -126,7 +126,15 @@ type Miner struct {
type Worker struct { type Worker struct {
Miner Miner
TotalHR int64 `json:"hr2"` TotalHR int64 `json:"hr2"`
ValidShares int64 `json:"valid"`
StaleShares int64 `json:"stale"`
InvalidShares int64 `json:"invalid"`
ValidPercent float64 `json:"v_per"`
StalePercent float64 `json:"s_per"`
InvalidPercent float64 `json:"i_per"`
WorkerStatus int64 `json:"w_stat"`
WorkerStatushas int64 `json:"w_stat_s"`
} }
func NewRedisClient(cfg *Config, prefix string, pplns int64) *RedisClient { func NewRedisClient(cfg *Config, prefix string, pplns int64) *RedisClient {
@ -1004,7 +1012,7 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login
currentHashrate := int64(0) currentHashrate := int64(0)
online := int64(0) online := int64(0)
offline := int64(0) offline := int64(0)
workers := convertWorkersStats(smallWindow, cmds[1].(*redis.ZSliceCmd), cmds[4].(*redis.ZSliceCmd)) workers := convertWorkersStats(smallWindow, cmds[1].(*redis.ZSliceCmd), cmds[4].(*redis.ZSliceCmd), login, r)
for id, worker := range workers { for id, worker := range workers {
timeOnline := now - worker.startedAt timeOnline := now - worker.startedAt
@ -1046,8 +1054,68 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login
currentHashrate += worker.HR currentHashrate += worker.HR
totalHashrate += worker.TotalHR totalHashrate += worker.TotalHR
valid_share, stale_share, invalid_share, _ := r.getSharesStatus(login, id)
worker.ValidShares = int64(5)
worker.StaleShares = int64(5)
worker.InvalidShares = int64(5)
worker.ValidShares = valid_share
worker.StaleShares = stale_share
worker.InvalidShares = invalid_share
//test percentage
worker.ValidPercent = float64(0)
worker.StalePercent = float64(0)
worker.InvalidPercent = float64(0)
tot_share := int64(0)
tot_share += valid_share
tot_share += stale_share
tot_share += invalid_share
if tot_share > 0 {
d := float64(100)
//tot_share += ////error
cost_per := float64(tot_share) / d
v_per := float64(valid_share) / cost_per
worker.ValidPercent = toFixed(v_per, 1)
s_per := float64(stale_share) / cost_per
worker.StalePercent = toFixed(s_per, 1)
i_per := float64(invalid_share) / cost_per
worker.InvalidPercent = toFixed(i_per, 1)
} else {
worker.ValidPercent = toFixed(0, 1)
worker.StalePercent = toFixed(0, 1)
worker.InvalidPercent = toFixed(0, 1)
}
w_stat := int64(0) //test worker large hashrate indicator
if worker.HR >= worker.TotalHR {
w_stat = 1
worker.WorkerStatus = w_stat
} else if worker.HR < worker.TotalHR {
w_stat = 0
worker.WorkerStatus = w_stat
}
///test small hr
tot_w := r.client.HGet(r.formatKey("minerShare", login, id), "hashrate")
if tot_w.Err() == redis.Nil {
tx.HSet(r.formatKey("minerShare", login, id), "hashrate", strconv.FormatInt(0, 10))
//return nil, nil
} else if tot_w.Err() != nil {
tx.HSet(r.formatKey("minerShare", login, id), "hashrate", strconv.FormatInt(0, 10))
//return nil, tot_w.Err()
}
last_hr, _ := tot_w.Int64()
w_stat_s := int64(0) //test worker hashrate indicator
if worker.HR > last_hr {
w_stat_s = 1
worker.WorkerStatushas = w_stat_s
} else if worker.HR <= last_hr {
w_stat_s = 0
worker.WorkerStatushas = w_stat_s
}
tx.HSet(r.formatKey("minerShare", login, id), "hashrate", strconv.FormatInt(worker.HR, 10))
workers[id] = worker workers[id] = worker
} }
stats["workers"] = workers stats["workers"] = workers
stats["workersTotal"] = len(workers) stats["workersTotal"] = len(workers)
stats["workersOnline"] = online stats["workersOnline"] = online
@ -1081,6 +1149,15 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login
return stats, nil return stats, nil
} }
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output
}
func (r *RedisClient) CollectLuckStats(windows []int) (map[string]interface{}, error) { func (r *RedisClient) CollectLuckStats(windows []int) (map[string]interface{}, error) {
stats := make(map[string]interface{}) stats := make(map[string]interface{})
@ -1243,7 +1320,7 @@ func convertBlockResults(rows ...*redis.ZSliceCmd) []*BlockData {
// Build per login workers's total shares map {'rig-1': 12345, 'rig-2': 6789, ...} // Build per login workers's total shares map {'rig-1': 12345, 'rig-2': 6789, ...}
// TS => diff, id, ms // TS => diff, id, ms
func convertWorkersStats(window int64, raw *redis.ZSliceCmd, blocks *redis.ZSliceCmd) map[string]Worker { func convertWorkersStats(window int64, raw *redis.ZSliceCmd, blocks *redis.ZSliceCmd, login string, r *RedisClient) map[string]Worker {
now := util.MakeTimestamp() / 1000 now := util.MakeTimestamp() / 1000
workers := make(map[string]Worker) workers := make(map[string]Worker)
@ -1264,6 +1341,14 @@ func convertWorkersStats(window int64, raw *redis.ZSliceCmd, blocks *redis.ZSlic
// Add for large window // Add for large window
worker.TotalHR += share worker.TotalHR += share
worker.ValidShares = int64(4)
worker.ValidPercent = float64(0)
worker.StalePercent = float64(0)
worker.InvalidPercent = float64(0)
worker.WorkerStatus = int64(0)
worker.WorkerStatushas = int64(0)
//worker.StatleShares = int64(4)
//worker.InvalidShares = int64(4)
// Add for small window if matches // Add for small window if matches
if score >= now-window { if score >= now-window {
@ -1392,3 +1477,109 @@ func convertPaymentChartsResults(raw *redis.ZSliceCmd) []*PaymentCharts {
} }
return reverse return reverse
} }
func (r *RedisClient) GetCurrentHashrate(login string) (int64, error) {
hashrate := r.client.HGet(r.formatKey("currenthashrate", login), "hashrate")
if hashrate.Err() == redis.Nil {
return 0, nil
} else if hashrate.Err() != nil {
return 0, hashrate.Err()
}
return hashrate.Int64()
}
// Need a function to delete on round end or whatever, and another function to get.
func (r *RedisClient) ResetWorkerShareStatus() {
tx := r.client.Multi()
defer tx.Close()
tx.Exec(func() error {
tx.HDel(r.formatKey("minerShare"))
return nil
})
// THis should do it ay ?
// fuck it
}
// Don't know if this will work, returning three values, but let's see
func (r *RedisClient) getSharesStatus(login string, id string) (int64, int64, int64, error) {
valid_shares := r.client.HGet(r.formatKey("minerShare", login, id), "valid")
stale_shares := r.client.HGet(r.formatKey("minerShare", login, id), "stale")
invalid_shares := r.client.HGet(r.formatKey("minerShare", login, id), "invalid")
if valid_shares.Err() == redis.Nil || stale_shares.Err() == redis.Nil || invalid_shares.Err() == redis.Nil {
return 0, 0, 0, nil
} else if valid_shares.Err() != nil || stale_shares.Err() != nil || invalid_shares.Err() != nil {
return 0, 0, 0, valid_shares.Err()
}
v_c, _ := valid_shares.Int64()
s_c, _ := stale_shares.Int64()
i_c, _ := invalid_shares.Int64()
return v_c, s_c, i_c, nil
}
//lets try to fuck without understanding and see if it works
func (r *RedisClient) WriteWorkerShareStatus(login string, id string, valid bool, stale bool, invalid bool) {
valid_int := 0
stale_int := 0
invalid_int := 0
if valid {
valid_int = 1
}
if stale {
stale_int = 1
}
if invalid {
invalid_int = 1
}
// var after = time.Now().AddDate(0, 0, -1).Unix()
// var now = time.Now().Unix()
// if(now >= after){
// tx.HDel(r.formatKey("minerShare", login, id))
// }
t := time.Now().Local()
if t.Format("15:04:05") >= "23:59:00" {
tx := r.client.Multi()
defer tx.Close()
tx.Exec(func() error {
//tx.Del(r.formatKey("minerShare", login, id))
tx.HSet(r.formatKey("minerShare", login, id), "valid", strconv.FormatInt(0, 10))
tx.HSet(r.formatKey("minerShare", login, id), "stale", strconv.FormatInt(0, 10))
tx.HSet(r.formatKey("minerShare", login, id), "invalid", strconv.FormatInt(0, 10))
return nil
})
} else {
// So, we need to initiate the tx object
tx := r.client.Multi()
defer tx.Close()
tx.Exec(func() error {
// OK, good, no need to read reset and add if i use Hset and HGet shit
tx.HIncrBy(r.formatKey("minerShare", login, id), "valid", int64(valid_int))
tx.HIncrBy(r.formatKey("minerShare", login, id), "stale", int64(stale_int))
tx.HIncrBy(r.formatKey("minerShare", login, id), "invalid", int64(invalid_int))
tx.HIncrBy(r.formatKey("chartsNum", "share", login), "valid", int64(valid_int))
tx.HIncrBy(r.formatKey("chartsNum", "share", login), "stale", int64(stale_int)) // Would that work?
return nil
})
} //end else
}
func (r *RedisClient) NumberStratumWorker(count int) {
tx := r.client.Multi()
defer tx.Close()
tx.Exec(func() error {
tx.Del(r.formatKey("WorkersTot"))
tx.HIncrBy(r.formatKey("WorkersTot"), "workers", int64(count))
//tx.HSet(r.formatKey("WorkersTotal"), "workers", int64(count))
return nil
})
}

6
www/app/templates/account/index.hbs

@ -10,6 +10,7 @@
<th>Hashrate (rough, short average)</th> <th>Hashrate (rough, short average)</th>
<th>Hashrate (accurate, long average)</th> <th>Hashrate (accurate, long average)</th>
<th>Blocks</th> <th>Blocks</th>
<th>Valid / Stale / Invalid 24h</th>
<th>Last Share</th> <th>Last Share</th>
</tr> </tr>
</thead> </thead>
@ -17,9 +18,10 @@
{{#each-in model.workers as |k v|}} {{#each-in model.workers as |k v|}}
<tr class="{{if v.offline "warning" "success"}}"> <tr class="{{if v.offline "warning" "success"}}">
<td>{{k}}</td> <td>{{k}}</td>
<td>{{format-hashrate v.hr}}</td> <td>{{format-hashrate v.hr}} {{#if v.w_stat_s}}<i class="fa fa-arrow-up" style="color:rgb(0, 9, 128)" aria-hidden="true"></i>{{else}}<i class="fa fa-arrow-down" style="color:red" aria-hidden="true"></i>{{/if}}</td>
<td>{{format-hashrate v.hr2}}</td> <td>{{format-hashrate v.hr2}} {{#if v.w_stat}}<i class="fa fa-arrow-up" style="color:rgb(0, 9, 128)" aria-hidden="true"></i>{{else}}<i class="fa fa-arrow-down" style="color:red" aria-hidden="true"></i>{{/if}}</td>
<td>{{v.blocks}}</td> <td>{{v.blocks}}</td>
<td><span class="text-green">{{v.valid}}</span> ({{v.v_per}}%) / <span class="text-yellow">{{v.stale}}</span> ({{v.s_per}}%) / <span class="text-red">{{v.invalid}}</span> ({{v.i_per}}%)</td>
<td>{{format-relative (seconds-to-ms v.lastBeat)}}</td> <td>{{format-relative (seconds-to-ms v.lastBeat)}}</td>
</tr> </tr>
{{/each-in}} {{/each-in}}

Loading…
Cancel
Save