|
|
|
|
@ -23,7 +23,7 @@ type Config struct {
|
|
|
|
|
type RedisClient struct { |
|
|
|
|
client *redis.Client |
|
|
|
|
prefix string |
|
|
|
|
pplns int64 |
|
|
|
|
pplns int64 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type PoolCharts struct { |
|
|
|
|
@ -47,25 +47,23 @@ type PaymentCharts struct {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type SumRewardData struct { |
|
|
|
|
Interval int64 `json:"inverval"` |
|
|
|
|
Reward int64 `json:"reward"` |
|
|
|
|
Name string `json:"name"` |
|
|
|
|
Offset int64 `json:"offset"` |
|
|
|
|
Interval int64 `json:"inverval"` |
|
|
|
|
Reward int64 `json:"reward"` |
|
|
|
|
Name string `json:"name"` |
|
|
|
|
Offset int64 `json:"offset"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type BlockData struct { |
|
|
|
|
Login string `json:"login"` |
|
|
|
|
Login string `json:"login"` |
|
|
|
|
Height int64 `json:"height"` |
|
|
|
|
Timestamp int64 `json:"timestamp"` |
|
|
|
|
Difficulty int64 `json:"difficulty"` |
|
|
|
|
@ -203,7 +201,11 @@ func convertPoolChartsResults(raw *redis.ZSliceCmd) []*PoolCharts {
|
|
|
|
|
pc.PoolHash, _ = strconv.ParseInt(str[strings.LastIndex(str, ":")+1:], 10, 64) |
|
|
|
|
result = append(result, &pc) |
|
|
|
|
} |
|
|
|
|
return result |
|
|
|
|
var reverse []*PoolCharts |
|
|
|
|
for i := len(result) - 1; i >= 0; i-- { |
|
|
|
|
reverse = append(reverse, result[i]) |
|
|
|
|
} |
|
|
|
|
return reverse |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func convertMinerChartsResults(raw *redis.ZSliceCmd) []*MinerCharts { |
|
|
|
|
@ -219,7 +221,11 @@ func convertMinerChartsResults(raw *redis.ZSliceCmd) []*MinerCharts {
|
|
|
|
|
mc.WorkerOnline = strings.Split(str, ":")[4] |
|
|
|
|
result = append(result, &mc) |
|
|
|
|
} |
|
|
|
|
return result |
|
|
|
|
var reverse []*MinerCharts |
|
|
|
|
for i := len(result) - 1; i >= 0; i-- { |
|
|
|
|
reverse = append(reverse, result[i]) |
|
|
|
|
} |
|
|
|
|
return reverse |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RedisClient) GetAllMinerAccount() (account []string, err error) { |
|
|
|
|
@ -379,9 +385,9 @@ func (r *RedisClient) WriteBlock(login, id string, params []string, diff, roundD
|
|
|
|
|
return false, err |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
shares := cmds[len(cmds) - 1].(*redis.StringSliceCmd).Val() |
|
|
|
|
shares := cmds[len(cmds)-1].(*redis.StringSliceCmd).Val() |
|
|
|
|
|
|
|
|
|
tx2 := r.client.Multi() |
|
|
|
|
tx2 := r.client.Multi() |
|
|
|
|
defer tx2.Close() |
|
|
|
|
|
|
|
|
|
totalshares := make(map[string]int64) |
|
|
|
|
@ -399,7 +405,7 @@ func (r *RedisClient) WriteBlock(login, id string, params []string, diff, roundD
|
|
|
|
|
return false, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sharesMap, _ := cmds[len(cmds) - 3].(*redis.StringStringMapCmd).Result() |
|
|
|
|
sharesMap, _ := cmds[len(cmds)-3].(*redis.StringStringMapCmd).Result() |
|
|
|
|
totalShares := int64(0) |
|
|
|
|
for _, v := range sharesMap { |
|
|
|
|
n, _ := strconv.ParseInt(v, 10, 64) |
|
|
|
|
@ -491,12 +497,12 @@ func (r *RedisClient) GetImmatureBlocks(maxHeight int64) ([]*BlockData, error) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
if cmd.Err() != nil { |
|
|
|
|
return nil, cmd.Err() |
|
|
|
|
} |
|
|
|
|
return convertRewardResults(cmd), nil |
|
|
|
|
option := redis.ZRangeByScore{Min: "0", Max: strconv.FormatInt(10, 10)} |
|
|
|
|
cmd := r.client.ZRangeByScoreWithScores(r.formatKey("rewards", login), option) |
|
|
|
|
if cmd.Err() != nil { |
|
|
|
|
return nil, cmd.Err() |
|
|
|
|
} |
|
|
|
|
return convertRewardResults(cmd), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RedisClient) GetRoundShares(height int64, nonce string) (map[string]int64, error) { |
|
|
|
|
@ -651,9 +657,9 @@ 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.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.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) |
|
|
|
|
@ -664,24 +670,24 @@ func (r *RedisClient) WritePayment(login, txHash string, amount int64) error {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RedisClient) WriteReward(login string, amount int64, percent *big.Rat, immature bool, block *BlockData) error { |
|
|
|
|
if (amount <= 0) { |
|
|
|
|
if amount <= 0 { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
tx := r.client.Multi() |
|
|
|
|
defer tx.Close() |
|
|
|
|
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) |
|
|
|
|
remscore := block.Timestamp - 3600 * 24 * 40 // Store the last 40 Days
|
|
|
|
|
addStr := join(amount, percent, immature, block.Hash, block.Height, block.Timestamp) |
|
|
|
|
remStr := join(amount, percent, !immature, block.Hash, block.Height, block.Timestamp) |
|
|
|
|
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)) |
|
|
|
|
_, 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 |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RedisClient) WriteImmatureBlock(block *BlockData, roundRewards map[string]int64) error { |
|
|
|
|
@ -741,7 +747,7 @@ 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) |
|
|
|
|
tx.Expire(r.formatKey("credits", block.Height, block.Hash), 604800*time.Second) |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
return err |
|
|
|
|
@ -916,7 +922,7 @@ func (r *RedisClient) CollectStats(smallWindow time.Duration, maxBlocks, maxPaym
|
|
|
|
|
tx.ZCard(r.formatKey("blocks", "matured")) |
|
|
|
|
tx.HGet(r.formatKey("paymentsTotal"), "all") |
|
|
|
|
tx.ZRevRangeWithScores(r.formatKey("payments", "all"), 0, maxPayments-1) |
|
|
|
|
tx.LLen(r.formatKey("lastshares")) |
|
|
|
|
tx.LLen(r.formatKey("lastshares")) |
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
@ -925,7 +931,7 @@ func (r *RedisClient) CollectStats(smallWindow time.Duration, maxBlocks, maxPaym
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
result, _ := cmds[2].(*redis.StringStringMapCmd).Result() |
|
|
|
|
result["nShares"] = strconv.FormatInt(cmds[11].(*redis.IntCmd).Val(), 10) |
|
|
|
|
result["nShares"] = strconv.FormatInt(cmds[11].(*redis.IntCmd).Val(), 10) |
|
|
|
|
stats["stats"] = convertStringMap(result) |
|
|
|
|
candidates := convertCandidateResults(cmds[3].(*redis.ZSliceCmd)) |
|
|
|
|
stats["candidates"] = candidates |
|
|
|
|
@ -1015,22 +1021,20 @@ func (r *RedisClient) CollectWorkersStats(sWindow, lWindow time.Duration, login
|
|
|
|
|
stats["currentHashrate"] = currentHashrate |
|
|
|
|
|
|
|
|
|
stats["rewards"] = convertRewardResults(cmds[2].(*redis.ZSliceCmd)) // last 40
|
|
|
|
|
rewards := convertRewardResults(cmds[3].(*redis.ZSliceCmd)) // all
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rewards := convertRewardResults(cmds[3].(*redis.ZSliceCmd)) // all
|
|
|
|
|
|
|
|
|
|
var dorew []*SumRewardData |
|
|
|
|
dorew = append(dorew, &SumRewardData{ Name: "Last 60 minutes", Interval: 3600, Offset: 0 }) |
|
|
|
|
dorew = append(dorew, &SumRewardData{ Name: "Last 12 hours", Interval: 3600 * 12, Offset: 0 }) |
|
|
|
|
dorew = append(dorew, &SumRewardData{ Name: "Last 24 hours", Interval: 3600 * 24, Offset: 0 }) |
|
|
|
|
dorew = append(dorew, &SumRewardData{ Name: "Last 7 days", Interval: 3600 * 24 * 7, Offset: 0 }) |
|
|
|
|
dorew = append(dorew, &SumRewardData{ Name: "Last 30 days", Interval: 3600 * 24 * 30, Offset: 0 }) |
|
|
|
|
dorew = append(dorew, &SumRewardData{Name: "Last 60 minutes", Interval: 3600, Offset: 0}) |
|
|
|
|
dorew = append(dorew, &SumRewardData{Name: "Last 12 hours", Interval: 3600 * 12, Offset: 0}) |
|
|
|
|
dorew = append(dorew, &SumRewardData{Name: "Last 24 hours", Interval: 3600 * 24, Offset: 0}) |
|
|
|
|
dorew = append(dorew, &SumRewardData{Name: "Last 7 days", Interval: 3600 * 24 * 7, Offset: 0}) |
|
|
|
|
dorew = append(dorew, &SumRewardData{Name: "Last 30 days", Interval: 3600 * 24 * 30, Offset: 0}) |
|
|
|
|
|
|
|
|
|
for _, reward := range rewards { |
|
|
|
|
|
|
|
|
|
for _,dore := range dorew { |
|
|
|
|
for _, dore := range dorew { |
|
|
|
|
dore.Reward += 0 |
|
|
|
|
if reward.Timestamp > now - dore.Interval { |
|
|
|
|
if reward.Timestamp > now-dore.Interval { |
|
|
|
|
dore.Reward += reward.Reward |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -1108,7 +1112,7 @@ 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.Login = fields[6] |
|
|
|
|
block.candidateKey = v.Member.(string) |
|
|
|
|
result = append(result, &block) |
|
|
|
|
} |
|
|
|
|
@ -1116,23 +1120,23 @@ func convertCandidateResults(raw *redis.ZSliceCmd) []*BlockData {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func convertRewardResults(rows ...*redis.ZSliceCmd) []*RewardData { |
|
|
|
|
var result []*RewardData |
|
|
|
|
for _, row := range rows { |
|
|
|
|
for _, v := range row.Val() { |
|
|
|
|
// "amount:percent:immature:block.Hash:block.height"
|
|
|
|
|
reward := RewardData{} |
|
|
|
|
reward.Timestamp = int64(v.Score) |
|
|
|
|
fields := strings.Split(v.Member.(string), ":") |
|
|
|
|
//block.UncleHeight, _ = strconv.ParseInt(fields[0], 10, 64)
|
|
|
|
|
reward.BlockHash = fields[3] |
|
|
|
|
var result []*RewardData |
|
|
|
|
for _, row := range rows { |
|
|
|
|
for _, v := range row.Val() { |
|
|
|
|
// "amount:percent:immature:block.Hash:block.height"
|
|
|
|
|
reward := RewardData{} |
|
|
|
|
reward.Timestamp = int64(v.Score) |
|
|
|
|
fields := strings.Split(v.Member.(string), ":") |
|
|
|
|
//block.UncleHeight, _ = strconv.ParseInt(fields[0], 10, 64)
|
|
|
|
|
reward.BlockHash = fields[3] |
|
|
|
|
reward.Reward, _ = strconv.ParseInt(fields[0], 10, 64) |
|
|
|
|
reward.Percent, _ = strconv.ParseFloat(fields[1], 64) |
|
|
|
|
reward.Percent, _ = strconv.ParseFloat(fields[1], 64) |
|
|
|
|
reward.Immature, _ = strconv.ParseBool(fields[2]) |
|
|
|
|
reward.Height, _ = strconv.ParseInt(fields[4], 10, 64) |
|
|
|
|
result = append(result, &reward) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return result |
|
|
|
|
result = append(result, &reward) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func convertBlockResults(rows ...*redis.ZSliceCmd) []*BlockData { |
|
|
|
|
@ -1154,7 +1158,7 @@ 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.Login = fields[8] |
|
|
|
|
block.immatureKey = v.Member.(string) |
|
|
|
|
result = append(result, &block) |
|
|
|
|
} |
|
|
|
|
@ -1253,6 +1257,10 @@ func convertPaymentsResults(raw *redis.ZSliceCmd) []map[string]interface{} {
|
|
|
|
|
} |
|
|
|
|
result = append(result, tx) |
|
|
|
|
} |
|
|
|
|
var reverse []map[string]interface{} |
|
|
|
|
for i := len(result) - 1; i >= 0; i-- { |
|
|
|
|
reverse = append(reverse, result[i]) |
|
|
|
|
} |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1284,5 +1292,9 @@ func convertPaymentChartsResults(raw *redis.ZSliceCmd) []*PaymentCharts {
|
|
|
|
|
result = append(result, &pc) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return result |
|
|
|
|
var reverse []*PaymentCharts |
|
|
|
|
for i := len(result) - 1; i >= 0; i-- { |
|
|
|
|
reverse = append(reverse, result[i]) |
|
|
|
|
} |
|
|
|
|
return reverse |
|
|
|
|
} |