|
|
|
|
@ -77,6 +77,8 @@ type RewardData struct {
|
|
|
|
|
|
|
|
|
|
type BlockData struct { |
|
|
|
|
Login string `json:"login"` |
|
|
|
|
Worker string `json:"worker"` |
|
|
|
|
ActualDiff int64 `json:"shareDiff"` |
|
|
|
|
Height int64 `json:"height"` |
|
|
|
|
Timestamp int64 `json:"timestamp"` |
|
|
|
|
Difficulty int64 `json:"difficulty"` |
|
|
|
|
@ -129,7 +131,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.Login, b.ActualDiff, b.Worker) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type Miner struct { |
|
|
|
|
@ -499,7 +501,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, height uint64, window time.Duration) (bool, error) { |
|
|
|
|
exist, err := r.checkPoWExist(height, params) |
|
|
|
|
if err != nil { |
|
|
|
|
return false, err |
|
|
|
|
@ -515,14 +517,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, window) |
|
|
|
|
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 uint64, window time.Duration) (bool, error) { |
|
|
|
|
exist, err := r.checkPoWExist(height, params) |
|
|
|
|
if err != nil { |
|
|
|
|
return false, err |
|
|
|
|
@ -538,7 +540,7 @@ 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, window) |
|
|
|
|
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)) |
|
|
|
|
@ -581,13 +583,13 @@ func (r *RedisClient) WriteBlock(login, id string, params []string, diff, roundD
|
|
|
|
|
totalShares += n |
|
|
|
|
} |
|
|
|
|
hashHex := strings.Join(params, ":") |
|
|
|
|
s := join(hashHex, ts, roundDiff, totalShares, login) |
|
|
|
|
s := join(hashHex, ts, roundDiff, totalShares, login, actualDiff, id) |
|
|
|
|
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, expire time.Duration) { |
|
|
|
|
times := int(diff / 1000000000) |
|
|
|
|
for i := 0; i < times; i++ { |
|
|
|
|
tx.LPush(r.formatKey("lastshares"), login) |
|
|
|
|
@ -599,6 +601,7 @@ func (r *RedisClient) writeShare(tx *redis.Multi, ms, ts int64, login, id string
|
|
|
|
|
tx.ZAdd(r.formatKey("hashrate", login), redis.Z{Score: float64(ts), Member: join(diff, id, ms)}) |
|
|
|
|
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) { |
|
|
|
|
@ -1419,6 +1422,8 @@ func convertCandidateResults(raw *redis.ZSliceCmd) []*BlockData {
|
|
|
|
|
block.Difficulty, _ = strconv.ParseInt(fields[4], 10, 64) |
|
|
|
|
block.TotalShares, _ = strconv.ParseInt(fields[5], 10, 64) |
|
|
|
|
block.Login = fields[6] |
|
|
|
|
block.ActualDiff, _ = strconv.ParseInt(fields[7], 10, 64) |
|
|
|
|
block.Worker = fields[8] |
|
|
|
|
block.candidateKey = v.Member.(string) |
|
|
|
|
result = append(result, &block) |
|
|
|
|
} |
|
|
|
|
@ -1465,6 +1470,8 @@ func convertBlockResults(rows ...*redis.ZSliceCmd) []*BlockData {
|
|
|
|
|
block.RewardString = fields[7] |
|
|
|
|
block.ImmatureReward = fields[7] |
|
|
|
|
block.Login = fields[8] |
|
|
|
|
block.ActualDiff, _ = strconv.ParseInt(fields[9], 10, 64) |
|
|
|
|
block.Worker = fields[10] |
|
|
|
|
block.immatureKey = v.Member.(string) |
|
|
|
|
result = append(result, &block) |
|
|
|
|
} |
|
|
|
|
|