From 159b730eebe49c6db01ddcd708b5f32e25f251b9 Mon Sep 17 00:00:00 2001 From: yuriy0803 <68668177+yuriy0803@users.noreply.github.com> Date: Fri, 12 Mar 2021 17:19:25 +0100 Subject: [PATCH] Update redis.go --- storage/redis.go | 452 ++++++++++++++++++++--------------------------- 1 file changed, 188 insertions(+), 264 deletions(-) diff --git a/storage/redis.go b/storage/redis.go index 98f67f1..9a12801 100644 --- a/storage/redis.go +++ b/storage/redis.go @@ -4,14 +4,15 @@ import ( "fmt" "math" "math/big" - "sort" + "sort" "strconv" "strings" "time" + "log" "gopkg.in/redis.v3" - "github.com/yuriy0803/open-etc-pool-friends/util" + "github.com/feeleep75/open-ethereum-pool/util" ) type Config struct { @@ -25,12 +26,13 @@ type RedisClient struct { client *redis.Client prefix string pplns int64 + CoinName string } type PoolCharts struct { - Timestamp int64 `json:"x"` - TimeFormat string `json:"timeFormat"` - PoolHash int64 `json:"y"` + Timestamp int64 `json:"x"` + PoolHash int64 `json:"y"` + Diff int64 `json:"d"` } type MinerCharts struct { @@ -57,24 +59,29 @@ type LuckCharts struct { } type SumRewardData struct { - Interval int64 `json:"inverval"` - Reward int64 `json:"reward"` - Name string `json:"name"` - Offset int64 `json:"offset"` - Blocks int64 `json:"blocks"` + Interval int64 `json:"inverval"` + Reward int64 `json:"reward"` + Name string `json:"name"` + Offset int64 `json:"offset"` + Blocks int64 `json:"blocks"` + Effort float64 `json:"personalEffort"` + Count float64 `json:"_"` + ESum float64 `json:"_"` } - type RewardData struct { - Height int64 `json:"blockheight"` - Timestamp int64 `json:"timestamp"` - BlockHash string `json:"blockhash"` - Reward int64 `json:"reward"` - Percent float64 `json:"percent"` - Immature bool `json:"immature"` + Height int64 `json:"blockheight"` + Timestamp int64 `json:"timestamp"` + BlockHash string `json:"blockhash"` + Reward int64 `json:"reward"` + Percent float64 `json:"percent"` + Immature bool `json:"immature"` + Difficulty int64 `json:"-"` + PersonalShares int64 `json:"-"` + PersonalEffort float64 `json:"personalEffort"` } - type BlockData struct { - Login string `json:"login"` + Finder string `json:"finder"` + ActualDiff int64 `json:"shareDiff"` Height int64 `json:"height"` Timestamp int64 `json:"timestamp"` Difficulty int64 `json:"difficulty"` @@ -93,6 +100,7 @@ type BlockData struct { RoundHeight int64 `json:"-"` candidateKey string immatureKey string + PersonalShares int64 `json:"-"` } func (b *BlockData) RewardInShannon() int64 { @@ -113,7 +121,7 @@ func (b *BlockData) RoundKey() string { } func (b *BlockData) key() string { - return join(b.UncleHeight, b.Orphan, b.Nonce, b.serializeHash(), b.Timestamp, b.Difficulty, b.TotalShares, b.Reward, b.Login) + return join(b.UncleHeight, b.Orphan, b.Nonce, b.serializeHash(), b.Timestamp, b.Difficulty, b.TotalShares, b.Reward, b.Finder, b.ActualDiff, b.PersonalShares) } type Miner struct { @@ -126,25 +134,20 @@ type Miner struct { type Worker struct { Miner - 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 { + TotalHR int64 `json:"hr2"` + PortDiff string `json:"portDiff"` + WorkerDiff int64 `json:"difficulty"` + WorkerHostname string `json:"hostname"` +} + +func NewRedisClient(cfg *Config, prefix string, pplns int64, CoinName string) *RedisClient { client := redis.NewClient(&redis.Options{ Addr: cfg.Endpoint, Password: cfg.Password, DB: cfg.Database, PoolSize: cfg.PoolSize, }) - return &RedisClient{client: client, prefix: prefix, pplns: pplns} + return &RedisClient{client: client, prefix: prefix, pplns: pplns, CoinName: CoinName} } func (r *RedisClient) Client() *redis.Client { @@ -177,9 +180,9 @@ func (r *RedisClient) GetWhitelist() ([]string, error) { return cmd.Val(), nil } -func (r *RedisClient) WritePoolCharts(time1 int64, time2 string, poolHash string) error { - s := join(time1, time2, poolHash) - cmd := r.client.ZAdd(r.formatKey("charts", "pool"), redis.Z{Score: float64(time1), Member: s}) +func (r *RedisClient) WritePoolCharts(time int64, poolHash string, diff string) error { + s := join(time, poolHash, diff) + cmd := r.client.ZAdd(r.formatKey("charts", "pool"), redis.Z{Score: float64(time), Member: s}) return cmd.Err() } @@ -190,22 +193,17 @@ func (r *RedisClient) WriteMinerCharts(time1 int64, time2, k string, hash, large } func (r *RedisClient) GetPoolCharts(poolHashLen int64) (stats []*PoolCharts, err error) { - tx := r.client.Multi() defer tx.Close() - now := util.MakeTimestamp() / 1000 - cmds, err := tx.Exec(func() error { tx.ZRemRangeByScore(r.formatKey("charts", "pool"), "-inf", fmt.Sprint("(", now-172800)) tx.ZRevRangeWithScores(r.formatKey("charts", "pool"), 0, poolHashLen) return nil }) - if err != nil { return nil, err } - stats = convertPoolChartsResults(cmds[1].(*redis.ZSliceCmd)) return stats, nil } @@ -213,12 +211,11 @@ func (r *RedisClient) GetPoolCharts(poolHashLen int64) (stats []*PoolCharts, err func convertPoolChartsResults(raw *redis.ZSliceCmd) []*PoolCharts { var result []*PoolCharts for _, v := range raw.Val() { - // "Timestamp:TimeFormat:Hash" pc := PoolCharts{} pc.Timestamp = int64(v.Score) - str := v.Member.(string) - pc.TimeFormat = str[strings.Index(str, ":")+1 : strings.LastIndex(str, ":")] - pc.PoolHash, _ = strconv.ParseInt(str[strings.LastIndex(str, ":")+1:], 10, 64) + fields := strings.Split(v.Member.(string), ":") + pc.PoolHash, _ = strconv.ParseInt(fields[1], 10, 64) + pc.Diff, _ = strconv.ParseInt(fields[2], 10, 64) result = append(result, &pc) } var reverse []*PoolCharts @@ -228,6 +225,7 @@ func convertPoolChartsResults(raw *redis.ZSliceCmd) []*PoolCharts { return reverse } + func convertMinerChartsResults(raw *redis.ZSliceCmd) []*MinerCharts { var result []*MinerCharts for _, v := range raw.Val() { @@ -243,7 +241,7 @@ func convertMinerChartsResults(raw *redis.ZSliceCmd) []*MinerCharts { } var reverse []*MinerCharts for i := len(result) - 1; i >= 0; i-- { - reverse = append(reverse, result[i]) + reverse = append(reverse, result[i]); } return reverse } @@ -304,7 +302,7 @@ func (r *RedisClient) GetPaymentCharts(login string) (stats []*PaymentCharts, er return stats, nil } -func (r *RedisClient) WriteNodeState(id string, height uint64, diff *big.Int) error { +func (r *RedisClient) WriteNodeState(id string, height uint64, diff *big.Int, blocktime float64) error { tx := r.client.Multi() defer tx.Close() @@ -315,6 +313,7 @@ func (r *RedisClient) WriteNodeState(id string, height uint64, diff *big.Int) er tx.HSet(r.formatKey("nodes"), join(id, "height"), strconv.FormatUint(height, 10)) tx.HSet(r.formatKey("nodes"), join(id, "difficulty"), diff.String()) tx.HSet(r.formatKey("nodes"), join(id, "lastBeat"), strconv.FormatInt(now, 10)) + tx.HSet(r.formatKey("nodes"), join(id, "blocktime"), strconv.FormatFloat(blocktime, 'f', 4, 64)) return nil }) return err @@ -352,7 +351,7 @@ func (r *RedisClient) checkPoWExist(height uint64, params []string) (bool, error return val == 0, err } -func (r *RedisClient) WriteShare(login, id string, params []string, diff int64, height uint64, window time.Duration) (bool, error) { +func (r *RedisClient) WriteShare(login, id string, params []string, diff int64, actualDiff int64, netDiff int64, height, topHeight uint64, window time.Duration, hostname string) (bool, error) { exist, err := r.checkPoWExist(height, params) if err != nil { return false, err @@ -368,14 +367,14 @@ func (r *RedisClient) WriteShare(login, id string, params []string, diff int64, ts := ms / 1000 _, err = tx.Exec(func() error { - r.writeShare(tx, ms, ts, login, id, diff, window) + r.writeShare(tx, ms, ts, login, id, diff, actualDiff, height, topHeight, netDiff, window, hostname) tx.HIncrBy(r.formatKey("stats"), "roundShares", diff) return nil }) return false, err } -func (r *RedisClient) WriteBlock(login, id string, params []string, diff, roundDiff int64, height uint64, window time.Duration) (bool, error) { +func (r *RedisClient) WriteBlock(login, id string, params []string, diff, actualDiff int64, roundDiff int64, height, topHeight uint64, window time.Duration, hostname string) (bool, error) { exist, err := r.checkPoWExist(height, params) if err != nil { return false, err @@ -391,9 +390,10 @@ func (r *RedisClient) WriteBlock(login, id string, params []string, diff, roundD ts := ms / 1000 cmds, err := tx.Exec(func() error { - r.writeShare(tx, ms, ts, login, id, diff, window) + r.writeShare(tx, ms, ts, login, id, diff, actualDiff, height, topHeight, roundDiff, window, hostname) tx.HSet(r.formatKey("stats"), "lastBlockFound", strconv.FormatInt(ts, 10)) tx.HDel(r.formatKey("stats"), "roundShares") + tx.HSet(r.formatKey("miners", login), "roundShares", strconv.FormatInt(0, 10)) tx.ZIncrBy(r.formatKey("finders"), 1, login) tx.HIncrBy(r.formatKey("miners", login), "blocksFound", 1) tx.HGetAllMap(r.formatKey("shares", "roundCurrent")) @@ -432,14 +432,18 @@ func (r *RedisClient) WriteBlock(login, id string, params []string, diff, roundD n, _ := strconv.ParseInt(v, 10, 64) totalShares += n } + + personalShares := int64(0) + personalShares = cmds[len(cmds)-14].(*redis.IntCmd).Val() + hashHex := strings.Join(params, ":") - s := join(hashHex, ts, roundDiff, totalShares, login) + s := join(hashHex, ts, roundDiff, totalShares, login, actualDiff, personalShares) cmd := r.client.ZAdd(r.formatKey("blocks", "candidates"), redis.Z{Score: float64(height), Member: s}) return false, cmd.Err() } } -func (r *RedisClient) writeShare(tx *redis.Multi, ms, ts int64, login, id string, diff int64, expire time.Duration) { +func (r *RedisClient) writeShare(tx *redis.Multi, ms, ts int64, login, id string, diff int64, actualDiff int64, height, topHeight uint64, netDiff int64, expire time.Duration, hostname string) { /* # Note To Me: Will have to write to get from redis the current value for round shares and increase by 1, then include the new number to be added to redis @@ -450,11 +454,13 @@ func (r *RedisClient) writeShare(tx *redis.Multi, ms, ts int64, login, id string tx.LPush(r.formatKey("lastshares"), login) tx.LTrim(r.formatKey("lastshares"), 0, r.pplns) + tx.HIncrBy(r.formatKey("miners", login), "roundShares", diff) tx.HIncrBy(r.formatKey("shares", "roundCurrent"), login, diff) - tx.ZAdd(r.formatKey("hashrate"), redis.Z{Score: float64(ts), Member: join(diff, login, id, ms)}) - tx.ZAdd(r.formatKey("hashrate", login), redis.Z{Score: float64(ts), Member: join(diff, id, ms)}) + tx.ZAdd(r.formatKey("hashrate"), redis.Z{Score: float64(ts), Member: join(diff, login, id, ms, hostname)}) + tx.ZAdd(r.formatKey("hashrate", login), redis.Z{Score: float64(ts), Member: join(diff, id, ms, hostname)}) tx.Expire(r.formatKey("hashrate", login), expire) // Will delete hashrates for miners that gone tx.HSet(r.formatKey("miners", login), "lastShare", strconv.FormatInt(ts, 10)) + tx.HSet(r.formatKey("miners", login), "lastShareDiff", strconv.FormatInt(actualDiff, 10)) } func (r *RedisClient) WriteBlocksFound(ms, ts int64, login, id, share string, diff int64) { @@ -487,13 +493,6 @@ func join(args ...interface{}) string { } else { s[i] = "0" } - case *big.Rat: - x := v.(*big.Rat) - if x != nil { - s[i] = x.FloatString(9) - } else { - s[i] = "0" - } case *big.Int: n := v.(*big.Int) if n != nil { @@ -501,6 +500,13 @@ func join(args ...interface{}) string { } else { s[i] = "0" } + case *big.Rat: + x := v.(*big.Rat) + if x != nil { + s[i] = x.FloatString(9) + } else { + s[i] = "0" + } default: panic("Invalid type specified for conversion") } @@ -525,7 +531,6 @@ func (r *RedisClient) GetImmatureBlocks(maxHeight int64) ([]*BlockData, error) { } return convertBlockResults(cmd), nil } - func (r *RedisClient) GetRewards(login string) ([]*RewardData, error) { option := redis.ZRangeByScore{Min: "0", Max: strconv.FormatInt(10, 10)} cmd := r.client.ZRangeByScoreWithScores(r.formatKey("rewards", login), option) @@ -594,6 +599,15 @@ func (r *RedisClient) GetBalance(login string) (int64, error) { } return cmd.Int64() } +func (r *RedisClient) GetTreshold(login string) (int64, error) { + cmd := r.client.HGet(r.formatKey("miners", login), "payouttreshold") + if cmd.Err() == redis.Nil { + return 0, nil + } else if cmd.Err() != nil { + return 0, cmd.Err() + } + return cmd.Int64() +} func (r *RedisClient) LockPayouts(login string, amount int64) error { key := r.formatKey("payments", "lock") @@ -687,18 +701,13 @@ func (r *RedisClient) WritePayment(login, txHash string, amount int64) error { tx.HIncrBy(r.formatKey("finances"), "pending", (amount * -1)) tx.HIncrBy(r.formatKey("finances"), "paid", amount) tx.ZAdd(r.formatKey("payments", "all"), redis.Z{Score: float64(ts), Member: join(txHash, login, amount)}) - tx.ZRemRangeByRank(r.formatKey("payments", "all"), 0, -10000) tx.ZAdd(r.formatKey("payments", login), redis.Z{Score: float64(ts), Member: join(txHash, amount)}) - tx.ZRemRangeByRank(r.formatKey("payments", login), 0, -100) tx.ZRem(r.formatKey("payments", "pending"), join(login, amount)) tx.Del(r.formatKey("payments", "lock")) - tx.HIncrBy(r.formatKey("paymentsTotal"), "all", 1) - tx.HIncrBy(r.formatKey("paymentsTotal"), login, 1) return nil }) return err } - func (r *RedisClient) WriteReward(login string, amount int64, percent *big.Rat, immature bool, block *BlockData) error { if amount <= 0 { return nil @@ -706,15 +715,15 @@ func (r *RedisClient) WriteReward(login string, amount int64, percent *big.Rat, tx := r.client.Multi() defer tx.Close() - addStr := join(amount, percent, immature, block.Hash, block.Height, block.Timestamp) - remStr := join(amount, percent, !immature, block.Hash, block.Height, block.Timestamp) + addStr := join(amount, percent, immature, block.Hash, block.Height, block.Timestamp, block.Difficulty, block.PersonalShares) + remStr := join(amount, percent, !immature, block.Hash, block.Height, block.Timestamp, block.Difficulty, block.PersonalShares) + remscore := block.Timestamp - 3600*24*40 // Store the last 40 Days _, err := tx.Exec(func() error { tx.ZAdd(r.formatKey("rewards", login), redis.Z{Score: float64(block.Timestamp), Member: addStr}) tx.ZRem(r.formatKey("rewards", login), remStr) tx.ZRemRangeByScore(r.formatKey("rewards", login), "-inf", "("+strconv.FormatInt(remscore, 10)) - return nil }) return err @@ -777,7 +786,6 @@ func (r *RedisClient) WriteMaturedBlock(block *BlockData, roundRewards map[strin tx.HSet(r.formatKey("finances"), "lastCreditHeight", strconv.FormatInt(block.Height, 10)) tx.HSet(r.formatKey("finances"), "lastCreditHash", block.Hash) tx.HIncrBy(r.formatKey("finances"), "totalMined", block.RewardInShannon()) - tx.Expire(r.formatKey("credits", block.Height, block.Hash), 604800*time.Second) return nil }) return err @@ -851,11 +859,9 @@ func (r *RedisClient) GetMinerStats(login string, maxPayments int64) (map[string cmds, err := tx.Exec(func() error { tx.HGetAllMap(r.formatKey("miners", login)) tx.ZRevRangeWithScores(r.formatKey("payments", login), 0, maxPayments-1) - tx.HGet(r.formatKey("paymentsTotal"), login) + tx.ZCard(r.formatKey("payments", login)) tx.HGet(r.formatKey("shares", "currentShares"), login) tx.LRange(r.formatKey("lastshares"), 0, r.pplns) - tx.ZRevRangeWithScores(r.formatKey("rewards", login), 0, 39) - tx.ZRevRangeWithScores(r.formatKey("rewards", login), 0, -1) return nil }) @@ -866,7 +872,7 @@ func (r *RedisClient) GetMinerStats(login string, maxPayments int64) (map[string stats["stats"] = convertStringMap(result) payments := convertPaymentsResults(cmds[1].(*redis.ZSliceCmd)) stats["payments"] = payments - stats["paymentsTotal"], _ = cmds[2].(*redis.StringCmd).Int64() + stats["paymentsTotal"] = cmds[2].(*redis.IntCmd).Val() shares := cmds[4].(*redis.StringSliceCmd).Val() csh := 0 for _, val := range shares { @@ -950,14 +956,15 @@ func (r *RedisClient) CollectStats(smallWindow time.Duration, maxBlocks, maxPaym tx.ZCard(r.formatKey("blocks", "candidates")) tx.ZCard(r.formatKey("blocks", "immature")) tx.ZCard(r.formatKey("blocks", "matured")) - tx.HGet(r.formatKey("paymentsTotal"), "all") + tx.ZCard(r.formatKey("payments", "all")) tx.ZRevRangeWithScores(r.formatKey("payments", "all"), 0, maxPayments-1) tx.LLen(r.formatKey("lastshares")) - tx.ZRevRangeWithScores(r.formatKey("finders"), 0, -1) + tx.HGetAllMap(r.formatKey("exchange", r.CoinName)) + tx.ZRevRangeWithScores(r.formatKey("finders"), 0, -1) return nil }) - if (err != nil) && (err != redis.Nil) { + if err != nil { return nil, err } @@ -978,15 +985,21 @@ func (r *RedisClient) CollectStats(smallWindow time.Duration, maxBlocks, maxPaym payments := convertPaymentsResults(cmds[10].(*redis.ZSliceCmd)) stats["payments"] = payments - stats["paymentsTotal"], _ = cmds[9].(*redis.StringCmd).Int64() + stats["paymentsTotal"] = cmds[9].(*redis.IntCmd).Val() - finders := convertFindersResults(cmds[12].(*redis.ZSliceCmd)) - stats["finders"] = finders totalHashrate, miners := convertMinersStats(window, cmds[1].(*redis.ZSliceCmd)) stats["miners"] = miners stats["minersTotal"] = len(miners) stats["hashrate"] = totalHashrate + + exchangedata, _ := cmds[12].(*redis.StringStringMapCmd).Result() + stats["exchangedata"] = exchangedata + + finders := convertFindersResults(cmds[13].(*redis.ZSliceCmd)) + stats["finders"] = finders + + return stats, nil } @@ -1003,6 +1016,7 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login cmds, err := tx.Exec(func() error { tx.ZRemRangeByScore(r.formatKey("hashrate", login), "-inf", fmt.Sprint("(", now-largeWindow)) tx.ZRangeWithScores(r.formatKey("hashrate", login), 0, -1) + tx.LRange(r.formatKey("lastshares"), 0, r.pplns) tx.ZRevRangeWithScores(r.formatKey("rewards", login), 0, 39) tx.ZRevRangeWithScores(r.formatKey("rewards", login), 0, -1) tx.ZRangeWithScores(r.formatKey("worker", "blocks", login), 0, -1) @@ -1017,7 +1031,7 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login currentHashrate := int64(0) online := int64(0) offline := int64(0) - workers := convertWorkersStats(smallWindow, cmds[1].(*redis.ZSliceCmd), cmds[4].(*redis.ZSliceCmd), login, r) + workers := convertWorkersStats(smallWindow, cmds[1].(*redis.ZSliceCmd), cmds[5].(*redis.ZSliceCmd)) for id, worker := range workers { timeOnline := now - worker.startedAt @@ -1044,7 +1058,7 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login online++ } - blocks := cmds[4].(*redis.ZSliceCmd).Val() + blocks := cmds[5].(*redis.ZSliceCmd).Val() for _, val := range blocks { parts := strings.Split(val.Member.(string), ":") @@ -1059,68 +1073,25 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login currentHashrate += worker.HR 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 } + shares := cmds[2].(*redis.StringSliceCmd).Val() + + csh := 0 + //var myshares []string + for _, val := range shares { + //text := "█" + if val != login { + //text = "▁" + } else { + csh++ + } + //myshares = append(myshares, strconv.FormatInt(int64(ind) 10)) + //myshares = append(myshares, text) + } + stats["roundShares"] = csh + //stats["shares"] = myshares stats["workers"] = workers stats["workersTotal"] = len(workers) stats["workersOnline"] = online @@ -1128,8 +1099,8 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login stats["hashrate"] = totalHashrate stats["currentHashrate"] = currentHashrate - stats["rewards"] = convertRewardResults(cmds[2].(*redis.ZSliceCmd)) // last 40 - rewards := convertRewardResults(cmds[3].(*redis.ZSliceCmd)) // all + stats["rewards"] = convertRewardResults(cmds[3].(*redis.ZSliceCmd)) // last 40 + rewards := convertRewardResults(cmds[4].(*redis.ZSliceCmd)) // all var dorew []*SumRewardData dorew = append(dorew, &SumRewardData{Name: "Last 60 minutes", Interval: 3600, Offset: 0}) @@ -1139,30 +1110,27 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login dorew = append(dorew, &SumRewardData{Name: "Last 30 days", Interval: 3600 * 24 * 30, Offset: 0}) for _, reward := range rewards { - for _, dore := range dorew { + dore.Count += 0 + dore.ESum += 0 dore.Reward += 0 dore.Blocks += 0 + dore.Effort += 0 if reward.Timestamp > now-dore.Interval { dore.Reward += reward.Reward dore.Blocks++ + dore.ESum += reward.PersonalEffort + dore.Count++ + dore.Effort = dore.ESum / dore.Count } } } + stats["sumrewards"] = dorew stats["24hreward"] = dorew[2].Reward 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) { stats := make(map[string]interface{}) @@ -1269,7 +1237,9 @@ func convertCandidateResults(raw *redis.ZSliceCmd) []*BlockData { block.Timestamp, _ = strconv.ParseInt(fields[3], 10, 64) block.Difficulty, _ = strconv.ParseInt(fields[4], 10, 64) block.TotalShares, _ = strconv.ParseInt(fields[5], 10, 64) - block.Login = fields[6] + block.Finder = fields[6] + block.ActualDiff, _ = strconv.ParseInt(fields[7], 10, 64) + block.PersonalShares, _ = strconv.ParseInt(fields[8], 10, 64) block.candidateKey = v.Member.(string) result = append(result, &block) } @@ -1290,6 +1260,11 @@ func convertRewardResults(rows ...*redis.ZSliceCmd) []*RewardData { reward.Percent, _ = strconv.ParseFloat(fields[1], 64) reward.Immature, _ = strconv.ParseBool(fields[2]) reward.Height, _ = strconv.ParseInt(fields[4], 10, 64) + reward.Difficulty, _ = strconv.ParseInt(fields[6], 10, 64) + reward.PersonalShares, _ = strconv.ParseInt(fields[7], 10, 64) + Difficulty, _ := strconv.ParseFloat(fields[6], 64) + PersonalShares, _ := strconv.ParseFloat(fields[7], 64) + reward.PersonalEffort = float64(PersonalShares / Difficulty) result = append(result, &reward) } } @@ -1315,7 +1290,9 @@ func convertBlockResults(rows ...*redis.ZSliceCmd) []*BlockData { block.TotalShares, _ = strconv.ParseInt(fields[6], 10, 64) block.RewardString = fields[7] block.ImmatureReward = fields[7] - block.Login = fields[8] + block.Finder = fields[8] + block.ActualDiff, _ = strconv.ParseInt(fields[9], 10, 64) + block.PersonalShares, _ = strconv.ParseInt(fields[10], 10, 64) block.immatureKey = v.Member.(string) result = append(result, &block) } @@ -1325,7 +1302,7 @@ func convertBlockResults(rows ...*redis.ZSliceCmd) []*BlockData { // Build per login workers's total shares map {'rig-1': 12345, 'rig-2': 6789, ...} // TS => diff, id, ms -func convertWorkersStats(window int64, raw *redis.ZSliceCmd, blocks *redis.ZSliceCmd, login string, r *RedisClient) map[string]Worker { +func convertWorkersStats(window int64, raw *redis.ZSliceCmd, blocks *redis.ZSliceCmd) map[string]Worker { now := util.MakeTimestamp() / 1000 workers := make(map[string]Worker) @@ -1340,26 +1317,34 @@ func convertWorkersStats(window int64, raw *redis.ZSliceCmd, blocks *redis.ZSlic for _, v := range raw.Val() { parts := strings.Split(v.Member.(string), ":") share, _ := strconv.ParseInt(parts[0], 10, 64) + + //By Mohannad + var hostname string + if len(parts)>3 { + hostname = parts[3] + }else{ + hostname = "unknown" + } + id := parts[1] score := int64(v.Score) worker := workers[id] // Add for large window 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) + + // Addition from Mohannad Otaibi to report Difficulty + worker.WorkerDiff = share + worker.WorkerHostname = hostname + // End Mohannad Adjustments + // Add for small window if matches if score >= now-window { worker.HR += share } + if worker.LastBeat < score { worker.LastBeat = score } @@ -1432,7 +1417,7 @@ func convertPaymentsResults(raw *redis.ZSliceCmd) []map[string]interface{} { } var reverse []map[string]interface{} for i := len(result) - 1; i >= 0; i-- { - reverse = append(reverse, result[i]) + reverse = append(reverse, result[i]); } return result } @@ -1448,6 +1433,41 @@ func convertFindersResults(raw *redis.ZSliceCmd) []map[string]interface{} { return result } +func (r *RedisClient) StoreExchangeData(ExchangeData []map[string]interface{}) { + + tx := r.client.Multi() + defer tx.Close() + + log.Printf("ExchangeData: %s", ExchangeData) + + for _, coindata := range ExchangeData { + for key, value := range coindata { + + cmd := tx.HSet(r.formatKey("exchange", coindata["symbol"]), fmt.Sprintf("%v", key), fmt.Sprintf("%v", value)) + err := cmd.Err() + if err != nil { + log.Printf("Error while Storing %s : Key-%s , value-%s , Error : %v", coindata["symbol"], key, value, err) + } + + } + } + log.Printf("Writing Exchange Data ") + return +} + +func (r *RedisClient) GetExchangeData(coinsymbol string) (map[string]string, error) { + + cmd := r.client.HGetAllMap(r.formatKey("exchange", coinsymbol)) + + result, err := cmd.Result() + + if err != nil { + return nil, err + } + + return result, err +} + /* Timestamp int64 `json:"x"` TimeFormat string `json:"timeFormat"` @@ -1478,7 +1498,7 @@ func convertPaymentChartsResults(raw *redis.ZSliceCmd) []*PaymentCharts { } var reverse []*PaymentCharts for i := len(result) - 1; i >= 0; i-- { - reverse = append(reverse, result[i]) + reverse = append(reverse, result[i]); } return reverse } @@ -1492,99 +1512,3 @@ func (r *RedisClient) GetCurrentHashrate(login string) (int64, error) { } 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 - }) -}