[MERGE] Development
This commit is contained in:
commit
105d772a21
4
.gitignore
vendored
4
.gitignore
vendored
@ -18,6 +18,10 @@
|
|||||||
/include/config/global.inc.scrypt.php
|
/include/config/global.inc.scrypt.php
|
||||||
/include/config/global.inc.sha.php
|
/include/config/global.inc.sha.php
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
/scripts/test.php
|
||||||
|
/cronjobs/test.php
|
||||||
|
|
||||||
# IDE Settings
|
# IDE Settings
|
||||||
/.idea/*
|
/.idea/*
|
||||||
.buildpath
|
.buildpath
|
||||||
|
|||||||
@ -27,7 +27,7 @@ require_once('shared.inc.php');
|
|||||||
|
|
||||||
// Header
|
// Header
|
||||||
$log->logInfo('Running statistical queries, errors may just mean no shares were available');
|
$log->logInfo('Running statistical queries, errors may just mean no shares were available');
|
||||||
$strLogMask = "| %-26.26s | %8.8s | %-6.6s |";
|
$strLogMask = "| %-33.33s | %8.8s | %-6.6s |";
|
||||||
$log->logInfo(sprintf($strLogMask, 'Method', 'Runtime', 'Status'));
|
$log->logInfo(sprintf($strLogMask, 'Method', 'Runtime', 'Status'));
|
||||||
|
|
||||||
// Per user share statistics based on all shares submitted
|
// Per user share statistics based on all shares submitted
|
||||||
@ -37,9 +37,15 @@ $log->logInfo(sprintf($strLogMask, 'getAllUserShares', number_format(microtime(t
|
|||||||
|
|
||||||
// Get all user hashrate statistics for caching
|
// Get all user hashrate statistics for caching
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
$statistics->getAllUserMiningStats() ? $status = 'OK' : $status = 'ERROR';
|
$statistics->fetchAllUserMiningStats() ? $status = 'OK' : $status = 'ERROR';
|
||||||
$log->logInfo(sprintf($strLogMask, 'getAllUserMiningStats', number_format(microtime(true) - $start, 3), $status));
|
$log->logInfo(sprintf($strLogMask, 'fetchAllUserMiningStats', number_format(microtime(true) - $start, 3), $status));
|
||||||
|
|
||||||
|
// Store our statistical data into our `statistics_users` table
|
||||||
|
$start = microtime(true);
|
||||||
|
$statistics->storeAllUserMiningStatsSnapshot($statistics->getAllUserMiningStats()) ? $status = 'OK' : $status = 'ERROR';
|
||||||
|
$log->logInfo(sprintf($strLogMask, 'storeAllUserMiningStatsSnapshot', number_format(microtime(true) - $start, 3), $status));
|
||||||
|
|
||||||
|
// Get stats for pool overview
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
$statistics->getTopContributors('hashes') ? $status = 'OK' : $status = 'ERROR';
|
$statistics->getTopContributors('hashes') ? $status = 'OK' : $status = 'ERROR';
|
||||||
$log->logInfo(sprintf($strLogMask, 'getTopContributors(hashes)', number_format(microtime(true) - $start, 3), $status));
|
$log->logInfo(sprintf($strLogMask, 'getTopContributors(hashes)', number_format(microtime(true) - $start, 3), $status));
|
||||||
|
|||||||
@ -65,7 +65,7 @@ $status = 'OK';
|
|||||||
$message = '';
|
$message = '';
|
||||||
$affected = $share->purgeArchive();
|
$affected = $share->purgeArchive();
|
||||||
if ($affected === false) {
|
if ($affected === false) {
|
||||||
$message = 'Failed to delete notifications: ' . $oToken->getCronError();
|
$message = 'Failed to delete shares: ' . $share->getCronError();
|
||||||
$status = 'ERROR';
|
$status = 'ERROR';
|
||||||
$monitoring->endCronjob($cron_name, 'E0008', 0, false, false);
|
$monitoring->endCronjob($cron_name, 'E0008', 0, false, false);
|
||||||
} else {
|
} else {
|
||||||
@ -73,6 +73,19 @@ if ($affected === false) {
|
|||||||
}
|
}
|
||||||
$log->logInfo(sprintf($strLogMask, 'purgeArchive', $affected, number_format(microtime(true) - $start, 3), $status, $message));
|
$log->logInfo(sprintf($strLogMask, 'purgeArchive', $affected, number_format(microtime(true) - $start, 3), $status, $message));
|
||||||
|
|
||||||
|
// Clenaup shares archive
|
||||||
|
$start = microtime(true);
|
||||||
|
$status = 'OK';
|
||||||
|
$message = '';
|
||||||
|
$affected = $statistics->purgeUserStats($setting->getValue('statistics_graphing_days', 1));
|
||||||
|
if ($affected === false) {
|
||||||
|
$message = 'Failed to delete entries: ' . $statistics->getCronError();
|
||||||
|
$status = 'ERROR';
|
||||||
|
$monitoring->endCronjob($cron_name, 'E0008', 0, false, false);
|
||||||
|
} else {
|
||||||
|
$affected == 0 ? $message = 'No entries deleted' : $message = 'Deleted old entries';
|
||||||
|
}
|
||||||
|
$log->logInfo(sprintf($strLogMask, 'purgeUserStats', $affected, number_format(microtime(true) - $start, 3), $status, $message));
|
||||||
|
|
||||||
// Cron cleanup and monitoring
|
// Cron cleanup and monitoring
|
||||||
require_once('cron_end.inc.php');
|
require_once('cron_end.inc.php');
|
||||||
|
|||||||
@ -9,6 +9,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
|||||||
**/
|
**/
|
||||||
class Statistics extends Base {
|
class Statistics extends Base {
|
||||||
protected $table = 'statistics_shares';
|
protected $table = 'statistics_shares';
|
||||||
|
protected $table_user_stats = 'statistics_users';
|
||||||
private $getcache = true;
|
private $getcache = true;
|
||||||
|
|
||||||
// Disable fetching values from cache
|
// Disable fetching values from cache
|
||||||
@ -18,6 +19,12 @@ class Statistics extends Base {
|
|||||||
public function getGetCache() {
|
public function getGetCache() {
|
||||||
return $this->getcache;
|
return $this->getcache;
|
||||||
}
|
}
|
||||||
|
public function getAllUserMiningStats() {
|
||||||
|
return $this->allUserMiningStats;
|
||||||
|
}
|
||||||
|
public function getUserStatsTableName() {
|
||||||
|
return $this->table_user_stats;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get our first block found
|
* Get our first block found
|
||||||
@ -104,7 +111,7 @@ class Statistics extends Base {
|
|||||||
b.*,
|
b.*,
|
||||||
a.username AS finder,
|
a.username AS finder,
|
||||||
a.is_anonymous AS is_anonymous,
|
a.is_anonymous AS is_anonymous,
|
||||||
ROUND(difficulty * POW(2, 32 - " . $this->coin->getTargetBits() . "), 0), 4) AS estshares
|
ROUND(difficulty * POW(2, 32 - " . $this->coin->getTargetBits() . "), 0) AS estshares
|
||||||
FROM " . $this->block->getTableName() . " AS b
|
FROM " . $this->block->getTableName() . " AS b
|
||||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||||
ON b.account_id = a.id
|
ON b.account_id = a.id
|
||||||
@ -254,12 +261,12 @@ class Statistics extends Base {
|
|||||||
SELECT
|
SELECT
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
SELECT ROUND(COUNT(id) / ?, 2) AS sharerate
|
SELECT ROUND(SUM(difficulty) / ?, 2) AS sharerate
|
||||||
FROM " . $this->share->getTableName() . "
|
FROM " . $this->share->getTableName() . "
|
||||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||||
AND our_result = 'Y'
|
AND our_result = 'Y'
|
||||||
) + (
|
) + (
|
||||||
SELECT ROUND(COUNT(id) / ?, 2) AS sharerate
|
SELECT ROUND(SUM(difficulty) / ?, 2) AS sharerate
|
||||||
FROM " . $this->share->getArchiveTableName() . "
|
FROM " . $this->share->getArchiveTableName() . "
|
||||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||||
AND our_result = 'Y'
|
AND our_result = 'Y'
|
||||||
@ -451,16 +458,19 @@ class Statistics extends Base {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch all user hashrates based on shares and archived shares
|
* Fetch all user hashrates based on shares and archived shares
|
||||||
|
* Store it in cache, also keep a copy of the data internally to
|
||||||
|
* return it for further processing
|
||||||
* @return data array Set of all user stats
|
* @return data array Set of all user stats
|
||||||
**/
|
**/
|
||||||
public function getAllUserMiningStats($interval=180) {
|
public function fetchAllUserMiningStats($interval=180) {
|
||||||
$this->debug->append("STA " . __METHOD__, 4);
|
$this->debug->append("STA " . __METHOD__, 4);
|
||||||
$stmt = $this->mysqli->prepare("
|
$stmt = $this->mysqli->prepare("
|
||||||
SELECT
|
SELECT
|
||||||
a.id AS id,
|
a.id AS id,
|
||||||
a.username AS account,
|
a.username AS account,
|
||||||
|
COUNT(DISTINCT t1.username) AS workers,
|
||||||
IFNULL(SUM(t1.difficulty), 0) AS shares,
|
IFNULL(SUM(t1.difficulty), 0) AS shares,
|
||||||
ROUND(COUNT(t1.id) / ?, 2) AS sharerate,
|
ROUND(SUM(t1.difficulty) / ?, 2) AS sharerate,
|
||||||
IFNULL(AVG(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS avgsharediff
|
IFNULL(AVG(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS avgsharediff
|
||||||
FROM (
|
FROM (
|
||||||
SELECT
|
SELECT
|
||||||
@ -489,12 +499,45 @@ class Statistics extends Base {
|
|||||||
$aData['data'][$row['id']] = $row;
|
$aData['data'][$row['id']] = $row;
|
||||||
$aData['data'][$row['id']]['hashrate'] = $this->coin->calcHashrate($row['shares'], $interval);
|
$aData['data'][$row['id']]['hashrate'] = $this->coin->calcHashrate($row['shares'], $interval);
|
||||||
}
|
}
|
||||||
|
$this->allUserMiningStats = $aData;
|
||||||
return $this->memcache->setStaticCache(STATISTICS_ALL_USER_HASHRATES, $aData, 600);
|
return $this->memcache->setStaticCache(STATISTICS_ALL_USER_HASHRATES, $aData, 600);
|
||||||
} else {
|
} else {
|
||||||
return $this->sqlError();
|
return $this->sqlError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store our gathered data into our statistic table for users
|
||||||
|
* @param aData array Data created by fetchAllUserMiningStats
|
||||||
|
* @return bool true or false
|
||||||
|
**/
|
||||||
|
public function storeAllUserMiningStatsSnapshot($aData) {
|
||||||
|
$this->debug->append("STA " . __METHOD__, 4);
|
||||||
|
if (!isset($aData['data'])) return false;
|
||||||
|
// initilize
|
||||||
|
$timestamp = time(); // Store all entries with the same timestamp to reduce cardinality
|
||||||
|
$ok = 0;
|
||||||
|
$failed = 0;
|
||||||
|
foreach ($aData['data'] as $key => $aUserData) {
|
||||||
|
$stmt = $this->mysqli->prepare("
|
||||||
|
INSERT INTO " . $this->getUserStatsTableName() . "
|
||||||
|
( account_id, hashrate, workers, sharerate, timestamp ) VALUES ( ?, ?, ?, ?, ?)");
|
||||||
|
if ($this->checkStmt($stmt) && $stmt->bind_param("ididi", $aUserData['id'], $aUserData['hashrate'], $aUserData['workers'], $aUserData['sharerate'], $timestamp) && $stmt->execute() ) {
|
||||||
|
$ok++;
|
||||||
|
} else {
|
||||||
|
$failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array('ok' => $ok, 'failed' => $failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch unpaid PPS shares for an account
|
||||||
|
* @param username string Username
|
||||||
|
* @param account_id int User ID
|
||||||
|
* @param last_paid_pps_id int Last paid out share by pps_payout cron
|
||||||
|
* @return data int Sum of unpaid diff1 shares
|
||||||
|
**/
|
||||||
public function getUserUnpaidPPSShares($username, $account_id=NULL, $last_paid_pps_id) {
|
public function getUserUnpaidPPSShares($username, $account_id=NULL, $last_paid_pps_id) {
|
||||||
$this->debug->append("STA " . __METHOD__, 4);
|
$this->debug->append("STA " . __METHOD__, 4);
|
||||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||||
@ -515,7 +558,7 @@ class Statistics extends Base {
|
|||||||
* Get Shares per x interval by user
|
* Get Shares per x interval by user
|
||||||
* @param username string username
|
* @param username string username
|
||||||
* @param $account_id int account id
|
* @param $account_id int account id
|
||||||
* @return data integer Current Sharerate in shares/s
|
* @return data integer Current Sharerate in diff1 shares/s
|
||||||
**/
|
**/
|
||||||
public function getUserMiningStats($username, $account_id=NULL, $interval=180) {
|
public function getUserMiningStats($username, $account_id=NULL, $interval=180) {
|
||||||
$this->debug->append("STA " . __METHOD__, 4);
|
$this->debug->append("STA " . __METHOD__, 4);
|
||||||
@ -532,7 +575,7 @@ 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,
|
IFNULL(SUM(difficulty) / ?, 0) AS sharerate,
|
||||||
IFNULL(SUM(difficulty), 0) AS shares,
|
IFNULL(SUM(difficulty), 0) AS shares,
|
||||||
IFNULL(AVG(difficulty), 0) AS avgsharediff
|
IFNULL(AVG(difficulty), 0) AS avgsharediff
|
||||||
FROM (
|
FROM (
|
||||||
@ -655,78 +698,24 @@ class Statistics extends Base {
|
|||||||
* @param $account_id int account id
|
* @param $account_id int account id
|
||||||
* @return data array NOT FINISHED YET
|
* @return data array NOT FINISHED YET
|
||||||
**/
|
**/
|
||||||
public function getHourlyHashrateByAccount($username, $account_id=NULL) {
|
public function getHourlyMiningStatsByAccount($account_id, $format='array', $days = 1) {
|
||||||
$this->debug->append("STA " . __METHOD__, 4);
|
$this->debug->append("STA " . __METHOD__, 4);
|
||||||
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
|
||||||
id,
|
timestamp,
|
||||||
IFNULL(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares,
|
FROM_UNIXTIME(timestamp, '%Y-%m-%d %H:%i') AS time,
|
||||||
HOUR(time) AS hour
|
AVG(hashrate) AS hashrate,
|
||||||
FROM " . $this->share->getTableName() . "
|
AVG(workers) AS workers,
|
||||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
AVG(sharerate) AS sharerate
|
||||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
FROM " . $this->getUserStatsTableName() . "
|
||||||
AND our_result = 'Y'
|
WHERE FROM_UNIXTIME(timestamp) >= DATE_SUB(NOW(), INTERVAL $days DAY)
|
||||||
AND username LIKE ?
|
AND account_id = ?
|
||||||
GROUP BY HOUR(time)
|
GROUP BY DAY(FROM_UNIXTIME(timestamp)), HOUR(FROM_UNIXTIME(timestamp))");
|
||||||
UNION
|
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||||
SELECT
|
$aData = $result->fetch_all(MYSQLI_ASSOC);
|
||||||
share_id,
|
if ($format == 'json') $aData = json_encode($aData);
|
||||||
IFNULL(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares,
|
return $this->memcache->setCache(__FUNCTION__ . $account_id . $format, $aData);
|
||||||
HOUR(time) AS hour
|
|
||||||
FROM " . $this->share->getArchiveTableName() . "
|
|
||||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
|
||||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
|
||||||
AND our_result = 'Y'
|
|
||||||
AND username LIKE ?
|
|
||||||
GROUP BY HOUR(time)");
|
|
||||||
$username = $username . ".%";
|
|
||||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ss', $username, $username) && $stmt->execute() && $result = $stmt->get_result()) {
|
|
||||||
$iStartHour = date('G');
|
|
||||||
// Initilize array
|
|
||||||
for ($i = 0; $i < 24; $i++) $aData[($iStartHour + $i) % 24] = 0;
|
|
||||||
// Fill data
|
|
||||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += (int) $this->coin->calcHashrate($row['shares'], 3600);
|
|
||||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData);
|
|
||||||
}
|
|
||||||
return $this->sqlError();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get Hourly hashrate for the pool
|
|
||||||
* @param none
|
|
||||||
* @return data array NOT FINISHED YET
|
|
||||||
**/
|
|
||||||
public function getHourlyHashrateByPool() {
|
|
||||||
$this->debug->append("STA " . __METHOD__, 4);
|
|
||||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__)) return $data;
|
|
||||||
$stmt = $this->mysqli->prepare("
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
IFNULL(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS shares,
|
|
||||||
HOUR(s.time) AS hour
|
|
||||||
FROM " . $this->share->getTableName() . " AS s
|
|
||||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
|
||||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
|
||||||
AND our_result = 'Y'
|
|
||||||
GROUP BY HOUR(time)
|
|
||||||
UNION
|
|
||||||
SELECT
|
|
||||||
share_id,
|
|
||||||
IFNULL(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS shares,
|
|
||||||
HOUR(s.time) AS hour
|
|
||||||
FROM " . $this->share->getArchiveTableName() . " AS s
|
|
||||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
|
||||||
AND time >= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60)) - INTERVAL 24 HOUR
|
|
||||||
AND our_result = 'Y'
|
|
||||||
GROUP BY HOUR(time)");
|
|
||||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
|
|
||||||
$iStartHour = date('G');
|
|
||||||
// Initilize array
|
|
||||||
for ($i = 0; $i < 24; $i++) $aData[($iStartHour + $i) % 24] = 0;
|
|
||||||
// Fill data
|
|
||||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += (int) $this->coin->calcHashrate($row['shares'], 3600);
|
|
||||||
return $this->memcache->setCache(__FUNCTION__, $aData);
|
|
||||||
}
|
}
|
||||||
return $this->sqlError();
|
return $this->sqlError();
|
||||||
}
|
}
|
||||||
@ -914,6 +903,17 @@ class Statistics extends Base {
|
|||||||
return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->total);
|
return $this->memcache->setCache(__FUNCTION__, $result->fetch_object()->total);
|
||||||
return $this->sqlError();
|
return $this->sqlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purge older entries from our statistics_users table
|
||||||
|
**/
|
||||||
|
public function purgeUserStats($days = 1) {
|
||||||
|
// Fallbacks if unset
|
||||||
|
$stmt = $this->mysqli->prepare("DELETE FROM " . $this->getUserStatsTableName() . " WHERE FROM_UNIXTIME(timestamp) <= DATE_SUB(NOW(), INTERVAL ? DAY)");
|
||||||
|
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $days) && $stmt->execute())
|
||||||
|
return $stmt->affected_rows;
|
||||||
|
return $this->sqlError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$statistics = new Statistics();
|
$statistics = new Statistics();
|
||||||
|
|||||||
@ -496,7 +496,7 @@ class User extends Base {
|
|||||||
$this->setErrorMessage('Donation above allowed 100% limit');
|
$this->setErrorMessage('Donation above allowed 100% limit');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
if ($email != 'hidden' && $email != NULL && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
$this->setErrorMessage('Invalid email address');
|
$this->setErrorMessage('Invalid email address');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -540,6 +540,9 @@ class User extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we hide our email or it's not set, fetch current one to update
|
||||||
|
if ($email == 'hidden' || $email == NULL)
|
||||||
|
$email = $this->getUserEmailById($userID);
|
||||||
// We passed all validation checks so update the account
|
// We passed all validation checks so update the account
|
||||||
$stmt = $this->mysqli->prepare("UPDATE $this->table SET ap_threshold = ?, donate_percent = ?, email = ?, timezone = ?, is_anonymous = ? WHERE id = ?");
|
$stmt = $this->mysqli->prepare("UPDATE $this->table SET ap_threshold = ?, donate_percent = ?, email = ?, timezone = ?, is_anonymous = ? WHERE id = ?");
|
||||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ddssii', $threshold, $donate, $email, $timezone, $is_anonymous, $userID) && $stmt->execute()) {
|
if ($this->checkStmt($stmt) && $stmt->bind_param('ddssii', $threshold, $donate, $email, $timezone, $is_anonymous, $userID) && $stmt->execute()) {
|
||||||
|
|||||||
@ -160,6 +160,13 @@ $aSettings['statistics'][] = array(
|
|||||||
'name' => 'statistics_ajax_data_interval', 'value' => $setting->getValue('statistics_ajax_data_interval'),
|
'name' => 'statistics_ajax_data_interval', 'value' => $setting->getValue('statistics_ajax_data_interval'),
|
||||||
'tooltip' => 'Time in minutes, interval for hashrate and sharerate calculations. Higher intervals allow for better accuracy at a higer server load.'
|
'tooltip' => 'Time in minutes, interval for hashrate and sharerate calculations. Higher intervals allow for better accuracy at a higer server load.'
|
||||||
);
|
);
|
||||||
|
$aSettings['statistics'][] = array(
|
||||||
|
'display' => 'Graphing Days', 'type' => 'text',
|
||||||
|
'size' => 25,
|
||||||
|
'default' => 1,
|
||||||
|
'name' => 'statistics_graphing_days', 'value' => $setting->getValue('statistics_graphing_days'),
|
||||||
|
'tooltip' => 'How many days to graph out on the statistics -> graphs page.'
|
||||||
|
);
|
||||||
$aSettings['statistics'][] = array(
|
$aSettings['statistics'][] = array(
|
||||||
'display' => 'Block Statistics Count', 'type' => 'text',
|
'display' => 'Block Statistics Count', 'type' => 'text',
|
||||||
'size' => 25,
|
'size' => 25,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
|||||||
$api->isActive();
|
$api->isActive();
|
||||||
|
|
||||||
// Check for valid API key
|
// Check for valid API key
|
||||||
$id = $user->checkApiKey($_REQUEST['api_key']);
|
$id = $user->checkApiKey(@$_REQUEST['api_key']);
|
||||||
|
|
||||||
header('HTTP/1.1 400 Bad Request');
|
header('HTTP/1.1 400 Bad Request');
|
||||||
die('400 Bad Request');
|
die('400 Bad Request');
|
||||||
|
|||||||
@ -53,6 +53,7 @@ if ($user->isAuthenticated()) {
|
|||||||
$smarty->assign('BLOCKSFOUND', $aLastBlocks);
|
$smarty->assign('BLOCKSFOUND', $aLastBlocks);
|
||||||
$smarty->assign('DISABLED_DASHBOARD', $setting->getValue('disable_dashboard'));
|
$smarty->assign('DISABLED_DASHBOARD', $setting->getValue('disable_dashboard'));
|
||||||
$smarty->assign('DISABLED_DASHBOARD_API', $setting->getValue('disable_dashboard_api'));
|
$smarty->assign('DISABLED_DASHBOARD_API', $setting->getValue('disable_dashboard_api'));
|
||||||
|
$smarty->assign('DISABLED_API', $setting->getValue('disable_api'));
|
||||||
$smarty->assign('ESTIMATES', array('shares' => $iEstShares, 'percent' => $dEstPercent));
|
$smarty->assign('ESTIMATES', array('shares' => $iEstShares, 'percent' => $dEstPercent));
|
||||||
$smarty->assign('NETWORK', array('difficulty' => $dDifficulty, 'block' => $iBlock, 'EstNextDifficulty' => $dEstNextDifficulty, 'EstTimePerBlock' => $dExpectedTimePerBlock, 'BlocksUntilDiffChange' => $iBlocksUntilDiffChange));
|
$smarty->assign('NETWORK', array('difficulty' => $dDifficulty, 'block' => $iBlock, 'EstNextDifficulty' => $dEstNextDifficulty, 'EstTimePerBlock' => $dExpectedTimePerBlock, 'BlocksUntilDiffChange' => $iBlocksUntilDiffChange));
|
||||||
$smarty->assign('INTERVAL', $interval / 60);
|
$smarty->assign('INTERVAL', $interval / 60);
|
||||||
|
|||||||
@ -4,11 +4,9 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
|||||||
if (!$smarty->isCached('master.tpl', $smarty_cache_key)) {
|
if (!$smarty->isCached('master.tpl', $smarty_cache_key)) {
|
||||||
$debug->append('No cached version available, fetching from backend', 3);
|
$debug->append('No cached version available, fetching from backend', 3);
|
||||||
if ($user->isAuthenticated()) {
|
if ($user->isAuthenticated()) {
|
||||||
$aHourlyHashRates = $statistics->getHourlyHashrateByAccount($_SESSION['USERDATA']['username'], $_SESSION['USERDATA']['id']);
|
$aHourlyMiningStats = $statistics->getHourlyMiningStatsByAccount($_SESSION['USERDATA']['id'], 'json', $setting->getValue('statistics_graphing_days', 1));
|
||||||
$aPoolHourlyHashRates = $statistics->getHourlyHashrateByPool();
|
|
||||||
}
|
}
|
||||||
$smarty->assign("YOURHASHRATES", @$aHourlyHashRates);
|
$smarty->assign('YOURMININGSTATS', @$aHourlyMiningStats);
|
||||||
$smarty->assign("POOLHASHRATES", @$aPoolHourlyHashRates);
|
|
||||||
} else {
|
} else {
|
||||||
$debug->append('Using cached page', 3);
|
$debug->append('Using cached page', 3);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||||
|
|
||||||
define('MPOS_VERSION', '0.0.4');
|
define('MPOS_VERSION', '0.0.4');
|
||||||
define('DB_VERSION', '0.0.13');
|
define('DB_VERSION', '0.0.14');
|
||||||
define('CONFIG_VERSION', '0.0.8');
|
define('CONFIG_VERSION', '0.0.8');
|
||||||
define('HASH_VERSION', 1);
|
define('HASH_VERSION', 1);
|
||||||
|
|
||||||
|
|||||||
@ -144,7 +144,7 @@ CREATE TABLE IF NOT EXISTS `settings` (
|
|||||||
UNIQUE KEY `setting` (`name`)
|
UNIQUE KEY `setting` (`name`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
INSERT INTO `settings` (`name`, `value`) VALUES ('DB_VERSION', '0.0.13');
|
INSERT INTO `settings` (`name`, `value`) VALUES ('DB_VERSION', '0.0.14');
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `shares` (
|
CREATE TABLE IF NOT EXISTS `shares` (
|
||||||
`id` bigint(30) NOT NULL AUTO_INCREMENT,
|
`id` bigint(30) NOT NULL AUTO_INCREMENT,
|
||||||
@ -239,12 +239,15 @@ CREATE TABLE IF NOT EXISTS `transactions` (
|
|||||||
KEY `account_id_archived` (`account_id`,`archived`)
|
KEY `account_id_archived` (`account_id`,`archived`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `templates` (
|
CREATE TABLE `statistics_users` (
|
||||||
`template` varchar(255) NOT NULL,
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
`active` tinyint(1) NOT NULL DEFAULT 0,
|
`account_id` int(11) NOT NULL,
|
||||||
`content` mediumtext,
|
`hashrate` int(11) NOT NULL,
|
||||||
`modified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`workers` int(11) NOT NULL,
|
||||||
PRIMARY KEY (`template`)
|
`sharerate` float NOT NULL,
|
||||||
|
`timestamp` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `account_id_timestamp` (`account_id`,`timestamp`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>E-Mail</label>
|
<label>E-Mail</label>
|
||||||
{nocache}<input class="form-control" type="text" name="email" value="{$GLOBAL.userdata.email|escape}" size="20" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/>{/nocache}
|
{nocache}<input class="form-control" type="text" name="email" value="hidden" size="20" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/>{/nocache}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Timezone</label>
|
<label>Timezone</label>
|
||||||
|
|||||||
@ -16,7 +16,9 @@
|
|||||||
{include file="dashboard/overview/default.tpl"}
|
{include file="dashboard/overview/default.tpl"}
|
||||||
{include file="dashboard/round_statistics/$PAYOUT_SYSTEM/default.tpl"}
|
{include file="dashboard/round_statistics/$PAYOUT_SYSTEM/default.tpl"}
|
||||||
{include file="dashboard/account_data/default.tpl"}
|
{include file="dashboard/account_data/default.tpl"}
|
||||||
|
{if !$DISABLED_API}
|
||||||
{include file="dashboard/worker_information/default.tpl"}
|
{include file="dashboard/worker_information/default.tpl"}
|
||||||
|
{/if}
|
||||||
{include file="dashboard/blocks/default.tpl"}
|
{include file="dashboard/blocks/default.tpl"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -178,7 +178,7 @@ $(document).ready(function(){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (blocks[0].height > lastBlock) {
|
if (blocks[0].height > lastBlock) {
|
||||||
if(canCreateSoundJS) {
|
if(canCreateSoundJS) {
|
||||||
createjs.Sound.play('ding');
|
createjs.Sound.play('ding');
|
||||||
}
|
}
|
||||||
lastBlock = blocks[0].height;
|
lastBlock = blocks[0].height;
|
||||||
@ -234,6 +234,7 @@ $(document).ready(function(){
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
{/literal}{if !$DISABLED_API}{literal}
|
||||||
// Worker process to update active workers in the account details table
|
// Worker process to update active workers in the account details table
|
||||||
(function worker2() {
|
(function worker2() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -250,7 +251,9 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
{/literal}{/if}{literal}
|
||||||
|
|
||||||
|
{/literal}{if !$DISABLED_API}{literal}
|
||||||
// Worker process to update user account balances
|
// Worker process to update user account balances
|
||||||
// Our worker process to keep worker information updated
|
// Our worker process to keep worker information updated
|
||||||
(function worker3() {
|
(function worker3() {
|
||||||
@ -265,7 +268,8 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
{/literal}{/if}{literal}
|
||||||
|
|
||||||
// Mute Button
|
// Mute Button
|
||||||
$('#muteButton').click(function(){
|
$('#muteButton').click(function(){
|
||||||
if(muteFlag == 2) {
|
if(muteFlag == 2) {
|
||||||
@ -280,8 +284,6 @@ $(document).ready(function(){
|
|||||||
$(this).find($(".fa")).removeClass('fa-volume-up').addClass('fa-volume-off');
|
$(this).find($(".fa")).removeClass('fa-volume-up').addClass('fa-volume-off');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
{/literal}
|
{/literal}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
{if is_array($YOURHASHRATES) && is_array($POOLHASHRATES)}
|
|
||||||
<div class="tab-pane fade in" id="both">
|
|
||||||
<div class="panel-heading">
|
|
||||||
Your vs. Pool Hashrate
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div id="both-area-chart"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
@ -1,95 +1,48 @@
|
|||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
var hashChart = Morris.Line({
|
||||||
|
element: 'hashrate-area-chart',
|
||||||
|
data: {$YOURMININGSTATS},
|
||||||
|
xkey: 'time',
|
||||||
|
ykeys: ['hashrate'],
|
||||||
|
labels: ['Hashrate'],
|
||||||
|
pointSize: 1,
|
||||||
|
hideHover: 'auto',
|
||||||
|
resize: true,
|
||||||
|
fillOpacity: 1.00,
|
||||||
|
lineColors: ['#24A665'],
|
||||||
|
pointFillColors: ['#24A665'],
|
||||||
|
pointStrokeColors: ['#24A665']
|
||||||
|
});
|
||||||
|
|
||||||
// needed for automatic activation of first tab
|
var workersChart = Morris.Line({
|
||||||
$(function () {
|
element: 'workers-area-chart',
|
||||||
$('#hashrategraph a:first').tab('show')
|
data: {$YOURMININGSTATS},
|
||||||
})
|
xkey: 'time',
|
||||||
|
ykeys: ['workers'],
|
||||||
|
labels: ['Workers'],
|
||||||
|
pointSize: 1,
|
||||||
|
hideHover: 'auto',
|
||||||
|
resize: true,
|
||||||
|
fillOpacity: 1.00,
|
||||||
|
lineColors: ['#24A665'],
|
||||||
|
pointFillColors: ['#24A665'],
|
||||||
|
pointStrokeColors: ['#24A665']
|
||||||
|
});
|
||||||
|
|
||||||
// You can't draw here chart directly, because it's on hidden tab, instead let's do the workaround
|
var shareCharts= Morris.Line({
|
||||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
element: 'sharerate-area-chart',
|
||||||
// this ain't pretty, but you should get the idea
|
data: {$YOURMININGSTATS},
|
||||||
if ($(e.target).attr('href') == '#pool' && $('#pool-area-chart').html().length == 0) {
|
xkey: 'time',
|
||||||
Morris.Area({
|
ykeys: ['sharerate'],
|
||||||
element: 'pool-area-chart',
|
labels: ['Sharerate'],
|
||||||
data: [
|
pointSize: 1,
|
||||||
{foreach $POOLHASHRATES as $hour=>$hashrate}
|
hideHover: 'auto',
|
||||||
{
|
resize: true,
|
||||||
period: '{$hour|default:"0"}:00',
|
fillOpacity: 1.00,
|
||||||
Pool: '{$hashrate|default:"0"}',
|
lineColors: ['#24A665'],
|
||||||
},
|
pointFillColors: ['#24A665'],
|
||||||
{/foreach}
|
pointStrokeColors: ['#24A665']
|
||||||
],
|
|
||||||
parseTime: false,
|
|
||||||
behaveLikeLine: true,
|
|
||||||
xkey: 'period',
|
|
||||||
ykeys: ['Pool'],
|
|
||||||
labels: ['Hashrate'],
|
|
||||||
pointSize: 2,
|
|
||||||
hideHover: 'auto',
|
|
||||||
lineColors: ['#0b62a4'],
|
|
||||||
pointFillColors: ['#FFFFFF'],
|
|
||||||
resize: true,
|
|
||||||
fillOpacity: 1.00,
|
|
||||||
postUnits: ' KH/s'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($(e.target).attr('href') == '#mine' && $('#mine-area-chart').html().length == 0) {
|
|
||||||
Morris.Area({
|
|
||||||
element: 'mine-area-chart',
|
|
||||||
data: [
|
|
||||||
{foreach $YOURHASHRATES as $yourhour=>$yourhashrate}
|
|
||||||
{
|
|
||||||
period: '{$yourhour|default:"0"}:00',
|
|
||||||
Mine: '{$yourhashrate|default:"0"}',
|
|
||||||
},
|
|
||||||
{/foreach}
|
|
||||||
],
|
|
||||||
parseTime: false,
|
|
||||||
behaveLikeLine: true,
|
|
||||||
xkey: 'period',
|
|
||||||
ykeys: ['Mine'],
|
|
||||||
labels: ['Hashrate'],
|
|
||||||
pointSize: 2,
|
|
||||||
hideHover: 'auto',
|
|
||||||
lineColors: ['#24A665'],
|
|
||||||
pointFillColors: ['#FFFFFF'],
|
|
||||||
resize: true,
|
|
||||||
fillOpacity: 1.00,
|
|
||||||
postUnits: ' KH/s'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($(e.target).attr('href') == '#both' && $('#both-area-chart').html().length == 0) {
|
|
||||||
Morris.Area({
|
|
||||||
element: 'both-area-chart',
|
|
||||||
data: [
|
|
||||||
{foreach $YOURHASHRATES as $yourhour=>$yourhashrate}
|
|
||||||
{
|
|
||||||
period: '{$yourhour|default:"0"}:00',
|
|
||||||
Mine: '{$yourhashrate|default:"0"}',
|
|
||||||
{foreach $POOLHASHRATES as $poolhour=>$poolhashrate}
|
|
||||||
{if $yourhour eq $poolhour}
|
|
||||||
Pool: '{$poolhashrate|default:"0"}',
|
|
||||||
{/if}
|
|
||||||
{/foreach}
|
|
||||||
},
|
|
||||||
{/foreach}
|
|
||||||
],
|
|
||||||
parseTime: false,
|
|
||||||
behaveLikeLine: true,
|
|
||||||
xkey: 'period',
|
|
||||||
ykeys: ['Mine', 'Pool'],
|
|
||||||
labels: ['Your Hashrate', 'Pool Hashrate'],
|
|
||||||
pointSize: 2,
|
|
||||||
hideHover: 'auto',
|
|
||||||
resize: true,
|
|
||||||
fillOpacity: 0.1,
|
|
||||||
postUnits: ' KH/s'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -98,19 +51,45 @@ $(function () {
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<div class="panel panel-info">
|
<div class="panel panel-info">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-signal fa-fw"></i> Stats
|
<i class="fa fa-signal fa-fw"></i> Average Hashrate past 24h
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ul class="nav nav-pills" id="hashrategraph">
|
<div id="hashrate-area-chart"></div>
|
||||||
<li><a href="#mine" data-toggle="tab">Mine</a></li>
|
</div>
|
||||||
<li><a href="#pool" data-toggle="tab">Pool</a></li>
|
<div class="panel-footer">
|
||||||
<li><a href="#both" data-toggle="tab">Both</a></li>
|
Your average hashrate per hour, updated every backend cron run.
|
||||||
</ul>
|
</div>
|
||||||
<div class="tab-content">
|
</div>
|
||||||
{include file="{$smarty.request.page|escape}/{$smarty.request.action|escape}/mine.tpl"}
|
</div>
|
||||||
{include file="{$smarty.request.page|escape}/{$smarty.request.action|escape}/pool.tpl"}
|
</div>
|
||||||
{include file="{$smarty.request.page|escape}/{$smarty.request.action|escape}/both.tpl"}
|
|
||||||
</div>
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="panel panel-info">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<i class="fa fa-signal fa-fw"></i> Average Workers past 24h
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div id="workers-area-chart"></div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">
|
||||||
|
Your average active workers per hour, updated every backend cron run.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="panel panel-info">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<i class="fa fa-signal fa-fw"></i> Average Sharerate past 24h
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div id="sharerate-area-chart"></div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">
|
||||||
|
Your share rate per hour, updated every backend cron run.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
{if is_array($YOURHASHRATES)}
|
|
||||||
<div class="tab-pane fade in" id="mine">
|
|
||||||
<div class="panel-heading">
|
|
||||||
Your Hashrate
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div id="mine-area-chart"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
{if is_array($POOLHASHRATES)}
|
|
||||||
<div class="tab-pane fade in" id="pool">
|
|
||||||
<div class="panel-heading">
|
|
||||||
Pool Hashrate
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div id="pool-area-chart"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
function run_0013() {
|
function run_0013() {
|
||||||
// Ugly but haven't found a better way
|
// Ugly but haven't found a better way
|
||||||
global $setting, $config, $user, $mysqli, $transaction;
|
global $setting, $config, $user, $mysqli;
|
||||||
|
|
||||||
// Version information
|
// Version information
|
||||||
$db_version_old = '0.0.12'; // What version do we expect
|
$db_version_old = '0.0.12'; // What version do we expect
|
||||||
@ -9,8 +9,17 @@ function run_0013() {
|
|||||||
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
|
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
|
||||||
|
|
||||||
// Upgrade specific variables
|
// Upgrade specific variables
|
||||||
$aSql[] = "ALTER TABLE " . $transaction->getTableName() . " CHANGE `amount` `amount` DECIMAL(50,30) NULL DEFAULT '0'";
|
$aSql[] = "CREATE TABLE `statistics_users` (
|
||||||
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.13' WHERE name = 'DB_VERSION'";
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`account_id` int(11) NOT NULL,
|
||||||
|
`hashrate` int(11) NOT NULL,
|
||||||
|
`workers` int(11) NOT NULL,
|
||||||
|
`sharerate` float NOT NULL,
|
||||||
|
`timestamp` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `account_id_timestamp` (`account_id`,`timestamp`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||||
|
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.13' WHERE name = 'DB_VERSION'";
|
||||||
|
|
||||||
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
|
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
|
||||||
// Run the upgrade
|
// Run the upgrade
|
||||||
|
|||||||
30
upgrade/definitions/0.0.13_to_0.0.14.inc.php
Normal file
30
upgrade/definitions/0.0.13_to_0.0.14.inc.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
function run_0014() {
|
||||||
|
// Ugly but haven't found a better way
|
||||||
|
global $setting, $config, $user, $mysqli, $transaction;
|
||||||
|
|
||||||
|
// Version information
|
||||||
|
$db_version_old = '0.0.13'; // What version do we expect
|
||||||
|
$db_version_new = '0.0.14'; // What is the new version we wish to upgrade to
|
||||||
|
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
|
||||||
|
|
||||||
|
// Upgrade specific variables
|
||||||
|
$aSql[] = "ALTER TABLE " . $transaction->getTableName() . " CHANGE `amount` `amount` DECIMAL(50,30) NULL DEFAULT '0'";
|
||||||
|
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.13' WHERE name = 'DB_VERSION'";
|
||||||
|
|
||||||
|
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
|
||||||
|
// Run the upgrade
|
||||||
|
echo '- Starting database migration to version ' . $db_version_new . PHP_EOL;
|
||||||
|
foreach ($aSql as $sql) {
|
||||||
|
echo '- Preparing: ' . $sql . PHP_EOL;
|
||||||
|
$stmt = $mysqli->prepare($sql);
|
||||||
|
if ($stmt && $stmt->execute()) {
|
||||||
|
echo '- success' . PHP_EOL;
|
||||||
|
} else {
|
||||||
|
echo '- failed: ' . $mysqli->error . PHP_EOL;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
Loading…
Reference in New Issue
Block a user