[FIX] Hashrate increase on round ends

This should address issues with pools finishing very long rounds where
hashrate statistics suddenly dramatically increased. This was caused due
to both shares and archived shares being added before they they were
deleted from shares.

* adds the proper way to calculate user based hash- and sharerates.
* replaces `UNION ALL` with `UNION`

Fixes #642 once merged.
This commit is contained in:
Sebastian Grewe 2013-11-23 22:17:10 +01:00
parent c418e98aca
commit 1e7e92b5fe

View File

@ -434,7 +434,7 @@ class Statistics extends Base {
} }
/** /**
* Same as getUserShares for Hashrate * Fetch total user hashrate based on shares and archived shares
* @param account_id integer User ID * @param account_id integer User ID
* @return data integer Current Hashrate in khash/s * @return data integer Current Hashrate in khash/s
**/ **/
@ -443,25 +443,29 @@ class Statistics extends Base {
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data; if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
( IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0), 0) AS hashrate
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate FROM (
FROM " . $this->share->getTableName() . " AS s, SELECT
" . $this->user->getTableName() . " AS u s.id, s.our_result, IF(s.difficulty = 0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty) AS difficulty
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 ) FROM
AND our_result = 'Y' shares AS s,
AND s.time > DATE_SUB(now(), INTERVAL ? SECOND) accounts AS u
AND u.id = ? WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
) + ( AND s.time > DATE_SUB(now(), INTERVAL ? SECOND)
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate AND s.our_result = 'Y'
FROM " . $this->share->getArchiveTableName() . " AS s, AND u.id = ?
" . $this->user->getTableName() . " AS u UNION
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 ) SELECT
AND our_result = 'Y' s.share_id, s.our_result, IF(s.difficulty = 0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty) AS difficulty
AND s.time > DATE_SUB(now(), INTERVAL ? SECOND) FROM
AND u.id = ? shares_archive AS s,
) AS hashrate accounts AS u
FROM DUAL"); WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
if ($this->checkStmt($stmt) && $stmt->bind_param("iiiiii", $interval, $interval, $account_id, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() ) AND s.time > DATE_SUB(now(), INTERVAL ? SECOND)
AND s.our_result = 'Y'
AND u.id = ?
) AS temp");
if ($this->checkStmt($stmt) && $stmt->bind_param("iiiii", $interval, $interval, $account_id, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->hashrate); return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->hashrate);
return $this->sqlError(); return $this->sqlError();
} }
@ -516,27 +520,29 @@ class Statistics extends Base {
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data; if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
( IFNULL(COUNT(*) / ?, 0) AS sharerate
( FROM (
SELECT COUNT(s.id) / ? AS sharerate SELECT
FROM " . $this->share->getTableName() . " AS s, s.id
" . $this->user->getTableName() . " AS u FROM
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 ) shares AS s,
AND our_result = 'Y' accounts AS u
AND s.time > DATE_SUB(now(), INTERVAL ? SECOND) WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND u.id = ? AND s.time > DATE_SUB(now(), INTERVAL ? SECOND)
) + ( AND s.our_result = 'Y'
SELECT COUNT(s.id) / ? AS sharerate AND u.id = ?
FROM " . $this->share->getArchiveTableName() . " AS s, UNION
" . $this->user->getTableName() . " AS u SELECT
WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 ) s.share_id
AND our_result = 'Y' FROM
AND s.time > DATE_SUB(now(), INTERVAL ? SECOND) shares_archive AS s,
AND u.id = ? accounts AS u
) WHERE u.username = SUBSTRING_INDEX( s.username, '.', 1 )
) AS sharerate AND s.time > DATE_SUB(now(), INTERVAL ? SECOND)
FROM DUAL"); AND s.our_result = 'Y'
if ($this->checkStmt($stmt) && $stmt->bind_param("iiiiii", $interval, $interval, $account_id, $interval, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() ) AND u.id = ?
) AS temp");
if ($this->checkStmt($stmt) && $stmt->bind_param("iiiii", $interval, $interval, $account_id, $interval, $account_id) && $stmt->execute() && $result = $stmt->get_result() )
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->sharerate); return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_object()->sharerate);
return $this->sqlError(); return $this->sqlError();
} }
@ -621,9 +627,9 @@ class Statistics extends Base {
IFNULL(ROUND(SUM(t1.difficulty) * POW(2, " . $this->config['target_bits'] . ") / 600 / 1000, 2), 0) AS hashrate IFNULL(ROUND(SUM(t1.difficulty) * POW(2, " . $this->config['target_bits'] . ") / 600 / 1000, 2), 0) AS hashrate
FROM FROM
( (
SELECT IFNULL(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0) AS difficulty, username FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y' SELECT id, IFNULL(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0) AS difficulty, username FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y'
UNION ALL UNION
SELECT IFNULL(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0) AS difficulty, username FROM " . $this->share->getArchiveTableName() ." WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y' SELECT share_id, IFNULL(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0) AS difficulty, username FROM " . $this->share->getArchiveTableName() ." WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y'
) AS t1 ) AS t1
LEFT JOIN " . $this->user->getTableName() . " AS a LEFT JOIN " . $this->user->getTableName() . " AS a
ON SUBSTRING_INDEX( t1.username, '.', 1 ) = a.username ON SUBSTRING_INDEX( t1.username, '.', 1 ) = a.username
@ -646,7 +652,8 @@ class Statistics extends Base {
if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data; if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate, id,
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
HOUR(s.time) AS hour HOUR(s.time) AS hour
FROM " . $this->share->getTableName() . " AS s, accounts AS a FROM " . $this->share->getTableName() . " AS s, accounts AS a
WHERE time < NOW() - INTERVAL 1 HOUR WHERE time < NOW() - INTERVAL 1 HOUR
@ -655,8 +662,9 @@ class Statistics extends Base {
AND a.username = SUBSTRING_INDEX( s.username, '.', 1 ) AND a.username = SUBSTRING_INDEX( s.username, '.', 1 )
AND a.id = ? AND a.id = ?
GROUP BY HOUR(time) GROUP BY HOUR(time)
UNION ALL UNION
SELECT SELECT
share_id,
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate, IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
HOUR(s.time) AS hour HOUR(s.time) AS hour
FROM " . $this->share->getArchiveTableName() . " AS s, accounts AS a FROM " . $this->share->getArchiveTableName() . " AS s, accounts AS a
@ -687,6 +695,7 @@ class Statistics extends Base {
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data; if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
$stmt = $this->mysqli->prepare(" $stmt = $this->mysqli->prepare("
SELECT SELECT
id,
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate, IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
HOUR(s.time) AS hour HOUR(s.time) AS hour
FROM " . $this->share->getTableName() . " AS s FROM " . $this->share->getTableName() . " AS s
@ -694,8 +703,9 @@ class Statistics extends Base {
AND time > NOW() - INTERVAL 25 HOUR AND time > NOW() - INTERVAL 25 HOUR
AND our_result = 'Y' AND our_result = 'Y'
GROUP BY HOUR(time) GROUP BY HOUR(time)
UNION ALL UNION
SELECT SELECT
share_id,
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate, IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
HOUR(s.time) AS hour HOUR(s.time) AS hour
FROM " . $this->share->getArchiveTableName() . " AS s FROM " . $this->share->getArchiveTableName() . " AS s